12 - primary fluorescence


parameters

var output = {};
var spad;
var data = json.data_raw;
var vhplus;
var tau;
var ECSt;
var quality_flag = 0;
var i = 0;
var j = 0;
var h = 0;
var k = 0;
var smooth1 = data.slice(300,600);
var smooth0 = data.slice(300,600);



//var pulsedistance = 1; // pulse distance for the ECS portion of the trace in seconds
//var ecsPulses = 300; // pulses during each light cycle duing ECS portion of trace (300 light on, 300 light off, 300 light on)
//var fit_cutoff = .01; // valueless number indicating what portion of the decay curve to pass to the decay fitting subroutine
//var hit_cutoff_times = 1;  // this is a counter to ensure we don't just hit a weird portion of the curve and cutoff too soon.   

// we need an array representing the time (in us) and data for each pulse in the ECS trace.  Subtract first and less point so it's 898 points total


//output["ecsArray raw"] = data.slice(0,ecsPulses*3);
// sanity check - do the arrays look as we expect?
//output["all_ecs length"] = ecsArray.length;
//output["all_time length"] = timeArray.length;
//output["ecsArray cleaned"] = ecsArray;

// first lets make the ECS trace flat, in case for some reason it's tilted up or down. Skip first and last point in case there were blips
/*
var flattenData = ecsArray.slice(0,ecsPulses);
var flattenTime = timeArray.slice(0,ecsPulses);

// make some error catching things - standard deviation of the first portion of the trace... etc.
var flattenData_std = MathSTDEV(flattenData);
var endOfTrace_std =  MathSTDEV(ecsArray.slice(ecsPulses*2,ecsPulses*3));
//output["flattenData_std"] = flattenData_std;
//output["endOfTrace_std"] = endOfTrace_std;

// if the standard deviation is too high, then let's not output ECS values

// now let's run a regression to determine the slope
  
var flattenReg = MathLINREG(flattenTime,flattenData);

output["flatten slope"] = MathROUND(flattenReg.m,4);
//output["flatten y-int"] = flattenReg.b;
// sanity check - what does the slope look like before by checking the first and last value in the initial light period?  Compare with after the flattening adjustment
//output["ecsArray pre 0"] = ecsArray[0];
//output["ecsArray pre 300"] = ecsArray[300];
//output["ecsArray"] = ecsArray;


// now we assume this slope applies to the whole ECS trace, and subtract off the slope at each point

var ecsArray_flat = ecsArray.slice(0,ecsPulses*3);
for (var i = 0; i < timeArray.length; i++) {
  var adjustment = flattenReg.m*timeArray[i]; 
  ecsArray_flat[i] = ecsArray_flat[i]-adjustment;
}
// now we can calculate the initial and max ecs values to calculate ECSt
// calculated as the median value within 25 pulses of the light-on phase (minimum) and within 50 pulses of the light off phase (maximum)
ecs_initial = MathROUND(MathMEDIAN(ecsArray_flat.slice(ecsPulses-25,ecsPulses)),2);
ecs_max = MathROUND(MathMEDIAN(ecsArray_flat.slice(ecsPulses*2-100,ecsPulses*2)),2);
ecst_estimate = ecs_max - ecs_initial;
output["ecs_initial"] = MathROUND(MathMEDIAN(ecsArray_flat.slice(ecsPulses-25,ecsPulses)),2);
output["ecs_max"] = MathROUND(MathMEDIAN(ecsArray_flat.slice(ecsPulses*2-100,ecsPulses*2)),2);

//output["ecsArray flattened"] = ecsArray_flat;
// sanity check - ok these two numbers should be much closer to each other (slope has moved towards 0), and make sure our flattening worked
//output["ecsArray post 0"] = ecsArray_flat[0];
//output["ecsArray post 300"] = ecsArray_flat[300];

// Then convert these values into absorbance in the form abs = -log(Io/I), where we set Io to ecs_initial.  
// For the decay fitting subroutine, we also try to set the estimated asymptote (ecs_max) to zero - this helps the fitting subroutine reduce iterations to converge to the correct value
ecsArray_flat_log = [];
for (var i = 0; i < timeArray.length; i++) {
  var abs = MathLOG(ecs_initial/(ecsArray_flat[i])); 
  ecsArray_flat_log[i] = abs - MathLOG(ecs_initial/ecs_max);
}

//output["ECS full"] = ecsArray_flat_log;

  output["ecs_r_squared"] = flattenReg.r;

if (ecs_initial <= 8000) {
  warning("There was a technical error with your measurement, please retake the measurement", output);
}

else if (ecs_initial >= 58000) {
  warning("There was a technical error with your measurement, please retake the measurement", output);
}

if (ecst_estimate < 2 || json.light_intensity < 50) {
  output["ECSt"] = 0;
  output["vH+"] = 0;
  output["gH+"] = 0;
  warning("proton motive force signal too low.  May be due to low ambient light, or normal biological variation.  ECSt, vH+, and gH+ have been set to zero", output);
}
if (flattenData_std > 25 || endOfTrace_std > 25) {
  output["ECSt"] = "NA";
  output["vH+"] = "NA";
  output["gH+"] = "NA";
  warning("Proton Motive Force too noisy", output);
}
if (!(flattenData_std > 25 || endOfTrace_std > 25 || ecst_estimate < 2 || json.light_intensity < 50)) {
  // Now we fit a best fit line to the curve.  We need to put our data in the format [[x,y],[x,y]...] first though
  var expData = ecsArray_flat_log.slice(ecsPulses,ecsPulses+100);
  var expTime = [];
  // normalize time to zero for the fit
  for (var i = 0; i < timeArray.slice(ecsPulses, ecsPulses*2).length; i++) {
    expTime.push(i);
  }
  //output["time array"] = expTime;
//  output["ECS decay"] = expData;

  var expFitArray = [];
  for (var i = 0; i < 100; i++) {
    expFitArray[i] = [expTime[i], expData[i]];
  }
  
  expReg = MathEXPINVREG(expFitArray);

  // questions for kevin - ECSt would be y int + outputted asymptote, correct?

  //output["asymptote"] = expReg.asymptote;
  //output["ECSt"] = MathROUND(expReg.results[0],4);
  //output["expFit slope"] = expReg.slope;
  //output["vH+"] = MathROUND(expReg.slope,8);
  //output["expFit lifetime"] = expReg.lifetime;
  //output["gH+"] = MathROUND(expReg.lifetime,4);
}

// Check to make sure that the detector2 setting which determines the intensity of the green LED is not zero or maxed
if (json.detector_read2 == 65535 || json.detector_read2 < 1) {
  danger("Something is wrong with the auto-intensity calibration detector_read2.  Make sure device is stable and completely clamped on measurement.  Measure again.", output);
}

*/  


