atlas-ftag-tools 0.2.6__py3-none-any.whl → 0.2.7__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {atlas_ftag_tools-0.2.6.dist-info → atlas_ftag_tools-0.2.7.dist-info}/METADATA +1 -1
- {atlas_ftag_tools-0.2.6.dist-info → atlas_ftag_tools-0.2.7.dist-info}/RECORD +12 -12
- {atlas_ftag_tools-0.2.6.dist-info → atlas_ftag_tools-0.2.7.dist-info}/WHEEL +1 -1
- ftag/__init__.py +5 -4
- ftag/flavours.py +5 -0
- ftag/labeller.py +18 -9
- ftag/labels.py +127 -0
- ftag/sample.py +2 -1
- ftag/wps/discriminant.py +5 -4
- ftag/wps/working_points.py +1 -1
- ftag/flavour.py +0 -127
- ftag/test_cli_utils.py +0 -34
- {atlas_ftag_tools-0.2.6.dist-info → atlas_ftag_tools-0.2.7.dist-info}/entry_points.txt +0 -0
- {atlas_ftag_tools-0.2.6.dist-info → atlas_ftag_tools-0.2.7.dist-info}/top_level.txt +0 -0
@@ -1,14 +1,14 @@
|
|
1
|
-
ftag/__init__.py,sha256=
|
1
|
+
ftag/__init__.py,sha256=k5qBmtC7Ieh0trgm2Ba9Qj_6A2wQSpmAmXo2iIOAaI0,737
|
2
2
|
ftag/cli_utils.py,sha256=w3TtQmUHSyAKChS3ewvOtcSDAUJAZGIIomaNi8f446U,298
|
3
3
|
ftag/cuts.py,sha256=9_ooLZHaO3SnIQBNxwbaPZn-qptGdKnB27FdKQGTiTY,2933
|
4
|
-
ftag/
|
4
|
+
ftag/flavours.py,sha256=ShH4M2UjQZpZ_NlCctTm2q1tJbzYxjmGteioQ2GcqEU,114
|
5
5
|
ftag/flavours.yaml,sha256=E_vpn38qJ3-Tygg2aHlH4wkn_rR1On_lMeaG8OemHCQ,8285
|
6
6
|
ftag/git_check.py,sha256=Y-XqM80CVXZ5ZKrDdZcYOJt3X64uU6W3OP6Z0D7AZU0,1663
|
7
|
-
ftag/labeller.py,sha256=
|
7
|
+
ftag/labeller.py,sha256=IXUgU9UBir39PxVWRKs5r5fqI66Tv0x7nJD3-RYpbrg,2780
|
8
|
+
ftag/labels.py,sha256=C7IylPTnc32dFXq8C2Ks2wuljYK3WaY2EsPLGrhtXy8,3932
|
8
9
|
ftag/mock.py,sha256=Eyj3tkkaSSnqvS3G6NS7fq8sB__Nx8YE9-OM2_lpdoQ,4992
|
9
10
|
ftag/region.py,sha256=ANv0dGI2W6NJqD9fp7EfqAUReH4FOjc1gwl_Qn8llcM,360
|
10
|
-
ftag/sample.py,sha256=
|
11
|
-
ftag/test_cli_utils.py,sha256=xa08vf6SEOow58SSFagYdAselb-dkNOVvWsWheMnW-g,1001
|
11
|
+
ftag/sample.py,sha256=3N0FrRcu9l1sX8ohuGOHuMYGD0See6gMO4--7NzR2tE,2538
|
12
12
|
ftag/track_selector.py,sha256=fJNk_kIBQriBqV4CPT_3ReJbOUnavDDzO-u3EQlRuyk,2654
|
13
13
|
ftag/transform.py,sha256=uEGGJSnqoKOzLYQv650XdK_kDNw4Aw-5dc60z9Dp_y0,3963
|
14
14
|
ftag/vds.py,sha256=nRViQZQIORB95nC7NZsW3KsSoGkLzEdOsuCViH5h8-U,3296
|
@@ -19,10 +19,10 @@ ftag/hdf5/h5split.py,sha256=4Wy6Xc3J58MdD9aBaSZHf5ZcVFnJSkWsm42R5Pgo-R4,2448
|
|
19
19
|
ftag/hdf5/h5utils.py,sha256=-4zKTMtNCrDZr_9Ww7uzfsB7M7muBKpmm_1IkKJnHOI,3222
|
20
20
|
ftag/hdf5/h5writer.py,sha256=9FkClV__UbBqmFsq_h2jwiZnbWVm8QFRL_4mDZZBbTs,5316
|
21
21
|
ftag/wps/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
22
|
-
ftag/wps/discriminant.py,sha256=
|
23
|
-
ftag/wps/working_points.py,sha256=
|
24
|
-
atlas_ftag_tools-0.2.
|
25
|
-
atlas_ftag_tools-0.2.
|
26
|
-
atlas_ftag_tools-0.2.
|
27
|
-
atlas_ftag_tools-0.2.
|
28
|
-
atlas_ftag_tools-0.2.
|
22
|
+
ftag/wps/discriminant.py,sha256=VJdZlJJUwaTeyxmIDEk23rQSAuvWs6wDA3XRjDI6-_c,4277
|
23
|
+
ftag/wps/working_points.py,sha256=cvStSpP8Cbb_FWM8v59tFsscUvdeqi831tLn5BiHUEg,9741
|
24
|
+
atlas_ftag_tools-0.2.7.dist-info/METADATA,sha256=oo5m85dK467AWuK-L8xaIbLDVmRUO3r7vA_J1vgR5b8,5169
|
25
|
+
atlas_ftag_tools-0.2.7.dist-info/WHEEL,sha256=R06PA3UVYHThwHvxuRWMqaGcr-PuniXahwjmQRFMEkY,91
|
26
|
+
atlas_ftag_tools-0.2.7.dist-info/entry_points.txt,sha256=LfVLsZHQolqbPnwPgtmc5IQTh527BKkN2v-IpXWTNHw,137
|
27
|
+
atlas_ftag_tools-0.2.7.dist-info/top_level.txt,sha256=qiYQuKcAvMim-31FwkT3MTQu7WQm0s58tPAia5KKWqs,5
|
28
|
+
atlas_ftag_tools-0.2.7.dist-info/RECORD,,
|
ftag/__init__.py
CHANGED
@@ -2,13 +2,13 @@
|
|
2
2
|
|
3
3
|
from __future__ import annotations
|
4
4
|
|
5
|
-
__version__ = "v0.2.
|
6
|
-
|
5
|
+
__version__ = "v0.2.7"
|
7
6
|
|
8
7
|
from ftag import hdf5
|
9
8
|
from ftag.cuts import Cuts
|
10
|
-
from ftag.
|
9
|
+
from ftag.flavours import Flavours
|
11
10
|
from ftag.labeller import Labeller
|
11
|
+
from ftag.labels import Label, LabelContainer
|
12
12
|
from ftag.mock import get_mock_file
|
13
13
|
from ftag.sample import Sample
|
14
14
|
from ftag.transform import Transform
|
@@ -17,8 +17,9 @@ from ftag.wps.working_points import get_working_points
|
|
17
17
|
|
18
18
|
__all__ = [
|
19
19
|
"Cuts",
|
20
|
-
"Flavour",
|
21
20
|
"Flavours",
|
21
|
+
"Label",
|
22
|
+
"LabelContainer",
|
22
23
|
"Labeller",
|
23
24
|
"Sample",
|
24
25
|
"Transform",
|
ftag/flavours.py
ADDED
ftag/labeller.py
CHANGED
@@ -4,8 +4,9 @@ from dataclasses import dataclass
|
|
4
4
|
|
5
5
|
import numpy as np
|
6
6
|
|
7
|
-
from ftag
|
7
|
+
from ftag import Flavours
|
8
8
|
from ftag.hdf5 import join_structured_arrays, structured_from_dict
|
9
|
+
from ftag.labels import Label, LabelContainer
|
9
10
|
|
10
11
|
|
11
12
|
@dataclass
|
@@ -13,28 +14,36 @@ class Labeller:
|
|
13
14
|
"""
|
14
15
|
Defines a labelling scheme.
|
15
16
|
|
16
|
-
|
17
|
+
Classes are assigned integer labels in [0, ..., n] based on pre-defined selections.
|
17
18
|
|
18
19
|
Parameters
|
19
20
|
----------
|
20
|
-
labels :
|
21
|
+
labels : LabelContainer | list[str | Label]
|
21
22
|
The labels to be use.
|
22
23
|
require_labels : bool
|
23
24
|
Whether to require that all objects are labelled.
|
24
25
|
"""
|
25
26
|
|
26
|
-
labels:
|
27
|
+
labels: LabelContainer | list[str | Label]
|
27
28
|
require_labels: bool = True
|
28
29
|
|
29
|
-
@property
|
30
|
-
def variables(self):
|
31
|
-
return sum((label.cuts.variables for label in self.labels), [])
|
32
|
-
|
33
30
|
def __post_init__(self) -> None:
|
34
|
-
if isinstance(self.labels,
|
31
|
+
if isinstance(self.labels, LabelContainer):
|
35
32
|
self.labels = list(self.labels)
|
36
33
|
self.labels = sorted([Flavours[label] for label in self.labels])
|
37
34
|
|
35
|
+
@property
|
36
|
+
def variables(self) -> list[str]:
|
37
|
+
"""
|
38
|
+
Returns the variables used for labelling.
|
39
|
+
|
40
|
+
Returns
|
41
|
+
-------
|
42
|
+
list[str]
|
43
|
+
The variables used for labelling.
|
44
|
+
"""
|
45
|
+
return sum((label.cuts.variables for label in self.labels), []) # type: ignore[union-attr]
|
46
|
+
|
38
47
|
def get_labels(self, array: np.ndarray) -> np.ndarray:
|
39
48
|
"""
|
40
49
|
Returns the labels for the given array.
|
ftag/labels.py
ADDED
@@ -0,0 +1,127 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
3
|
+
from collections.abc import Iterator
|
4
|
+
from dataclasses import dataclass
|
5
|
+
from pathlib import Path
|
6
|
+
|
7
|
+
import yaml
|
8
|
+
|
9
|
+
from ftag.cuts import Cuts
|
10
|
+
|
11
|
+
|
12
|
+
def remove_suffix(string: str, suffix: str) -> str:
|
13
|
+
if string.endswith(suffix):
|
14
|
+
return string[: -len(suffix)]
|
15
|
+
return string
|
16
|
+
|
17
|
+
|
18
|
+
@dataclass(frozen=True)
|
19
|
+
class Label:
|
20
|
+
name: str
|
21
|
+
label: str
|
22
|
+
cuts: Cuts
|
23
|
+
colour: str
|
24
|
+
category: str
|
25
|
+
_px: str | None = None
|
26
|
+
|
27
|
+
@property
|
28
|
+
def px(self) -> str:
|
29
|
+
return self._px or f"p{remove_suffix(self.name, 'jets')}"
|
30
|
+
|
31
|
+
@property
|
32
|
+
def eff_str(self) -> str:
|
33
|
+
return self.label.replace("jets", "jet") + " efficiency"
|
34
|
+
|
35
|
+
@property
|
36
|
+
def rej_str(self) -> str:
|
37
|
+
return self.label.replace("jets", "jet") + " rejection"
|
38
|
+
|
39
|
+
@property
|
40
|
+
def frac_str(self) -> str:
|
41
|
+
return "f" + remove_suffix(self.name, "jets")
|
42
|
+
|
43
|
+
def __str__(self) -> str:
|
44
|
+
return self.name
|
45
|
+
|
46
|
+
def __lt__(self, other) -> bool:
|
47
|
+
return self.name < other.name
|
48
|
+
|
49
|
+
|
50
|
+
@dataclass
|
51
|
+
class LabelContainer:
|
52
|
+
labels: dict[str, Label]
|
53
|
+
|
54
|
+
def __iter__(self) -> Iterator:
|
55
|
+
yield from self.labels.values()
|
56
|
+
|
57
|
+
def __getitem__(self, key) -> Label:
|
58
|
+
if isinstance(key, Label):
|
59
|
+
key = key.name
|
60
|
+
try:
|
61
|
+
return self.labels[key]
|
62
|
+
except KeyError as e:
|
63
|
+
raise KeyError(f"Label '{key}' not found") from e
|
64
|
+
|
65
|
+
def __getattr__(self, name) -> Label:
|
66
|
+
return self[name]
|
67
|
+
|
68
|
+
def __contains__(self, label: str | Label) -> bool:
|
69
|
+
if isinstance(label, Label):
|
70
|
+
label = label.name
|
71
|
+
return label in self.labels
|
72
|
+
|
73
|
+
def __eq__(self, other) -> bool:
|
74
|
+
if isinstance(other, LabelContainer):
|
75
|
+
return self.labels == other.labels
|
76
|
+
if isinstance(other, list) and all(isinstance(f, str) for f in other):
|
77
|
+
return {f.name for f in self} == set(other)
|
78
|
+
return False
|
79
|
+
|
80
|
+
def __repr__(self) -> str:
|
81
|
+
return f"{self.__class__.__name__}({', '.join([f.name for f in self])})"
|
82
|
+
|
83
|
+
@property
|
84
|
+
def categories(self) -> list[str]:
|
85
|
+
return list(dict.fromkeys(f.category for f in self))
|
86
|
+
|
87
|
+
def by_category(self, category: str) -> LabelContainer:
|
88
|
+
f = LabelContainer({k: v for k, v in self.labels.items() if v.category == category})
|
89
|
+
if not f.labels:
|
90
|
+
raise KeyError(f"No labels with category '{category}' found")
|
91
|
+
return f
|
92
|
+
|
93
|
+
def from_cuts(self, cuts: list | Cuts) -> Label:
|
94
|
+
if isinstance(cuts, list):
|
95
|
+
cuts = Cuts.from_list(cuts)
|
96
|
+
for label in self:
|
97
|
+
if label.cuts == cuts:
|
98
|
+
return label
|
99
|
+
raise KeyError(f"Label with {cuts} not found")
|
100
|
+
|
101
|
+
@classmethod
|
102
|
+
def from_yaml(cls, yaml_path: Path | None = None) -> LabelContainer:
|
103
|
+
if yaml_path is None:
|
104
|
+
yaml_path = Path(__file__).parent / "flavours.yaml"
|
105
|
+
with open(yaml_path) as f:
|
106
|
+
config = yaml.safe_load(f)
|
107
|
+
|
108
|
+
# sanity checks
|
109
|
+
cuts = [Cuts.from_list(f["cuts"]) for f in config]
|
110
|
+
if duplicates := [c for c in cuts if cuts.count(c) > 1]:
|
111
|
+
raise ValueError(f"Duplicate label definitions detected: {duplicates}")
|
112
|
+
names = [f["name"] for f in config]
|
113
|
+
if duplicates := [n for n in names if names.count(n) > 1]:
|
114
|
+
raise ValueError(f"Duplicate label names detected: {duplicates}")
|
115
|
+
|
116
|
+
labels = {f["name"]: Label(cuts=Cuts.from_list(f.pop("cuts")), **f) for f in config}
|
117
|
+
return cls(labels)
|
118
|
+
|
119
|
+
@classmethod
|
120
|
+
def from_list(cls, labels: list[Label]) -> LabelContainer:
|
121
|
+
return cls({f.name: f for f in labels})
|
122
|
+
|
123
|
+
def backgrounds(self, label: Label, only_signals: bool = True) -> LabelContainer:
|
124
|
+
bkg = [f for f in self if f.category == label.category and f != label]
|
125
|
+
if not only_signals:
|
126
|
+
bkg = [f for f in bkg if f.name not in {"ujets", "qcd"}]
|
127
|
+
return LabelContainer.from_list(bkg)
|
ftag/sample.py
CHANGED
@@ -4,7 +4,7 @@ import glob
|
|
4
4
|
from dataclasses import dataclass
|
5
5
|
from pathlib import Path
|
6
6
|
|
7
|
-
from ftag.
|
7
|
+
from ftag.labels import remove_suffix
|
8
8
|
from ftag.vds import create_virtual_file
|
9
9
|
|
10
10
|
|
@@ -13,6 +13,7 @@ class Sample:
|
|
13
13
|
pattern: Path | str | tuple[Path | str, ...]
|
14
14
|
ntuple_dir: Path | str | None = None
|
15
15
|
name: str | None = None
|
16
|
+
weights: list[float] | None = None
|
16
17
|
|
17
18
|
def __post_init__(self) -> None:
|
18
19
|
if not self.pattern:
|
ftag/wps/discriminant.py
CHANGED
@@ -4,13 +4,14 @@ from typing import Callable
|
|
4
4
|
|
5
5
|
import numpy as np
|
6
6
|
|
7
|
-
from ftag
|
7
|
+
from ftag import Flavours
|
8
|
+
from ftag.labels import Label, remove_suffix
|
8
9
|
|
9
10
|
|
10
11
|
def discriminant(
|
11
12
|
jets: np.ndarray,
|
12
13
|
tagger: str,
|
13
|
-
signal:
|
14
|
+
signal: Label,
|
14
15
|
fxs: dict[str, float],
|
15
16
|
epsilon: float = 1e-10,
|
16
17
|
) -> np.ndarray:
|
@@ -87,7 +88,7 @@ def hcc_discriminant(jets, tagger, ftop=0.25, fhbb=0.3, epsilon=1e-10):
|
|
87
88
|
|
88
89
|
|
89
90
|
def get_discriminant(
|
90
|
-
jets: np.ndarray, tagger: str, signal:
|
91
|
+
jets: np.ndarray, tagger: str, signal: Label | str, epsilon: float = 1e-10, **fxs
|
91
92
|
):
|
92
93
|
"""Calculate the b-tag or c-tag discriminant for a given tagger.
|
93
94
|
|
@@ -97,7 +98,7 @@ def get_discriminant(
|
|
97
98
|
Structured array of jets containing tagger outputs
|
98
99
|
tagger : str
|
99
100
|
Name of the tagger
|
100
|
-
signal :
|
101
|
+
signal : Label
|
101
102
|
Signal flavour (bjets/cjets or hbb/hcc)
|
102
103
|
epsilon : float, optional
|
103
104
|
Small number to avoid division by zero, by default 1e-10
|
ftag/wps/working_points.py
CHANGED
@@ -8,9 +8,9 @@ from pathlib import Path
|
|
8
8
|
import numpy as np
|
9
9
|
import yaml
|
10
10
|
|
11
|
+
from ftag import Flavours
|
11
12
|
from ftag.cli_utils import HelpFormatter
|
12
13
|
from ftag.cuts import Cuts
|
13
|
-
from ftag.flavour import Flavours
|
14
14
|
from ftag.hdf5 import H5Reader
|
15
15
|
from ftag.wps.discriminant import get_discriminant
|
16
16
|
|
ftag/flavour.py
DELETED
@@ -1,127 +0,0 @@
|
|
1
|
-
from __future__ import annotations
|
2
|
-
|
3
|
-
from collections.abc import Iterator
|
4
|
-
from dataclasses import dataclass
|
5
|
-
from pathlib import Path
|
6
|
-
|
7
|
-
import yaml
|
8
|
-
|
9
|
-
from ftag.cuts import Cuts
|
10
|
-
|
11
|
-
|
12
|
-
def remove_suffix(string: str, suffix: str) -> str:
|
13
|
-
if string.endswith(suffix):
|
14
|
-
return string[: -len(suffix)]
|
15
|
-
return string
|
16
|
-
|
17
|
-
|
18
|
-
@dataclass(frozen=True)
|
19
|
-
class Flavour:
|
20
|
-
name: str
|
21
|
-
label: str
|
22
|
-
cuts: Cuts
|
23
|
-
colour: str
|
24
|
-
category: str
|
25
|
-
_px: str | None = None
|
26
|
-
|
27
|
-
@property
|
28
|
-
def px(self) -> str:
|
29
|
-
return self._px or f"p{remove_suffix(self.name, 'jets')}"
|
30
|
-
|
31
|
-
@property
|
32
|
-
def eff_str(self) -> str:
|
33
|
-
return self.label.replace("jets", "jet") + " efficiency"
|
34
|
-
|
35
|
-
@property
|
36
|
-
def rej_str(self) -> str:
|
37
|
-
return self.label.replace("jets", "jet") + " rejection"
|
38
|
-
|
39
|
-
@property
|
40
|
-
def frac_str(self) -> str:
|
41
|
-
return "f" + remove_suffix(self.name, "jets")
|
42
|
-
|
43
|
-
def __str__(self) -> str:
|
44
|
-
return self.name
|
45
|
-
|
46
|
-
def __lt__(self, other) -> bool:
|
47
|
-
return self.name < other.name
|
48
|
-
|
49
|
-
|
50
|
-
@dataclass
|
51
|
-
class FlavourContainer:
|
52
|
-
flavours: dict[str, Flavour]
|
53
|
-
|
54
|
-
def __iter__(self) -> Iterator:
|
55
|
-
yield from self.flavours.values()
|
56
|
-
|
57
|
-
def __getitem__(self, key) -> Flavour:
|
58
|
-
if isinstance(key, Flavour):
|
59
|
-
key = key.name
|
60
|
-
try:
|
61
|
-
return self.flavours[key]
|
62
|
-
except KeyError as e:
|
63
|
-
raise KeyError(f"Flavour '{key}' not found") from e
|
64
|
-
|
65
|
-
def __getattr__(self, name) -> Flavour:
|
66
|
-
return self[name]
|
67
|
-
|
68
|
-
def __contains__(self, flavour: str | Flavour) -> bool:
|
69
|
-
if isinstance(flavour, Flavour):
|
70
|
-
flavour = flavour.name
|
71
|
-
return flavour in self.flavours
|
72
|
-
|
73
|
-
def __eq__(self, other) -> bool:
|
74
|
-
if isinstance(other, FlavourContainer):
|
75
|
-
return self.flavours == other.flavours
|
76
|
-
if isinstance(other, list) and all(isinstance(f, str) for f in other):
|
77
|
-
return {f.name for f in self} == set(other)
|
78
|
-
return False
|
79
|
-
|
80
|
-
def __repr__(self) -> str:
|
81
|
-
return f"{self.__class__.__name__}({', '.join([f.name for f in self])})"
|
82
|
-
|
83
|
-
@property
|
84
|
-
def categories(self) -> list[str]:
|
85
|
-
return list(dict.fromkeys(f.category for f in self))
|
86
|
-
|
87
|
-
def by_category(self, category: str) -> FlavourContainer:
|
88
|
-
f = FlavourContainer({k: v for k, v in self.flavours.items() if v.category == category})
|
89
|
-
if not f.flavours:
|
90
|
-
raise KeyError(f"No flavours with category '{category}' found")
|
91
|
-
return f
|
92
|
-
|
93
|
-
def from_cuts(self, cuts: list | Cuts) -> Flavour:
|
94
|
-
if isinstance(cuts, list):
|
95
|
-
cuts = Cuts.from_list(cuts)
|
96
|
-
for flavour in self:
|
97
|
-
if flavour.cuts == cuts:
|
98
|
-
return flavour
|
99
|
-
raise KeyError(f"Flavour with {cuts} not found")
|
100
|
-
|
101
|
-
@classmethod
|
102
|
-
def from_yaml(cls, yaml_path: Path | None = None) -> FlavourContainer:
|
103
|
-
if yaml_path is None:
|
104
|
-
yaml_path = Path(__file__).parent / "flavours.yaml"
|
105
|
-
|
106
|
-
with open(yaml_path) as f:
|
107
|
-
flavours_yaml = yaml.safe_load(f)
|
108
|
-
|
109
|
-
flavours_dict = {
|
110
|
-
f["name"]: Flavour(cuts=Cuts.from_list(f.pop("cuts")), **f) for f in flavours_yaml
|
111
|
-
}
|
112
|
-
assert len(flavours_dict) == len(flavours_yaml), "Duplicate flavour names detected"
|
113
|
-
|
114
|
-
return cls(flavours_dict)
|
115
|
-
|
116
|
-
@classmethod
|
117
|
-
def from_list(cls, flavours: list[Flavour]) -> FlavourContainer:
|
118
|
-
return cls({f.name: f for f in flavours})
|
119
|
-
|
120
|
-
def backgrounds(self, flavour: Flavour, keep_possible_signals: bool = True) -> FlavourContainer:
|
121
|
-
bkg = [f for f in self if f.category == flavour.category and f != flavour]
|
122
|
-
if not keep_possible_signals:
|
123
|
-
bkg = [f for f in bkg if f.name not in {"ujets", "qcd"}]
|
124
|
-
return FlavourContainer.from_list(bkg)
|
125
|
-
|
126
|
-
|
127
|
-
Flavours = FlavourContainer.from_yaml()
|
ftag/test_cli_utils.py
DELETED
@@ -1,34 +0,0 @@
|
|
1
|
-
from __future__ import annotations
|
2
|
-
|
3
|
-
from pathlib import Path
|
4
|
-
from tempfile import NamedTemporaryFile, TemporaryDirectory
|
5
|
-
|
6
|
-
import pytest
|
7
|
-
|
8
|
-
from ftag.cli_utils import valid_path
|
9
|
-
|
10
|
-
|
11
|
-
def test_valid_path_existing_file():
|
12
|
-
# Test when the input path is an existing file
|
13
|
-
# get a temp directory
|
14
|
-
with TemporaryDirectory() as tmpdir, NamedTemporaryFile(dir=tmpdir) as f:
|
15
|
-
input_path = f.name
|
16
|
-
expected_output = Path(f.name)
|
17
|
-
result = valid_path(input_path)
|
18
|
-
assert result == expected_output
|
19
|
-
|
20
|
-
|
21
|
-
def test_valid_path_non_existing_file():
|
22
|
-
# Test when the input path is a non-existing file
|
23
|
-
input_path = "non_existing_file.txt"
|
24
|
-
with pytest.raises(FileNotFoundError) as e:
|
25
|
-
valid_path(input_path)
|
26
|
-
assert str(e.value) == input_path
|
27
|
-
|
28
|
-
|
29
|
-
def test_valid_path_directory():
|
30
|
-
# Test when the input path is a directory
|
31
|
-
input_path = "directory/"
|
32
|
-
with pytest.raises(FileNotFoundError) as e:
|
33
|
-
valid_path(input_path)
|
34
|
-
assert str(e.value) == input_path
|
File without changes
|
File without changes
|