Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Nallo workflow metrics-deliver #4142

Open
wants to merge 7 commits into
base: master
Choose a base branch
from

Conversation

peterpru
Copy link
Member

@peterpru peterpru commented Jan 22, 2025

Description

This PR aims to add the cg workflow metrics-deliver command for nallo, and adds nallo to more config-case pytests.

For sysdev: this is identical to how it is implemented for tomte and the first PR of raredisease.

Added

  • cg workflow nallo metrics-deliver
  • nallo to config-case pytests

Changed

Fixed

How to prepare for test

  • Ssh to relevant server (depending on type of change)
  • Use stage: us
  • Paxa the environment: paxa
  • Install on stage (example for Hasta):
    bash /home/proj/production/servers/resources/hasta.scilifelab.se/update-tool-stage.sh -e S_cg -t cg -b add-nallo-metrics-deliver

How to test

  • cg workflow nallo metrics-deliver trustingchipmunk
  • nano /home/proj/stage/analysis/cases/trustingchipmunk/multiqc/multiqc_data/multiqc_data.json
  • change median coverage in the json file to 14
  • cg workflow nallo metrics-deliver trustingchipmunk

Expected test outcome

  • Check that command succeeds and metrics yaml file is generated.
  • Take a screenshot and attach or copy/paste the output.
image
  • Check that the command show an error with the low coverage set to 14.
  • Check that Trailblazer status is set to failed and shows the failed metric as comment.
image image

Review

  • Tests executed by
  • "Merge and deploy" approved by
    Thanks for filling in who performed the code review and the test!

This version is a

  • MAJOR - when you make incompatible API changes
  • MINOR - when you add functionality in a backwards compatible manner
  • PATCH - when you make backwards compatible bug fixes or documentation/instructions

Implementation Plan

  • Document in ...
  • Deploy this branch on ...
  • Inform to ...

@peterpru peterpru self-assigned this Jan 22, 2025
@fevac
Copy link
Contributor

fevac commented Jan 24, 2025

To avoid those obscure errors due to cases missing in trailblazer I wonder if you could replace the validate_qc_metrics cg/meta/workflow/nf_analysis.py by the following code. It would need to be tested though:

    def _validate_metrics(self, case_id: str) -> None:
        """Perform the actual QC metrics validation."""
        metrics_deliverables_path: Path = self.get_metrics_deliverables_path(case_id=case_id)
        qc_metrics_raw: dict = ReadFile.get_content_from_file(
            file_format=FileFormat.YAML, file_path=metrics_deliverables_path
        )
        MetricsDeliverablesCondition(**qc_metrics_raw)

    def _set_analysis_status(self, case_id: str, status: AnalysisStatus) -> None:
        """Safely set the analysis status in Trailblazer, with error logging."""
        try:
            self.trailblazer_api.set_analysis_status(case_id=case_id, status=str(status))
        except Exception as error:
            LOG.error(f"Failed to set analysis status to '{status}' for {case_id}: {error}")

    def _generate_trailblazer_comment(self, case_id: str, error: MetricsQCError) -> str:
        """Safely generate a formatted Trailblazer comment based on the error."""
        try:
            samples = self.status_db.get_samples_by_case_id(case_id=case_id)
            trailblazer_comment = str(error)
            for sample in samples:
                trailblazer_comment = trailblazer_comment.replace(
                    f"{sample.internal_id} - ", f"{sample.name} ({sample.internal_id}) - "
                )
            return trailblazer_comment
        except Exception as error:
            LOG.error(f"Failed to generate Trailblazer comments for {case_id}: {error}")

    def _add_trailblazer_comment(self, case_id: str, comment: str) -> None:
        """Safely add a comment in Trailblazer, with error logging."""
        try:
            self.trailblazer_api.add_comment(case_id=case_id, comment=comment)
        except Exception as error:
            LOG.error(f"Failed to add comment in Trailblazer for {case_id}: {error}")

    def validate_qc_metrics(self, case_id: str, dry_run: bool = False) -> None:
        """Validate the information from a QC metrics deliverable file."""

        if dry_run:
            LOG.info("Dry-run: QC metrics validation would be performed")
            return

        LOG.info("Validating QC metrics")
        try:
            self._validate_metrics(case_id)
        except MetricsQCError as error:
            LOG.error(f"QC metrics validation failed for {case_id}, with: {error}")
            self._set_analysis_status(case_id, AnalysisStatus.ERROR)
            trailblazer_comment = self._generate_trailblazer_comment(case_id, error)
            self._add_trailblazer_comment(case_id, trailblazer_comment)
            raise
        except CgError as error:
            LOG.error(f"Failed to create metrics deliverables file for {case_id}: {error}")
            self._set_analysis_status(case_id, AnalysisStatus.ERROR)
            raise
        else:
            self._set_analysis_status(case_id, AnalysisStatus.COMPLETED)


