diff --git a/clarity_epp.py b/clarity_epp.py index 1c89751..917124c 100755 --- a/clarity_epp.py +++ b/clarity_epp.py @@ -115,10 +115,16 @@ def export_removed_samples(args): clarity_epp.export.sample.removed_samples(lims, args.output_file) -def export_sample_indications(args): - """Export sample indication table.""" - clarity_epp.export.sample.sample_indications( - lims, args.output_file, args.artifact_name, args.sequencing_run, args.sequencing_run_project +def export_sample_udf_dx(args): + "Export table sample udf (Dx-udf only)""" + clarity_epp.export.sample.sample_udf_dx( + lims, + args.output_file, + args.artifact_name, + args.sequencing_run, + args.sequencing_run_project, + args.udf, + args.column_name ) @@ -335,16 +341,18 @@ def placement_pipetting(args): ) parser_export_removed_samples.set_defaults(func=export_removed_samples) - parser_export_sample_indications = subparser_export.add_parser( - 'sample_indications', help='Export sample indication table.', parents=[output_parser] + parser_export_sample_udf_dx = subparser_export.add_parser( + 'sample_udf_dx', help='Export sample udf table (Dx-udf only).', parents=[output_parser] ) - parser_export_sample_indications_group = parser_export_sample_indications.add_mutually_exclusive_group(required=True) - parser_export_sample_indications_group.add_argument('-a', '--artifact_name', help='Artifact name') - parser_export_sample_indications_group.add_argument('-r', '--sequencing_run', help='Sequencing run name') - parser_export_sample_indications.add_argument( + parser_export_sample_udf_dx_group = parser_export_sample_udf_dx.add_mutually_exclusive_group(required=True) + parser_export_sample_udf_dx_group.add_argument('-a', '--artifact_name', help='Artifact name') + parser_export_sample_udf_dx_group.add_argument('-r', '--sequencing_run', help='Sequencing run name') + parser_export_sample_udf_dx.add_argument( '-p', '--sequencing_run_project', nargs='?', help='Sequencing run project name' ) - parser_export_sample_indications.set_defaults(func=export_sample_indications) + parser_export_sample_udf_dx.add_argument('-u', '--udf', help='udf to query (limited to only Dx-udf)') + parser_export_sample_udf_dx.add_argument('-c', '--column_name', help='naming of column') + parser_export_sample_udf_dx.set_defaults(func=export_sample_udf_dx) parser_export_sample_related_mip = subparser_export.add_parser( 'sample_related_mip', help='Export related mip samples.', parents=[output_parser] diff --git a/clarity_epp/export/ped.py b/clarity_epp/export/ped.py index 822b0e3..2859608 100644 --- a/clarity_epp/export/ped.py +++ b/clarity_epp/export/ped.py @@ -44,7 +44,7 @@ def create_file(lims, process_id, output_file): ped_sample['sex'] = 0 # Determine affection - ped_sample['affection'] = 0 # unkown + ped_sample['affection'] = 0 # unknown if 'Bevestiging diagnose' in sample.udf['Dx Onderzoeksreden']: ped_sample['affection'] = 2 # affected elif 'Informativiteitstest' in sample.udf['Dx Onderzoeksreden']: diff --git a/clarity_epp/export/sample.py b/clarity_epp/export/sample.py index 74bee68..1d02d84 100644 --- a/clarity_epp/export/sample.py +++ b/clarity_epp/export/sample.py @@ -124,8 +124,8 @@ def removed_samples(lims, output_file): )) -def sample_indications(lims, output_file, artifact_name=None, sequencing_run=None, sequencing_run_project=None): - """Export table with sample indications. Lookup samples by sample name or sequencing run (project).""" +def get_samples(lims, artifact_name=None, sequencing_run=None, sequencing_run_project=None): + """Lookup samples by sample name or sequencing run (project).""" samples = [] # Get samples by artifact_name @@ -142,22 +142,38 @@ def sample_indications(lims, output_file, artifact_name=None, sequencing_run=Non artifacts = lims.get_artifacts(type='Analyte', udf=udf_query) samples = {artifact.name: artifact.samples[0] for artifact in artifacts} + return samples + + +def sample_udf_dx(lims, output_file, artifact_name=None, sequencing_run=None, sequencing_run_project=None, udf=None, column_name=None): + """Export table with sample udf (Dx-udf only).""" + samples = get_samples(lims, artifact_name, sequencing_run, sequencing_run_project) # Write result if samples: - output_file.write('Sample\tIndication\n') + output_file.write(f'Sample\t{column_name}\n') for sample_name, sample in samples.items(): - if 'Dx Onderzoeksindicatie' in sample.udf: - output_file.write( - '{sample}\t{indication}\n'.format( - sample=sample_name, - indication=sample.udf['Dx Onderzoeksindicatie'].split(';')[0] # select newest indication + if udf in sample.udf: + if 'Dx' in udf: + if type (sample.udf[udf]) == str: + udf_value=sample.udf[udf].split(';')[0] # select newest udf value + else: + udf_value=sample.udf[udf] + + output_file.write( + '{sample}\t{udf_value}\n'.format( + sample=sample_name, + udf_value=udf_value + ) + ) + else: + output_file.write( + f'Warning, udf is not type \'Dx\'\n' ) - ) else: output_file.write( - '{sample}\t{indication}\n'.format( + '{sample}\t{udf_value}\n'.format( sample=sample_name, - indication='unkown_indication' + udf_value='unknown' ) ) else: diff --git a/requirements.txt b/requirements.txt index fa62ecd..bde4499 100755 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,5 @@ genologics==0.3.20 argparse==1.4.0 -xmltodict==0.12.0 \ No newline at end of file +xmltodict==0.12.0 +pytest==7.0.1 +pytest-mock==3.6.1 diff --git a/tests/test_export_sample.py b/tests/test_export_sample.py new file mode 100644 index 0000000..e62fded --- /dev/null +++ b/tests/test_export_sample.py @@ -0,0 +1,59 @@ +import sys + +from clarity_epp.export import sample + + +class MyMock: + def __init__(self, udf): + self.udf = udf + + +def test_sample_udf_withudf(mocker, capsys): + # Test output for sample with known Dx-udf in database + samples_mock[sample_name] = MyMock({"Dx geslacht": "Vrouw"}) + patched_clarity_epp = mocker.patch( + 'clarity_epp.export.sample.get_samples', + return_value=samples_mock + ) + sample.sample_udf_dx("lims", sys.stdout, udf="Dx geslacht", column_name=column_name) + captured = capsys.readouterr() + assert captured.out == f"Sample\t{column_name}\n{sample_name}\tVrouw\n" + + +def test_sample_udf_withoutudf(mocker, capsys): + # Test output for sample with no known udf in database + samples_mock[sample_name] = MyMock({"Dx geslacht": "Vrouw"}) + patched_clarity_epp = mocker.patch( + 'clarity_epp.export.sample.get_samples', + return_value=samples_mock + ) + sample.sample_udf_dx("lims", sys.stdout, udf="udf2", column_name=column_name) + captured = capsys.readouterr() + assert captured.out == f"Sample\t{column_name}\n{sample_name}\tunknown\n" + +def test_sample_udf_withoutdxudf(mocker, capsys): + # Test output for sample with known udf in database, but not Dx-udf + samples_mock[sample_name] = MyMock({"Geslacht": "Vrouw"}) + patched_clarity_epp = mocker.patch( + 'clarity_epp.export.sample.get_samples', + return_value=samples_mock + ) + sample.sample_udf_dx("lims", sys.stdout, udf="Geslacht", column_name=column_name) + captured = capsys.readouterr() + assert captured.out == f"Sample\t{column_name}\nWarning, udf is not type \'Dx\'\n" + + +def test_sample_udf_nosamples(mocker, capsys): + # Test output for sample not known in database + samples_mock[sample_name] = MyMock({"Dx geslacht": "Vrouw"}) + patched_clarity_epp = mocker.patch( + 'clarity_epp.export.sample.get_samples', + return_value=None + ) + sample.sample_udf_dx("lims", sys.stdout) + captured = capsys.readouterr() + assert captured.out == "no_sample_found\n" + +column_name = "test_column" +sample_name = "test_sample" +samples_mock = {}