// CALCULATIONS FOR ABSORBANCE / SPAD PORTION OF THE TRACE
//----------------------------

var abs_starts = 280; // when does the Phi2 measurement start
var data = json.data_raw;
var lights = [1,2,3,4,6,8,9,10];// define the lights to have absorbance measured
var wavelengths = ["530","650","605","420","940","850","730","880"];// define the lights to have absorbance measured
var raw_at_blank1 = [0,0,0,0,0,0,0,0];
var raw_at_blank2 = [0,0,0,0,0,0,0,0];
var raw_at_blank3 = [0,0,0,0,0,0,0,0];
var abs_at_blank1 = [0,0,0,0,0,0,0,0];
var abs_at_blank2 = [0,0,0,0,0,0,0,0];
var abs_at_blank3 = [0,0,0,0,0,0,0,0];
var trans_at_blank1 = [0,0,0,0,0,0,0,0];
var trans_at_blank2 = [0,0,0,0,0,0,0,0];
var trans_at_blank3 = [0,0,0,0,0,0,0,0];
var spad_at_blank1 = [0,0,0,0,0,0,0,0];
var spad_at_blank2 = [0,0,0,0,0,0,0,0];
var spad_at_blank3 = [0,0,0,0,0,0,0,0];
var minolta_spad1 = 0;
var minolta_spad2 = 0;
var minolta_spad3 = 0;
var minolta_spad = 0;
var minolta_spad_averages = 0;
var choose = 0;
var light;
var wavelengthString;
var pulses = 10;// number of pulses in a cycle

/* // this is what the recall object looks like --> 
"recall":{"colorcal_blank1[1]":0.000000,"colorcal_blank1[2]":0.000000,"colorcal_blank1[3]":0.000000,"colorcal_blank1[4]":0.00000
0,"colorcal_blank1[6]":0.000000,"colorcal_blank1[8]":0.000000,"colorcal_blank1[9]":0.000000,"colorcal_blank1[10]":0.000000,"colo
rcal_blank2[1]":0.000000,"colorcal_blank2[2]":0.000000,"colorcal_blank2[3]":0.000000,"colorcal_blank2[4]":0.000000,"colorcal_bla
nk2[6]":0.000000,"colorcal_blank2[8]":0.000000,"colorcal_blank2[9]":0.000000,"colorcal_blank2[10]":0.000000,"colorcal_blank3[1]"
:0.000000,"colorcal_blank3[2]":0.000000,"colorcal_blank3[3]":0.000000,"colorcal_blank3[4]":0.000000,"colorcal_blank3[6]":0.00000
0,"colorcal_blank3[8]":0.000000,"colorcal_blank3[9]":0.000000,"colorcal_blank3[10]":0.000000},
*/

/*
** Loop through the lights.  If it's zero, skip it.  If it's not in the acceptable range (>500 but <65534 (max)) skip it.
** Then choose the first blank (starting with 1 moving to 3) which fulfills this criteria
** Otherwise, calculate absorbance and transmittance and a 'spad'-like value using LED 6 (940 on clamp) to calibrate thickness
*/
//----------------------------