Copy link

@peterpru peterpru added the nallo label Jan 27, 2025
@peterpru peterpru marked this pull request as ready for review January 27, 2025 11:50
@peterpru peterpru requested a review from a team as a code owner January 27, 2025 11:50
@peterpru
Copy link
Member Author

To avoid those obscure errors due to cases missing in trailblazer I wonder if you could replace the validate_qc_metrics cg/meta/workflow/nf_analysis.py by the following code. It would need to be tested though:

    def _validate_metrics(self, case_id: str) -> None:
        """Perform the actual QC metrics validation."""
        metrics_deliverables_path: Path = self.get_metrics_deliverables_path(case_id=case_id)
        qc_metrics_raw: dict = ReadFile.get_content_from_file(
            file_format=FileFormat.YAML, file_path=metrics_deliverables_path
        )
        MetricsDeliverablesCondition(**qc_metrics_raw)

    def _set_analysis_status(self, case_id: str, status: AnalysisStatus) -> None:
        """Safely set the analysis status in Trailblazer, with error logging."""
        try:
            self.trailblazer_api.set_analysis_status(case_id=case_id, status=str(status))
        except Exception as error:
            LOG.error(f"Failed to set analysis status to '{status}' for {case_id}: {error}")

    def _generate_trailblazer_comment(self, case_id: str, error: MetricsQCError) -> str:
        """Safely generate a formatted Trailblazer comment based on the error."""
        try:
            samples = self.status_db.get_samples_by_case_id(case_id=case_id)
            trailblazer_comment = str(error)
            for sample in samples:
                trailblazer_comment = trailblazer_comment.replace(
                    f"{sample.internal_id} - ", f"{sample.name} ({sample.internal_id}) - "
                )
            return trailblazer_comment
        except Exception as error:
            LOG.error(f"Failed to generate Trailblazer comments for {case_id}: {error}")

    def _add_trailblazer_comment(self, case_id: str, comment: str) -> None:
        """Safely add a comment in Trailblazer, with error logging."""
        try:
            self.trailblazer_api.add_comment(case_id=case_id, comment=comment)
        except Exception as error:
            LOG.error(f"Failed to add comment in Trailblazer for {case_id}: {error}")

    def validate_qc_metrics(self, case_id: str, dry_run: bool = False) -> None:
        """Validate the information from a QC metrics deliverable file."""

        if dry_run:
            LOG.info("Dry-run: QC metrics validation would be performed")
            return

        LOG.info("Validating QC metrics")
        try:
            self._validate_metrics(case_id)
        except MetricsQCError as error:
            LOG.error(f"QC metrics validation failed for {case_id}, with: {error}")
            self._set_analysis_status(case_id, AnalysisStatus.ERROR)
            trailblazer_comment = self._generate_trailblazer_comment(case_id, error)
            self._add_trailblazer_comment(case_id, trailblazer_comment)
            raise
        except CgError as error:
            LOG.error(f"Failed to create metrics deliverables file for {case_id}: {error}")
            self._set_analysis_status(case_id, AnalysisStatus.ERROR)
            raise
        else:
            self._set_analysis_status(case_id, AnalysisStatus.COMPLETED)

Thanks for this, Eva. In this case it turned out that the error was from something else, but this would be good to implement. I will add it in a separate issue and I will leave it out of this PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants