Passed
Push — main ( 7824be...e5b5eb )
by Douglas
02:02
created

ClinicalTrialsGovUtils.status_map()   A

Complexity

Conditions 1

Size

Total Lines 16
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 16
nop 1
dl 0
loc 16
rs 9.6
c 0
b 0
f 0
1
from __future__ import annotations
0 ignored issues
show
introduced by
Missing module docstring
Loading history...
2
3
import enum
4
from dataclasses import dataclass
5
from datetime import date
6
from typing import (
7
    AbstractSet,
8
    FrozenSet,
9
    Mapping,
10
    NamedTuple,
11
    Optional,
12
    Sequence,
13
    Set,
14
    Tuple,
15
    Union,
16
)
17
18
import orjson
0 ignored issues
show
introduced by
Unable to import 'orjson'
Loading history...
19
from pocketutils.core.dot_dict import NestedDotDict
0 ignored issues
show
introduced by
Unable to import 'pocketutils.core.dot_dict'
Loading history...
20
from pocketutils.core.enums import CleverEnum
0 ignored issues
show
introduced by
Unable to import 'pocketutils.core.enums'
Loading history...
21
from pocketutils.core.exceptions import XTypeError, XValueError
0 ignored issues
show
introduced by
Unable to import 'pocketutils.core.exceptions'
Loading history...
22
from pocketutils.tools.string_tools import StringTools
0 ignored issues
show
introduced by
Unable to import 'pocketutils.tools.string_tools'
Loading history...
23
24
from mandos.model.apis.pubchem_support._nav_fns import Mapx
25
from mandos.model.apis.pubchem_support._patterns import Patterns
26
from mandos.model.utils.setup import MandosResources
27
28
hazards = MandosResources.file("hazards.json").read_text(encoding="utf8")
29
hazards = NestedDotDict(orjson.loads(hazards))
30
hazards = {d["code"]: d for d in hazards["signals"]}
31
32
33
@dataclass(frozen=True, repr=True, eq=True, order=True)
0 ignored issues
show
introduced by
Missing class docstring
Loading history...
34
class ComputedProperty:
35
    key: str
36
    value: Union[int, str, float, bool]
37
    unit: Optional[str]
38
    ref: str
39
40
    def req_is(self, type_) -> Union[int, str, float, bool]:
0 ignored issues
show
introduced by
Missing function or method docstring
Loading history...
41
        if not isinstance(self.value, type_):
42
            raise XTypeError(f"{self.key}->{self.value} has {type(self.value)}, not {type_}")
43
        return self.value
44
45
    @property
46
    def as_str(self) -> str:
0 ignored issues
show
introduced by
Missing function or method docstring
Loading history...
47
        return f"{self.value} {self.unit}"
48
49
50
class Code(str):
0 ignored issues
show
introduced by
Missing class docstring
Loading history...
51
    @property
52
    def type_name(self) -> str:
0 ignored issues
show
introduced by
Missing function or method docstring
Loading history...
53
        return self.__class__.__name__.lower()
54
55
    @classmethod
56
    def of(cls, value: Union[str, int, float]) -> __qualname__:
0 ignored issues
show
Comprehensibility Best Practice introduced by
Undefined variable '__qualname__'
Loading history...
Coding Style Naming introduced by
Method name "of" doesn't conform to snake_case naming style ('([^\\W\\dA-Z][^\\WA-Z]2,|_[^\\WA-Z]*|__[^\\WA-Z\\d_][^\\WA-Z]+__)$' pattern)

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
introduced by
Missing function or method docstring
Loading history...
57
        value = StringTools.strip_off_end(str(value).strip(), ".0").strip()
58
        return cls(value)
59
60
    @classmethod
61
    def of_nullable(cls, value: Union[None, str, int, float]) -> Optional[__qualname__]:
0 ignored issues
show
introduced by
Missing function or method docstring
Loading history...
62
        if value is None:
63
            return None
64
        return cls.of(value)
65
66
67
class Codes:
68
    """
69
    These turn out to be extremely useful for documenting return types.
70
    For example, ``DrugbankInteraction`` might have a ``gene`` field,
71
    which can be described as a ``GenecardSymbol`` if known.
72
    """
73
74
    class ChemIdPlusOrganism(Code):
75
        """
76
        E.g. 'women', 'frog', 'infant', or 'domestic animals - goat/sheep'
77
        """
78
79
        @property
80
        def is_human(self) -> bool:
0 ignored issues
show
introduced by
Missing function or method docstring
Loading history...
81
            return str(self) in {"women", "woman", "men", "man", "infant", "infants", "human"}
82
83
    class ChemIdPlusEffect(Code):
84
        """
85
        E.g. 'BEHAVIORAL: MUSCLE WEAKNESS'
86
        """
87
88
        @property
89
        def category(self) -> str:
0 ignored issues
show
introduced by
Missing function or method docstring
Loading history...
90
            return self[: self.index(":")].strip()
91
92
        @property
93
        def subcategory(self) -> str:
0 ignored issues
show
introduced by
Missing function or method docstring
Loading history...
94
            return self[self.index(":") + 1 :].strip()
95
96
    class EcNumber(Code):
97
        """
98
        e.g. 'EC:4.6.1.1'
99
        """
100
101
    class GeneId(Code):
102
        """
103
        GeneCard, UniProt gene name, etc.
104
        e.g. 'slc1a2'
105
        """
106
107
    class ClinicaltrialId(Code):
108
        """
109
        From clinicaltrials.gov
110
        """
111
112
    class GenericDiseaseCode(Code):
113
        """
114
        From clinicaltrials.gov; pure int
115
        """
116
117
    class GenecardSymbol(GeneId):
0 ignored issues
show
Documentation introduced by
Empty class docstring
Loading history...
118
        """ """
119
120
    class UniprotId(GeneId):
0 ignored issues
show
Documentation introduced by
Empty class docstring
Loading history...
121
        """ """
122
123
    class PubchemCompoundId(Code):
124
        """
125
        e.g. 2352
126
        """
127
128
        @property
129
        def value(self) -> int:
0 ignored issues
show
introduced by
Missing function or method docstring
Loading history...
130
            return int(self)
131
132
    class AtcCode(Code):
0 ignored issues
show
Documentation introduced by
Empty class docstring
Loading history...
133
        """ """
134
135
    class PubmedId(Code):
0 ignored issues
show
Documentation introduced by
Empty class docstring
Loading history...
136
        """ """
137
138
    class Doi(Code):
0 ignored issues
show
Documentation introduced by
Empty class docstring
Loading history...
139
        """ """
140
141
    class MeshCode(Code):
0 ignored issues
show
Documentation introduced by
Empty class docstring
Loading history...
142
        """ """
143
144
    class PdbId(Code):
0 ignored issues
show
Documentation introduced by
Empty class docstring
Loading history...
145
        """ """
146
147
    class MeshHeading(Code):
0 ignored issues
show
Documentation introduced by
Empty class docstring
Loading history...
148
        """ """
149
150
    class MeshSubheading(Code):
0 ignored issues
show
Documentation introduced by
Empty class docstring
Loading history...
151
        """ """
152
153
    class DrugbankCompoundId(Code):
0 ignored issues
show
Documentation introduced by
Empty class docstring
Loading history...
154
        """ """
155
156
    class DeaSchedule(Code):
0 ignored issues
show
Documentation introduced by
Empty class docstring
Loading history...
157
        """ """
158
159
        @property
160
        def value(self) -> int:
0 ignored issues
show
introduced by
Missing function or method docstring
Loading history...
161
            return Mapx.roman_to_arabic(1, 5)(self)
162
163
    class GhsCode(Code):
0 ignored issues
show
Documentation introduced by
Empty class docstring
Loading history...
164
        """ """
165
166
167
class CoOccurrenceType(CleverEnum):
0 ignored issues
show
introduced by
Missing class docstring
Loading history...
168
    chemical = enum.auto()
169
    gene = enum.auto()
170
    disease = enum.auto()
171
172
    @property
173
    def x_name(self) -> str:
0 ignored issues
show
introduced by
Missing function or method docstring
Loading history...
174
        if self is CoOccurrenceType.chemical:
0 ignored issues
show
unused-code introduced by
Unnecessary "elif" after "return"
Loading history...
175
            return "ChemicalNeighbor"
176
        elif self is CoOccurrenceType.gene:
177
            return "ChemicalGeneSymbolNeighbor"
178
        elif self is CoOccurrenceType.disease:
179
            return "ChemicalDiseaseNeighbor"
180
        raise AssertionError(f"{self} not found!!")
181
182
    @property
183
    def id_name(self) -> str:
0 ignored issues
show
introduced by
Missing function or method docstring
Loading history...
184
        if self is CoOccurrenceType.chemical:
0 ignored issues
show
unused-code introduced by
Unnecessary "elif" after "return"
Loading history...
185
            return "CID"
186
        elif self is CoOccurrenceType.gene:
187
            return "GeneSymbol"
188
        elif self is CoOccurrenceType.disease:
189
            return "MeSH"
190
        raise AssertionError(f"{self} not found!!")
191
192
193
class _PM(NamedTuple):
194
    name: str
195
    score: float
196
197
198
class _SM(NamedTuple):
199
    name: str
200
    simplified: str
201
202
203
_phase_map: Mapping[str, _PM] = dict(
204
    phase_4=_PM("Phase 4", 4),
205
    phase_3=_PM("Phase 3", 3),
206
    phase_2=_PM("Phase 2", 2),
207
    phase_1=_PM("Phase 1", 1),
208
    early_phase_1=_PM("Early Phase 1", 0.5),
209
    phase_2_or_3=_PM("Phase 2/Phase 3", 2.5),
210
    na=_PM("N/A", 0.5),
211
    unknown=_PM("", 0.5),  # doesn't occur in the wild
212
)
213
_status_map: Mapping[str, _SM] = dict(
214
    unknown=_SM("Unknown status", "unknown"),
215
    completed=_SM("Completed", "completed"),
216
    terminated=_SM("Terminated", "stopped"),
217
    suspended=_SM("Suspended", "stopped"),
218
    withdrawn=_SM("Withdrawn", "stopped"),
219
    not_yet_recruiting=_SM("Not yet recruiting", "ongoing"),
220
    recruiting=_SM("Recruiting", "ongoing"),
221
    enrolling_by_invitation=_SM("Enrolling by invitation", "ongoing"),
222
    active_not_recruiting=_SM("Active, not recruiting", "ongoing"),
223
    available=_SM("Available", "completed"),
224
    no_longer_available=_SM("No longer available", "completed"),
225
    temporarily_not_available=_SM("Temporarily not available", "completed"),
226
    approved_for_marketing=_SM("Approved for marketing", "completed"),
227
)
228
229
230
class ClinicalTrialSimplifiedStatus(CleverEnum):
0 ignored issues
show
introduced by
Missing class docstring
Loading history...
231
    unknown = ()
232
    completed = ()
233
    stopped = ()
234
    ongoing = ()
235
236
    @classmethod
237
    def parse(cls, st: str) -> AbstractSet[ClinicalTrialSimplifiedStatus]:
0 ignored issues
show
Coding Style Naming introduced by
Argument name "st" doesn't conform to snake_case naming style ('([^\\W\\dA-Z][^\\WA-Z]2,|_[^\\WA-Z]*|__[^\\WA-Z\\d_][^\\WA-Z]+__)$' pattern)

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
introduced by
Missing function or method docstring
Loading history...
238
        _mp = {"@all": set(cls)}
239
        found: Set[ClinicalTrialSimplifiedStatus] = set()
240
        for s in st.lower().split(","):
0 ignored issues
show
Coding Style Naming introduced by
Variable name "s" doesn't conform to snake_case naming style ('([^\\W\\dA-Z][^\\WA-Z]2,|_[^\\WA-Z]*|__[^\\WA-Z\\d_][^\\WA-Z]+__)$' pattern)

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
241
            found.update(_mp.get(s.strip(), {s.strip()}))
242
        return found
243
244
245
class ClinicalTrialPhase(CleverEnum):
0 ignored issues
show
introduced by
Missing class docstring
Loading history...
246
    unknown = ()
247
    na = ()
248
    phase_2_or_3 = ()
249
    early_phase_1 = ()
250
    phase_1 = ()
251
    phase_2 = ()
252
    phase_3 = ()
253
    phase_4 = ()
254
255
    @classmethod
256
    def _unmatched_type(cls) -> Optional[__qualname__]:
257
        return cls.unknown
258
259
    @classmethod
260
    def parse(cls, st: str) -> AbstractSet[ClinicalTrialPhase]:
0 ignored issues
show
introduced by
Missing function or method docstring
Loading history...
Coding Style Naming introduced by
Argument name "st" doesn't conform to snake_case naming style ('([^\\W\\dA-Z][^\\WA-Z]2,|_[^\\WA-Z]*|__[^\\WA-Z\\d_][^\\WA-Z]+__)$' pattern)

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
261
        _by_score = {"@" + str(v): {x for x in cls if x.score == v} for v in {x.score for x in cls}}
262
        _map = {**{"@all": set(cls)}, **_by_score}
263
        found: Set[ClinicalTrialPhase] = set()
264
        for s in [s.strip() for s in st.lower().split(",")]:
0 ignored issues
show
Coding Style Naming introduced by
Variable name "s" doesn't conform to snake_case naming style ('([^\\W\\dA-Z][^\\WA-Z]2,|_[^\\WA-Z]*|__[^\\WA-Z\\d_][^\\WA-Z]+__)$' pattern)

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
265
            found.update(_map.get(s, {cls[s]}))
266
        return found
267
268
    @classmethod
269
    def of(cls, s: Union[str, __qualname__]) -> __qualname__:
0 ignored issues
show
introduced by
Missing function or method docstring
Loading history...
Coding Style Naming introduced by
Argument name "s" doesn't conform to snake_case naming style ('([^\\W\\dA-Z][^\\WA-Z]2,|_[^\\WA-Z]*|__[^\\WA-Z\\d_][^\\WA-Z]+__)$' pattern)

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
Coding Style Naming introduced by
Method name "of" doesn't conform to snake_case naming style ('([^\\W\\dA-Z][^\\WA-Z]2,|_[^\\WA-Z]*|__[^\\WA-Z\\d_][^\\WA-Z]+__)$' pattern)

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
270
        if isinstance(s, str):
271
            s = _phase_map.get(s, _PM(s, -1)).name
272
        return super().of(s)
273
274
    @property
275
    def raw_name(self) -> str:
0 ignored issues
show
introduced by
Missing function or method docstring
Loading history...
276
        return _phase_map[self.name].name
277
278
    @property
279
    def score(self) -> float:
0 ignored issues
show
introduced by
Missing function or method docstring
Loading history...
280
        return _phase_map[self.name].score
281
282
283
class ClinicalTrialStatus(CleverEnum):
0 ignored issues
show
introduced by
Missing class docstring
Loading history...
284
285
    unknown = ()
286
    completed = ()
287
    terminated = ()
288
    suspended = ()
289
    withdrawn = ()
290
    not_yet_recruiting = ()
291
    recruiting = ()
292
    enrolling_by_invitation = ()
293
    active_not_recruiting = ()
294
    available = ()
295
    no_longer_available = ()
296
    temporarily_not_available = ()
297
    approved_for_marketing = ()
298
299
    @classmethod
300
    def _unmatched_type(cls) -> Optional[__qualname__]:
301
        return cls.unknown
302
303
    @classmethod
304
    def parse(cls, st: str) -> AbstractSet[ClinicalTrialStatus]:
0 ignored issues
show
introduced by
Missing function or method docstring
Loading history...
Coding Style Naming introduced by
Argument name "st" doesn't conform to snake_case naming style ('([^\\W\\dA-Z][^\\WA-Z]2,|_[^\\WA-Z]*|__[^\\WA-Z\\d_][^\\WA-Z]+__)$' pattern)

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
305
        _by_simple = {
306
            "@" + v: {x for x in cls if x.simplified.name == v}
307
            for v in {x.simplified.name for x in cls}
308
        }
309
        _map = {**{"@all": set(cls)}, **_by_simple}
310
        found: Set[ClinicalTrialStatus] = set()
311
        for s in [s.strip() for s in st.lower().split(",")]:
0 ignored issues
show
Coding Style Naming introduced by
Variable name "s" doesn't conform to snake_case naming style ('([^\\W\\dA-Z][^\\WA-Z]2,|_[^\\WA-Z]*|__[^\\WA-Z\\d_][^\\WA-Z]+__)$' pattern)

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
312
            found.update(_map.get(s, {cls[s]}))
313
        return found
314
315
    @classmethod
316
    def of(cls, s: Union[str, __qualname__]) -> __qualname__:
0 ignored issues
show
introduced by
Missing function or method docstring
Loading history...
Coding Style Naming introduced by
Argument name "s" doesn't conform to snake_case naming style ('([^\\W\\dA-Z][^\\WA-Z]2,|_[^\\WA-Z]*|__[^\\WA-Z\\d_][^\\WA-Z]+__)$' pattern)

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
Coding Style Naming introduced by
Method name "of" doesn't conform to snake_case naming style ('([^\\W\\dA-Z][^\\WA-Z]2,|_[^\\WA-Z]*|__[^\\WA-Z\\d_][^\\WA-Z]+__)$' pattern)

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
317
        if isinstance(s, str):
318
            s = _status_map.get(s, _SM(s, "--")).name
319
        return super().of(s)
320
321
    @property
322
    def raw_name(self) -> str:
0 ignored issues
show
introduced by
Missing function or method docstring
Loading history...
323
        return _status_map[self.name][0]
324
325
    @property
326
    def simplified(self) -> ClinicalTrialSimplifiedStatus:
0 ignored issues
show
introduced by
Missing function or method docstring
Loading history...
327
        return _status_map[self.name][1]
328
329
330
@dataclass(frozen=True, repr=True, eq=True)
0 ignored issues
show
best-practice introduced by
Too many instance attributes (9/7)
Loading history...
introduced by
Missing class docstring
Loading history...
331
class ClinicalTrial:
332
    ctid: Codes.ClinicaltrialId
333
    title: str
334
    conditions: FrozenSet[str]
335
    disease_ids: FrozenSet[Codes.ClinicaltrialId]
336
    phase: str
337
    status: str
338
    interventions: FrozenSet[str]
339
    cids: FrozenSet[Codes.PubchemCompoundId]
340
    source: str
341
342
    @property
343
    def mapped_phase(self) -> ClinicalTrialPhase:
0 ignored issues
show
introduced by
Missing function or method docstring
Loading history...
344
        return ClinicalTrialPhase.of(self.phase)
345
346
    @property
347
    def mapped_status(self) -> ClinicalTrialStatus:
0 ignored issues
show
introduced by
Missing function or method docstring
Loading history...
348
        return ClinicalTrialStatus.of(self.status)
349
350
351
@dataclass(frozen=True, repr=True, eq=True)
0 ignored issues
show
introduced by
Missing class docstring
Loading history...
352
class GhsCode:
353
    code: Codes.GhsCode
354
    statement: str
355
    clazz: str
356
    categories: FrozenSet[str]
357
    signal_word: str
358
    type: str
359
360
    @classmethod
361
    def find(cls, code: str) -> GhsCode:
0 ignored issues
show
introduced by
Missing function or method docstring
Loading history...
362
        h = hazards[code]
0 ignored issues
show
Coding Style Naming introduced by
Variable name "h" doesn't conform to snake_case naming style ('([^\\W\\dA-Z][^\\WA-Z]2,|_[^\\WA-Z]*|__[^\\WA-Z\\d_][^\\WA-Z]+__)$' pattern)

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
363
        cats = h["category"]  # TODO
0 ignored issues
show
Coding Style introduced by
TODO and FIXME comments should generally be avoided.
Loading history...
364
        return GhsCode(
365
            code=Codes.GhsCode(code),
366
            statement=h["statement"],
367
            clazz=h["class"],
368
            categories=cats,
369
            signal_word=h["signal_word"],
370
            type=h["type"],
371
        )
372
373
    @property
374
    def level(self) -> int:
0 ignored issues
show
introduced by
Missing function or method docstring
Loading history...
375
        return int(self.code[1])
376
377
378
@dataclass(frozen=True, repr=True, eq=True)
0 ignored issues
show
introduced by
Missing class docstring
Loading history...
379
class AcuteEffectEntry:
380
    gid: int
381
    effects: FrozenSet[Codes.ChemIdPlusEffect]
382
    organism: Codes.ChemIdPlusOrganism
383
    test_type: str
384
    route: str
385
    dose: str
386
387
    @property
388
    def mg_per_kg(self) -> float:
0 ignored issues
show
introduced by
Missing function or method docstring
Loading history...
389
        match = Patterns.mg_per_kg_pattern.search(self.dose)
390
        if match is None:
391
            # e.g. mg/m3/2H (mass per liter per time)
392
            raise XValueError(f"Dose {self.dose} (acute effect {self.gid}) could not be parsed")
393
        scale = dict(g=1e3, gm=1e3, mg=1, ug=10e-3, ng=10e-6, pg=10e-9)[match.group(2)]
394
        return float(match.group(1)) * scale
395
396
397
@dataclass(frozen=True, repr=True, eq=True)
0 ignored issues
show
introduced by
Missing class docstring
Loading history...
398
class AssociatedDisorder:
399
    gid: str
400
    disease_id: Codes.MeshCode
401
    disease_name: str
402
    evidence_type: str
403
    n_refs: int
404
405
406
@dataclass(frozen=True, repr=True, eq=True)
0 ignored issues
show
introduced by
Missing class docstring
Loading history...
407
class AtcCode:
408
    code: str
409
    name: str
410
411
    @property
412
    def level(self) -> int:
0 ignored issues
show
introduced by
Missing function or method docstring
Loading history...
413
        return len(self.parts)
414
415
    @property
416
    def parts(self) -> Sequence[str]:
0 ignored issues
show
introduced by
Missing function or method docstring
Loading history...
417
        match = Patterns.atc_parts_pattern.fullmatch(self.code)
418
        return [g for g in match.groups() if g is not None]
419
420
421
class DrugbankTargetType(CleverEnum):
0 ignored issues
show
introduced by
Missing class docstring
Loading history...
422
    target = enum.auto()
423
    carrier = enum.auto()
424
    transporter = enum.auto()
425
    enzyme = enum.auto()
426
427
428
@dataclass(frozen=True, repr=True, eq=True)
0 ignored issues
show
introduced by
Missing class docstring
Loading history...
best-practice introduced by
Too many instance attributes (10/7)
Loading history...
429
class DrugbankInteraction:
430
    record_id: Optional[str]
431
    gene_symbol: Codes.GeneId
432
    action: Optional[str]
433
    protein_id: str
434
    target_type: DrugbankTargetType
435
    target_name: str
436
    general_function: Optional[str]
437
    specific_function: str
438
    pmids: FrozenSet[Codes.PubmedId]
439
    dois: FrozenSet[Codes.Doi]
440
441
442
@dataclass(frozen=True, repr=True, eq=True)
0 ignored issues
show
introduced by
Missing class docstring
Loading history...
443
class DrugbankDdi:
444
    drug_drugbank_id: Codes.DrugbankCompoundId
445
    drug_pubchem_id: Codes.PubchemCompoundId
446
    drug_drugbank_name: str
447
    description: str
448
449
450
class Activity(CleverEnum):
0 ignored issues
show
introduced by
Missing class docstring
Loading history...
451
    active = enum.auto()
452
    inactive = enum.auto()
453
    inconclusive = enum.auto()
454
    unspecified = enum.auto()
455
456
457
@dataclass(frozen=True, repr=True, eq=True)
0 ignored issues
show
introduced by
Missing class docstring
Loading history...
best-practice introduced by
Too many instance attributes (13/7)
Loading history...
458
class Bioactivity:
459
    assay_id: int
460
    assay_type: str
461
    assay_ref: str
462
    assay_name: str
463
    assay_made_date: date
464
    gene_id: Optional[Codes.GeneId]
465
    tax_id: Optional[int]
466
    pmid: Optional[Codes.PubmedId]
467
    activity: Optional[Activity]
468
    activity_name: Optional[str]
469
    activity_value: Optional[float]
470
    target_name: Optional[str]
471
    compound_name: str
472
473
    @property
474
    def target_name_abbrev_species(self) -> Tuple[Optional[str], str, Optional[str]]:
0 ignored issues
show
introduced by
Missing function or method docstring
Loading history...
475
        # first, look for a species name in parentheses
476
        # We use \)+ at the end instead of \)
477
        # this is to catch cases where we have parentheses inside of the species name
478
        # this happens with some virus strains, for e.g.
479
        match = Patterns.target_name_abbrev_species_pattern_1.fullmatch(self.target_name)
480
        if match is None:
481
            species = None
482
            target = self.target_name
483
        else:
484
            species = match.group(2)
485
            target = match.group(1)
486
        # now try to get an abbreviation
487
        match = Patterns.target_name_abbrev_species_pattern_2.fullmatch(target)
488
        if match is None:
489
            abbrev = None
490
            name = target
491
        else:
492
            abbrev = match.group(1)
493
            name = match.group(2)
494
        return name, abbrev, species
