@@ -106,29 +106,37 @@ def to_file(
106
106
calib_map .to_file (path )
107
107
108
108
109
+ CalibConditions_T = Tuple [float , Tuple [str , ...], Tuple [str , ...]]
110
+
111
+
109
112
class CalibMovieDelaysMapping (MutableMapping ):
110
- """Calibrated delays depend on the exposure time as well as information
111
- requested in movie header: requesting a lot of common information might
112
- elongate the initialization, large per-image headers may take too long to
113
- collect during `exposure`, artificially inflating yield times.
114
- This class loads, stores, and saves instances of `CalibMovieDelays`
115
- calibrated for each combination of exposure and common/variable header.
116
-
117
- Instances of `CalibMovieDelays` are indexed using a composite string key,
118
- which takes form "exposure;common,header,elements;variable,header,elements".
119
- However, this class also allows accessing instances using the tuple-form.
113
+ """Calibrated delays depend on the exposure time as well information
114
+ requested for movie header. This information can be split into two kinds:
115
+ common information is collected once at the beginning of the movie,
116
+ potentially leading to long initialization times. Variable information is
117
+ collect for each image individually while it is gathered, potentially
118
+ artificially inflating the "dead" time. This class manages instances of
119
+ `CalibMovieDelays` calibrated for each combination of exposure and headers.
120
+
121
+ From the code perspective, the easiest way to express `CalibConditions_T`,
122
+ i.e. exposure, common headers, and variable headers, is via a tuple.
123
+ Unfortunately, tuples can not be used as a key for serialization purposes.
124
+ Therefore, this class also allows converting the conditions to a string
125
+ representation: "exposure;common,header,elements;variable,header,elements".
126
+
127
+ Instances of `CalibMovieDelays` are indexed using this composite header key;
128
+ However, for convenience, this class allows accessing stored instances of
129
+ `CalibMovieDelays` using either the composite string or tuple-style key.
120
130
"""
121
131
122
- ExposureHeadersHeaders_T = Tuple [float , Tuple [str , ...], Tuple [str , ...]]
123
-
124
132
def __init__ (self , dict_ : Dict [str , CalibMovieDelays ] = None ) -> None :
125
133
self .dict = dict_ if dict_ else {}
126
134
127
- def __delitem__ (self , k : Union [str , ExposureHeadersHeaders_T ]) -> None :
128
- del self .dict [k if isinstance (k , str ) else self .ehh_to_str ( * k )]
135
+ def __delitem__ (self , k : Union [str , CalibConditions_T ]) -> None :
136
+ del self .dict [k if isinstance (k , str ) else self .calib_conditions2str ( k )]
129
137
130
- def __getitem__ (self , k : Union [str , ExposureHeadersHeaders_T ]) -> CalibMovieDelays :
131
- return self .dict [k if isinstance (k , str ) else self .ehh_to_str ( * k )]
138
+ def __getitem__ (self , k : Union [str , CalibConditions_T ]) -> CalibMovieDelays :
139
+ return self .dict [k if isinstance (k , str ) else self .calib_conditions2str ( k )]
132
140
133
141
def __len__ (self ) -> int :
134
142
return len (self .dict )
@@ -137,20 +145,29 @@ def __iter__(self) -> Iterator:
137
145
return self .dict .__iter__ ()
138
146
139
147
def __setitem__ (self , k , v ) -> None :
140
- self .dict [k if isinstance (k , str ) else self .ehh_to_str (* k )] = v
148
+ self .dict [k if isinstance (k , str ) else self .calib_conditions2str (k )] = v
149
+
150
+ def str2tuple (self , str_ : str , delimiter : str = ',' ) -> Tuple [str , ...]:
151
+ """Convert a `delimiter`-delimited string into a tuple of strings."""
152
+ return tuple (sorted (str_ .split (delimiter )))
153
+
154
+ def tuple2str (self , tuple_ : Tuple [str , ...], delimiter : str = ',' ) -> str :
155
+ """Convert a tuple of strings into a `delimiter`-delimited string."""
156
+ return delimiter .join ([str (t ) for t in sorted (tuple_ )])
141
157
142
- @staticmethod
143
- def str_to_ehh (key : str ) -> ExposureHeadersHeaders_T :
144
- """Convert a "1.0;t11,t12;t21"-form str to float & tuples t1 & t2."""
158
+ def str2calib_conditions (self , key : str ) -> CalibConditions_T :
159
+ """Convert calibration conditions from ,/;-delimited str to tuple."""
145
160
exposure , header_keys_common , header_keys_variable = key .split (';' , 3 )
146
- header_keys_common = tuple ( sorted ( header_keys_common . split ( ',' )) )
147
- header_keys_variable = tuple ( sorted ( header_keys_variable . split ( ',' )) )
161
+ header_keys_common = self . str2tuple ( header_keys_common , ',' )
162
+ header_keys_variable = self . str2tuple ( header_keys_variable , ',' )
148
163
return float (exposure ), header_keys_common , header_keys_variable
149
164
150
- @staticmethod
151
- def ehh_to_str (e : float , t1 : Sequence [str , ...], t2 : Sequence [str , ...]) -> str :
152
- """Convert float & tuples t1 & t2 to "e;t11,t12;t21,t22"-form str."""
153
- return f'{ round (e , 3 ):.3f} ;' + ',' .join (sorted (t1 )) + ';' + ',' .join (sorted (t2 ))
165
+ def calib_conditions2str (self , c : CalibConditions_T ) -> str :
166
+ """Convert calibration conditions from tuple to ,/;-delimited str."""
167
+ exposure , header_keys_common , header_keys_variable = c
168
+ hkc = self .tuple2str (header_keys_common , ',' )
169
+ hkv = self .tuple2str (header_keys_variable , ',' )
170
+ return f'{ round (exposure , 3 ):.3f} ;{ hkc } ;{ hkv } '
154
171
155
172
@classmethod
156
173
def from_dict (cls , dict_ : Dict [str , Dict [str , float ]]) -> Self :
0 commit comments