-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathspecification.py
More file actions
118 lines (80 loc) · 3.45 KB
/
specification.py
File metadata and controls
118 lines (80 loc) · 3.45 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
from __future__ import annotations
from abc import abstractmethod
from dataclasses import dataclass
from typing import Any, Optional, Set
import dlstbx.mimas
class BaseSpecification:
@abstractmethod
def is_satisfied_by(self, candidate: Any) -> bool:
raise NotImplementedError()
def __and__(self, other: BaseSpecification) -> AndSpecification:
return AndSpecification(self, other)
def __or__(self, other: BaseSpecification) -> OrSpecification:
return OrSpecification(self, other)
def __invert__(self) -> InvertSpecification:
return InvertSpecification(self)
@dataclass(frozen=True)
class AndSpecification(BaseSpecification):
first: BaseSpecification
second: BaseSpecification
def is_satisfied_by(self, candidate: Any) -> bool:
return self.first.is_satisfied_by(candidate) and self.second.is_satisfied_by(
candidate
)
@dataclass(frozen=True)
class OrSpecification(BaseSpecification):
first: BaseSpecification
second: BaseSpecification
def is_satisfied_by(self, candidate: Any) -> bool:
return self.first.is_satisfied_by(candidate) or self.second.is_satisfied_by(
candidate
)
@dataclass(frozen=True)
class InvertSpecification(BaseSpecification):
subject: BaseSpecification
def is_satisfied_by(self, candidate: Any) -> bool:
return not self.subject.is_satisfied_by(candidate)
class ScenarioSpecification(BaseSpecification):
@abstractmethod
def is_satisfied_by(self, candidate: dlstbx.mimas.MimasScenario) -> bool:
raise NotImplementedError()
@dataclass(frozen=True)
class BeamlineSpecification(ScenarioSpecification):
beamline: Optional[str] = None
beamlines: Optional[set[str]] = None
def is_satisfied_by(self, candidate: dlstbx.mimas.MimasScenario) -> bool:
return (
(self.beamline and candidate.beamline == self.beamline)
or (self.beamlines and candidate.beamline in self.beamlines)
or False
)
@dataclass(frozen=True)
class EventSpecification(ScenarioSpecification):
event: dlstbx.mimas.MimasEvent
def is_satisfied_by(self, candidate: dlstbx.mimas.MimasScenario) -> bool:
return candidate.event == self.event
@dataclass(frozen=True)
class DCClassSpecification(ScenarioSpecification):
dcclass: dlstbx.mimas.MimasDCClass
def is_satisfied_by(self, candidate: dlstbx.mimas.MimasScenario) -> bool:
return candidate.dcclass == self.dcclass
@dataclass(frozen=True)
class DetectorClassSpecification(ScenarioSpecification):
detectorclass: dlstbx.mimas.MimasDetectorClass
def is_satisfied_by(self, candidate: dlstbx.mimas.MimasScenario) -> bool:
return candidate.detectorclass == self.detectorclass
@dataclass(frozen=True)
class ImageKindSpecification(ScenarioSpecification):
imagekind: dlstbx.mimas.MimasImageKind
def is_satisfied_by(self, candidate: dlstbx.mimas.MimasScenario) -> bool:
return candidate.imagekind == self.imagekind
@dataclass(frozen=True)
class VisitSpecification(ScenarioSpecification):
visits: Set[str]
def is_satisfied_by(self, candidate: dlstbx.mimas.MimasScenario) -> bool:
return (
candidate.visit and candidate.visit.startswith(tuple(self.visits))
) or False
# class HasSpaceGroupSpecification(ScenarioSpecification):
# def is_satisfied_by(self, candidate: dlstbx.mimas.MimasScenario) -> bool:
# return candidate.spacegroup is not None