def test_ph_multiples(self): """ Test ability of ph_calc_phwater to process multiple pH measurements in a single block. """ bout = ph.ph_battery(self.braw) tout = ph.ph_thermistor(self.traw) a434 = ph.ph_434_intensity(self.light) # no unit tests, just checking to see if they work print a434 a578 = ph.ph_578_intensity(self.light) print a578 # reset calibration values to an array, replicating how ION will pass # the data when processing blocks of values. ea434 = np.ones(15) * self.ea434 eb434 = np.ones(15) * self.eb434 ea578 = np.ones(15) * self.ea578 eb578 = np.ones(15) * self.eb578 ind_slp = np.ones(15) * self.ind_slp ind_off = np.ones(15) * self.ind_off # test the function pout = ph.ph_calc_phwater( self.ref, self.light, tout, ea434, eb434, ea578, eb578, ind_slp, ind_off, self.salinity ) # test above output where records were processed one at a time np.testing.assert_array_almost_equal(bout, self.vbatt, 4) np.testing.assert_array_almost_equal(tout, self.therm, 4) np.testing.assert_array_almost_equal(pout, self.pH, 4)
def test_ph_multiples(self): """ Test ability of ph_calc_phwater to process multiple pH measurements in a single block. """ bout = ph.ph_battery(self.braw) tout = ph.ph_thermistor(self.traw) a434 = ph.ph_434_intensity( self.light) # no unit tests, just checking to see if they work print a434 a578 = ph.ph_578_intensity(self.light) print a578 # reset calibration values to an array, replicating how ION will pass # the data when processing blocks of values. ea434 = np.ones(15) * self.ea434 eb434 = np.ones(15) * self.eb434 ea578 = np.ones(15) * self.ea578 eb578 = np.ones(15) * self.eb578 ind_slp = np.ones(15) * self.ind_slp ind_off = np.ones(15) * self.ind_off # test the function pout = ph.ph_calc_phwater(self.ref, self.light, tout, ea434, eb434, ea578, eb578, ind_slp, ind_off, self.salinity) # test above output where records were processed one at a time np.testing.assert_array_almost_equal(bout, self.vbatt, 4) np.testing.assert_array_almost_equal(tout, self.therm, 4) np.testing.assert_array_almost_equal(pout, self.pH, 4)
def test_ph_singles(self): """ Test ability of ph_calc_phwater to process a single pH measurement, one measurement at a time. """ # determine the number of records and create the output arrays nRec = self.ref.shape[0] bout = np.zeros(nRec, dtype=np.float) tout = np.zeros(nRec, dtype=np.float) a434 = np.zeros((nRec, 23), dtype=np.float) a578 = np.zeros((nRec, 23), dtype=np.float) pout = np.zeros(nRec, dtype=np.float) # index through the records, calculating pH one record at a time for iRec in range(nRec): # compute the battery voltage, final temperature in deg_C and pH, # record by record. bout[iRec] = ph.ph_battery(self.braw[iRec]) a434[iRec, :] = ph.ph_434_intensity(self.light[iRec, :]) a578[iRec, :] = ph.ph_578_intensity(self.light[iRec, :]) tout[iRec] = ph.ph_thermistor(self.traw[iRec]) pout[iRec] = ph.ph_calc_phwater(self.ref[iRec, :], self.light[iRec, :], tout[iRec], self.ea434, self.eb434, self.ea578, self.eb578, self.ind_slp, self.ind_off, self.salinity[iRec]) # test above output where records were processed one at a time np.testing.assert_array_almost_equal(bout, self.vbatt, 4) np.testing.assert_array_almost_equal(tout, self.therm, 4) np.testing.assert_array_almost_equal(pout, self.pH, 4)
def test_ph_multiples(self): """ Test ability of ph_calc_phwater to process multiple pH measurements in a single block. """ bout = self.braw * 15. / 4096. tout = ph.ph_thermistor(self.traw) # reset calibration values to an array, replicating how ION will pass # the data when processing blocks of values. ea434 = np.ones(6) * self.ea434 eb434 = np.ones(6) * self.eb434 ea578 = np.ones(6) * self.ea578 eb578 = np.ones(6) * self.eb578 # test the function pout = ph.ph_calc_phwater(self.ref, self.light, tout, ea434, eb434, ea578, eb578) # test above output where records were processed one at a time np.testing.assert_array_almost_equal(bout, self.vbatt, 4) np.testing.assert_array_almost_equal(tout, self.therm, 4) np.testing.assert_array_almost_equal(pout, self.pH, 4)
def test_ph_singles(self): """ Test ability of ph_calc_phwater to process a single pH measurement, one measurement at a time. """ # determine the number of records and create the output arrays nRec = self.ref.shape[0] bout = np.zeros(nRec, dtype=np.float) tout = np.zeros(nRec, dtype=np.float) a434 = np.zeros((nRec, 23), dtype=np.float) a578 = np.zeros((nRec, 23), dtype=np.float) pout = np.zeros(nRec, dtype=np.float) # index through the records, calculating pH one record at a time for iRec in range(nRec): # compute the battery voltage, final temperature in deg_C and pH, # record by record. bout[iRec] = ph.ph_battery(self.braw[iRec]) a434[iRec, :] = ph.ph_434_intensity(self.light[iRec, :]) a578[iRec, :] = ph.ph_578_intensity(self.light[iRec, :]) tout[iRec] = ph.ph_thermistor(self.traw[iRec]) pout[iRec] = ph.ph_calc_phwater( self.ref[iRec, :], self.light[iRec, :], tout[iRec], self.ea434, self.eb434, self.ea578, self.eb578, self.ind_slp, self.ind_off, self.salinity[iRec], ) # test above output where records were processed one at a time np.testing.assert_array_almost_equal(bout, self.vbatt, 4) np.testing.assert_array_almost_equal(tout, self.therm, 4) np.testing.assert_array_almost_equal(pout, self.pH, 4)
def main(): # load the input arguments args = inputs() infile = os.path.abspath(args.infile) outfile = os.path.abspath(args.outfile) # load the parsed, json data file with open(infile, 'rb') as f: phsen = Munch(json.load(f)) if len(phsen.time) == 0: # This is an empty file, end processing return None # convert the raw battery voltage and thermistor values from counts # to V and degC, respectively phsen.thermistor_start = ph_thermistor(np.array( phsen.thermistor_start)).tolist() therm = ph_thermistor(np.array(phsen.thermistor_end)) phsen.thermistor_end = therm.tolist() phsen.voltage_battery = ph_battery(np.array( phsen.voltage_battery)).tolist() # compare the instrument clock to the GPS based DCL time stamp # --> PHSEN uses the OSX date format of seconds since 1904-01-01 mac = datetime.strptime("01-01-1904", "%m-%d-%Y") offset = [] for i in range(len(phsen.time)): rec = mac + timedelta(seconds=phsen.record_time[i]) rec.replace(tzinfo=timezone('UTC')) dcl = datetime.utcfromtimestamp(phsen.time[i]) offset.append((rec - dcl).total_seconds()) phsen.time_offset = offset # set default calibration values (could later roll this into a coefficients file) nRec = len(phsen.thermistor_end) ea434 = np.ones(nRec) * 17533. eb434 = np.ones(nRec) * 2229. ea578 = np.ones(nRec) * 101. eb578 = np.ones(nRec) * 38502. slope = np.ones(nRec) * 0.9698 offset = np.ones(nRec) * 0.2484 # if available, load the co-located CTDBP data file corresponding to the # PHSEN data file if args.ctdfile: # load the ctd data ctdfile = os.path.abspath(args.ctdfile) with open(ctdfile, 'rb') as f: ctd = Munch(json.load(f)) data = np.array( [ctd.time, ctd.conductivity, ctd.temperature, ctd.pressure]) # process the bursts, creating a median averaged dataset of the bursts, # yielding a 15 minute data record m = np.where(np.diff(data[0, :]) > 300) # find beginning of each burst burst = [] strt = 0 # process the bursts ... for indx in m[0] + 1: time = np.atleast_1d(np.mean(data[0, strt:indx])) smpl = np.median(data[1:, strt:indx], axis=1) burst.append(np.hstack((time, smpl))) strt = indx # ... and the last burst time = np.atleast_1d(np.mean(data[0, strt:])) smpl = np.median(data[1:, strt:], axis=1) burst.append(np.hstack((time, smpl))) burst = np.atleast_1d(burst) # interpolate the ctd burst data records onto the phsen record interpf = sci.interp1d(burst[:, 0], burst[:, 1:], kind='linear', axis=0, bounds_error=False) ctd = interpf(np.array(phsen.time)) # calculate the salinity from the CTD data, psu = ctd_pracsal(ctd[:, 0], ctd[:, 1], ctd[:, 2]).reshape( (ctd.shape[0], 1)) ctd = np.hstack((ctd, psu)) else: data = np.array((np.nan, np.nan, np.nan, args.salinity)) ctd = np.tile(data, (len(phsen.time), 1)) # calculate the pH refnc = np.array(phsen.reference_measurements) light = np.array(phsen.light_measurements) pH = ph_calc_phwater(refnc, light, therm, ea434, eb434, ea578, eb578, slope, offset, ctd[:, 3]) phsen.pH = pH.tolist() # save the resulting data to a json formatted file with open(outfile, 'w') as f: f.write(phsen.toJSON())