[INSTRM-354] On missing, unconverted, or invalid numeric values, write a string FITS complaint Created: 03/May/18  Updated: 22/Apr/22  Resolved: 22/Apr/22

Status: Done
Project: Instrument control development
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Task Priority: Normal
Reporter: cloomis Assignee: cloomis
Resolution: Done Votes: 0
Labels: FITS
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Relates
relates to INSTRM-484 Update FITS headers based on Subaru f... Done
relates to PIPE2D-404 Support for raw exposures with W_PFDS... Done
relates to INSTRM-130 Refactor CCD header generation Done

 Description   

As it stands, when the routines which generate FITS cards get an invalid or missing value, they do not generate the card, but write a COMMENT instead.

We should write out 'NaN' for floating point numbers and, say, 'INVALID' for integers. Probably leave the semi-informative COMMENTS, but it is better for readers to get invalid values than no card.

n.b. NaNs are valid pixel values, but NaN is not a valid card value.



 Comments   
Comment by cloomis [ 03/Jul/18 ]

Pinning the conventions down a bit more:

Unavailable values (where there is no Gen2 or MHS keyword at all, say):

  • Subaru already uses '##NODATA##'. Can we always use that, as ugly as it is? Good for all types.

Invalid and out-of-range values:

  • FLTCARD = NaN is not valid FITS: use FLTCARD = 'NaN'.
  • Because of that, should we simply use INTCARD = 'NaN'? Using a string which suggests a float might be a problem.

The most common use-case for the invalid integer is for stepper motors whose position is not known. Yes, you can often use -9999 etc., but that often causes trouble.

Comment by hassan [ 10/Dec/18 ]

Hisanori Furusawa check how invalid values are converted prior to ingestion. By the next FITS WG meeting.

Comment by hassan [ 10/Dec/18 ]

A meta keyword that qualifies (valid/invalid) the keyword in question may be an option.

Comment by cloomis [ 21/Feb/19 ]

Per the 4.0 standard's 4.1.2.3:

"The value field, when present, shall contain the ASCII text representation of a literal string constant, a logical constant, or a numerical constant, in the format specified in Sect. 4.2. The value field may be a null field; i.e., it may consist entirely of spaces, in which case the value associated with the keyword is undefined."

So we could just leave out the value. Is that OK for Subaru?

Comment by Hisanori Furusawa [ 25/Mar/19 ]

We are checking this - sorry for taking long, but could you elaborate on what exactly the problems are if we set the values like -9999? I am still inclined to set these normal but impossible numbers as default, since they are simply db loadable as they are without any type conversion, and will not conflict with real measurements. We could define multiple values for different states like -9999 (measurement failure), -8888 (not set; not ready etc for known reason)..

Comment by cloomis [ 18/Apr/19 ]

If type conversion is a significant problem for the db ingest programs, I agree that using special values is probably the right choice. I was hoping to use a defined FITS standard, but if we can't so be it.
Do you know whether the ingest programs handle any special values, like the string "NaN" for a floating point value? I also wonder whether the common Gen2 keyword value "##NODATA##" is handled specially?

Let me talk to myself out loud.

The source of every FITS card is an MHS keyword. Each MHS keyword has a special invalid value, which is generally unused or which defaults to NaN. That value is currently used when sending MHS keywords within the ICS system.
We could use that mechanism, certainly for strings and integers, and use some defaults (your suggested -9999 or -8888, say)

Thinking through our devices, I suspect that -9999, etc. would work. Sigh.

We do need to decide on this very soon, since people are starting to use the data files.

Comment by cloomis [ 14/Aug/19 ]

I'll be generating two special values, "invalid" and "out-of-date". The real NaNs, etc. can in general be useful, so those are still used within the instrument software. The new special values are only used for FITS headers. We need cover the four header card types: integer, real, string, and logical.

For invalid, -9999, -9999.0, and "invalid value". The comment will have "INVALID" appended.
For out-of-date, -9998, -9998.0, and "expired value". The comment will have "NOT CURRENT" appended.

Logicals are left untouched in the case of expired values, and have no invalid value.

Am adding the "value" to the strings so as not to get confused with the common "invalid" enumeration value (both limit switches being set, for instance).

Some measurement errors will show other "invalid" values. For instance the cryostat temperatures will be -9999 for no readings, 400K for off-scale high, and 0K for off scale low. In this case, the internal NaN signals that an ADC channel could not be read, and the other two that the circuit is open/shorted. This ticket only translates the NaN.

If we need a different special value for some cards, it would not be hard to add the mechanism. But I am not doing it until we actually encounter the problem.

Can you check off on this please, Hisanori Furusawa?

Comment by Hisanori Furusawa [ 15/Aug/19 ]

Thank you for your proposal. Could you elaborate a bit on it? Do you mean with the "invalid value" and "expired value" string values will be set in the FITS header, or they are still numeric that is the same type as regular values for a certain card? For instance, are the invalid values 400 and 0 for the cryostat temperatures?
I believe a concern by the archive team is that if the value type in a certain card varies frame by frame, they need to deal with it in their ingesting program, which leads to cumbersome case-by-case exceptional code. So, we want to ingest values as they are without any type casting or pre-processing for conversion for reliable operation and maintenability of the code.

Comment by cloomis [ 15/Aug/19 ]

Sorry, I meant that for when the FITS writer cannot determine a valid value (the internal value is "NaN" or None or blank, or "##NODATA##"), it will use a type-correct value: -9999 for integer cards, -9999.0 for float cards, and "invalid value" for string cards. Logical cards will always be T or F.

Likewise for "expired" values. In some sense there is no difference between "invalid" and "expired" values, but I would like to be able to express as much as I can about things which have gone wrong. But if you would prefer I can convert all failures to the "invalid" values.

I only mentioned the cryostat temperatures to point out that there may be other type-correct values which indicate errors.

Comment by Hisanori Furusawa [ 15/Aug/19 ]

Thank you. I understand. This plan looks fine to me. They want to have a dictionary that defines such special values for each card, so that they could perform validation of data on the archive side.
Currently, SMOKA ingests '##NODATA##' without any conversion since it always appears in string cards and there is no conversion issue, but I agree on that, instead, having dedicated values for failures such as "invalid value" and "expired value" is good for health check and data quality control.

Comment by cloomis [ 22/Apr/22 ]

Long since done.

Generated at Sat Feb 10 16:24:08 JST 2024 using Jira 8.3.4#803005-sha1:1f96e09b3c60279a408a2ae47be3c745f571388b.