Conversation
| CALCAT_PROXY_URL = "http://exflcalproxy.desy.de:8080/" | ||
|
|
||
|
|
||
| def any_is_none(*values): |
There was a problem hiding this comment.
Not remotely important to the overall PR, but this can be one line with the builtin any() function.
There was a problem hiding this comment.
Certainly, but explicitly checking for is None seemed to become fairly clunky: any([x is None for x in [a, b, c]])
As I was already writing a function for it, the allocation cost for the comprehension seemed unnecessary.
src/extra/calibration.py
Outdated
| self.constant_groups = constant_groups | ||
| self.module_details = module_details | ||
| self.detector_name = detector_name | ||
| self.condition = condition |
There was a problem hiding this comment.
Do we have a use case in mind, or is this a general 'don't throw away information'?
If we don't have a concrete use case, I might be inclined to get rid of it, or make it ._condition, just for debugging. Making it easy to assume constants always come with a condition object could make it harder to use the flexibility of finding constants in other ways - like from a report in CalCat, from the correction metadata of a run, or combining different groups of constants.
It should also be possible to look up the conditions associated with each individual constant in CalCat, at least where we have the IDs, which is a more general option.
There was a problem hiding this comment.
The idea was to expose the entire condition inferred from data, i.e. access the generated ConditionsBase object. I didn't consider looking into individual CCVs for their condition. Technically one could ConditionsBase.from_data() before to obtain it, but that means leaving out on inferring detector type and creation date from data.
| self.sources = sources | ||
|
|
||
| def __str__(self): | ||
| msg = 'required parameters could not be inferred from data: ' + \ |
There was a problem hiding this comment.
Our other error messages generally start with a capital letter (although admittedly this isn't as general a convention as I thought it was - Python itself seems to prefer lowercase)
There was a problem hiding this comment.
The latter is indeed the reason I generally try to stick with lowercase, but you're right EXtra-data mostly uses upper cases with EXtra being somewhere in the middle.
Would you prefer to set a general rule?
f6e8ecc to
a8e0ca1
Compare
a8e0ca1 to
33a54f5
Compare
|
Rebased on top of |
9914ee6 to
c793eee
Compare
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #373 +/- ##
==========================================
- Coverage 73.14% 72.74% -0.40%
==========================================
Files 35 35
Lines 6248 6521 +273
==========================================
+ Hits 4570 4744 +174
- Misses 1678 1777 +99 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
b7cd956 to
427cceb
Compare
93146aa to
caeac0c
Compare
6753085 to
f42f922
Compare
caeac0c to
7868e3e
Compare
7868e3e to
830bfc7
Compare
830bfc7 to
8767ba3
Compare
61867de to
e1524a2
Compare
|
Rebased on top of the main branch after merging |
e1524a2 to
4c02cdd
Compare
e382416 to
4b10e0c
Compare
4b10e0c to
feef5da
Compare
|
I've started adding tests replicating the ones done in
We have encountered the latter issue already in |
One of the original ideas behind the
CalibrationDataAPI is to integrate the determination of detector condition from data, i.e. the various properties of control devices and/or the data itself. Due to various changes over the years to hardware and/or software, this can unfortunately be somewhat messy and is nowadays encoded in calibration notebooks, amongst other places.This is an attempt to bring this functionality to the
CalibrationDataAPI in EXtra. Ideally, it makes obtaining calibration data as simply as:As it happens, the new design lends itself to this quite nicely by separating the detector-specific and -agnostic parts as before across the
CalibrationDataclass andConditionsBaseimplementation:Each detector-specific
ConditionsBaseobject gains a.from_data()class method taking anextra_data.DataCollectionas well as the CalCat detector name. From that, it attempts to initialize itself by inferring the necessary fields from the data. ForAGIPDConditionse.g., its signature is:fpga_comp,mpod,fpga_control,xtdfare inferred from the detector entry in CalCat and what's indata, or can be overwritten manually. The same applies to themoduleslist, which allows taking only the given modules into account (e.g. when a module is powered down, but part of the data).**paramscan be any of the regular parameter conditions, and prevents it from being inferred from data. The object attempts to be as greedy as possible and determine it from any applicable source, e.g. acquisition rate can be taken from the AGIPD FPGA comp device or the difference of pulse IDs in the data stream. If the sources indataare insufficient to construct the condition, an exception is thrown. This can be prevented by passing the missing parameters manually.For diagnostics, the actual extraction of any given parameter from data is implemented in its own static method, but that is an optional pattern.
The
CalibrationDataclass itself gains a.from_data()class method taking anextra_data.DataCollectionand optionally a detector name. From that, it attempts to infer the detector name if missing via EXtra-data components, its detector type via CalCat and this pick the correspondingConditionsBasetype. Also, it infersbegin_atfrom the data and thus attempt to initialize a proper .CalibrationDataobject via.from_condition. Any additional keyword arguments are passed to the conditions object, e.g. to overwrite parameters or sources.For now, I implemented the necessary code to infer the condition for AGIPD, LPD and Jungfrau based on what we use in
pycalibration, including (most) of its idiosyncracies. For AGIPD, I isolated the exactpycalibrationcode and ran it against this new API for a sample run of every proposal an AGIPD correction ever ran on with full agreement on all of them.You can find a minimal example showcasing several situations here.