for (var i = 0;i<lights.length;i++) { // loop through and save one averaged 'point' for each of the cycles
  light = lights[i];
  wavelengthString = wavelengths[i];
  var value1 = MathMEDIAN(json.data_raw.slice((abs_starts + i*pulses+2),(abs_starts + i*pulses+8)));
  var value2 = MathMEDIAN(json.data_raw.slice((abs_starts + i*pulses+82),(abs_starts + i*pulses+88)));
  var value3 = MathMEDIAN(json.data_raw.slice((abs_starts + i*pulses+162),(abs_starts + i*pulses+168)));
  raw_at_blank1[light] = value1;
  raw_at_blank2[light] = value2;
  raw_at_blank3[light] = value3;
  if (json.recall["colorcal_blank1["+light+"]"] != 0 && raw_at_blank1[light] > 500 && raw_at_blank1[light] < 65534) {
    abs_at_blank1[light] = MathROUND(-1*MathLOG(raw_at_blank1[light]/json.recall["colorcal_blank1["+light+"]"]),3);
//    trans_at_blank1[light] = MathROUND(raw_at_blank1[light]/json.recall["colorcal_blank1["+light+"]"],3);
//	output ["light".concat(light.toString(),"_transmittance")]  = trans_at_blank1[light];
    //output ["absorbance_".concat(wavelengthString)]  = abs_at_blank1[light];
//	output ["light".concat(light.toString(),"_blank1")]  = json.recall["colorcal_blank1["+light+"]"];
  }
}

// so the raw value needs to be >~2000, while the 940 needs to be greater than ~5000, otherwise it's out of range
// the acceptable range is different for each blank (1,2,3) thus a separate if statement for each blank.
// once you hit an intensity which is within the acceptable range, then keep that value and skip the rest

for (var i = 0;i<8;i++) { // loop through and save one averaged SPAD value for each of the cycles.  If we have additional calibration values (like minolta spad) use those and output that value
  light = lights[i];
  wavelengthString = wavelengths[i];
  spad_at_blank2[light] = MathROUND(100*MathLOG((raw_at_blank2[6] / json.recall["colorcal_blank2[6]"])/(raw_at_blank2[light] / json.recall["colorcal_blank2["+light+"]"])),2);
  spad_at_blank1[light] = MathROUND(100*MathLOG((raw_at_blank1[6] / json.recall["colorcal_blank1[6]"])/(raw_at_blank1[light] / json.recall["colorcal_blank1["+light+"]"])),2);
  spad_at_blank3[light] = MathROUND(100*MathLOG((raw_at_blank3[6] / json.recall["colorcal_blank3[6]"])/(raw_at_blank3[light] / json.recall["colorcal_blank3["+light+"]"])),2);
  if (light == 2) { // if it's the red light, the also calculate minolta spad
    //output ["light".concat(light.toString(),"_raw1")]  = raw_at_blank1[light];
    //output ["light6_raw1"]  = raw_at_blank1[6];
    //output ["spad_raw1"]  = spad_at_blank1[2];
    //output ["light".concat(light.toString(),"_raw2")]  = raw_at_blank2[light];
    //output ["light6_raw2"]  = raw_at_blank2[6];
    //output ["spad_raw2"]  = spad_at_blank2[2];
   // output ["light".concat(light.toString(),"_raw3")]  = raw_at_blank3[light];
   // output ["light6_raw3"]  = raw_at_blank3[6];
   // output ["spad_raw3"]  = spad_at_blank3[2];
  }
  if (json.recall["colorcal_blank1["+light+"]"] != 0 && raw_at_blank1[light] > 30 && raw_at_blank1[light] < 65534 
      && raw_at_blank1[6] > 4500 && raw_at_blank1[6] < 65534) {
    if (light == 2) { // if it's the red light, the also calculate minolta spad
      minolta_spad = (spad_at_blank1[2] - json.recall["colorcal_intensity1_yint[2]"]) / json.recall["colorcal_intensity1_slope[2]"];	
      //output ["SPAD_".concat(wavelengthString)]  = MathROUND(minolta_spad,2);
      //output ["SPAD_".concat(wavelengthString,"_intensity")]  = 1;
        choose = 1;
      continue;
    }
    else if (light != 6) {
     // output ["SPAD_".concat(wavelengthString)] = MathROUND(spad_at_blank1[light],2);
    // output ["SPAD_".concat(wavelengthString,"_intensity")] = 1;
//      output ["SPAD1_".concat(wavelengthString)] = MathROUND(spad_at_blank1[light],2);
//      output ["SPAD1_".concat(wavelengthString,"_intensity")] = 1;
      continue;
    }
  }
  if (json.recall["colorcal_blank2["+light+"]"] != 0 && raw_at_blank2[light] > 500 && raw_at_blank2[light] < 65534 
      && raw_at_blank2[6] > 3000 && raw_at_blank2[6] < 65534) {
    if (light == 2) { // if it's the red light, the also calculate minolta spad
      minolta_spad = (spad_at_blank2[2] - json.recall["colorcal_intensity2_yint[2]"]) / json.recall["colorcal_intensity2_slope[2]"];
      //output ["SPAD_".concat(wavelengthString)] = MathROUND(minolta_spad,2);
     // output ["SPAD_".concat(wavelengthString,"_intensity")] = 2;
        choose = 2;
      continue;
     
    }
    else if (light != 6) {
     // output ["SPAD_".concat(wavelengthString)] = MathROUND(spad_at_blank2[light],2);
      //output ["SPAD_".concat(wavelengthString,"_intensity")] = 2;
//      output ["SPAD2_".concat(wavelengthString)] = MathROUND(spad_at_blank2[light],2);
//      output ["SPAD2_".concat(wavelengthString,"_intensity")] = 2;
      continue;
    }
  }
  if (json.recall["colorcal_blank3["+light+"]"] != 0 && raw_at_blank3[light] > 750 && raw_at_blank3[light] < 65534 
      && raw_at_blank3[6] > 3000 && raw_at_blank3[6] < 65534) {
    if (light == 2) { // if it's the red light, the also calculate minolta spad
      minolta_spad = (spad_at_blank3[2] - json.recall["colorcal_intensity3_yint[2]"]) / json.recall["colorcal_intensity3_slope[2]"];
     // output ["SPAD_".concat(wavelengthString)]  = MathROUND(minolta_spad,2);
     // output ["SPAD_".concat(wavelengthString,"_intensity")]  = 3;
      choose = 3;
      continue;
    }
    else if (light != 6) {
     // output ["SPAD_".concat(wavelengthString)] = MathROUND(spad_at_blank3[light],2);
     // output ["SPAD_".concat(wavelengthString,"_intensity")] = 3;
//      output ["SPAD3_".concat(wavelengthString)] = MathROUND(spad_at_blank3[light],2);
//      output ["SPAD3_".concat(wavelengthString,"_intensity")] = 3;
      continue;
    }
  }
}

if (choose == 0) {
  //output ["SPAD_650"]  = 0;
  danger("Chlorophyll content SPAD is outside the acceptable range.  The leaf may be too thick, too thin, or have holes in it.", output);
}
else if (minolta_spad <= 2) {
  danger("Chlorophyll Content SPAD is very low.  If leaf is visibly green, ensure leaf completely covers the light guide and retry.  If still too low, consider recalibrating device.", output);
}
else if (minolta_spad >= 100) {
  danger("Chlorophyll Content SPAD is very high.  If this value is associated with a typical leaf, consider recalibrating device.", output);
}

/*
    if (minolta_spad <= 2) {
      info("Chlorophyll Content SPAD is very low.  If leaf is visibly green, ensure leaf completely covers the light guide and retry.  If still too low, consider recalibrating device.", output);
    }
    else if (minolta_spad1 >= 100) {
      info("Chlorophyll Content SPAD is very high.  If this value is associated with a typical leaf, consider recalibrating device.", output);
    }
*/

// calculate chlorophyll content SPAD values with Minolta SPAD calibration -->

/*
if (choose == 0) {
    output ["SPAD"]  = 0;
    output ["SPAD intensity"]  = 0;
  	
	danger("Chlorophyll content SPAD is outside the acceptable range.  The leaf may be too thick, too thin, or have holes in it.", output);
}
else if (choose == 1) {
    output ["SPAD"]  = MathROUND(minolta_spad1,2);
    output ["SPAD intensity"]  = 1;
    if (minolta_spad1 <= 2) {
      info("Chlorophyll Content SPAD is very low.  If leaf is visibly green, ensure leaf completely covers the light guide and retry.  If still too low, consider recalibrating device.", output);
    }
    else if (minolta_spad1 >= 100) {
      info("Chlorophyll Content SPAD is very high.  If this value is associated with a typical leaf, consider recalibrating device.", output);
    }
}
else if (choose == 2) {
    output ["SPAD"]  = MathROUND(minolta_spad2,2);
    output ["SPAD intensity"]  = 2;
	if (minolta_spad2 <= 2) {
      info("Chlorophyll Content SPAD is very low.  If leaf is visibly green, ensure leaf completely covers the light guide and retry.  If still too low, consider recalibrating device.", output);
    }
    else if (minolta_spad2 >= 100) {
      info("Chlorophyll Content SPAD is very high.  If this value is associated with a typical leaf, consider recalibrating device.", output);
    }
}
else if (choose == 3) {
    output ["SPAD"]  = MathROUND(minolta_spad3,2);
    output ["SPAD intensity"]  = 3;
	if (minolta_spad3 <= 2) {
      info("Chlorophyll Content SPAD is very low.  If leaf is visibly green, ensure leaf completely covers the light guide and retry.  If still too low, consider recalibrating device.", output);
    }
    else if (minolta_spad3 >= 100) {
      info("Chlorophyll Content SPAD is very high.  If this value is associated with a typical leaf, consider recalibrating device.", output);
    }
}
*/

