To receive notifications about scheduled maintenance, please subscribe to the mailing-list gitlab-operations@sympa.ethz.ch. You can subscribe to the mailing-list at https://sympa.ethz.ch

Commit c35cdad1 authored by holukas's avatar holukas
Browse files

Implemented calibration gas gain correction data block for LI-7200

parent 403c22ac
<?xml version="1.0" encoding="UTF-8"?>
<module type="PYTHON_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="jdk" jdkName="Python 3.6.0 (C:\Users\holukas\Anaconda3\python.exe)" jdkType="Python SDK" />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/fct" isTestSource="false" />
<excludeFolder url="file://$MODULE_DIR$/_archive" />
<excludeFolder url="file://$MODULE_DIR$/_raw_photoshop" />
</content>
<orderEntry type="jdk" jdkName="Python 3.6 (FCT1)" jdkType="Python SDK" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>
\ No newline at end of file
......@@ -19,5 +19,5 @@
</profile-state>
</entry>
</component>
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.6.0 (C:\Users\holukas\Anaconda3\python.exe)" project-jdk-type="Python SDK" />
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.6 (FCT1)" project-jdk-type="Python SDK" />
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>
\ No newline at end of file
This diff is collapsed.
......@@ -2,6 +2,10 @@
* CHANGELOG *
*************
v 0.94, 2020-05-01
* added support for data block to correct for use of wrong calibration gas (LI-7200):
data_block_irga_li7200_extended_co2_gain0974
v 0.93, 2020-01-24
* updated EddyPro to version 7.0.6 (18 Dec 2019)
......
def version_info():
version_info_dict = {
'FluxCalcTool': 'v0.93',
'FluxCalcTool': 'v0.94',
'EddyPro': 'v7.0.6 (18 Dec 2019)',
'last edit': '24 Jan 2020'
'last edit': '1 May 2020'
}
return version_info_dict
......@@ -828,6 +828,150 @@ def data_block_irga_li7200_extended(open_file_object): # size: 12 columns / 25
return data_size, status_code, '-9999', '-9999', '-9999', '-9999', '-9999', \
'-9999', '-9999', '-9999', '-9999', '-9999', '-9999'
def data_block_irga_li7200_extended_co2_gain0974(open_file_object): # size: 12 columns / 25 bytes
"""Same as data_block_irga_li7200_extended, but with an additional gain applied to
the CO2 data columns. Gain is necessary in some years when a wrong calibration gas
was used to calibrate the LI-7200.
More info here:
https://www.swissfluxnet.ethz.ch/index.php/knowledge-base/wrong-calibration-gas-2017/
Data block added in v0.94
"""
calib_gas_corr_gain = 0.974
# byte 1: number of bytes in Licor 7200 record (2 = missing, 25 = available)
# B...unsigned char, integer, 1 Byte
# h...short integer, 2 Bytes
# >...big-endian, MSB at lowest address
byte = open_file_object.read(2)
if byte: # if there are data to read
s = struct.Struct('B B')
if len(byte) == 2:
unpacked_data = s.unpack(byte)
data_size = unpacked_data[0] # col 1/13
status_code = unpacked_data[1] # col 2/13
if data_size == 26: # if no missing data
# read next 24 bytes for a total of 26 bytes / byte 3 is OCTAL, todo correct output for octal
byte = open_file_object.read(24)
if len(byte) == 24: # check if we really have 24 more bytes
s = struct.Struct('>h B B B B B B B B B B B B B B B B B B B B B B')
unpacked_data = s.unpack(byte)
# DIAGNOSTIC VALUE
# Li72 manual: "The cell diagnostic value is a 2 byte unsigned integer (value between 0 and 8191)"
diag_val = unpacked_data[0] # diagnostic value, MSB! # col 3/13
# extract info from diag_val; for the output, we use only the diag_val integer value
# exception: signal strength is part of the default output
diag_val_bin = bin(diag_val)[2:].zfill(16)
# bits 13-15: always read 0
unused = diag_val_bin[0:3]
# bit 12: sensor head attached to LI-7550; 1 = LI-7200
head_detect = diag_val_bin[3:4]
# bit 11: 1 = thermocouple OK; 0 = thermocouple open circuit
Toutlet = diag_val_bin[4:5]
# bit 10: 1 = thermocouple OK; 0 = thermocouple open circuit
Tintlet = diag_val_bin[5:6]
# bit 9: 1 = internal reference voltages OK;
# 0 = internal reference voltages not OK, analyzer interface unit needs service
aux_input = diag_val_bin[6:7]
# bit 8: 1 = good, 0.1 to 4.9V; 0 = out of range; d=delta
dpressure = diag_val_bin[7:8]
# bit 7: 1 = chopper wheel temp is near setpoint;
# 0 = not near setpoint
chopper = diag_val_bin[8:9]
# bit 6: 1 = detector temp is near setpoint
# 0 = not near setpoint
detector = diag_val_bin[9:10]
# bit 5: 1 = OK; lock bit, indicates that optical wheel is rotating at the correct rate
PLL = diag_val_bin[10:11]
# bit 4: always set to 1 (OK)
sync = diag_val_bin[11:12]
# bits 0-3: value x 6.67 = signal strength
signal_strength = diag_val_bin[12:16]
signal_strength = int(str(signal_strength), 2) # convert bin to int
signal_strength = (signal_strength * 6.67) # col 4/13
# dry mole fraction, mmol mol-1; col 5/13
h2o_ppt = 0.001 * ((unpacked_data[1] * 256 * 256) + (unpacked_data[2] * 256) + unpacked_data[3])
# dry mole fraction, umol mol-1; col 6/13
co2_ppm = 0.0001 * ((unpacked_data[4] * 256 * 256) + (unpacked_data[5] * 256) + unpacked_data[6])
co2_ppm = co2_ppm * calib_gas_corr_gain
# col 7/13
h2o_mmol_m3 = 0.001 * ((unpacked_data[7] * 256 * 256) + (unpacked_data[8] * 256) + unpacked_data[9])
# col 8/13
co2_mmol_m3 = 0.0001 * (
(unpacked_data[10] * 256 * 256) + (unpacked_data[11] * 256) + unpacked_data[12])
co2_mmol_m3 = co2_mmol_m3 * calib_gas_corr_gain
# offset; col 9/13
cell_temp_in_deg_c = 0.01 * ((unpacked_data[13] * 256) + unpacked_data[14])
cell_temp_in_deg_c -= 100
# to hPa; col 10/13
cell_press_hpa = 10 * ((unpacked_data[15] * 256) + unpacked_data[16]) # Pa
cell_press_hpa *= 0.01
# to hPa; col 11/13
atm_press_hpa = 10 * ((unpacked_data[17] * 256) + unpacked_data[18]) # Pa
atm_press_hpa *= 0.01
# col 12/13
cooler_v = 0.001 * ((unpacked_data[19] * 256) + (unpacked_data[20]))
# col 13/13
flow_l_min = 0.001 * ((unpacked_data[21] * 256) + (unpacked_data[22]))
return data_size, status_code, diag_val, signal_strength, h2o_ppt, co2_ppm, h2o_mmol_m3, \
co2_mmol_m3, cell_temp_in_deg_c, cell_press_hpa, atm_press_hpa, cooler_v, flow_l_min
else:
return data_size, status_code, '-9999', '-9999', '-9999', '-9999', '-9999', \
'-9999', '-9999', '-9999', '-9999', '-9999', '-9999'
else:
# -----------------------------------------------
# this part was included in v 0.86
# necessary b/c in CH-DAV starting in Oct 2018 sometimes a 16 Byte data_size is detected
# the exact reason for this is unknown, but it seems like the sonicread script tries
# to store an IRGA75 data block (but IRGA75 is not installed at the site)
# therefore, in this part here, we look at the data size that is given in the file (e.g. 16 Bytes),
# then read that given number of Bytes minus 2 bytes (b/c the first two Bytes were already read)
# from the file, and then output the normal missing data header.
# a similar case was reported above for the IRGA75 (see description in data block).
# -----------------------------------------------
if data_size == 2:
return data_size, status_code, '-9999', '-9999', '-9999', '-9999', '-9999', \
'-9999', '-9999', '-9999', '-9999', '-9999', '-9999'
elif data_size > 0:
# in case the data size is different than the typical 2 or 26 Bytes, the given number
# of Bytes is read from the file and the regular header is output
for xx in range(0, data_size - 2):
byte = open_file_object.read(1)
if len(byte) == 1: # 2015-04-24
s = struct.Struct('B')
unpacked_data = s.unpack(byte)
return data_size, status_code, '-9999', '-9999', '-9999', '-9999', '-9999', \
'-9999', '-9999', '-9999', '-9999', '-9999', '-9999'
elif data_size == 0:
print("!ATTENTION! IRGA LI-7200 data size is not 2 or 26 bytes. Found data_size = 0.")
return data_size, status_code, '-9999', '-9999', '-9999', '-9999', '-9999', \
'-9999', '-9999', '-9999', '-9999', '-9999', '-9999'
def data_block_irga_li7200(open_file_object): # size: 12 columns / 25 bytes
# print('------- Li7200 IRGA information')
......
......@@ -208,6 +208,9 @@ def detect_instruments(root_dir): # uses the eddypro metadata file to detect in
elif found_instruments_id[x] == 'li-7200_extended':
data_block_order.append('data_block_irga_li7200_extended')
data_block_order_id.append(found_instruments_id[x])
elif found_instruments_id[x] == 'li-7200_extended_co2_gain0974':
data_block_order.append('data_block_irga_li7200_extended_co2_gain0974')
data_block_order_id.append(found_instruments_id[x])
elif found_instruments_id[x] == 'li-7200_extended_synctest': # new in 0.87
data_block_order.append('data_block_irga_li7200_extended_synctest')
data_block_order_id.append(found_instruments_id[x])
......@@ -585,6 +588,15 @@ def construct_header(data_block_order, data_block_order_id):
'CO2_ppm_72', 'H2O_mmol_m-3_72', 'CO2_mmol_m-3_72', 'cell_temp_in_degC_72', 'cell_press_hPa_72',
'ambient_press_hPa_72', 'cooler_V_72', 'flow_l_min-1_72')
elif data_block_order_id[x] == 'li-7200_extended_co2_gain0974':
# v0.94: same as 'li-7200_extended', but gain of 0.974 is applied to CO2 columns due
# to usage of a wrong calibration gas between 2017-2019
# https://www.swissfluxnet.ethz.ch/index.php/knowledge-base/wrong-calibration-gas-2017/
header_csv += (
'data_size_72', 'status_code_72', 'diagnostic_value_72', 'signal_strength_72', 'H2O_ppt_72',
'CO2_ppm_72', 'H2O_mmol_m-3_72', 'CO2_mmol_m-3_72', 'cell_temp_in_degC_72', 'cell_press_hPa_72',
'ambient_press_hPa_72', 'cooler_V_72', 'flow_l_min-1_72')
elif data_block_order_id[x] == 'li-7200_extended_synctest':
header_csv += (
'data_size_72', 'status_code_72', 'diagnostic_value_72', 'cooler_V_72', 'AUX3',
......
download_raw_binary_data_from_server=0
download_how_many_files_max=9999
convert_raw=0
convert_raw=1
download_eddypro_settings_from_server=0
plot_availability=0
plot_raw=0
plot_raw=1
calc_fluxes=0
plot_full_output=1
plot_diurnal_cycles_output=1
plot_full_output=0
plot_diurnal_cycles_output=0
use_rds=0
fluxes_from=2014-12-31 00:00
fluxes_until=2015-12-31 23:59
fluxes_from=2017-12-31 00:00
fluxes_until=2018-12-31 23:59
raw_binary_file_extension=*.o*
raw_binary_min_filesize_bytes=900
site_to_process=CH-OE2
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment