-
Notifications
You must be signed in to change notification settings - Fork 322
add raw counts calibration type to Metop-SG A1 reader (vii_l1b_nc.py) #3373
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -48,7 +48,11 @@ def __init__(self, filename, filename_info, filetype_info, **kwargs): | |
| self._bt_conversion_a = self["data/calibration_data/bt_conversion_a"].values | ||
| self._bt_conversion_b = self["data/calibration_data/bt_conversion_b"].values | ||
| self._channel_cw_thermal = self["data/calibration_data/channel_cw_thermal"].values | ||
| self._integrated_solar_irradiance = self["data/calibration_data/band_averaged_solar_irradiance"].values | ||
| # Test data has been seen for both variants below... | ||
| try: | ||
| self._integrated_solar_irradiance = self["data/calibration_data/band_averaged_solar_irradiance"].values | ||
| except KeyError: | ||
| self._integrated_solar_irradiance = self["data/calibration_data/Band_averaged_solar_irradiance"].values | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What files have the "B" and what files have the "b" naming?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @djhoese - the test data I have, and am using for co-dev on the PyADDE server, have the cap-B: I am unsure of the origin for this test data, but can find out if needed. For some reason, back in 2024, the cap "B" was changed to a lowercase "b". See: I am under the assumption there must be test data with both variants in the wild, and added the try/except to support that.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah I guess my main concern is whether this should be supported if it is from old files or from a different processing chain. If it is possible your test data is old and it is reasonable for you to get newer test data then it'd be great to have simpler code here. If this try/except stays in then maybe a comment could be added to the cap-B case to state it is for older test data or whatever is actually the case. |
||
| # Computes the angle factor for reflectance calibration as inverse of cosine of solar zenith angle | ||
| # (the values in the product file are on tie points and in degrees, | ||
| # therefore interpolation and conversion to radians are required) | ||
|
|
@@ -83,6 +87,19 @@ def _perform_calibration(self, variable: xr.DataArray, dataset_info: dict) -> xr | |
| calibrated_variable.attrs = variable.attrs | ||
| elif calibration_name == "radiance": | ||
| calibrated_variable = variable | ||
| elif calibration_name == "counts": | ||
| # xarray automatically applies scale_factor and add_offset when reading the netCDF. | ||
| # To get raw counts, reverse this process using the original parameters. | ||
|
Comment on lines
+91
to
+92
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We could ask xarray not to do this and then have the radiance calculation do the scaling.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hhmmm... not sure what is most appropriate at the moment. Need to have a think on this one.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's pretty easy to turn off in Turning off
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah I'm not completely against the way it is implemented, but others may feel differently. |
||
| scale_factor = variable.encoding.get("scale_factor", variable.attrs.get("scale_factor", 1.0)) | ||
| add_offset = variable.encoding.get("add_offset", variable.attrs.get("add_offset", 0.0)) | ||
|
|
||
| calibrated_variable = (variable - add_offset) / scale_factor | ||
|
|
||
| # Cast back to the original integer datatype (e.g., uint16) for strict counts | ||
| original_dtype = variable.encoding.get("dtype", variable.dtype) | ||
| calibrated_variable = calibrated_variable.astype(original_dtype) | ||
|
|
||
| calibrated_variable.attrs = variable.attrs | ||
| else: | ||
| raise ValueError("Unknown calibration %s for dataset %s" % (calibration_name, dataset_info["name"])) | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like this is inconsistent in Satpy, but I think counts should have units of
"1". @simonrp84 @mraspaud @pnuu @gerritholl thoughts? Even the custom reader documentation says to dounits: "count"as done here.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the terminology of ISO 80000-1:2013 (the version I have a copy of, but I doubt it has radically changed), counts would be a quantity of dimension one (also referred to as dimensionless for historical reasons, but this is not strictly correct). ISO 80000-1 defines a unit of measurement as:
Thinking about it, I don't think "count" meets this definition. Neither does 1. There is no quantity measured by "200 counts" that is 100 counts more than "100 counts". There is no convention that defines what 1 count is. And 1 is just a number.
Counts are recognised by UDUNITS, but that package has a rather liberal approach including anything that people use, and is not prescriptive on what is correct.
We can be pragmatic and use count, even if it is not strictly a unit.
We can be pragmatic and use 1, like we do for other quantities that have no unit, for example:
satpy/satpy/etc/readers/viirs_l2.yaml
Lines 110 to 113 in c1537e3
Or we can be strict, and in that case I would set units empty or leave it out entirely.
When there is no unit "1" is not the worst to use, because ISO 80000-1 says we multiply a number with its unit to get a quantity, and multiplication with 1 is a no-op. But it doesn't really work, because counts — digital number — does not really express a quantity of anything in the first place.
BS EN ISO 80000-1-2013--[2017-03-23--10-09-20 AM].pdf
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In conclusion, I think counts — digital number — should not have a unit at all, because it is not calibrated and does not express a quantity.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think in other parts of Satpy we (or more likely past Dave's code) assume a non-empty units or at least a not-None units value.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@gerritholl - thank you for the commentary. I would push back on one thing, however.
You say a digital number does not express a quantity, based on ISO-80000-1, but I would argue it does.
A DN compares an incoming analog signal with a known reference, and scales that ratio. That's a quantity.
In fact I would even say DN is itself could be considered an appropriate answer here. But what is a DN in this world - it is a quantity where the physical units, volts/volts, cancel out with a result of 1.
I think the answer comes down to whether we prefer strict ISO compliance, or human readability. Counts is fairly well understood and prevents confusion with calibrated values.
One of y'all should just make an executive decision. 😁
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Of course the counts relate to a physical quantity, or the detector output couldn't be used to measure anything physical. But the number refers to a digital detector output, without a universal definition. The meaning of the difference between "1 count" and "2 counts", or even "-10 counts" (HIRS) depends on the instrument/detector. That is clearly not the counts I learned when covering CCDs in university, which are the number of photons falling onto the pixel multiplied by the quantum efficiency, and thus cannot be negative. That might just be a scaling for digital storage reasons, but it shows there is no one way to define a count. Microwave radiometers are again different entirely.
There's nothing about count in ISO 80000-1 explicitly. A web search for ISO "count" in a broader context yields mostly results about particle count in a context of ionising radiation (and even kilocount), something entirely different with the same word, and something with a direct physical definition. Those "counts" have unit 1: The unit of Becquerel is s⁻¹ (not count·s⁻¹).
If we must have a unit, I would argue for
1, because I don't think there is such a thing as a unit "count".Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, let's go with "1". If I don't hear any further reasons for something else, I'll update the PR tomorrow, thanks everyone!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If y'all want, once this PR is resolved, I'm happy to make a separate PR to update any remaining raw counts calibration references that are inconsistent.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah I think it'd be nice to have an issue, rather than PR, where we can discuss what the correct unit for this should be.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@simonrp84 - agree but to be clear, separate GitHub ticket/issue for adopting a convention system-wide. I still want to get this PR pushed through independently.