// consider adding some warnings here... could be noisy, but also if the signal is > blank (suggest to recalibate?)



// consider adding some warnings here... could be noisy, but also if the signal is > blank (suggest to recalibate?)


// CALCULATIONS FOR PHI2 PORTION OF THE TRACE
//----------------------------

// calculate the ir baseline for LED 3 which is used as the measuring light.  This subtract IR generated by the LED from the IR generated by the plant
//----------------------------
var sample_cal = json.detector_read1;

var shinyness = (sample_cal-json.recall["ir_baseline_yint[5]"])/json.recall["ir_baseline_slope[5]"]; // where 0 is dull black electrical tape, and 1 is shiny aluminum
var baseline = json.recall["ir_baseline_slope[3]"]*shinyness+json.recall["ir_baseline_yint[3]"];

if (!baseline || !json.recall["ir_baseline_yint[5]"] || sample_cal == 65535) {						// if it hasn't been calibrated or there's an error or it's maxed, set baseline == 0
  baseline = 0;
}


//output["shinyness"] = shinyness;
//output["baseline"] = baseline;
//output["recall led slope"] = json.recall["ir_baseline_slope[3]"];
//output["recall led yint"] = json.recall["ir_baseline_yint[3]"];
//output["recall cal slope"] = json.recall["ir_baseline_slope[5]"];
//output["recall cal yint"] = json.recall["ir_baseline_yint[5]"];
//output["sample led"] = json.detector_read1;


//var sample_cal = MathMEAN(data.slice(2,18));

var inverse_intensity = [1/4500,1/4050,1/3600,1/3150];
var ps2_starts = 0;// when does the Phi2 measurement start

// Set our Apparent FmPrime, 3 FmPrime steps, and Fs to calculate both traditional fv/fm and new Multi-phase flash fv/fm
//----------------------------
var Fs = MathMEAN(data.slice(ps2_starts + 14,ps2_starts + 19)) - baseline; // take only the first 4 values in the Fs range, excluding the very first
var Fs_std = MathSTDEV(data.slice(ps2_starts + 1,ps2_starts + 4)); // create standard deviation for this value for error checking

var sat_vals = data.slice(ps2_starts + 25,ps2_starts + 48).sort();  // sort the saturating light values from low to high
var AFmP = MathMEAN(sat_vals.slice(2,20)) - baseline; // take the 18 largest values and average them
var AFmP_std = MathSTDEV(sat_vals); // create standard deviation for this value for error checkingjson.data_raw.slice(953,955)

sat_vals = data.slice(ps2_starts + 84,ps2_starts + 110).sort();  // sort the saturating light values from low to high
var FmP_end = MathMEAN(sat_vals.slice(2,23)) - baseline; // take the 21 largest values and average them
var FmP_end_std = MathSTDEV(sat_vals); // create standard deviation for this value for error checking

sat_vals = data.slice(ps2_starts + 52,ps2_starts + 60).sort();  // sort the saturating light values from low to high
var FmP_step1 = MathMEAN(sat_vals.slice(2,6)) - baseline; // take the 4 largest values and average them
var FmP_step1_std = MathSTDEV(sat_vals); // create standard deviation for this value for error checking

sat_vals = data.slice(ps2_starts + 62,ps2_starts + 70).sort();  // sort the saturating light values from low to high
var FmP_step2 = MathMEAN(sat_vals.slice(2,6)) - baseline; // take the 4 largest values and average them
var FmP_step2_std = MathSTDEV(sat_vals); // create standard deviation for this value for error checking

sat_vals = data.slice(ps2_starts + 72,ps2_starts + 80).sort();  // sort the saturating light values from low to high
var FmP_step3 = MathMEAN(sat_vals.slice(2,6)) - baseline; // take the 4 largest values and average them
var FmP_step3_std = MathSTDEV(sat_vals); // create standard deviation for this value for error checking

// Calculations for F0'
// ----------------------------
var FoPrime_values = json.data_raw.slice(ps2_starts + 160,ps2_starts + 270).sort();
var FoPrime = MathMEAN(FoPrime_values.slice(5,10)) - baseline;
var FoPrime_std = MathSTDEV(FoPrime_values); // create standard deviation for this value for error checking

// Calculations for corrected FmPrime using multi-phase flash
// ----------------------------
var reg = MathLINREG(inverse_intensity, [AFmP,FmP_step1,FmP_step2,FmP_step3]);

// Calculate Phi2 w/ and w/out multi-phase flash
// ----------------------------
var fvfm_noMPF = (AFmP-Fs)/AFmP;
var fvfm_MPF = (reg.b-Fs)/reg.b;