495
496
497
@dataclass(frozen=True, repr=True, eq=True)
0 ignored issues
show
introduced by
Missing class docstring
Loading history...
best-practice introduced by
Too many instance attributes (9/7)
Loading history...
498
class PdbEntry:
499
    pdbid: Codes.PdbId
500
    title: str
501
    exp_method: str
502
    resolution: float
503
    lig_names: FrozenSet[str]
504
    cids: FrozenSet[Codes.PubchemCompoundId]
505
    uniprot_ids: FrozenSet[Codes.UniprotId]
506
    pmids: FrozenSet[Codes.PubmedId]
507
    dois: FrozenSet[Codes.Doi]
508
509
510
@dataclass(frozen=True, repr=True, eq=True)
0 ignored issues
show
best-practice introduced by
Too many instance attributes (11/7)
Loading history...
introduced by
Missing class docstring
Loading history...
511
class PubmedEntry:
512
    pmid: Codes.PubmedId
513
    article_type: str
514
    pmidsrcs: FrozenSet[str]
515
    mesh_headings: FrozenSet[Codes.MeshHeading]
516
    mesh_subheadings: FrozenSet[Codes.MeshSubheading]
517
    mesh_codes: FrozenSet[Codes.MeshCode]
518
    cids: FrozenSet[Codes.PubchemCompoundId]
519
    article_title: str
520
    article_abstract: str
521
    journal_name: str
522
    pub_date: date
523
524
525
@dataclass(frozen=True, repr=True, eq=True)
0 ignored issues
show
introduced by
Missing class docstring
Loading history...
526
class Publication:
527
    pmid: Codes.PubmedId
528
    pub_date: date
529
    is_review: bool
530
    title: str
531
    journal: str
532
    relevance_score: int
533
534
535
@dataclass(frozen=True, repr=True, eq=True)
0 ignored issues
show
best-practice introduced by
Too many instance attributes (8/7)
Loading history...
introduced by
Missing class docstring
Loading history...
536
class CoOccurrence:
537
    neighbor_id: str
538
    neighbor_name: str
539
    kind: CoOccurrenceType
540
    # https://pubchemdocs.ncbi.nlm.nih.gov/knowledge-panels
541
    article_count: int
542
    query_article_count: int
543
    neighbor_article_count: int
544
    score: int
545
    publications: FrozenSet[Publication]
546
547
    def strip_pubs(self) -> CoOccurrence:
0 ignored issues
show
introduced by
Missing function or method docstring
Loading history...
548
        return CoOccurrence(
549
            self.neighbor_id,
550
            self.neighbor_name,
551
            self.kind,
552
            self.article_count,
553
            self.query_article_count,
554
            self.neighbor_article_count,
555
            self.score,
556
            frozenset({}),
557
        )
558
559
560
@dataclass(frozen=True, repr=True, eq=True)
0 ignored issues
show
Documentation introduced by
Empty class docstring
Loading history...
561
class DrugGeneInteraction:
562
    """ """
563
564
    gene_name: Optional[str]
565
    gene_claim_id: Optional[str]
566
    source: str
567
    interactions: FrozenSet[str]
568
    pmids: FrozenSet[Codes.PubmedId]
569
    dois: FrozenSet[Codes.Doi]
570
571
572
@dataclass(frozen=True, repr=True, eq=True)
0 ignored issues
show
introduced by
Missing class docstring
Loading history...
573
class ChemicalGeneInteraction:
574
    gene_name: Optional[Codes.GeneId]
575
    interactions: FrozenSet[str]
576
    tax_id: Optional[int]
577
    tax_name: Optional[str]
578
    pmids: FrozenSet[Codes.PubmedId]
579
580
581
__all__ = [
582
    "ClinicalTrial",
583
    "AssociatedDisorder",
584
    "AtcCode",
585
    "DrugbankInteraction",
586
    "DrugbankDdi",
587
    "Bioactivity",
588
    "Activity",
589
    "DrugGeneInteraction",
590
    "ChemicalGeneInteraction",
591
    "GhsCode",
592
    "PubmedEntry",
593
    "Code",
594
    "Codes",
595
    "CoOccurrenceType",
596
    "CoOccurrence",
597
    "Publication",
598
    "ComputedProperty",
599
    "ClinicalTrialStatus",
600
    "ClinicalTrialSimplifiedStatus",
601
    "ClinicalTrialPhase",
602
    "AcuteEffectEntry",
603
    "DrugbankTargetType",
604
]
605