def test_delete_case_with_father_links( cli_runner: CliRunner, base_context: CGConfig, helpers: StoreHelpers ): """Test that the delete case will not delete a sample linked to another case as father""" # GIVEN a database with a case base_store: Store = base_context.status_db case_obj = helpers.add_case(base_store, "first_case_linked_to_sample") case_id = case_obj.internal_id sample_father = helpers.add_sample(base_store, "father") sample_child = helpers.add_sample(base_store, "child") helpers.add_relationship(store=base_store, case=case_obj, sample=sample_father) case_obj2 = helpers.add_case(base_store, "second_case_linked_to_sample") helpers.add_relationship( store=base_store, case=case_obj2, sample=sample_child, father=sample_father ) assert base_store.Family.query.count() == 2 assert base_store.FamilySample.query.count() == 2 assert base_store.Sample.query.count() == 2 # WHEN deleting a case result = cli_runner.invoke(delete_case_command, [case_id, "--yes"], obj=base_context) # THEN the first case should be gone with its link to the sample but not the other or # the father sample assert result.exit_code == SUCCESS assert base_store.Family.query.count() == 1 assert base_store.FamilySample.query.count() == 1 assert base_store.Sample.query.count() == 2
def test_delete_child_case(cli_runner: CliRunner, base_context: CGConfig, helpers: StoreHelpers): """Test that the delete case will not delete a sample linked to another case as mother""" # GIVEN a database with a mother case and a child case with the mother as mother base_store: Store = base_context.status_db case_mother = helpers.add_case(base_store, "case_mother") sample_mother = helpers.add_sample(base_store, "mother") sample_child = helpers.add_sample(base_store, "child") helpers.add_relationship(store=base_store, case=case_mother, sample=sample_mother) case_child = helpers.add_case(base_store, "case_child") case_child_id = case_child.internal_id helpers.add_relationship( store=base_store, case=case_child, sample=sample_child, mother=sample_mother ) assert base_store.Family.query.count() == 2 assert base_store.FamilySample.query.count() == 2 assert base_store.Sample.query.count() == 2 # WHEN deleting the child case result = cli_runner.invoke(delete_case_command, [case_child_id, "--yes"], obj=base_context) # THEN the child sample is deletable assert result.exit_code == SUCCESS assert base_store.Family.query.count() == 1 assert base_store.FamilySample.query.count() == 1 assert base_store.Sample.query.count() == 1
def fixture_analysis_store(base_store: Store, workflow_case_id: str, helpers: StoreHelpers) -> Store: """Store to be used in tests""" _store = base_store case = helpers.add_case(_store, workflow_case_id, data_analysis=Pipeline.MIP_DNA) dna_sample = helpers.add_sample(_store, "dna_sample", is_rna=False, sequenced_at=datetime.now(), reads=10000000) helpers.add_relationship(_store, sample=dna_sample, case=case) case = helpers.add_case(_store, "rna_case", data_analysis=Pipeline.MIP_RNA) rna_sample = helpers.add_sample(_store, "rna_sample", is_rna=True, sequenced_at=datetime.now(), reads=10000000) helpers.add_relationship(_store, sample=rna_sample, case=case) case = helpers.add_case(_store, "dna_rna_mix_case", data_analysis=Pipeline.MIP_DNA) helpers.add_relationship(_store, sample=rna_sample, case=case) helpers.add_relationship(_store, sample=dna_sample, case=case) return _store
def test_add_relationship_mother(cli_runner: CliRunner, base_context: CGConfig, helpers: StoreHelpers): """Test to add a relationship with a mother""" # GIVEN a database with a sample and an case disk_store: Store = base_context.status_db sample = helpers.add_sample(disk_store) sample_id = sample.internal_id mother = helpers.add_sample(disk_store, name="mother") mother_id = mother.internal_id case = helpers.add_case(disk_store) case_id = case.internal_id status = "affected" # WHEN adding a relationship result = cli_runner.invoke( add, [ "relationship", case_id, sample_id, "-s", status, "-m", mother_id, ], obj=base_context, ) # THEN it should be added assert result.exit_code == 0 assert disk_store.FamilySample.query.count() == 1 assert disk_store.FamilySample.query.first( ).mother.internal_id == mother_id
def test_delete_case_with_dry_run( cli_runner: CliRunner, base_context: CGConfig, helpers: StoreHelpers, caplog ): """Test that the delete case will not delete the case in dry-run mode""" # GIVEN a database with a case base_store: Store = base_context.status_db case_obj = helpers.add_case(base_store) case_id = case_obj.internal_id sample = helpers.add_sample(base_store) helpers.add_relationship(store=base_store, case=case_obj, sample=sample) assert base_store.Family.query.count() == 1 assert base_store.FamilySample.query.count() == 1 assert base_store.Sample.query.count() == 1 # WHEN deleting a case caplog.set_level(logging.DEBUG) result = cli_runner.invoke( delete_case_command, [case_id, "--yes", "--dry-run"], obj=base_context ) # THEN it should not have been deleted assert result.exit_code == SUCCESS assert base_store.Family.query.count() == 1 assert base_store.FamilySample.query.count() == 1 assert base_store.Sample.query.count() == 1 assert "Link:" in caplog.text assert "Sample is linked" in caplog.text assert "Case:" in caplog.text assert " was NOT deleted due to --dry-run" in caplog.text
def test_validate_sex_unknown_new_sex(orders_api: OrdersAPI, mip_order_to_submit: dict, helpers: StoreHelpers): # GIVEN we have an order with a sample that is already in the database and with different gender but the new is of # type "unknown" order_data = OrderIn.parse_obj(mip_order_to_submit, project=OrderType.MIP_DNA) store = orders_api.status customer_obj = store.customer(order_data.customer) # add sample with different sex than in order for sample in order_data.samples: sample_obj: models.Sample = helpers.add_sample( store=store, subject_id=sample.subject_id, name=sample.name, gender=sample.sex, customer_id=customer_obj.internal_id, ) sample.sex = "unknown" store.add_commit(sample_obj) for sample in order_data.samples: assert sample_obj.sex != sample.sex submitter: MipDnaSubmitter = MipDnaSubmitter(lims=orders_api.lims, status=orders_api.status) # WHEN calling _validate_sex submitter._validate_subject_sex(samples=order_data.samples, customer_id=order_data.customer)
def test_validate_sex_inconsistent_sex(orders_api: OrdersAPI, mip_order_to_submit: dict, helpers: StoreHelpers): # GIVEN we have an order with a sample that is already in the database but with different sex order_data = OrderIn.parse_obj(mip_order_to_submit, project=OrderType.MIP_DNA) store = orders_api.status customer_obj = store.customer(order_data.customer) # add sample with different sex than in order sample: MipDnaSample for sample in order_data.samples: sample_obj: models.Sample = helpers.add_sample( store=store, subject_id=sample.subject_id, name=sample.name, gender="male" if sample.sex == "female" else "female", customer_id=customer_obj.internal_id, ) store.add_commit(sample_obj) assert sample_obj.sex != sample.sex submitter: MipDnaSubmitter = MipDnaSubmitter(lims=orders_api.lims, status=orders_api.status) # WHEN calling _validate_sex # THEN an OrderError should be raised on non-matching sex with pytest.raises(OrderError): submitter._validate_subject_sex(samples=order_data.samples, customer_id=order_data.customer)
def test_add_relationship_bad_father(cli_runner: CliRunner, base_context: CGConfig, helpers: StoreHelpers): """Test to add a relationship using a non-existing father""" # GIVEN a database with a sample and an case disk_store: Store = base_context.status_db sample = helpers.add_sample(disk_store) sample_id = sample.internal_id father_id = "bad_father" case = helpers.add_case(disk_store) case_id = case.internal_id status = "affected" # WHEN adding a relationship result = cli_runner.invoke( add, [ "relationship", case_id, sample_id, "-s", status, "-f", father_id, ], obj=base_context, ) # THEN it should not be added assert result.exit_code == 1 assert disk_store.FamilySample.query.count() == 0
def test_validate_submitted_order(sarscov2_order_to_submit: dict, base_store: Store, helpers: StoreHelpers): # GIVEN sarscov2 order with three samples, all in the database order: OrderIn = OrderIn.parse_obj(sarscov2_order_to_submit, OrderType.SARS_COV_2) sample: SarsCov2Sample for sample in order.samples: helpers.add_sample(store=base_store, name=sample.name, customer_id=order.customer) # WHEN validating the order # THEN it should be regarded as invalid with (pytest.raises(OrderError)): SarsCov2Submitter(status=base_store, lims=None).validate_order(order=order)
def test_validate_submitted_control_order(sarscov2_order_to_submit: dict, base_store: Store, helpers: StoreHelpers): # GIVEN sarscov2 order with three control samples, all in the database order: OrderIn = OrderIn.parse_obj(sarscov2_order_to_submit, OrderType.SARS_COV_2) sample: SarsCov2Sample for sample in order.samples: helpers.add_sample(store=base_store, name=sample.name, customer_id=order.customer) sample.control = ControlEnum.positive # WHEN validating the order # THEN it should be regarded as valid SarsCov2Submitter(status=base_store, lims=None).validate_order(order=order)
def test_get_samples_required(cli_runner: CliRunner, base_context: CGConfig, disk_store: Store, helpers: StoreHelpers): """Test to get several samples using only the required arguments""" # GIVEN a database with two samples sample_id1 = "1" helpers.add_sample(store=disk_store, internal_id=sample_id1) sample_id2 = "2" helpers.add_sample(store=disk_store, internal_id=sample_id2) assert disk_store.Sample.query.count() == 2 # WHEN getting a sample result = cli_runner.invoke(get, ["sample", sample_id1, sample_id2], obj=base_context) # THEN it should have been get assert result.exit_code == 0 assert sample_id1 in result.output assert sample_id2 in result.output
def test_families_by_subject_id( data_analysis: Pipeline, helpers: StoreHelpers, sample_store: Store, ): """Test that we get a case back for a subject id""" # GIVEN connected case exist subject_id = "a_subject_id" store: Store = sample_store rna_sample: models.Sample = helpers.add_sample(store=store, subject_id=subject_id) rna_case: models.Family = helpers.add_case(store=store, data_analysis=Pipeline.MIP_RNA, name="rna_case") helpers.add_relationship(store=store, case=rna_case, sample=rna_sample) store.add_commit(rna_case) dna_sample: models.Sample = helpers.add_sample(store=store, subject_id=subject_id) dna_case: models.Family = helpers.add_case(store=store, data_analysis=data_analysis, name="dna_case") helpers.add_relationship(store=store, case=dna_case, sample=dna_sample) store.add_commit(dna_case) customer: models.Customer = dna_case.customer # WHEN calling method families_by_subject_id all_cases: set[models.Family] = sample_store.families_by_subject_id( customer_id=customer.internal_id, subject_id=subject_id) dna_cases: set[models.Family] = sample_store.families_by_subject_id( customer_id=customer.internal_id, subject_id=subject_id, data_analyses=[data_analysis]) # THEN we got the case as result and another data_analysis not in result assert dna_case in all_cases assert rna_case in all_cases assert dna_case in dna_cases assert rna_case not in dna_cases
def store_samples_with_names_from_order(store: Store, helpers: StoreHelpers, order_data: OrderIn): customer_obj = store.customer(order_data.customer) for sample in order_data.samples: sample_name = sample.name if not store.find_samples(customer=customer_obj, name=sample_name).first(): sample_obj = helpers.add_sample( store=store, name=sample_name, customer_id=customer_obj.internal_id) store.add_commit(sample_obj)
def test_get_sample_required(cli_runner: CliRunner, base_context: CGConfig, disk_store: Store, helpers: StoreHelpers): """Test to get a sample using only the required argument""" # GIVEN a database with a sample sample = helpers.add_sample(disk_store) sample_id = sample.internal_id assert disk_store.Sample.query.count() == 1 # WHEN getting a sample result = cli_runner.invoke(get, ["sample", sample_id], obj=base_context) # THEN it should have been get assert result.exit_code == 0 assert sample_id in result.output
def test_get_sample_families_without_family(cli_runner: CliRunner, base_context: CGConfig, disk_store: Store, helpers: StoreHelpers): """Test that the --families flag works without families""" # GIVEN a database with a sample without related samples sample = helpers.add_sample(disk_store) sample_id = sample.internal_id assert not disk_store.Sample.query.first().links # WHEN getting a sample with the --families flag result = cli_runner.invoke(get, ["sample", sample_id, "--families"], obj=base_context) # THEN everything is fine assert result.exit_code == 0
def test_hide_sample_flowcells_without_flowcell(cli_runner: CliRunner, base_context: CGConfig, disk_store: Store, helpers: StoreHelpers): """Test that we can query samples and hide flowcell even when there are none""" # GIVEN a database with a sample without related flowcell sample = helpers.add_sample(disk_store) sample_id = sample.internal_id assert not disk_store.Flowcell.query.first() # WHEN getting a sample with the --flowcells flag result = cli_runner.invoke(get, ["sample", sample_id, "--hide-flowcell"], obj=base_context) # THEN everything is fine assert result.exit_code == 0
def test_get_sample_external_false(cli_runner: CliRunner, base_context: CGConfig, disk_store: Store, helpers: StoreHelpers): """Test that the output has the external-value of the sample""" # GIVEN a database with a sample with data sample = helpers.add_sample(disk_store, is_external=False) sample_id = sample.internal_id is_external_false = "No" is_external_true = "Yes" # WHEN getting a sample result = cli_runner.invoke(get, ["sample", sample_id], obj=base_context) # THEN it should have been get assert result.exit_code == 0 assert is_external_false in result.output assert is_external_true not in result.output
def test_lists_sample_in_unreceived_samples( cli_runner: CliRunner, base_context: CGConfig, helpers: StoreHelpers ): """Test to that cases displays case in database""" # GIVEN a database with a case base_store: Store = base_context.status_db case = helpers.add_case(base_store) sample1 = helpers.add_sample(base_store, "sample1") helpers.add_relationship(base_store, case=case, sample=sample1) # WHEN listing cases result = cli_runner.invoke(cases, ["-o", "count"], obj=base_context) # THEN the case should be listed assert result.exit_code == 0 assert case.internal_id in result.output assert "0/1" in result.output
def test_get_sample_flowcells_with_flowcell(cli_runner: CliRunner, base_context: CGConfig, disk_store: Store, helpers: StoreHelpers): """Test that we can query samples and hide flowcell, ensuring that no flowcell name is in the output""" # GIVEN a database with a sample and a related flowcell flowcell = helpers.add_flowcell(disk_store) sample = helpers.add_sample(disk_store, flowcell=flowcell) assert flowcell in disk_store.Sample.query.first().flowcells sample_id = sample.internal_id # WHEN getting a sample with the --flowcells flag result = cli_runner.invoke(get, ["sample", sample_id, "--hide-flowcell"], obj=base_context) # THEN the related flowcell should be listed in the output assert result.exit_code == 0 for flowcell in disk_store.Sample.query.first().flowcells: assert flowcell.name not in result.output
def test_get_sample_families_with_family(cli_runner: CliRunner, base_context: CGConfig, disk_store: Store, helpers: StoreHelpers): """Test that the --families flag does show case info""" # GIVEN a database with a sample with related samples case = helpers.add_case(disk_store) sample = helpers.add_sample(disk_store) sample_id = sample.internal_id helpers.add_relationship(disk_store, sample=sample, case=case) assert disk_store.Sample.query.first().links # WHEN getting a sample with the --families flag result = cli_runner.invoke(get, ["sample", sample_id, "--families"], obj=base_context) # THEN all related families should be listed in the output assert result.exit_code == 0 for link in disk_store.Sample.query.first().links: assert link.family.internal_id in result.output
def test_compress_fastq_cli_case_id(populated_compress_context: CGConfig, cli_runner: CliRunner, helpers: StoreHelpers, caplog): """Test to run the compress command with a specified case id""" caplog.set_level(logging.DEBUG) status_db: Store = populated_compress_context.status_db # GIVEN a context with a case that can be compressed case_id = "chonkywombat" valid_compressable_case = helpers.add_case( store=status_db, name=case_id, internal_id=case_id, data_analysis=Pipeline.MIP_DNA, action=None, ) valid_compressable_case.created_at = dt.datetime.now() - dt.timedelta( days=1000) sample1 = helpers.add_sample(store=status_db, internal_id="ACCR9000") sample2 = helpers.add_sample(store=status_db, internal_id="ACCR9001") helpers.add_relationship( store=status_db, sample=sample1, case=valid_compressable_case, ) helpers.add_relationship( store=status_db, sample=sample2, case=valid_compressable_case, ) status_db.commit() # WHEN running the compress command res = cli_runner.invoke(fastq_cmd, ["--case-id", case_id], obj=populated_compress_context) # THEN assert the program exits since no cases where found assert res.exit_code == 0 # THEN assert it was communicated that no families where found assert f"Individuals in 1 (completed) cases where compressed" in caplog.text
def fixture_dna_mip_context( cg_context: CGConfig, helpers: StoreHelpers, mip_case_ids: dict, real_housekeeper_api: HousekeeperAPI, tb_api, ) -> CGConfig: _store = cg_context.status_db cg_context.housekeeper_api_ = real_housekeeper_api cg_context.trailblazer_api_ = tb_api mip_analysis_api = MipDNAAnalysisAPI(config=cg_context) # Add apptag to db helpers.ensure_application_version(store=_store, application_tag="WGSA", application_type="wgs") # Add sample, cases and relationships to db for case_id in mip_case_ids: if not _store.family(case_id): case_obj = helpers.add_case( store=_store, data_analysis=Pipeline.MIP_DNA, internal_id=case_id, name=mip_case_ids[case_id]["name"], ) sample = helpers.add_sample( store=_store, customer_id="cust000", application_tag="WGSA", application_type="wgs", gender="unknown", ) helpers.add_relationship(store=_store, sample=sample, case=case_obj, status="affected") cg_context.meta_apis["analysis_api"] = mip_analysis_api return cg_context
def test_get_sample_output(cli_runner: CliRunner, base_context: CGConfig, disk_store: Store, helpers: StoreHelpers): """Test that the output has the data of the sample""" # GIVEN a database with a sample with data sample = helpers.add_sample(disk_store) sample_id = sample.internal_id name = sample.name customer_id = sample.customer.internal_id application_tag = sample.application_version.application.tag state = sample.state priority_human = sample.priority_human # WHEN getting a sample result = cli_runner.invoke(get, ["sample", sample_id], obj=base_context) # THEN it should have been get assert result.exit_code == 0 assert sample_id in result.output assert name in result.output assert customer_id in result.output assert application_tag in result.output assert state in result.output assert priority_human in result.output
def fluffy_context( cg_context: CGConfig, helpers: StoreHelpers, real_housekeeper_api: HousekeeperAPI, fluffy_samplesheet_bundle_data, fluffy_fastq_hk_bundle_data, fluffy_case_id_existing, fluffy_sample_lims_id, ) -> CGConfig: cg_context.housekeeper_api_ = real_housekeeper_api fluffy_analysis_api = FluffyAnalysisAPI(config=cg_context) helpers.ensure_hk_version(fluffy_analysis_api.housekeeper_api, bundle_data=fluffy_samplesheet_bundle_data) helpers.ensure_hk_version(fluffy_analysis_api.housekeeper_api, fluffy_fastq_hk_bundle_data) example_fluffy_case = helpers.add_case( fluffy_analysis_api.status_db, internal_id=fluffy_case_id_existing, name=fluffy_case_id_existing, data_analysis=Pipeline.FLUFFY, ) example_fluffy_sample = helpers.add_sample( fluffy_analysis_api.status_db, internal_id=fluffy_sample_lims_id, is_tumour=False, application_type="tgs", reads=100, sequenced_at=dt.datetime.now(), ) helpers.add_flowcell(fluffy_analysis_api.status_db, flowcell_id="flowcell", samples=[example_fluffy_sample]) helpers.add_relationship(fluffy_analysis_api.status_db, case=example_fluffy_case, sample=example_fluffy_sample) cg_context.meta_apis["analysis_api"] = fluffy_analysis_api return cg_context
def fixture_rna_store( base_store: Store, helpers: StoreHelpers, rna_case_id: str, dna_case_id: str, ) -> Store: """Populate store with an rna case that is connected to a dna case via sample.subject_id""" store: Store = base_store # an existing RNA case with related sample rna_case = helpers.ensure_case( store=store, name="rna_case", customer=helpers.ensure_customer(store=store), data_analysis=Pipeline.MIP_RNA, data_delivery=DataDelivery.SCOUT, ) rna_case.internal_id = rna_case_id rna_sample_son = helpers.add_sample(store=store, name="rna_son", subject_id="son") rna_sample_daughter = helpers.add_sample( store=store, name="rna_daughter", subject_id="daughter" ) rna_sample_mother = helpers.add_sample(store=store, name="rna_mother", subject_id="mother") rna_sample_father = helpers.add_sample(store=store, name="rna_father", subject_id="father") helpers.add_relationship( store=store, sample=rna_sample_son, case=rna_case, mother=rna_sample_mother, father=rna_sample_father, status="affected", ) helpers.add_relationship( store=store, sample=rna_sample_daughter, case=rna_case, mother=rna_sample_mother, father=rna_sample_father, status="unaffected", ) helpers.add_relationship( store=store, sample=rna_sample_mother, case=rna_case, status="unaffected" ) helpers.add_relationship( store=store, sample=rna_sample_father, case=rna_case, status="affected" ) for link in rna_case.links: link.sample.internal_id = link.sample.name # an existing DNA case with related sample dna_case = helpers.ensure_case( store=store, name="dna_case", customer=helpers.ensure_customer(store=store), data_analysis=Pipeline.MIP_DNA, data_delivery=DataDelivery.SCOUT, ) dna_case.internal_id = dna_case_id dna_sample_son = helpers.add_sample(store=store, name="dna_son", subject_id="son") dna_sample_daughter = helpers.add_sample( store=store, name="dna_daughter", subject_id="daughter" ) dna_sample_mother = helpers.add_sample(store=store, name="dna_mother", subject_id="mother") dna_sample_father = helpers.add_sample(store=store, name="dna_father", subject_id="father") helpers.add_relationship( store=store, sample=dna_sample_son, case=dna_case, mother=dna_sample_mother, father=dna_sample_father, status="affected", ) helpers.add_relationship( store=store, sample=dna_sample_daughter, case=dna_case, mother=dna_sample_mother, father=dna_sample_father, status="unaffected", ) helpers.add_relationship( store=store, sample=dna_sample_mother, case=dna_case, status="unaffected" ) helpers.add_relationship( store=store, sample=dna_sample_father, case=dna_case, status="affected" ) for link in dna_case.links: link.sample.internal_id = link.sample.name store.commit() return store
def clean_context( cg_context: CGConfig, helpers: StoreHelpers, project_dir: Path, timestamp_yesterday: datetime.datetime, timestamp_today: datetime.datetime, ) -> CGConfig: analysis_api = BalsamicAnalysisAPI(cg_context) store = analysis_api.status_db # Create textbook case for cleaning case_to_clean = helpers.add_case( store=store, internal_id="balsamic_case_clean", name="balsamic_case_clean", data_analysis=Pipeline.BALSAMIC, ) sample_case_to_clean = helpers.add_sample( store, internal_id="balsamic_sample_clean", is_tumour=True, application_type="wgs", ) helpers.add_relationship(store, case=case_to_clean, sample=sample_case_to_clean) helpers.add_analysis( store, case=case_to_clean, pipeline=Pipeline.BALSAMIC, started_at=timestamp_yesterday, uploaded_at=timestamp_yesterday, cleaned_at=None, ) Path(analysis_api.get_case_path("balsamic_case_clean")).mkdir( exist_ok=True, parents=True) # Create textbook case not for cleaning case_to_not_clean = helpers.add_case( store=store, internal_id="balsamic_case_not_clean", name="balsamic_case_not_clean", data_analysis=Pipeline.BALSAMIC, ) case_to_not_clean.action = "running" store.commit() sample_case_to_not_clean = helpers.add_sample( store, internal_id="balsamic_sample_not_clean", is_tumour=True, application_type="wgs", ) helpers.add_relationship(store, case=case_to_not_clean, sample=sample_case_to_not_clean) helpers.add_analysis( store, case=case_to_not_clean, pipeline="balsamic", started_at=timestamp_yesterday, uploaded_at=timestamp_yesterday, cleaned_at=None, ) Path(analysis_api.get_case_path("balsamic_case_not_clean")).mkdir( exist_ok=True, parents=True) cg_context.meta_apis["analysis_api"] = analysis_api cg_context.data_delivery.base_path = f"{project_dir}/rsync" return cg_context
def fixture_balsamic_context( cg_context: CGConfig, helpers: StoreHelpers, balsamic_lims: MockLimsAPI, balsamic_housekeeper: HousekeeperAPI, trailblazer_api: MockTB, hermes_api: HermesApi, cg_dir, ) -> CGConfig: """context to use in cli""" cg_context.housekeeper_api_ = balsamic_housekeeper cg_context.lims_api_ = balsamic_lims cg_context.trailblazer_api_ = trailblazer_api cg_context.meta_apis["analysis_api"] = BalsamicAnalysisAPI( config=cg_context) status_db: Store = cg_context.status_db # Create tgs application version helpers.ensure_application_version(store=status_db, application_tag="TGSA", application_type="tgs") # Create wes application version helpers.ensure_application_version(store=status_db, application_tag="WESA", application_type="wes") # Create textbook case for WGS PAIRED with enough reads case_wgs_paired_enough_reads = helpers.add_case( store=status_db, internal_id="balsamic_case_wgs_paired_enough_reads", name="balsamic_case_wgs_paired_enough_reads", data_analysis=Pipeline.BALSAMIC, ) sample_case_wgs_paired_tumor_enough_reads = helpers.add_sample( status_db, internal_id="sample_case_wgs_paired_tumor_enough_reads", is_tumour=True, application_type="wgs", reads=10, sequenced_at=dt.datetime.now(), ) sample_case_wgs_paired_normal_enough_reads = helpers.add_sample( status_db, internal_id="sample_case_wgs_paired_normal_enough_reads", is_tumour=False, application_type="wgs", reads=10, sequenced_at=dt.datetime.now(), ) helpers.add_relationship( status_db, case=case_wgs_paired_enough_reads, sample=sample_case_wgs_paired_tumor_enough_reads, ) helpers.add_relationship( status_db, case=case_wgs_paired_enough_reads, sample=sample_case_wgs_paired_normal_enough_reads, ) # Create textbook case for WGS PAIRED case_wgs_paired = helpers.add_case( store=status_db, internal_id="balsamic_case_wgs_paired", name="balsamic_case_wgs_paired", data_analysis=Pipeline.BALSAMIC, ) sample_case_wgs_paired_tumor = helpers.add_sample( status_db, internal_id="sample_case_wgs_paired_tumor", is_tumour=True, application_type="wgs", reads=10, sequenced_at=dt.datetime.now(), ) sample_case_wgs_paired_normal = helpers.add_sample( status_db, internal_id="sample_case_wgs_paired_normal", is_tumour=False, application_type="wgs", reads=10, sequenced_at=dt.datetime.now(), ) helpers.add_relationship(status_db, case=case_wgs_paired, sample=sample_case_wgs_paired_tumor) helpers.add_relationship(status_db, case=case_wgs_paired, sample=sample_case_wgs_paired_normal) # Create textbook case for TGS PAIRED without enough reads case_tgs_paired = helpers.add_case( status_db, internal_id="balsamic_case_tgs_paired", name="balsamic_case_tgs_paired", data_analysis=Pipeline.BALSAMIC, ) sample_case_tgs_paired_tumor = helpers.add_sample( status_db, internal_id="sample_case_tgs_paired_tumor", is_tumour=True, application_tag="TGSA", application_type="tgs", reads=10, sequenced_at=dt.datetime.now(), ) sample_case_tgs_paired_normal = helpers.add_sample( status_db, internal_id="sample_case_tgs_paired_normal", is_tumour=False, application_tag="TGSA", application_type="tgs", reads=0, sequenced_at=dt.datetime.now(), ) helpers.add_relationship(status_db, case=case_tgs_paired, sample=sample_case_tgs_paired_tumor) helpers.add_relationship(status_db, case=case_tgs_paired, sample=sample_case_tgs_paired_normal) # Create textbook case for WGS TUMOR ONLY case_wgs_single = helpers.add_case( status_db, internal_id="balsamic_case_wgs_single", name="balsamic_case_wgs_single", data_analysis=Pipeline.BALSAMIC, ) sample_case_wgs_single_tumor = helpers.add_sample( status_db, internal_id="sample_case_wgs_single_tumor", is_tumour=True, application_type="wgs", reads=100, sequenced_at=dt.datetime.now(), ) helpers.add_relationship(status_db, case=case_wgs_single, sample=sample_case_wgs_single_tumor) # Create textbook case for TGS TUMOR ONLY case_tgs_single = helpers.add_case( status_db, internal_id="balsamic_case_tgs_single", name="balsamic_case_tgs_single", data_analysis=Pipeline.BALSAMIC, ) sample_case_tgs_single_tumor = helpers.add_sample( status_db, internal_id="sample_case_tgs_single_tumor", is_tumour=True, application_tag="TGSA", application_type="tgs", sequenced_at=dt.datetime.now(), ) helpers.add_relationship(status_db, case=case_tgs_single, sample=sample_case_tgs_single_tumor) # Create ERROR case for TGS NORMAL ONLY case_tgs_single_error = helpers.add_case( status_db, internal_id="balsamic_case_tgs_single_error", name="balsamic_case_tgs_single_error", data_analysis=Pipeline.BALSAMIC, ) sample_case_tgs_single_normal_error = helpers.add_sample( status_db, internal_id="sample_case_tgs_single_normal_error", is_tumour=False, application_tag="TGSA", application_type="tgs", sequenced_at=dt.datetime.now(), ) helpers.add_relationship( status_db, case=case_tgs_single_error, sample=sample_case_tgs_single_normal_error, ) # Create ERROR case for TGS TWO TUMOR ONE NORMAL case_tgs_paired_error = helpers.add_case( status_db, internal_id="balsamic_case_tgs_paired_error", name="balsamic_case_tgs_paired_error", data_analysis=Pipeline.BALSAMIC, ) sample_case_tgs_paired_tumor_error = helpers.add_sample( status_db, internal_id="sample_case_tgs_paired_tumor_error", is_tumour=True, application_tag="TGSA", application_type="tgs", sequenced_at=dt.datetime.now(), ) sample_case_tgs_paired_tumor2_error = helpers.add_sample( status_db, internal_id="sample_case_tgs_paired_tumor2_error", is_tumour=True, application_tag="TGSA", application_type="tgs", sequenced_at=dt.datetime.now(), ) sample_case_tgs_paired_normal_error = helpers.add_sample( status_db, internal_id="sample_case_tgs_paired_normal_error", is_tumour=False, application_tag="TGSA", application_type="tgs", sequenced_at=dt.datetime.now(), ) helpers.add_relationship( status_db, case=case_tgs_paired_error, sample=sample_case_tgs_paired_tumor_error, ) helpers.add_relationship( status_db, case=case_tgs_paired_error, sample=sample_case_tgs_paired_tumor2_error, ) helpers.add_relationship( status_db, case=case_tgs_paired_error, sample=sample_case_tgs_paired_normal_error, ) # Create ERROR case for MIXED application type case_mixed_paired_error = helpers.add_case( status_db, internal_id="balsamic_case_mixed_paired_error", name="balsamic_case_mixed_paired_error", data_analysis=Pipeline.BALSAMIC, ) mixed_sample_case_wgs_paired_tumor_error = helpers.add_sample( status_db, internal_id="mixed_sample_case_wgs_paired_tumor_error", is_tumour=True, application_type="wgs", sequenced_at=dt.datetime.now(), ) mixed_sample_case_tgs_paired_normal_error = helpers.add_sample( status_db, internal_id="mixed_sample_case_tgs_paired_normal_error", is_tumour=False, application_tag="TGSA", application_type="tgs", sequenced_at=dt.datetime.now(), ) helpers.add_relationship( status_db, case=case_mixed_paired_error, sample=mixed_sample_case_wgs_paired_tumor_error, ) helpers.add_relationship( status_db, case=case_mixed_paired_error, sample=mixed_sample_case_tgs_paired_normal_error, ) # Create ERROR case for MIXED application type NOT BALSAMIC APPLICATION case_mixed_wgs_mic_paired_error = helpers.add_case( status_db, internal_id="balsamic_case_mixed_wgs_mic_paired_error", name="balsamic_case_mixed_wgs_mic_paired_error", data_analysis=Pipeline.BALSAMIC, ) mixed_sample_case_wgs_mic_paired_tumor_error = helpers.add_sample( status_db, internal_id="mixed_sample_case_wgs_mic_paired_tumor_error", is_tumour=True, application_type="wgs", sequenced_at=dt.datetime.now(), ) mixed_sample_case_wgs_mic_paired_normal_error = helpers.add_sample( status_db, internal_id="mixed_sample_case_wgs_mic_paired_normal_error", is_tumour=False, application_tag="MICA", application_type="mic", sequenced_at=dt.datetime.now(), ) helpers.add_relationship( status_db, case=case_mixed_wgs_mic_paired_error, sample=mixed_sample_case_wgs_mic_paired_tumor_error, ) helpers.add_relationship( status_db, case=case_mixed_wgs_mic_paired_error, sample=mixed_sample_case_wgs_mic_paired_normal_error, ) # Create ERROR case for MIXED TARGET BED case_mixed_bed_paired_error = helpers.add_case( status_db, internal_id="balsamic_case_mixed_bed_paired_error", name="balsamic_case_mixed_bed_paired_error", data_analysis=Pipeline.BALSAMIC, ) mixed_sample_case_mixed_bed_paired_tumor_error = helpers.add_sample( status_db, internal_id="mixed_sample_case_mixed_bed_paired_tumor_error", is_tumour=True, application_tag="TGSA", application_type="tgs", sequenced_at=dt.datetime.now(), ) mixed_sample_case_mixed_bed_paired_normal_error = helpers.add_sample( status_db, internal_id="mixed_sample_case_mixed_bed_paired_normal_error", is_tumour=False, application_tag="TGSA", application_type="tgs", sequenced_at=dt.datetime.now(), ) helpers.add_relationship( status_db, case=case_mixed_bed_paired_error, sample=mixed_sample_case_mixed_bed_paired_tumor_error, ) helpers.add_relationship( status_db, case=case_mixed_bed_paired_error, sample=mixed_sample_case_mixed_bed_paired_normal_error, ) # Create ERROR case for WGS TUMOR ONLY MIP CLI_OPTION_ANALYSIS ONLY mip_case_wgs_single = helpers.add_case( status_db, internal_id="mip_case_wgs_single", name="mip_case_wgs_single", data_analysis=Pipeline.MIP_DNA, ) mip_sample_case_wgs_single_tumor = helpers.add_sample( status_db, internal_id="mip_sample_case_wgs_single_tumor", is_tumour=True, application_type="wgs", sequenced_at=dt.datetime.now(), ) helpers.add_relationship( status_db, case=mip_case_wgs_single, sample=mip_sample_case_wgs_single_tumor, ) # Create ERROR case for WGS ONE TUMOR TWO NORMAL case_wgs_paired_two_normal_error = helpers.add_case( status_db, internal_id="balsamic_case_wgs_paired_two_normal_error", name="balsamic_case_wgs_paired_two_normal_error", data_analysis=Pipeline.BALSAMIC, ) sample_case_wgs_paired_two_normal_tumor_error = helpers.add_sample( status_db, internal_id="sample_case_wgs_paired_two_normal_tumor_error", is_tumour=True, application_tag="WGSA", application_type="wgs", sequenced_at=dt.datetime.now(), ) sample_case_wgs_paired_two_normal_normal1_error = helpers.add_sample( status_db, internal_id="sample_case_wgs_paired_two_normal_normal1_error", is_tumour=False, application_tag="WGSA", application_type="wgs", sequenced_at=dt.datetime.now(), ) sample_case_wgs_paired_two_normal_normal2_error = helpers.add_sample( status_db, internal_id="sample_case_wgs_paired_two_normal_normal2_error", is_tumour=False, application_tag="WGSA", application_type="wgs", sequenced_at=dt.datetime.now(), ) helpers.add_relationship( status_db, case=case_wgs_paired_two_normal_error, sample=sample_case_wgs_paired_two_normal_tumor_error, ) helpers.add_relationship( status_db, case=case_wgs_paired_two_normal_error, sample=sample_case_wgs_paired_two_normal_normal1_error, ) helpers.add_relationship( status_db, case=case_wgs_paired_two_normal_error, sample=sample_case_wgs_paired_two_normal_normal2_error, ) # Create WES case with 1 tumor sample case_wes_tumor = helpers.add_case( status_db, internal_id="balsamic_case_wes_tumor", name="balsamic_case_wes_tumor", data_analysis=Pipeline.BALSAMIC, ) sample_case_wes_tumor = helpers.add_sample( status_db, internal_id="sample_case_wes_tumor", is_tumour=True, application_tag="WESA", application_type="wes", sequenced_at=dt.datetime.now(), ) helpers.add_relationship(status_db, case=case_wes_tumor, sample=sample_case_wes_tumor) # Create ERROR case for WES when no panel is found case_wes_panel_error = helpers.add_case( status_db, internal_id="balsamic_case_wes_panel_error", name="balsamic_case_wes_panel_error", data_analysis=Pipeline.BALSAMIC, ) sample_case_wes_panel_error = helpers.add_sample( status_db, internal_id="sample_case_wes_panel_error", is_tumour=True, application_tag="WESA", application_type="wes", sequenced_at=dt.datetime.now(), ) helpers.add_relationship(status_db, case=case_wes_panel_error, sample=sample_case_wes_panel_error) # Create ERROR case with NO SAMPLES helpers.add_case(status_db, internal_id="no_sample_case", name="no_sample_case") # Create BED1 version 1 bed1_name = "BalsamicBed1" bed1_filename = "balsamic_bed_1.bed" Path(cg_dir, bed1_filename).touch(exist_ok=True) bed1 = status_db.add_bed(name=bed1_name) status_db.add_commit(bed1) version1 = status_db.add_bed_version(bed=bed1, version=1, filename=bed1_filename, shortname=bed1_name) status_db.add_commit(version1) # Create BED2 version 1 bed2_name = "BalsamicBed2" bed2_filename = "balsamic_bed_2.bed" Path(cg_dir, bed2_filename).touch(exist_ok=True) bed2 = status_db.add_bed(name=bed2_name) status_db.add_commit(bed2) version2 = status_db.add_bed_version(bed=bed2, version=1, filename=bed2_filename, shortname=bed2_name) status_db.add_commit(version2) return cg_context