// Calculate NPQt, PhiNPQ, PhiNO, qL w/ and w/out multi-phase flash
// ----------------------------
var npqt_MPF = (4.88 / ((reg.b / FoPrime) -1) )-1;
var npqt_noMPF = (4.88 / ((AFmP / FoPrime) -1) )-1;
var qL_MPF = ((reg.b - Fs)*FoPrime)/((reg.b-FoPrime)*Fs);
var qL_noMPF = ((AFmP - Fs)*FoPrime)/((AFmP-FoPrime)*Fs);
var PhiNO_MPF = 1/(npqt_MPF + 1 + qL_MPF*4.88); //based on equation 52 in Kramer et al., 2004 PRES
var PhiNO_noMPF = 1/(npqt_noMPF + 1 + qL_noMPF*4.88); //based on equation 52 in Kramer et al., 2004 PRES
var PhiNPQ_MPF = 1-fvfm_MPF-PhiNO_MPF; //based on equation 53 in Kramer et al., 2004 PRES 
var PhiNPQ_noMPF = 1-fvfm_noMPF-PhiNO_noMPF; //based on equation 53 in Kramer et al., 2004 PRES 

var qP_MPF = (reg.b - Fs)/(reg.b - FoPrime);
var qP_noMPF = (FmPrime - Fs)/(FmPrime - FoPrime);
var FvP_FmP_MPF = (reg.b-FoPrime)/reg.b;
var FvP_FmP_noMPF = (AFmP-FoPrime)/AFmP;

// Create the variables to be printed (assume to use the MPF values unless there is a good reason not to)
// ----------------------------
var fvfm = fvfm_MPF;
var npqt = npqt_MPF;
var PhiNO = PhiNO_MPF;
var PhiNPQ = PhiNPQ_MPF;
var qL = qL_MPF;
var FmPrime = reg.b;
var qP = qP_MPF;
var FvP_FmP = FvP_FmP_MPF;
var b = json.b;
var r = json.r;
var g = json.g;


/****************OUTPUT VALUES FROM MACRO *******************/

// If multi-phase flash steps are flat or positive slope, then just use the normal Phi2, NPQt, PhiNPQ, PhiNO... etc.
// If Phi2 or NPQt is less than zero, make zero and give user warning.  If Phi2 is higher than .85, give user danger flag.
// ----------------------------
if (reg.m > 0) {
  fvfm = fvfm_noMPF;
  npqt = npqt_noMPF;
  PhiNO = PhiNO_noMPF;
  PhiNPQ = PhiNPQ_noMPF;
  qL = qL_noMPF;
  FmPrime = AFmP;
  qP = qP_noMPF;
  FvP_FmP = FvP_FmP_noMPF;
};

output["Phi2"] = MathROUND(fvfm,3);
output["qL"] = MathROUND(qL,3);
output["NPQ"] = MathROUND(npqt,3);
output["PhiNO"] = MathROUND(PhiNO,3);
output["PhiNPQ"] = MathROUND(PhiNPQ,3);
output["FmPrime"] 		= MathROUND(FmPrime,3);
output["Fs"] 			= MathROUND(Fs,1);
output['FoPrime']		= MathROUND(FoPrime,0);

//output["RFd"]           = Number(MathROUND(((FmPrime/Fs)-1),3));
//output["ratio MPF/noMPF, Phi2"] = MathROUND(fvfm_MPF / fvfm_noMPF,5);
//output["ratio MPF/noMPF, PhiNPQ"] = MathROUND(PhiNPQ_MPF / PhiNPQ_noMPF,5);
//output["ratio MPF/noMPF, PhiNO"] = MathROUND(PhiNO_MPF / PhiNO_noMPF,5);
//output["ratio MPF/noMPF, PhiNO"] = MathROUND(npqt_MPF / npqt_noMPF,5);
//output["MPF_slope"] 	= MathROUND(reg.m,3);
 
//output["MPF_rsquared"] 	= MathROUND(reg.r,3);


  output["baseline"] 	= baseline;


// Finally, use the "order" object to define the order of the outputs (focus on the top 6 most important for the user to see)
//----------------------------
output["Light Intensity (PAR)"] = json.light_intensity;
//output["Leaf Temp Differential"] = json.contactless_temp - json.temperature;
output["Relative Chlorophyll"] = minolta_spad;
//output ["Rel Chl intensity"]  = choose;  	
output["Ambient Temperature"] = json.temperature;
output["Ambient Humidity"] = json.humidity;
//output["Leaf Angle"] = json.angle;

//output["order"] = ["Phi2","PhiNPQ","PhiNO","Relative Chlorophyll","Leaf Temp Differential","Leaf Angle", "Light Intensity (PAR)","Ambient Temperature","Ambient Humidity","ECSt","vH+","gH+"];

maxvalue = MathMAX([json.r,json.g,json.b]);
//output["R"] = Number(json.r);
//output["G"] = Number(json.g);
//output["B"] = Number(json.b);
//output["rval"] = json.r*(255/maxvalue);
//output["gval"] = json.g*(255/maxvalue);
//output["bval"] = json.b*(255/maxvalue);

