Closed oceancolorcoder closed 4 weeks ago
@ARamsay17 Data for testing provided in Data/PACE-PAX
@ARamsay17 I still can’t run PIU on PACE-PAX data on the Box. During processing of the fifth ensemble while running ProcessL2.ensemblesReflectance, we get to L1363:
stats = instrument.generateSensorStats("SeaBird",
dict(ES=esRawGroup, LI=liRawGroup, LT=ltRawGroup),
dict(ES=esRawSlice, LI=liRawSlice, LT=ltRawSlice),
instrument_wb)
This calls ProcessInstrumentUncertainties.lightDarkStats for HyperOCR:
# rawData here is the group, passed along only for the purpose of
# confirming "FrameTypes", i.e., ShutterLight or ShutterDark. Calculations
# are performed on the Slice.
# output contains:
# ave_Light: (array 1 x number of wavebands)
# ave_Dark: (array 1 x number of wavebands)
# std_Light: (array 1 x number of wavebands)
# std_Dark: (array 1 x number of wavebands)
# std_Signal: OrdDict by wavebands: sqrt( (std(Light)^2 + std(Dark)^2)/ave(Light)^2 )
output[sensortype] = self.lightDarkStats(
[rawData[sensortype]['LIGHT'],
rawData[sensortype]['DARK']],
[rawSlice[sensortype]['LIGHT'],
rawSlice[sensortype]['DARK']],
sensortype
)
As noted, these should all be 1x arrays plus the dictionary for std_Signal with waveband keys and a single spectrum. However, std_Signal for this ensemble yields waveband keys and an array of spectra. It may be important that this fifth ensemble has 25 spectra (the others are 32, 31, 35, 28) because HyperOCR.lightDarkStats (L1262) reads:
if N > 25: # normal case
std_Light.append(np.std(lightData[k])/np.sqrt(N))
std_Dark.append(np.std(darkData[k])/np.sqrt(Nd) ) # sigma here is essentially sigma**2 so N must sqrt
else: # few scans, use different statistics
std_Light.append((N-1/N-3)*(lightData[k] / np.sqrt(N))**2)
std_Dark.append((Nd-1/Nd-3)*(darkData[k] / np.sqrt(Nd))**2)
So, the structural problem is in how the alternate statistics are being calculated for N<=25.
Indeed, the result of the upper clause of the if statement yields a single number each time, while the result of the second clause yields a vector 25 long. This is the result of vectorwise use of lightData[k] in the latter, but scalarwise use of np.std(lightData[k] in the former. Could you link to the intended equation for low N?
(Side note: how is it that the number of spectra within the darkSlice are equivalent to the lightSlice here? Darks are only collected intermittently after every 6 lights or so (see the L1AQC groups in this L1BQC. So, unless darks in the slice variable, slice[1] were interpolated in time to the lights, slice[0], this doesn’t make sense. If they were interpolated, then taking the averages and standard deviations will introduce error, or …?)
Resolved with PR #263
@ARamsay17 this is a new bug in PIU processing new pySAS data