Skip to content

Commit ca6ccde

Browse files
Mark JessopMark Jessop
authored andcommitted
Initial test of O3 partial pressure calculations
1 parent d57d078 commit ca6ccde

File tree

2 files changed

+104
-14
lines changed

2 files changed

+104
-14
lines changed

js/tracker.js

Lines changed: 55 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1768,11 +1768,13 @@ function habitat_data(jsondata, alternative) {
17681768
"oif411_serial": "OIF411 Serial Number",
17691769
"oif411_diagnostics": "OIF411 Diagnostics",
17701770
"oif411_version": "OIF411 Version",
1771+
"oif411_O3_partial_pressure": "Ozone Partial Pressure"
17711772
};
17721773

17731774
var tooltips = {
17741775
"burst_timer": "If active, this indicates the time (HH:MM:SS) until the radiosonde will automatically power-off.",
1775-
"xdata": "Raw auxiliary data (as hexadecimal) from an external sensor package (often an Ozone sensor)."
1776+
"xdata": "Raw auxiliary data (as hexadecimal) from an external sensor package (often an Ozone sensor).",
1777+
"oif411_O3_partial_pressure": "Estimated O3 partial pressure, using nominal calibration values. +/- 1 mPa."
17761778
}
17771779

17781780
var hide_keys = {
@@ -1810,6 +1812,7 @@ function habitat_data(jsondata, alternative) {
18101812
"oif411_ozone_current_uA": " uA",
18111813
"oif411_ozone_pump_curr_mA": " mA",
18121814
"oif411_ozone_pump_temp": "°C",
1815+
"oif411_O3_partial_pressure": " mPa (+/- 1)"
18131816
};
18141817

18151818
try
@@ -3148,21 +3151,29 @@ function mapInfoBox_handle_path_new(data, vehicle, date) {
31483151
html += "<hr style='margin:0px;margin-top:5px'>";
31493152
html += "<div style='font-size:11px;'>"
31503153
html += "<div><b>XDATA:&nbsp;</b>" + data.xdata + "</div>";
3151-
var tempXDATA = parseXDATA(data.xdata);
3154+
if (data.hasOwnProperty("pressure")) {
3155+
xdata_pressure = data.pressure;
3156+
} else {
3157+
xdata_pressure = 1100.0;
3158+
}
3159+
var tempXDATA = parseXDATA(data.xdata, xdata_pressure);
31523160
if (tempXDATA.hasOwnProperty('xdata_instrument')) {
31533161
html += "<div><b>XDATA Instrument:&nbsp;</b>" + tempXDATA.xdata_instrument + "</div>";
31543162
}
31553163
if (tempXDATA.hasOwnProperty('oif411_ozone_battery_v')) {
3156-
html += "<div><b>OIF411 Battery:&nbsp;</b>" + tempXDATA.oif411_ozone_battery_v + " V</div>";
3164+
html += "<div><b>OIF411 Battery:&nbsp;</b>" + tempXDATA.oif411_ozone_battery_v.toFixed(1) + " V</div>";
31573165
}
31583166
if (tempXDATA.hasOwnProperty('oif411_ozone_current_uA')) {
3159-
html += "<div><b>Ozone Current:&nbsp;</b>" + tempXDATA.oif411_ozone_current_uA + " uA</div>";
3167+
html += "<div><b>Ozone Current:&nbsp;</b>" + tempXDATA.oif411_ozone_current_uA.toFixed(4) + " uA</div>";
3168+
}
3169+
if (tempXDATA.hasOwnProperty('oif411_O3_partial_pressure')) {
3170+
html += "<div><b>Ozone Partial Presure:&nbsp;</b>" + tempXDATA.oif411_O3_partial_pressure.toFixed(3) + " mPa (+/- 1)</div>";
31603171
}
31613172
if (tempXDATA.hasOwnProperty('oif411_ozone_pump_curr_mA')) {
3162-
html += "<div><b>Ozone Pump Current:&nbsp;</b>" + tempXDATA.oif411_ozone_pump_curr_mA + " mA</div>";
3173+
html += "<div><b>Ozone Pump Current:&nbsp;</b>" + tempXDATA.oif411_ozone_pump_curr_mA.toFixed(1) + " mA</div>";
31633174
}
31643175
if (tempXDATA.hasOwnProperty('oif411_ozone_pump_temp')) {
3165-
html += "<div><b>Ozone Pump Temperature:&nbsp;</b>" + tempXDATA.oif411_ozone_pump_temp + "°C</div>";
3176+
html += "<div><b>Ozone Pump Temperature:&nbsp;</b>" + tempXDATA.oif411_ozone_pump_temp.toFixed(1) + "°C</div>";
31663177
}
31673178
if (tempXDATA.hasOwnProperty('oif411_serial')) {
31683179
html += "<div><b>OIF411 Serial Number:&nbsp;</b>" + tempXDATA.oif411_serial + "</div>";
@@ -3895,7 +3906,7 @@ function addPosition(position) {
38953906

38963907
// Graph Stuff
38973908

3898-
var graph_inhibited_fields = ['frequency', 'frequency_tx', 'burst_timer', 'xdata', 'oif411_ozone_pump_temp', 'oif411_ozone_battery_v', 'oif411_ozone_pump_curr_mA', 'oif411_serial', 'oif411_version'];
3909+
var graph_inhibited_fields = ['frequency', 'frequency_tx', 'burst_timer', 'xdata', 'oif411_ozone_pump_temp', 'oif411_ozone_battery_v', 'oif411_ozone_pump_curr_mA', 'oif411_serial', 'oif411_version', 'oif411_ozone_current_uA'];
38993910

39003911
function updateGraph(vcallsign, reset_selection) {
39013912
if(!plot || !plot_open) return;
@@ -4230,7 +4241,13 @@ function formatData(data, live) {
42304241
}
42314242
if (data[entry].xdata) {
42324243
dataTempEntry.data.xdata = data[entry].xdata;
4233-
var tempXDATA = parseXDATA(data[entry].xdata);
4244+
4245+
if (data[entry].hasOwnProperty("pressure")) {
4246+
xdata_pressure = data[entry].pressure;
4247+
} else {
4248+
xdata_pressure = 1100.0;
4249+
}
4250+
var tempXDATA = parseXDATA(data[entry].xdata, xdata_pressure);
42344251
if (tempXDATA.hasOwnProperty('xdata_instrument')) {
42354252
dataTempEntry.data.xdata_instrument = tempXDATA.xdata_instrument;
42364253
}
@@ -4255,6 +4272,9 @@ function formatData(data, live) {
42554272
if (tempXDATA.hasOwnProperty('oif411_version')) {
42564273
dataTempEntry.oif411_version = tempXDATA.oif411_version;
42574274
}
4275+
if (tempXDATA.hasOwnProperty('oif411_O3_partial_pressure')) {
4276+
dataTempEntry.oif411_O3_partial_pressure = tempXDATA.oif411_O3_partial_pressure;
4277+
}
42584278
}
42594279
if (data[entry].serial.toLowerCase() != "xxxxxxxx") {
42604280
dataTemp.push(dataTempEntry);
@@ -4343,7 +4363,12 @@ function formatData(data, live) {
43434363
}
43444364
if (data.xdata) {
43454365
dataTempEntry.data.xdata = data.xdata;
4346-
var tempXDATA = parseXDATA(data.xdata);
4366+
if (data.hasOwnProperty("pressure")) {
4367+
xdata_pressure = data.pressure;
4368+
} else {
4369+
xdata_pressure = 1100.0;
4370+
}
4371+
var tempXDATA = parseXDATA(data.xdata, xdata_pressure);
43474372
if (tempXDATA.hasOwnProperty('xdata_instrument')) {
43484373
dataTempEntry.data.xdata_instrument = tempXDATA.xdata_instrument;
43494374
}
@@ -4368,6 +4393,9 @@ function formatData(data, live) {
43684393
if (tempXDATA.hasOwnProperty('oif411_version')) {
43694394
dataTempEntry.oif411_version = tempXDATA.oif411_version;
43704395
}
4396+
if (tempXDATA.hasOwnProperty('oif411_O3_partial_pressure')) {
4397+
dataTempEntry.oif411_O3_partial_pressure = tempXDATA.oif411_O3_partial_pressure;
4398+
}
43714399
}
43724400
if (data.serial.toLowerCase() != "xxxxxxxx") {
43734401
dataTemp.push(dataTempEntry);
@@ -4439,7 +4467,12 @@ function formatData(data, live) {
44394467
}
44404468
if (data[key][i].xdata) {
44414469
dataTempEntry.data.xdata = data[key][i].xdata;
4442-
var tempXDATA = parseXDATA(data[key][i].xdata);
4470+
if (data[key][i].hasOwnProperty("pressure")) {
4471+
xdata_pressure = data[key][i].pressure;
4472+
} else {
4473+
xdata_pressure = 1100.0;
4474+
}
4475+
var tempXDATA = parseXDATA(data[key][i].xdata, xdata_pressure);
44434476
if (tempXDATA.hasOwnProperty('xdata_instrument')) {
44444477
dataTempEntry.data.xdata_instrument = tempXDATA.xdata_instrument;
44454478
}
@@ -4464,6 +4497,9 @@ function formatData(data, live) {
44644497
if (tempXDATA.hasOwnProperty('oif411_version')) {
44654498
dataTempEntry.oif411_version = tempXDATA.oif411_version;
44664499
}
4500+
if (tempXDATA.hasOwnProperty('oif411_O3_partial_pressure')) {
4501+
dataTempEntry.oif411_O3_partial_pressure = tempXDATA.oif411_O3_partial_pressure;
4502+
}
44674503
}
44684504
if (data[key][i].serial.toLowerCase() != "xxxxxxxx") {
44694505
dataTemp.push(dataTempEntry);
@@ -4566,7 +4602,12 @@ function formatData(data, live) {
45664602
}
45674603
if (data[i].xdata) {
45684604
dataTempEntry.data.xdata = data[i].xdata;
4569-
var tempXDATA = parseXDATA(data[i].xdata);
4605+
if (data[i].hasOwnProperty("pressure")) {
4606+
xdata_pressure = data[i].pressure;
4607+
} else {
4608+
xdata_pressure = 1100.0;
4609+
}
4610+
var tempXDATA = parseXDATA(data[i].xdata, xdata_pressure);
45704611
if (tempXDATA.hasOwnProperty('xdata_instrument')) {
45714612
dataTempEntry.data.xdata_instrument = tempXDATA.xdata_instrument;
45724613
}
@@ -4591,6 +4632,9 @@ function formatData(data, live) {
45914632
if (tempXDATA.hasOwnProperty('oif411_version')) {
45924633
dataTempEntry.oif411_version = tempXDATA.oif411_version;
45934634
}
4635+
if (tempXDATA.hasOwnProperty('oif411_O3_partial_pressure')) {
4636+
dataTempEntry.oif411_O3_partial_pressure = tempXDATA.oif411_O3_partial_pressure;
4637+
}
45944638
}
45954639
dataTemp.push(dataTempEntry);
45964640
}

js/xdata.js

Lines changed: 49 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,45 @@
33
* Author: Mark Jessop
44
*/
55

6-
function parseOIF411(xdata){
6+
// Pump Efficiency Correction Parameters for ECC-6A Ozone Sensor, with 3.0cm^3 volume.
7+
// We are using these as a nominal correction value for pump efficiency vs pressure
8+
//
9+
OIF411_Cef_Pressure = [ 0, 2, 3, 5, 10, 20, 30, 50, 100, 200, 300, 500, 1000, 1100];
10+
OIF411_Cef = [ 1.171, 1.171, 1.131, 1.092, 1.055, 1.032, 1.022, 1.015, 1.011, 1.008, 1.006, 1.004, 1, 1];
11+
12+
13+
function lerp(x, y, a){
14+
// Helper function for linear interpolation between two points
15+
return x * (1 - a) + y * a
16+
}
17+
18+
19+
function get_oif411_Cef(pressure){
20+
// Get the Pump efficiency correction value for a given pressure.
21+
22+
// Off-scale use bottom-end value
23+
if (pressure <= OIF411_Cef_Pressure[0]){
24+
return OIF411_Cef[0];
25+
}
26+
27+
// Off-scale top, use top-end value
28+
if (pressure >= OIF411_Cef_Pressure[OIF411_Cef_Pressure.length-1]){
29+
return OIF411_Cef[OIF411_Cef.length-1];
30+
}
31+
32+
33+
// Within the correction range, perform linear interpolation.
34+
for(i= 1; i<OIF411_Cef_Pressure.length; i++){
35+
if (pressure < OIF411_Cef_Pressure[i]) {
36+
return lerp(OIF411_Cef[i-1], OIF411_Cef[i], ( (pressure-OIF411_Cef_Pressure[i-1]) / (OIF411_Cef_Pressure[i]-OIF411_Cef_Pressure[i-1])) );
37+
}
38+
}
39+
40+
// Otherwise, bomb out and return 1.0
41+
return 1.0;
42+
}
43+
44+
function parseOIF411(xdata, pressure){
745
// Attempt to parse an XDATA string from an OIF411 Ozone Sounder
846
// Returns an object with parameters to be added to the sondes telemetry.
947
//
@@ -76,6 +114,14 @@ function parseOIF411(xdata){
76114
// External Voltage
77115
_output['oif411_ext_voltage'] = parseInt(xdata.substr(18,2),16)*0.1; // Volts
78116

117+
// Now attempt to calculate the O3 partial pressure
118+
119+
// Calibration values
120+
Ibg = 0.0; // The BOM appear to use a Ozone background current value of 0 uA
121+
Cef = get_oif411_Cef(pressure); // Calculate the pump efficiency correction.
122+
FlowRate = 28.5; // Use a 'nominal' value for Flow Rate (seconds per 100mL).
123+
124+
_output['oif411_O3_partial_pressure'] = (4.30851e-4)*(_output['oif411_ozone_current_uA'] - Ibg)*(_output['oif411_ozone_pump_temp']+273.15)*FlowRate*Cef;
79125

80126
return _output
81127

@@ -84,7 +130,7 @@ function parseOIF411(xdata){
84130
}
85131
}
86132

87-
function parseXDATA(data){
133+
function parseXDATA(data, pressure){
88134
// Accept an XDATA string, or multiple XDATA entries, delimited by '#'
89135
// Attempt to parse each one, and return an object
90136
// Test datasets:
@@ -114,7 +160,7 @@ function parseXDATA(data){
114160
_output = {'xdata_instrument': 'V7'};
115161
} else if (_instrument === '05'){
116162
// OIF411
117-
_xdata_temp = parseOIF411(_current_xdata);
163+
_xdata_temp = parseOIF411(_current_xdata, pressure);
118164
_output = Object.assign(_output,_xdata_temp);
119165
} else if (_instrument === '08'){
120166
// CFH

0 commit comments

Comments
 (0)