//output["Color"] = [MathROUND(json.r*(255/maxvalue),2),MathROUND(json.g*(255/maxvalue),2),MathROUND(json.b*(255/maxvalue),2)];

return output;
{
  "time_offset": 180,
  "time": 1501003790441,
  "device_name": "MultispeQ",
  "device_version": "1",
  "device_id": "01:06:11:88",
  "device_battery": 80,
  "device_firmware": 1.17,
  "sample": [
    {
      "time": 1501003790458,
      "protocol_id": 1,
      "detector_read1": 8405,
      "light_intensity": 6,
      "r": 4,
      "g": 1,
      "b": 1,
      "light_intensity_raw": 6,
      "temperature": 25.24,
      "humidity": 50.152344,
      "pressure": 1016.369873,
      "temperature2": 25.459999,
      "humidity2": 49.125977,
      "pressure2": 1016.550293,
      "contactless_temp": 25.15,
      "thickness": 0.05,
      "compass_direction": "E",
      "compass": "90.00",
      "angle": 1.26,
      "angle_direction": "NW",
      "pitch": -1.09,
      "roll": -0.63,
      "recall": {
        "time": 1501003802598,
        "colorcal_blank1[1]": 16511.5,
        "colorcal_blank1[2]": 24324.5,
        "colorcal_blank1[3]": 29277.5,
        "colorcal_blank1[4]": 37138,
        "colorcal_blank1[6]": 33194,
        "colorcal_blank1[8]": 28720.5,
        "colorcal_blank1[9]": 31100,
        "colorcal_blank1[10]": 34614,
        "colorcal_blank2[1]": 21662,
        "colorcal_blank2[2]": 18077,
        "colorcal_blank2[3]": 21188.5,
        "colorcal_blank2[4]": 18162,
        "colorcal_blank2[6]": 16493.5,
        "colorcal_blank2[8]": 17087,
        "colorcal_blank2[9]": 18622,
        "colorcal_blank2[10]": 16523.5,
        "colorcal_blank3[1]": 20515.5,
        "colorcal_blank3[2]": 9866,
        "colorcal_blank3[3]": 19621.5,
        "colorcal_blank3[4]": 13418.5,
        "colorcal_blank3[6]": 5898.5,
        "colorcal_blank3[8]": 6295.5,
        "colorcal_blank3[9]": 5582,
        "colorcal_blank3[10]": 6047,
        "colorcal_intensity1_slope[2]": 2.309,
        "colorcal_intensity1_yint[2]": 1.7,
        "colorcal_intensity2_slope[2]": 2.377,
        "colorcal_intensity2_yint[2]": 3,
        "colorcal_intensity3_slope[2]": 2.554,
        "colorcal_intensity3_yint[2]": -17.299999,
        "ir_baseline_slope[5]": 8895,
        "ir_baseline_yint[5]": 13422.5,
        "ir_baseline_slope[3]": 526.5,
        "ir_baseline_yint[3]": 738.5
      },
      "data_raw": [
        23518,
        23547,
        23562,
        23579,
        23586,
        23587,
        23597,
        23605,
        23598,
        23609,
        23609,
        23607,
        23617,
        23615,
        23612,
        23619,
        23624,
        23624,
        23615,
        23623,
        25246,
        25449,
        25534,
        25576,
        25607,
        25628,
        25629,
        25649,
        25655,
        25665,
        25667,
        25661,
        25665,
        25669,
        25669,
        25670,
        25669,
        25667,
        25663,
        25663,
        25667,
        25663,
        25657,
        25663,
        25653,
        25651,
        25651,
        25654,
        25646,
        25651,
        25660,
        25655,
        25648,
        25642,
        25646,
        25650,
        25645,
        25641,
        25642,
        25633,
        25639,
        25638,
        25639,
        25639,
        25638,
        25637,
        25631,
        25625,
        25626,
        25629,
        25631,
        25628,
        25624,
        25619,
        25615,
        25620,
        25617,
        25615,
        25614,
        25615,
        25581,
        25578,
        25575,
        25579,
        25582,
        25575,
        25573,
        25571,
        25567,
        25559,
        25551,
        25553,
        25552,
        25553,
        25547,
        25547,
        25543,
        25537,
        25537,
        25529,
        25529,
        25523,
        25519,
        25521,
        25518,
        25514,
        25514,
        25509,
        25507,
        25503,
        24990,
        24677,
        24498,
        24391,
        24313,
        24251,
        24196,
        24153,
        24108,
        24073,
        24042,
        24014,
        23987,
        23955,
        23924,
        23908,
        23881,
        23858,
        23839,
        23809,
        13444,
        13171,
        13039,
        12927,
        12851,
        12781,
        12728,
        12672,
        12629,
        12597,
        12566,
        12536,
        12513,
        12490,
        12464,
        12447,
        12435,
        12421,
        12405,
        12401,
        12389,
        12375,
        12367,
        12361,
        12362,
        12357,
        12355,
        12353,
        12351,
        12342,
        12343,
        12345,
        12349,
        12350,
        12350,
        12354,
        12353,
        12357,
        12353,
        12359,
        12366,
        12370,
        12378,
        12380,
        12385,
        12385,
        12390,
        12395,
        12407,
        12412,
        12415,
        12423,
        12426,
        12429,
        12433,
        12442,
        12449,
        12455,
        12463,
        12467,
        12471,
        12473,
        12481,
        12491,
        12493,
        12501,
        12505,
        12509,
        12516,
        12514,
        12525,
        12532,
        12539,
        12547,
        12549,
        12551,
        12554,
        12564,
        12574,
        12575,
        12578,
        12586,
        12584,
        12587,
        12598,
        12603,
        12611,
        12613,
        12618,
        12619,
        12619,
        12630,
        12633,
        12637,
        12643,
        12645,
        12645,
        12647,
        12656,
        12661,
        12662,
        12666,
        12669,
        12667,
        12676,
        12678,
        12681,
        12683,
        12681,
        12679,
        12685,
        12694,
        12690,
        12689,
        12701,
        12699,
        12697,
        12703,
        12705,
        12707,
        12711,
        12706,
        12707,
        12711,
        12713,
        12714,
        12715,
        12712,
        12711,
        12718,
        12720,
        12721,
        12723,
        12717,
        12718,
        12723,
        12723,
        12723,
        12725,
        12719,
        12719,
        12723,
        12719,
        12727,
        12723,
        12717,
        12723,
        12723,
        12723,
        12718,
        554,
        645,
        645,
        646,
        646,
        645,
        645,
        648,
        644,
        646,
        166,
        185,
        185,
        187,
        187,
        185,
        185,
        186,
        186,
        187,
        9585,
        882,
        814,
        807,
        806,
        805,
        801,
        802,
        802,
        803,
        43,
        66,
        67,
        63,
        66,
        66,
        65,
        64,
        66,
        66,
        46783,
        10968,
        10503,
        10459,
        10450,
        10437,
        10431,
        10437,
        10425,
        10431,
        65535,
        11527,
        10789,
        10739,
        10695,
        10691,
        10688,
        10681,
        10677,
        10674,
        17671,
        9873,
        9775,
        9767,
        9763,
        9761,
        9760,
        9758,
        9758,
        9757,
        21541,
        12415,
        12279,
        12271,
        12268,
        12263,
        12262,
        12262,
        12259,
        12257,
        5365,
        7112,
        7117,
        7118,
        7111,
        7116,
        7117,
        7116,
        7117,
        7117,
        662,
        908,
        913,
        910,
        912,
        912,
        913,
        914,
        913,
        913,
        3563,
        5113,
        5124,
        5127,
        5129,
        5127,
        5130,
        5129,
        5130,
        5131,
        148,
        196,
        196,
        196,
        195,
        197,
        196,
        196,
        197,
        196,
        29644,
        43275,
        43427,
        43441,
        43442,
        43448,
        43441,
        43443,
        43448,
        43459,
        31618,
        47291,
        47449,
        47470,
        47469,
        47475,
        47487,
        47491,
        47479,
        47489,
        23583,
        35100,
        35233,
        35239,
        35242,
        35243,
        35243,
        35245,
        35249,
        35246,
        28031,
        42837,
        43022,
        43018,
        43019,
        43014,
        43006,
        43005,
        42998,
        42989,
        21227,
        28835,
        28869,
        28870,
        28869,
        28867,
        28868,
        28868,
        28867,
        28869,
        1395,
        1969,
        1975,
        1975,
        1975,
        1976,
        1977,
        1977,
        1975,
        1978,
        15666,
        26303,
        26377,
        26375,
        26370,
        26365,
        26359,
        26353,
        26355,
        26350,
        388,
        601,
        602,
        603,
        603,
        603,
        605,
        605,
        607,
        606,
        43455,
        43447,
        43450,
        43439,
        43447,
        43453,
        43453,
        43451,
        43441,
        43449,
        47707,
        47461,
        47463,
        47472,
        47467,
        47459,
        47468,
        47455,
        47471,
        47473,
        35262,
        35254,
        35259,
        35253,
        35257,
        35259,
        35255,
        35254,
        35257,
        35257,
        43039,
        43021,
        43017,
        43009,
        43003,
        42997,
        42990,
        42981,
        42977,
        42971
      ]
    }
  ],
  "app_os": "win",
  "app_name": "PhotosynQ",
  "app_version": "0.3.8",
  "app_device": "x86-32",
  "location": [
    "-32.9700821",
    "-60.6247448"
  ],
  "ConsoleMacro": null
}
Img 20171030 190259
Created by

Rodrigo Gomez


Protocol connections:
1
Latest Update:
Jul 2017