[med-svn] [Git][med-team/resfinder][master] 4 commits: routine-update: New upstream version
Andreas Tille (@tille)
gitlab at salsa.debian.org
Sun Feb 26 16:20:47 GMT 2023
Andreas Tille pushed to branch master at Debian Med / resfinder
Commits:
04052e0d by Andreas Tille at 2023-02-26T17:12:48+01:00
routine-update: New upstream version
- - - - -
40f6a94d by Andreas Tille at 2023-02-26T17:13:31+01:00
New upstream version 4.3.0
- - - - -
b2515373 by Andreas Tille at 2023-02-26T17:13:32+01:00
Update upstream source from tag 'upstream/4.3.0'
Update to upstream version '4.3.0'
with Debian dir 0006b9b73df909a3a9f8a72d02129193a58e5ac2
- - - - -
f08fa09b by Andreas Tille at 2023-02-26T17:18:42+01:00
Upload to unstable
- - - - -
19 changed files:
- CHANGELOG.md
- DEV_SETUP.md
- Dockerfile_no_dbs
- debian/changelog
- dockerfile
- src/resfinder/__init__.py
- src/resfinder/cge/config.py
- src/resfinder/cge/output/gene_result.py
- src/resfinder/cge/output/phenotype_result.py
- src/resfinder/cge/output/std_results.py
- src/resfinder/cge/phenotype2genotype/res_profile.py
- src/resfinder/cge/pointfinder.py
- src/resfinder/run_resfinder.py
- tests/resfinder/cge/output/test_gene_result.md
- tests/resfinder/cge/output/test_phenotype_result.md
- tests/resfinder/cge/output/test_std_results.md
- tests/resfinder/cge/phenotype2genotype/test_isolate.md
- tests/resfinder/cge/test_config.md
- + tests/resfinder/test_run_resfinder.md
Changes:
=====================================
CHANGELOG.md
=====================================
@@ -5,6 +5,22 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+## [4.3.0] - 2023-02-09
+
+### Added
+
+- JSON output now contains the 'software_exec' class. It contains the command used to invoke ResFinder and the value of all parameters.
+- JSON output now contains 'grades' for 'seq_regions' and 'phenotypes' corresponding to the colors known from the web tool: dark green, green, grey is 3, 2, 1, respectively. Phenotypes can also be 0 if no resistance features was found. Phenotype grades will as for the webtool be the highest grade of the resistance features found.
+
+### Changed
+
+- It is no longer necessary to set the flag --ignore_missing_species if '--species other' is set
+
+### Fixed
+
+- Case where species "other" is chosen and pointfinder is run causing error phenodb.mut_type_is_defined not found
+- Alignments in json output to include missing gene parts in query string
+
## [4.2.5] - 2023-01-23
### Fixed
=====================================
DEV_SETUP.md
=====================================
@@ -49,8 +49,14 @@ cd /path/to/resfinder/
# Run ResFinder
pdm run resfinder -h
+# Some tests requires the following environmental variables to be set
+export CGE_BLASTN="/path/to/blastn"
+export CGE_RESFINDER_RESGENE_DB="/path/to/resfinder_db"
+export CGE_RESFINDER_RESPOINT_DB="/path/to/pointfinder_db"
+export CGE_DISINFINDER_DB="/path/to/disinfinder_db"
+
# Run ResFinder tests
-pdm run tests
+pdm run test
```
=====================================
Dockerfile_no_dbs
=====================================
@@ -20,7 +20,7 @@ RUN cd /usr/src/; \
rm -rf kma/;
# Install ResFinder
-RUN pip install --no-cache-dir resfinder==4.2.1
+RUN pip install --no-cache-dir resfinder==4.3.0
# Setup environment
RUN cd /; \
=====================================
debian/changelog
=====================================
@@ -1,3 +1,9 @@
+resfinder (4.3.0-1) unstable; urgency=medium
+
+ * New upstream version
+
+ -- Andreas Tille <tille at debian.org> Sun, 26 Feb 2023 17:17:08 +0100
+
resfinder (4.2.5-2) unstable; urgency=medium
* Explicitly Depends: python3-cgelib
=====================================
dockerfile
=====================================
@@ -20,7 +20,7 @@ RUN cd /usr/src/; \
cd ..; \
rm -rf kma/;
-ENV RESFINDER_VERSION 4.2.5
+ENV RESFINDER_VERSION 4.3.0
# Install ResFinder
RUN pip install --no-cache-dir resfinder==$RESFINDER_VERSION
=====================================
src/resfinder/__init__.py
=====================================
@@ -1 +1 @@
-__version__ = '4.2.5'
+__version__ = '4.3.0'
=====================================
src/resfinder/cge/config.py
=====================================
@@ -103,7 +103,7 @@ class Config():
def get_species(in_species, species_def_filepath):
out_species = in_species
if(in_species is not None and in_species.lower() == "other"):
- out_species = None
+ out_species = "other"
elif(in_species is not None):
out_species = in_species.lower()
@@ -235,7 +235,8 @@ class Config():
sys.exit("ERROR: Chromosomal point mutations cannot be located if "
"no species has been provided. Please provide species "
"using the --species option.")
- elif(not self.species and args.ignore_missing_species):
+ elif((not self.species and args.ignore_missing_species)
+ or self.species.lower() == 'other'):
self.point = False
return
=====================================
src/resfinder/cge/output/gene_result.py
=====================================
@@ -6,7 +6,7 @@ from ..phenotype2genotype.res_profile import PhenoDB
class GeneResult(dict):
- def __init__(self, res_collection, res, db_name, conf=None):
+ def __init__(self, res_collection, res, db_name, conf=None, alignments=None):
"""
Input:
res_collection: Result object created by the cgelib package.
@@ -41,9 +41,18 @@ class GeneResult(dict):
self["notes"] = []
if conf and conf.output_aln:
- self["query_string"] = res["query_string"]
- self["alignment_string"] = res["homo_string"]
- self["ref_string"] = res["sbjct_string"]
+ for ab_class, hits in alignments.gene_align_query.items():
+ ab_class_keys = list(hits.keys())
+ hit_key = next(key for key in ab_class_keys
+ if key.startswith(self["ref_id"]))
+ hit_class = ab_class
+ break
+
+ self["query_string"] = alignments.gene_align_query[hit_class][
+ hit_key]
+ self["alignment_string"] = alignments.gene_align_homo[hit_class][
+ hit_key]
+ self["ref_string"] = alignments.gene_align_sbjct[hit_class][hit_key]
# BLAST coverage formatted results
coverage = res.get("coverage", None)
@@ -54,10 +63,21 @@ class GeneResult(dict):
coverage = float(coverage) * 100
self["coverage"] = coverage
+ self["grade"] = GeneResult.calc_gene_grade(coverage=self["coverage"], identity=self["identity"])
+
self.remove_NAs()
uniqueness = self._get_unique_gene_key(res_collection)
self["key"] = uniqueness
+ @staticmethod
+ def calc_gene_grade(coverage: float, identity: float) -> int:
+ if coverage == 100.0 and identity == 100.0:
+ return 3
+ elif coverage == 100.0:
+ return 2
+ else:
+ return 1
+
def remove_NAs(self):
"""
Remove all entries containing NA og None as values.
=====================================
src/resfinder/cge/output/phenotype_result.py
=====================================
@@ -14,6 +14,7 @@ class PhenotypeResult(dict):
self["amr_resistant"] = False
self["amr_species_relevant"] = PhenotypeResult.get_amr_relevance(
antibiotic.name, isolate)
+ self["grade"] = 0
@staticmethod
def get_amr_relevance(ab, isolate):
@@ -60,6 +61,14 @@ class PhenotypeResult(dict):
pheno_keys.append(self["key"])
feat_result["phenotypes"] = pheno_keys
+ # Compare the grade of the feature with what is already recorded,
+ # keep the greater value.
+ # seq_variations has not grade value as it will always be 3
+ feat_grade = feat_result.get("grade", 3)
+ if feat_grade > self["grade"]:
+ self["grade"] = feat_grade
+
+
# Add unique PMIDs to feature results
if(feature.pmids is not None):
for pmid in feature.pmids:
=====================================
src/resfinder/cge/output/std_results.py
=====================================
@@ -44,7 +44,7 @@ class ResFinderResultHandler():
Method loads the given res_collection with results from res.
"""
- for db_name, db in res.items():
+ for db_name, db in res.results.items():
if(db_name == "excluded"):
continue
@@ -52,14 +52,13 @@ class ResFinderResultHandler():
continue
for unique_id, hit_db in db.items():
- if(unique_id in res["excluded"]):
+ if(unique_id in res.results["excluded"]):
continue
gene_result = GeneResult(res_collection, hit_db, ref_db_name,
- conf)
+ conf, res)
add_gene_result_if_key_not_None(gene_result, res_collection)
-
@staticmethod
def load_res_profile(res_collection, isolate, amr_abbreviations):
"""
=====================================
src/resfinder/cge/phenotype2genotype/res_profile.py
=====================================
@@ -43,6 +43,10 @@ class PhenoDB(dict):
eprint("ERROR: No phenotype database files where specified.")
quit(1)
+ # mut_type_is_defined indicates the new pointfinder db with AA/NUC
+ # instead of DNA/RNA
+ self.mut_type_is_defined = False
+
if(acquired_file):
self.load_acquired_db(acquired_file)
@@ -51,9 +55,7 @@ class PhenoDB(dict):
self.load_disinfectant_db(disinf_file)
if(point_file):
- # mut_type_is_defined indicates the new db with AA/NUC
- # instead of DNA/RNA
- self.mut_type_is_defined = False
+
if os.path.basename(point_file) == "resistens-overview.txt":
self.load_point_old_db(point_file)
else:
=====================================
src/resfinder/cge/pointfinder.py
=====================================
@@ -395,7 +395,7 @@ class PointFinder(CGEFinder):
# Should only be one hit (the best)
for hit_key, entry in hits.items():
known_muts = PointFinder._get_known_mis_matches(
- hit_key, entry["mis_matches"], phenodb)
+ entry['sbjct_header'], entry["mis_matches"], phenodb)
entry["mis_matches"] = known_muts
gene_hits["mis_matches"] = known_muts
except AttributeError:
@@ -412,11 +412,8 @@ class PointFinder(CGEFinder):
@staticmethod
def _get_known_mis_matches(entry_key, mis_matches, phenodb):
- try:
- gene_ref_id = entry_key.split(":")[2]
- except:
- gene_ref_id = entry_key
- gene_db_id = gene_ref_id.replace("_", ";;")
+
+ gene_db_id = entry_key.replace("_", ";;")
known = []
for mis_match in mis_matches:
if mis_match[0] != 'sub':
=====================================
src/resfinder/run_resfinder.py
=====================================
@@ -6,6 +6,7 @@ import subprocess
from argparse import ArgumentParser
import pickle
import json
+import hashlib
from cgelib.output.result import Result
from cgelib.utils.loaders_mixin import LoadersMixin
@@ -30,6 +31,23 @@ def eprint(*args, **kwargs):
print(*args, file=sys.stderr, **kwargs)
+def get_software_exec_res(conf: Config) -> dict:
+ software_exec_res = {
+ "type": "software_exec",
+ "command": " ".join(sys.argv),
+ "parameters": get_call_parameters(conf)
+ }
+ software_exec_res["key"] = hashlib.sha1(
+ bytes(software_exec_res["command"], 'UTF-8')).hexdigest()
+ return software_exec_res
+
+
+def get_call_parameters(conf: Config) -> dict:
+ parameters = vars(conf).copy()
+ del (parameters['amr_abbreviations'])
+ return parameters
+
+
def main():
# version = read_version("VERSION")
@@ -206,13 +224,16 @@ def main():
}
std_result.add(**init_result_data)
- if(conf.acquired):
+ if conf.acquired:
std_result.init_database("ResFinder", conf.db_path_res)
- if(conf.point):
+ if conf.point:
std_result.init_database("PointFinder", conf.db_path_point_root)
- if(conf.disinf):
+ if conf.disinf:
std_result.init_database("DisinFinder", conf.db_path_disinf)
+ std_result.add_class(cl="software_executions", **
+ get_software_exec_res(conf))
+
# Load genotype to phenotype database
res_pheno_db = PhenoDB(
abclassdef_file=conf.abclassdef_file,
@@ -226,7 +247,7 @@ def main():
# ResFinder
##########################################################################
- if(conf.acquired is True):
+ if conf.acquired is True:
blast_results = None
kma_run = None
@@ -238,7 +259,7 @@ def main():
notes=conf.db_notes_file,
db_path_kma=conf.db_path_res_kma)
- if(conf.inputfasta):
+ if (conf.inputfasta):
blast_results = acquired_finder.blast(
inputfile=conf.inputfasta,
out_path=conf.outPath_res_blast,
@@ -256,12 +277,12 @@ def main():
software="ResFinder")
ResFinderResultHandler.standardize_results(std_result,
- blast_results.results,
+ blast_results,
"ResFinder",
conf)
else:
- if(conf.nanopore):
+ if (conf.nanopore):
kma_run = acquired_finder.kma(
inputfile_1=conf.inputfastq_1,
inputfile_2=conf.inputfastq_2,
@@ -301,13 +322,13 @@ def main():
software="ResFinder")
ResFinderResultHandler.standardize_results(std_result,
- kma_run.results,
+ kma_run,
"ResFinder",
conf)
##########################################################################
# DisinFinder
##########################################################################
- if(conf.disinf is True):
+ if (conf.disinf is True):
blast_results = None
kma_run = None
@@ -319,7 +340,7 @@ def main():
notes=conf.db_notes_disinf_file,
db_path_kma=conf.db_path_disinf_kma)
- if(conf.inputfasta):
+ if (conf.inputfasta):
blast_results = disinf_finder.blast(
inputfile=conf.inputfasta,
out_path=conf.outPath_disinf_blast,
@@ -337,12 +358,12 @@ def main():
software="DisinFinder")
ResFinderResultHandler.standardize_results(std_result,
- blast_results.results,
+ blast_results,
"DisinFinder",
conf)
else:
- if(conf.nanopore):
+ if (conf.nanopore):
kma_run = disinf_finder.kma(
inputfile_1=conf.inputfastq_1,
inputfile_2=conf.inputfastq_2,
@@ -382,14 +403,14 @@ def main():
software="DisinFinder")
ResFinderResultHandler.standardize_results(std_result,
- kma_run.results,
+ kma_run,
"DisinFinder",
conf)
##########################################################################
# PointFinder
##########################################################################
- if(conf.point):
+ if (conf.point):
blast_results = None
kma_run = None
@@ -400,7 +421,7 @@ def main():
ignore_indels=conf.ignore_indels,
ignore_stop_codons=conf.ignore_stop_codons)
- if(conf.inputfasta):
+ if (conf.inputfasta):
method = PointFinder.TYPE_BLAST
@@ -415,7 +436,7 @@ def main():
else:
method = PointFinder.TYPE_KMA
- if(conf.nanopore):
+ if (conf.nanopore):
kma_run = finder.kma(inputfile_1=conf.inputfastq_1,
inputfile_2=conf.inputfastq_2,
out_path=conf.outPath_point_kma,
@@ -445,15 +466,15 @@ def main():
results = kma_run.results
- if(conf.specific_gene):
+ if (conf.specific_gene):
results = PointFinder.discard_from_dict(
in_dict=results, wanted_list=conf.specific_gene)
- if(method == PointFinder.TYPE_BLAST):
+ if (method == PointFinder.TYPE_BLAST):
results_pnt = finder.find_best_seqs(results, conf.pf_gene_cov)
else:
results_pnt = results[finder.species]
- if(results_pnt == "No hit found"):
+ if (results_pnt == "No hit found"):
results_pnt = {}
else:
results_pnt["excluded"] = results["excluded"]
@@ -482,11 +503,11 @@ def main():
isolate = Isolate(name=conf.sample_name, species=conf.species,
amr_panel_file=conf.db_panels_file)
- if(conf.acquired or conf.disinf):
+ if (conf.acquired or conf.disinf):
isolate.load_finder_results(std_table=std_result,
phenodb=res_pheno_db,
type="seq_regions")
- if(conf.point):
+ if (conf.point):
isolate.load_finder_results(std_table=std_result,
phenodb=res_pheno_db,
type="seq_variations")
@@ -495,7 +516,7 @@ def main():
ResFinderResultHandler.load_res_profile(std_result, isolate,
conf.amr_abbreviations)
- if(conf.out_json):
+ if (conf.out_json):
std_result_file = conf.out_json
else:
std_result_file = "{}/{}.json".format(
@@ -507,7 +528,7 @@ def main():
pheno_profile_str = isolate.profile_to_str_table(header=True)
# TODO: REMOVE THE NEED FOR THE PICKLED FILE
- if(conf.pickle):
+ if (conf.pickle):
isolate_pickle = open("{}/isolate.p".format(conf.outputPath), "wb")
pickle.dump(isolate, isolate_pickle, protocol=2)
@@ -515,7 +536,7 @@ def main():
with open(pheno_table_file, 'w') as fh:
fh.write(pheno_profile_str)
- if(conf.species is not None):
+ if (conf.species is not None):
# Apply AMR panel
input_amr_panels = "{}/phenotype_panels.txt".format(conf.db_path_res)
res_sum_table = ResSumTable(pheno_profile_str)
@@ -527,8 +548,9 @@ def main():
# If specified species does not have an associated panel, just ignore it
# and exit.
except PanelNameError:
- eprint("Warning: No panel was detected for the species: {}"
- .format(conf.species))
+ if conf.species != 'other':
+ eprint("Warning: No panel was detected for the species: {}"
+ .format(conf.species))
sys.exit()
amr_panel_filename = conf.species.replace(" ", "_")
@@ -542,5 +564,6 @@ def main():
return 0
+
if __name__ == '__main__':
sys.exit(main())
=====================================
tests/resfinder/cge/output/test_gene_result.md
=====================================
@@ -70,15 +70,28 @@ results from a ResFinder hit.
## Methods
+### calc_gene_grade(coverage: float, identity: float) -> int
+
+```python
+
+>>> GeneResult.calc_gene_grade(coverage=100, identity=100)
+3
+>>> GeneResult.calc_gene_grade(coverage=100, identity=22.5)
+2
+>>> GeneResult.calc_gene_grade(coverage=10.1, identity=0)
+1
+
+```
+
### remove_NAs()
```python
-res["test_NA"] = "NA"
-res["test_None"] = None
-res.remove_NAs()
-assert("test_NA" not in res)
-assert("test_None" not in res)
+>>> gene_result_blast["test_NA"] = "NA"
+>>> gene_result_blast["test_None"] = None
+>>> gene_result_blast.remove_NAs()
+>>> assert("test_NA" not in gene_result_blast)
+>>> assert("test_None" not in gene_result_blast)
```
=====================================
tests/resfinder/cge/output/test_phenotype_result.md
=====================================
@@ -71,7 +71,8 @@
... "ref_acc": "KF986263",
... "ref_start_pos": 1,
... "ref_end_pos": 100,
-... "ref_database": ["ResFinder-unknown"]
+... "ref_database": ["ResFinder-unknown"],
+... "grade": 1
... }
>>> gyra = {
@@ -91,7 +92,8 @@
... 'query_start_pos': 1,
... 'query_end_pos': 2628,
... 'ref_database': ['PointFinder-a2b2ce4'],
-... 'coverage': 100.0
+... 'coverage': 100.0,
+... 'grade': 2
... }
>>> pg81d = {
@@ -211,8 +213,12 @@ True
['blaOXA-384;;1;;KF986263']
>>> res["phenotypes"]["carbapenem"]["amr_classes"]
['beta-lactam']
+>>> res["phenotypes"]["carbapenem"]["grade"]
+1
>>> res["seq_regions"]["blaOXA-384;;1;;KF986263"]["phenotypes"]
['carbapenem']
+>>> res["seq_regions"]["blaOXA-384;;1;;KF986263"]["grade"]
+1
>>> pheno2 = PhenotypeResult(ab_m1, isolate)
>>> pheno2.set_resistant(True)
=====================================
tests/resfinder/cge/output/test_std_results.md
=====================================
@@ -56,6 +56,8 @@ hit.
>>> from cgelib.output.result import Result
>>> from src.resfinder.cge.output.gene_result import GeneResult
+>>> from cgecore.blaster.blaster import Blaster
+>>> import os
>>> res = Result.init_software_result(name="ResFinder", gitdir=".")
>>> res.init_database("ResFinder", ".")
@@ -73,24 +75,13 @@ Here a dummy hit (obtained using KMA) is created, named rf\_dat\_kma. It is stor
rf\_custom\_kma.
```python
+import tempfile
->>> rf_dat_kma = {}
->>> rf_dat_kma["sbjct_header"] = "blaOXA-384_1_KF986263"
->>> rf_dat_kma["perc_ident"] = 97
->>> rf_dat_kma["HSP_length"] = 100
->>> rf_dat_kma["sbjct_length"] = 90
->>> rf_dat_kma["sbjct_start"] = 1
->>> rf_dat_kma["sbjct_end"] = 90
->>> rf_dat_kma["contig_name"] = "NA"
->>> rf_dat_kma["query_start"] = "NA"
->>> rf_dat_kma["query_end"] = "NA"
->>> rf_dat_kma["perc_coverage"] = 100
->>> rf_dat_kma["depth"] = 21
-
->>> rf_custom_kma = {}
->>> rf_custom_kma["excluded"] = {}
->>> rf_custom_kma["aminoglycoside"] = "No hit found"
->>> rf_custom_kma["beta-lactam"] = {"unique_hit_key": rf_dat_kma}
+>>> resfinder_db_path = os.environ["CGE_RESFINDER_RESGENE_DB"]
+>>> blast_path = os.environ["CGE_BLASTN"]
+>>> rf_custom_kma = Blaster(inputfile="tests/data/test_isolate_01.fa", databases=["beta-lactam"], db_path=resfinder_db_path, out_path="tests/tmp_out", blast=blast_path)
+... #doctest: +ELLIPSIS
+Found...
```
@@ -207,7 +198,7 @@ PointFinder-...
>>> for k in res["seq_regions"]:
... print(k)
-blaOXA-384;;1;;KF986263
+blaB-2;;1;;AF189300
```
@@ -247,9 +238,9 @@ Create Isolate object
>>> from src.resfinder.cge.output.std_results import PointFinderResultHandler
>>> ResFinderResultHandler.load_res_profile(res, isolate, amr_abbreviations)
>>> res["phenotypes"]["ampicillin"]["seq_regions"]
-[]
+['blaB-2;;1;;AF189300']
>>> res["result_summary"]
-'UBE'
+'AMO_AMP_TIC'
```
@@ -271,7 +262,7 @@ PointFinder-...
>>> for k in res["seq_regions"]:
... print(k)
-blaOXA-384;;1;;KF986263
+blaB-2;;1;;AF189300
gyrA;;1;;CP073768.1
>>> for k in res["seq_variations"]:
@@ -345,6 +336,6 @@ gyrA;;1;;CP073768.1;;82;;g
>>> sum_str = ResFinderResultHandler.create_amr_summary_str(res, amr_abbreviations)
>>> sum_str
-'AML_IMI_UBE'
+'AMO_AMP_AML_IMI_TIC'
```
=====================================
tests/resfinder/cge/phenotype2genotype/test_isolate.md
=====================================
@@ -72,23 +72,31 @@ std_results test documentation.
```python
->>> rf_dat_kma = {}
->>> rf_dat_kma["sbjct_header"] = "blaOXA-384_1_KF986263"
->>> rf_dat_kma["perc_ident"] = 97
->>> rf_dat_kma["HSP_length"] = 100
->>> rf_dat_kma["sbjct_length"] = 90
->>> rf_dat_kma["sbjct_start"] = 1
->>> rf_dat_kma["sbjct_end"] = 90
->>> rf_dat_kma["contig_name"] = "NA"
->>> rf_dat_kma["query_start"] = "NA"
->>> rf_dat_kma["query_end"] = "NA"
->>> rf_dat_kma["perc_coverage"] = 100
->>> rf_dat_kma["depth"] = 21
-
->>> rf_custom_kma = {}
->>> rf_custom_kma["excluded"] = {}
->>> rf_custom_kma["aminoglycoside"] = "No hit found"
->>> rf_custom_kma["beta-lactam"] = {"unique_hit_key": rf_dat_kma}
+# >>> rf_dat_kma = {}
+# >>> rf_dat_kma["sbjct_header"] = "blaOXA-384_1_KF986263"
+# >>> rf_dat_kma["perc_ident"] = 97
+# >>> rf_dat_kma["HSP_length"] = 100
+# >>> rf_dat_kma["sbjct_length"] = 90
+# >>> rf_dat_kma["sbjct_start"] = 1
+# >>> rf_dat_kma["sbjct_end"] = 90
+# >>> rf_dat_kma["contig_name"] = "NA"
+# >>> rf_dat_kma["query_start"] = "NA"
+# >>> rf_dat_kma["query_end"] = "NA"
+# >>> rf_dat_kma["perc_coverage"] = 100
+# >>> rf_dat_kma["depth"] = 21
+#
+# >>> rf_custom_kma = {}
+# >>> rf_custom_kma["excluded"] = {}
+# >>> rf_custom_kma["aminoglycoside"] = "No hit found"
+# >>> rf_custom_kma["beta-lactam"] = {"unique_hit_key": rf_dat_kma}
+>>> from cgecore.blaster.blaster import Blaster
+>>> import os
+>>> import tempfile
+
+>>> resfinder_db_path = os.environ["CGE_RESFINDER_RESGENE_DB"]
+>>> rf_custom_kma = Blaster(inputfile="tests/data/test_isolate_01.fa", databases=["beta-lactam"], db_path=resfinder_db_path, out_path="tests/tmp_out")
+... #doctest: +ELLIPSIS
+Found...
>>> gyrA_kma_hit = {}
>>> gyrA_kma_hit["sbjct_header"] = "gyrA_1_CP073768.1"
@@ -182,7 +190,7 @@ False
>>> isolate.load_finder_results(std_table=res, phenodb=res_pheno_db,
... type="seq_variations")
->>> isolate["blaOXA-384_KF986263"][0].ab_class.pop()
+>>> isolate["blaB-2_AF189300"][0].ab_class.pop()
'beta-lactam'
>>> isolate["gyrA;;1;;CP073768.1_81_d"][0].ref_codon
'ggt'
@@ -211,9 +219,9 @@ False
```python
->>> feat_res_dict = res["seq_regions"]["blaOXA-384;;1;;KF986263"]
+>>> feat_res_dict = res["seq_regions"]["blaB-2;;1;;AF189300"]
>>> Isolate.get_phenodb_id(feat_res_dict, "seq_regions")
-('blaOXA-384_KF986263', '')
+('blaB-2_AF189300', '')
>>> feat_res_dict = res["seq_variations"]["gyrA;;1;;CP073768.1;;81;;d"]
>>> Isolate.get_phenodb_id(feat_res_dict, "seq_variations")
=====================================
tests/resfinder/cge/test_config.md
=====================================
@@ -70,7 +70,7 @@
>>> args.point = False
>>> conf = Config(args)
>>> print(conf.species)
-None
+other
>>> conf.amr_abbreviations["Amoxicillin"][0]
'AMO'
@@ -156,7 +156,7 @@ SystemExit: ERROR: Path not found: /file/not/found
'escherichia coli'
>>> str(Config.get_species("Other", species_def_filepath))
-'None'
+'other'
```
=====================================
tests/resfinder/test_run_resfinder.md
=====================================
@@ -0,0 +1,73 @@
+# PointFinder class tests
+
+This is only testing a very small fraction of the run_resfinder.
+
+## Setup
+
+```python
+
+>>> from src.resfinder.run_resfinder import *
+>>> from src.resfinder.cge.config import Config
+
+>>> class DummyArgs():
+... def __init__(self):
+... self.inputfasta = None
+... self.inputfastq = None
+... self.outputPath = "./tests/tmp_out/"
+... self.blastPath = None
+... self.kmaPath = None
+... self.species = None
+... self.ignore_missing_species = None
+... self.db_path_res = None
+... self.db_path_res_kma = None
+... self.databases = None
+... self.acquired = True
+... self.acq_overlap = None
+... self.min_cov = None
+... self.threshold = None
+... self.point = True
+... self.db_path_point = None
+... self.db_path_point_kma = None
+... self.specific_gene = None
+... self.unknown_mut = None
+... self.min_cov_point = None
+... self.threshold_point = None
+... self.ignore_indels = None
+... self.ignore_stop_codons = None
+... self.pickle = False
+... self.nanopore = False
+... self.out_json = None
+... self.disinfectant = False
+... self.db_path_disinf = None
+... self.db_path_disinf_kma = None
+... self.output_aln = False
+... self.species = "ecoli"
+
+>>> args = DummyArgs()
+>>> conf = Config(args)
+
+```
+
+## get_call_parameters(conf: Config) -> dict
+
+```python
+
+>>> parameters = get_call_parameters(conf=conf)
+>>> parameters["species"]
+'escherichia coli'
+>>> parameters["acquired"]
+True
+
+```
+
+## get_software_exec_res(conf: Config) -> dict
+
+```python
+
+>>> soft_exec = get_software_exec_res(conf=conf)
+>>> soft_exec["type"]
+'software_exec'
+>>> len(soft_exec["key"])
+40
+
+```
View it on GitLab: https://salsa.debian.org/med-team/resfinder/-/compare/54984aaa03f3cda0ab08a370eb1ead016bbd4dcb...f08fa09bf2ec23dbde4ffd1291925bea61b723c1
--
View it on GitLab: https://salsa.debian.org/med-team/resfinder/-/compare/54984aaa03f3cda0ab08a370eb1ead016bbd4dcb...f08fa09bf2ec23dbde4ffd1291925bea61b723c1
You're receiving this email because of your account on salsa.debian.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/debian-med-commit/attachments/20230226/c037786d/attachment-0001.htm>
More information about the debian-med-commit
mailing list