fastlisaresponse 1.1.14__cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.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.
- fastlisaresponse/__init__.py +93 -0
- fastlisaresponse/_version.py +34 -0
- fastlisaresponse/cutils/__init__.py +141 -0
- fastlisaresponse/git_version.py +7 -0
- fastlisaresponse/git_version.py.in +7 -0
- fastlisaresponse/response.py +813 -0
- fastlisaresponse/utils/__init__.py +1 -0
- fastlisaresponse/utils/citations.py +356 -0
- fastlisaresponse/utils/config.py +793 -0
- fastlisaresponse/utils/exceptions.py +95 -0
- fastlisaresponse/utils/parallelbase.py +11 -0
- fastlisaresponse/utils/utility.py +82 -0
- fastlisaresponse-1.1.14.dist-info/METADATA +166 -0
- fastlisaresponse-1.1.14.dist-info/RECORD +17 -0
- fastlisaresponse-1.1.14.dist-info/WHEEL +6 -0
- fastlisaresponse_backend_cpu/git_version.py +7 -0
- fastlisaresponse_backend_cpu/responselisa.cpython-311-x86_64-linux-gnu.so +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .utility import get_overlap
|
|
@@ -0,0 +1,356 @@
|
|
|
1
|
+
# Collection of citations for modules in GBGPU package
|
|
2
|
+
|
|
3
|
+
"""
|
|
4
|
+
:code:`gbgpu.utils.citations`:
|
|
5
|
+
|
|
6
|
+
This module is used to collect citations for all modules in the package. This
|
|
7
|
+
module is then imported to add citations to module classes using their :code:`citation`
|
|
8
|
+
attribute.
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
import abc
|
|
12
|
+
import enum
|
|
13
|
+
from typing import Iterable, List, Optional, Union
|
|
14
|
+
|
|
15
|
+
from pydantic import BaseModel
|
|
16
|
+
|
|
17
|
+
from gbgpu.utils.exceptions import InvalidInputFile
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def _hyphen_replace(field: str) -> str:
|
|
21
|
+
return field.replace("_", "-")
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class HyphenUnderscoreAliasModel(BaseModel):
|
|
25
|
+
"""Pydantic model were hyphen replace underscore in field names."""
|
|
26
|
+
|
|
27
|
+
class Config:
|
|
28
|
+
alias_generator = _hyphen_replace
|
|
29
|
+
extra = "ignore"
|
|
30
|
+
frozen = True
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class Author(HyphenUnderscoreAliasModel):
|
|
34
|
+
"""Description of a reference author."""
|
|
35
|
+
|
|
36
|
+
family_names: str
|
|
37
|
+
given_names: str
|
|
38
|
+
orcid: Optional[str] = None
|
|
39
|
+
affiliation: Optional[str] = None
|
|
40
|
+
email: Optional[str] = None
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class Publisher(HyphenUnderscoreAliasModel):
|
|
44
|
+
"""Description of a publisher."""
|
|
45
|
+
|
|
46
|
+
name: str
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
class Identifier(HyphenUnderscoreAliasModel):
|
|
50
|
+
"""Description of an identifier."""
|
|
51
|
+
|
|
52
|
+
type: str
|
|
53
|
+
value: str
|
|
54
|
+
description: Optional[str] = None
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
class ReferenceABC(HyphenUnderscoreAliasModel, abc.ABC):
|
|
58
|
+
"""Abstract base class for references."""
|
|
59
|
+
|
|
60
|
+
@abc.abstractmethod
|
|
61
|
+
def to_bibtex(self) -> str:
|
|
62
|
+
"""Convert a reference object to a BibTeX string representation."""
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
class ArxivIdentifier(BaseModel):
|
|
66
|
+
"""Class representing an arXiv identifier"""
|
|
67
|
+
|
|
68
|
+
reference: str
|
|
69
|
+
primary_class: Optional[str] = None
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
class ArticleReference(ReferenceABC):
|
|
73
|
+
"""Description of an article."""
|
|
74
|
+
|
|
75
|
+
abbreviation: str
|
|
76
|
+
authors: List[Author]
|
|
77
|
+
title: str
|
|
78
|
+
journal: Optional[str] = None
|
|
79
|
+
year: int
|
|
80
|
+
month: Optional[int] = None
|
|
81
|
+
issue: Optional[int] = None
|
|
82
|
+
publisher: Optional[Publisher] = None
|
|
83
|
+
pages: Optional[int] = None
|
|
84
|
+
start: Optional[int] = None
|
|
85
|
+
issn: Optional[str] = None
|
|
86
|
+
doi: Optional[str] = None
|
|
87
|
+
identifiers: Optional[List[Identifier]] = None
|
|
88
|
+
|
|
89
|
+
@property
|
|
90
|
+
def arxiv_preprint(self) -> Optional[ArxivIdentifier]:
|
|
91
|
+
"""
|
|
92
|
+
Detect an arXiv identifier if any.
|
|
93
|
+
|
|
94
|
+
an arXiv identifier is:
|
|
95
|
+
- an identifier of type "other"
|
|
96
|
+
- which starts with "arxiv:" (case insensitive)
|
|
97
|
+
- whose second part is either:
|
|
98
|
+
- The arXiv reference (e.g. "arxiv:1912.07609")
|
|
99
|
+
- The primary class followed by '/' and the reference (e.g. "arxiv:gr-qc/1912.07609")
|
|
100
|
+
"""
|
|
101
|
+
if self.identifiers is None:
|
|
102
|
+
return None
|
|
103
|
+
|
|
104
|
+
for identifier in self.identifiers:
|
|
105
|
+
if identifier.type != "other":
|
|
106
|
+
continue
|
|
107
|
+
if not identifier.value.lower().startswith("arxiv:"):
|
|
108
|
+
continue
|
|
109
|
+
data = identifier.value.lower().removeprefix("arxiv:")
|
|
110
|
+
primary_class, reference = (
|
|
111
|
+
data.split("/", 1) if "/" in data else (None, data)
|
|
112
|
+
)
|
|
113
|
+
return ArxivIdentifier(primary_class=primary_class, reference=reference)
|
|
114
|
+
return None
|
|
115
|
+
|
|
116
|
+
def to_bibtex(self) -> str:
|
|
117
|
+
"""Build the BibTeX representation of an article."""
|
|
118
|
+
arxiv_id = self.arxiv_preprint
|
|
119
|
+
|
|
120
|
+
line_format = (
|
|
121
|
+
""" {:<10} = \"{}\"""" if arxiv_id is None else """ {:<13} = \"{}\""""
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
def format_line(key: str, value: str, format: str = line_format) -> str:
|
|
125
|
+
return format.format(key, value)
|
|
126
|
+
|
|
127
|
+
lines = []
|
|
128
|
+
lines.append("@article{" + self.abbreviation)
|
|
129
|
+
lines.append(
|
|
130
|
+
format_line(
|
|
131
|
+
"author",
|
|
132
|
+
" and ".join(
|
|
133
|
+
[
|
|
134
|
+
"{}, {}".format(author.family_names, author.given_names)
|
|
135
|
+
for author in self.authors
|
|
136
|
+
]
|
|
137
|
+
),
|
|
138
|
+
)
|
|
139
|
+
)
|
|
140
|
+
lines.append(format_line("title", "{" + self.title + "}"))
|
|
141
|
+
if self.journal is not None:
|
|
142
|
+
lines.append(format_line("journal", self.journal))
|
|
143
|
+
lines.append(format_line("year", str(self.year)))
|
|
144
|
+
if self.month is not None:
|
|
145
|
+
lines.append(format_line("month", str(self.month)))
|
|
146
|
+
if self.issue is not None:
|
|
147
|
+
lines.append(format_line("number", str(self.issue)))
|
|
148
|
+
if self.publisher is not None:
|
|
149
|
+
lines.append(format_line("publisher", str(self.publisher.name)))
|
|
150
|
+
if self.start is not None:
|
|
151
|
+
lines.append(
|
|
152
|
+
format_line(
|
|
153
|
+
"pages",
|
|
154
|
+
str(self.start)
|
|
155
|
+
if self.pages is None
|
|
156
|
+
else "{}--{}".format(self.start, self.start + self.pages),
|
|
157
|
+
)
|
|
158
|
+
)
|
|
159
|
+
if self.issn is not None:
|
|
160
|
+
lines.append(format_line("issn", str(self.issn)))
|
|
161
|
+
if self.doi is not None:
|
|
162
|
+
lines.append(format_line("doi", str(self.doi)))
|
|
163
|
+
if arxiv_id is not None:
|
|
164
|
+
lines.append(format_line("archivePrefix", "arXiv"))
|
|
165
|
+
lines.append(format_line("eprint", arxiv_id.reference))
|
|
166
|
+
if arxiv_id.primary_class is not None:
|
|
167
|
+
lines.append(format_line("primaryClass", arxiv_id.primary_class))
|
|
168
|
+
|
|
169
|
+
return ",\n".join(lines) + "\n}"
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
class SoftwareReference(ReferenceABC):
|
|
173
|
+
"""Description of a Software"""
|
|
174
|
+
|
|
175
|
+
authors: list[Author]
|
|
176
|
+
title: str
|
|
177
|
+
|
|
178
|
+
license: Optional[str] = None
|
|
179
|
+
url: Optional[str] = None
|
|
180
|
+
repository: Optional[str] = None
|
|
181
|
+
identifiers: Optional[List[Identifier]] = None
|
|
182
|
+
year: Optional[int] = None
|
|
183
|
+
month: Optional[int] = None
|
|
184
|
+
version: Optional[str] = None
|
|
185
|
+
|
|
186
|
+
@property
|
|
187
|
+
def doi(self) -> Optional[str]:
|
|
188
|
+
"""Return the first DOI in identifiers if any"""
|
|
189
|
+
if self.identifiers is None:
|
|
190
|
+
return None
|
|
191
|
+
|
|
192
|
+
for identifier in self.identifiers:
|
|
193
|
+
if identifier.type == "doi":
|
|
194
|
+
return identifier.value
|
|
195
|
+
return None
|
|
196
|
+
|
|
197
|
+
def to_bibtex(self) -> str:
|
|
198
|
+
"""Build the BibTeX representation of a software."""
|
|
199
|
+
|
|
200
|
+
def format_line(key: str, value: str) -> str:
|
|
201
|
+
return """ {:<10} = \"{}\"""".format(key, value)
|
|
202
|
+
|
|
203
|
+
lines = []
|
|
204
|
+
lines.append("@software{" + self.title)
|
|
205
|
+
lines.append(
|
|
206
|
+
format_line(
|
|
207
|
+
"author",
|
|
208
|
+
" and ".join(
|
|
209
|
+
[
|
|
210
|
+
"{}, {}".format(author.family_names, author.given_names)
|
|
211
|
+
for author in self.authors
|
|
212
|
+
]
|
|
213
|
+
),
|
|
214
|
+
)
|
|
215
|
+
)
|
|
216
|
+
lines.append(format_line("title", "{" + self.title + "}"))
|
|
217
|
+
if self.license is not None:
|
|
218
|
+
lines.append(format_line("license", self.license))
|
|
219
|
+
if self.url is not None:
|
|
220
|
+
lines.append(format_line("url", self.url))
|
|
221
|
+
if self.repository is not None:
|
|
222
|
+
lines.append(format_line("repository", self.repository))
|
|
223
|
+
if self.year is not None:
|
|
224
|
+
lines.append(format_line("year", str(self.year)))
|
|
225
|
+
if self.month is not None:
|
|
226
|
+
lines.append(format_line("month", str(self.month)))
|
|
227
|
+
if self.version is not None:
|
|
228
|
+
lines.append(format_line("version", self.version))
|
|
229
|
+
if self.doi is not None:
|
|
230
|
+
lines.append(format_line("doi", str(self.doi)))
|
|
231
|
+
|
|
232
|
+
return ",\n".join(lines) + "\n}"
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
Reference = Union[ArticleReference, SoftwareReference]
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
class REFERENCE(enum.Enum):
|
|
239
|
+
FAST_GB = "Cornish:2007if"
|
|
240
|
+
TRIPLES_1 = "Robson:2018svj"
|
|
241
|
+
GBGPU_SOFTWARE = "michael_l_katz_2022_6500434"
|
|
242
|
+
|
|
243
|
+
def __str__(self) -> str:
|
|
244
|
+
return str(self.value)
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
class CitationRegistry:
|
|
248
|
+
__slots__ = "registry"
|
|
249
|
+
|
|
250
|
+
registry: dict[str, Reference]
|
|
251
|
+
|
|
252
|
+
def __init__(self, **kwargs):
|
|
253
|
+
self.registry = kwargs
|
|
254
|
+
|
|
255
|
+
def get(self, key: Union[str, REFERENCE]) -> Reference:
|
|
256
|
+
"""Return a Reference object from its key."""
|
|
257
|
+
return self.registry[key if isinstance(key, str) else key.value]
|
|
258
|
+
|
|
259
|
+
def all(self) -> Iterable[Reference]:
|
|
260
|
+
return self.registry.values()
|
|
261
|
+
|
|
262
|
+
|
|
263
|
+
def build_citation_registry() -> CitationRegistry:
|
|
264
|
+
"""Read the package CITATION.cff and build the corresponding registry."""
|
|
265
|
+
import json
|
|
266
|
+
import pathlib
|
|
267
|
+
|
|
268
|
+
import jsonschema
|
|
269
|
+
import yaml
|
|
270
|
+
|
|
271
|
+
from gbgpu import __file__ as _gbgpu_root_file
|
|
272
|
+
from gbgpu import _is_editable as is_editable
|
|
273
|
+
|
|
274
|
+
gbgpu_root = pathlib.Path(_gbgpu_root_file).parent
|
|
275
|
+
cff_root = gbgpu_root.parent.parent if is_editable else gbgpu_root
|
|
276
|
+
citation_cff_path = cff_root / "CITATION.cff"
|
|
277
|
+
|
|
278
|
+
with open(citation_cff_path, "rt") as fid:
|
|
279
|
+
cff = yaml.safe_load(fid)
|
|
280
|
+
|
|
281
|
+
with open(pathlib.Path(__file__).parent / "cff_1_2_0.schema.json", "r") as f:
|
|
282
|
+
cff_schema = json.load(f)
|
|
283
|
+
|
|
284
|
+
try:
|
|
285
|
+
jsonschema.validate(cff, cff_schema)
|
|
286
|
+
except jsonschema.SchemaError as e:
|
|
287
|
+
raise InvalidInputFile("cff_1_2_0.schema.json is not a valid schema.") from e
|
|
288
|
+
except jsonschema.exceptions.ValidationError as e:
|
|
289
|
+
raise InvalidInputFile(
|
|
290
|
+
"The file {} does not match its expected schema. Contact gbgpu developers.".format(
|
|
291
|
+
citation_cff_path
|
|
292
|
+
)
|
|
293
|
+
) from e
|
|
294
|
+
|
|
295
|
+
def to_reference(ref_dict) -> Reference:
|
|
296
|
+
if ref_dict["type"] == "article":
|
|
297
|
+
return ArticleReference(**ref_dict)
|
|
298
|
+
if ref_dict["type"] == "software":
|
|
299
|
+
return SoftwareReference(**ref_dict)
|
|
300
|
+
|
|
301
|
+
raise InvalidInputFile(
|
|
302
|
+
"The file {} contains references whose type ({}) ".format(
|
|
303
|
+
citation_cff_path, ref_dict["type"]
|
|
304
|
+
)
|
|
305
|
+
+ "is not supported",
|
|
306
|
+
ref_dict,
|
|
307
|
+
)
|
|
308
|
+
|
|
309
|
+
references = {ref["abbreviation"]: to_reference(ref) for ref in cff["references"]}
|
|
310
|
+
|
|
311
|
+
return CitationRegistry(**references, **{cff["title"]: to_reference(cff)})
|
|
312
|
+
|
|
313
|
+
|
|
314
|
+
COMMON_REFERENCES = [
|
|
315
|
+
REFERENCE.FAST_GB,
|
|
316
|
+
REFERENCE.TRIPLES_1,
|
|
317
|
+
REFERENCE.GBGPU_SOFTWARE,
|
|
318
|
+
]
|
|
319
|
+
|
|
320
|
+
|
|
321
|
+
class Citable:
|
|
322
|
+
"""Base class for classes associated with specific citations."""
|
|
323
|
+
|
|
324
|
+
registry: Optional[CitationRegistry] = None
|
|
325
|
+
|
|
326
|
+
@classmethod
|
|
327
|
+
def citation(cls) -> str:
|
|
328
|
+
"""Return the module references as a printable BibTeX string."""
|
|
329
|
+
references = cls.module_references()
|
|
330
|
+
|
|
331
|
+
registry = cls._get_registry()
|
|
332
|
+
|
|
333
|
+
bibtex_entries = [registry.get(str(key)).to_bibtex() for key in references]
|
|
334
|
+
return "\n\n".join(bibtex_entries)
|
|
335
|
+
|
|
336
|
+
@classmethod
|
|
337
|
+
def all_citations(cls) -> str:
|
|
338
|
+
"""Return all the citations from the registry as printable BibTeX string"""
|
|
339
|
+
registry = cls._get_registry()
|
|
340
|
+
|
|
341
|
+
bibtex_entries = [entry.to_bibtex() for entry in registry.all()]
|
|
342
|
+
return "\n\n".join(bibtex_entries)
|
|
343
|
+
|
|
344
|
+
@classmethod
|
|
345
|
+
def module_references(cls) -> Iterable[Union[REFERENCE, str]]:
|
|
346
|
+
"""Method implemented by each class to define its list of references"""
|
|
347
|
+
return COMMON_REFERENCES
|
|
348
|
+
|
|
349
|
+
@classmethod
|
|
350
|
+
def _get_registry(cls) -> CitationRegistry:
|
|
351
|
+
if Citable.registry is None:
|
|
352
|
+
from gbgpu import get_logger
|
|
353
|
+
|
|
354
|
+
get_logger().debug("Building the Citation Registry from CITATION.cff")
|
|
355
|
+
Citable.registry = build_citation_registry()
|
|
356
|
+
return Citable.registry
|