v2.0 CALIBRATION: Relative Chlorophyll (SPAD) w offset


This performes a standard blank at 3 different simulated leaf thicknesses, and also calibrates each thickness to a known SPAD value from a Minolta SPAD meter. When you have multiple SPAD devices involved in a single project, you can use this protocol to ensure that all devices are calibrated together. MultispeQs have some natural variation in the SPAD value between devices, and this reduces that variation by calibrating them all against a common standard.
//============================================
// Macro for blank and spad calibration, Greg Austic
// created: 2/24/2015
//============================================
    
// blank1/2/3 represent the blanks for 3 leaf thicknesses (lowest to highest).  spad_cal1/2/3 is the calibration to a known Minolta SPAD meter value for each of those thicknesses in the form y = mx+b where the two saved values in the array are x and b.
 
 
var output = {};
var spad;
var sample_940 = [];
var sample_650 = [];
var spad1 = [];
var spad2 = [];
var spad3 = [];
var blank1 = [];
var blank2 = [];
var blank3 = [];
var spad_cal1 = [];
var spad_cal2 = [];
var spad_cal3 = [];
var minolta_spad = [];
var minolta_spad1 = [];
var minolta_spad2 = [];
var minolta_spad3 = [];
var message = json.message;
var nine40_temp = [];
var six50_temp = [];


// pull and average the calibration values for 940 and 650 LEDs from the trace
for (x=0;x<9;x++) {
	var temp_940 = MathROUND(MathMEAN(json.data_raw.slice(2+20*x,8+20*x)),0);
    sample_940.push(temp_940); 
  	if (sample_940<=0) {
      sample_940 = 0.1;
    }  
	var temp_650 = MathROUND(MathMEAN(json.data_raw.slice(12+20*x,18+20*x)),0);
    if (temp_650<=0) {
      temp_650 = 0.1;
    }
    sample_650.push(temp_650);  
  	}
var q=80;
var q2=80;
// calculate all of the spad values from each of the Minolta SPAD calibrations (3 calibrations for each leaf thickness, 3 points per calibration)
for (x=0;x<3;x++) {
	var spad1_temp= MathLOG(((sample_940[x]-q) / (json.recall["colorcal_blank1[6]"]-q)) / ((sample_650[x]-q2) / (json.recall["colorcal_blank1[2]"]-q)))*100;
	var spad2_temp= MathLOG((sample_940[x+3] / json.recall["colorcal_blank2[6]"]) / (sample_650[x+3] / json.recall["colorcal_blank2[2]"]))*100;
	var spad3_temp= MathLOG((sample_940[x+6] / json.recall["colorcal_blank3[6]"]) / (sample_650[x+6] / json.recall["colorcal_blank3[2]"]))*100;
    spad1.push(MathROUND(spad1_temp,1));
    spad2.push(MathROUND(spad2_temp,1));
    spad3.push(MathROUND(spad3_temp,1));
  
}


output ["spad1"] = (spad1);
output ["spad2"] = (spad2);
output ["spad3"] = (spad3);


// Pull out the actual Minolta numbers from the user inputted message
// If left blank, then use factory SPAD calibration sheet values.
// 8, 17.4, 31.2, 24.4, 38.8, 47.7, 25.8, 48.6, 72
// 6.1, 16.9, 32.8, 25.1, 38.8, 46.3, 20.6, 43.1, 72
// 8, 17.4, 31.2, 24.4, 38.8, 47.7, 25.8, 48.6, 72
// 8.1, 15.1, 29.9, 24.9, 39.7, 43.6, 23, 39, 49.9
// factory calibrations last updated 10/10/16
//8.4, 15.8, 30.9, 25.7, 39.8, 44.6, 21.8, 38.1, 48.6

//minolta_spad_factory = [8.4, 15.5, 30.4, 24.8, 39.2, 43.3, 21.8, 37.7, 48.1];

minolta_spad_factory = [7.5, 15.2, 30.6, 24.1, 38.8, 42.3, 21.8, 40.1, 51.4];

for (var x = 0; x < message.length; x=x+2) {
  if (Number(message[x][2]) == "") {
    minolta_spad.push(minolta_spad_factory[Math.floor(x/2)]);
  }
  else {
    minolta_spad.push(Number(message[x][2]));
  }
}

output ["minolta spad"] = minolta_spad;

/*
output ["allspad"] = minolta_spad+"+";
output ["allspad1"] = spad1+"+";
output ["allspad2"] = spad2+"+";
output ["allspad3"] = spad3+"+";
*/

//output ["minolta1"] = (minolta_spad);
// run regressions on PhotosynQ SPAD versus Minolta SPAD
var reg1 = MathLINREG(minolta_spad.slice(0,3),spad1);
var reg2 = MathLINREG(minolta_spad.slice(3,6),spad2);
var reg3 = MathLINREG(minolta_spad.slice(6,9),spad3);

if (reg1.r < .985) {
  warning("r2 on SPAD 1 is too low, please check signal quality for errors and try again",output);
}  
if (reg2.r < .985) {
  warning("r2 on SPAD 2 is too low, please check signal quality for errors and try again",output);
}  
if (reg3.r < .985) {
  warning("r2 on SPAD 3 is too low, please check signal quality for errors and try again",output);
}  

/*
*/

//if (json.recall["colorcal_blank1[6]"] > 65535 | json.recall["colorcal_blank2[6]"] > 65535 | json.recall["colorcal_blank3[6]"] > 65535 | json.recall["colorcal_blank1[2]"] > 65535 | json.recall["colorcal_blank2[2]"] > 65535 | json.recall["colorcal_blank3[2]"] > 65535) {
//  danger("the colorcal_blank values saved to the device are out too high.  Recalibrate blanks",output);
//}

if (json.recall["colorcal_blank1[6]"] <= 0 | json.recall["colorcal_blank2[6]"] <= 0 | json.recall["colorcal_blank3[6]"] <= 0 | json.recall["colorcal_blank1[2]"] <= 0 | json.recall["colorcal_blank2[2]"] <= 0 | json.recall["colorcal_blank3[2]"] <= 0) {
  danger("the colorcal_blank values saved to the device are out too low.  Recalibrate blanks",output);
}

// Now perform the regression to get y = mx + b for each leaf thickness

/*
output ["sample 940"] = sample_940;
output ["sample 650"] = sample_650;
output ["blank1"] = blank1;
output ["blank2"] = blank2;
output ["blank3"] = blank3;
output ["spad1"] = spad1;
output ["spad2"] = spad2;
output ["spad3"] = spad3;
output ["minolta_spad"]  = minolta_spad;
output ["minolta_spad1"] = minolta_spad1;
output ["minolta_spad2"] = minolta_spad2;
output ["minolta_spad3"] = minolta_spad3;
*/
output ["colorcal_blank1[6]"] = json.recall["colorcal_blank1[6]"];
output ["colorcal_blank2[6]"] = json.recall["colorcal_blank2[6]"];
output ["colorcal_blank3[6]"] = json.recall["colorcal_blank3[6]"];
output ["colorcal_blank1[2]"] = json.recall["colorcal_blank1[2]"];
output ["colorcal_blank2[2]"] = json.recall["colorcal_blank2[2]"];
output ["colorcal_blank3[2]"] = json.recall["colorcal_blank3[2]"];
output ["spad1_m"] = MathROUND(reg1.m);
output ["spad1_b"] = MathROUND(reg1.b);
output ["spad1 r2"] = MathROUND(reg1.r);
output ["spad2_m"] = MathROUND(reg2.m);
output ["spad2_b"] = MathROUND(reg2.b);
output ["spad2 r2"] = MathROUND(reg2.r);
output ["spad3_m"] = MathROUND(reg3.m);
output ["spad3_b"] = MathROUND(reg3.b);
output ["spad3 r2"] = MathROUND(reg3.r);

output ["toDevice"] = "set_colorcal1+2+";
output ["toDevice"] += Number(MathROUND(reg1.m, 3));
output ["toDevice"] += "+";
output ["toDevice"] += Number(MathROUND(reg1.b, 1));
output ["toDevice"] += "+-1+";
output ["toDevice"] += "set_colorcal2+2+";
output ["toDevice"] += Number(MathROUND(reg2.m, 3));
output ["toDevice"] += "+";
output ["toDevice"] += Number(MathROUND(reg2.b, 1));
output ["toDevice"] += "+-1+";
output ["toDevice"] += "set_colorcal3+2+";
output ["toDevice"] += Number(MathROUND(reg3.m, 3));
output ["toDevice"] += "+";
output ["toDevice"] += Number(MathROUND(reg3.b, 1));
output ["toDevice"] += "+-1+";

/*
output ["toDevice"] += "+";
output ["toDevice"] += "1022+";
output ["toDevice"] += blank1[0]+"+"+blank1[1];
output ["toDevice"] += "+";
output ["toDevice"] += "1023+";
output ["toDevice"] += blank2[0]+"+"+blank2[1];
output ["toDevice"] += "+";
output ["toDevice"] += "1024+";
output ["toDevice"] += blank3[0]+"+"+blank3[1];
output ["toDevice"] += "+";
output ["toDevice"] += "-1+";

*/

output ["order"] = ["spad1 r2","spad2 r2","spad3 r2"];

return output;
{
  "time": 1546548748469,
  "device_name": "MultispeQ",
  "device_version": "2",
  "device_id": "63:00:08:08",
  "device_battery": 106,
  "device_firmware": 2.006,
  "sample": [
    [
      {
        "time": 1546548748492,
        "protocol_id": 1,
        "message": [
          [
            "prompt",
            "Clamp tile 2 and Enter",
            ""
          ],
          [
            "0",
            "0",
            ""
          ],
          [
            "prompt",
            "Clamp tile 3 and Enter",
            ""
          ],
          [
            "0",
            "0",
            ""
          ],
          [
            "prompt",
            "Clamp tile 4 and Enter",
            ""
          ],
          [
            "0",
            "0",
            ""
          ],
          [
            "prompt",
            "Clamp tile 6 and Enter",
            ""
          ],
          [
            "0",
            "0",
            ""
          ],
          [
            "prompt",
            "Clamp tile 7 and Enter",
            ""
          ],
          [
            "0",
            "0",
            ""
          ],
          [
            "prompt",
            "Clamp tile 8 and Enter",
            ""
          ],
          [
            "0",
            "0",
            ""
          ],
          [
            "prompt",
            "Clamp tile 10 and Enter",
            ""
          ],
          [
            "0",
            "0",
            ""
          ],
          [
            "prompt",
            "Clamp tile 11 and Enter",
            ""
          ],
          [
            "0",
            "0",
            ""
          ],
          [
            "prompt",
            "Clamp tile 12 and Enter",
            ""
          ],
          [
            "0",
            "0",
            ""
          ]
        ],
        "recall": {
          "time": 1546548800902,
          "colorcal_blank1[2]": 27863,
          "colorcal_blank2[2]": 22781.5,
          "colorcal_blank3[2]": 19499.5,
          "colorcal_blank1[6]": 17676.5,
          "colorcal_blank2[6]": 12144,
          "colorcal_blank3[6]": 4109
        },
        "data_raw": [
          1507,
          1501,
          1496,
          1504,
          1503,
          1503,
          1506,
          1501,
          1503,
          1499,
          2068,
          2063,
          2061,
          2063,
          2063,
          2065,
          2065,
          2063,
          2063,
          2065,
          1397,
          1402,
          1391,
          1395,
          1397,
          1402,
          1391,
          1391,
          1397,
          1396,
          1102,
          1105,
          1102,
          1105,
          1102,
          1102,
          1105,
          1102,
          1102,
          1101,
          263,
          264,
          263,
          270,
          268,
          265,
          264,
          267,
          263,
          269,
          159,
          157,
          158,
          159,
          157,
          157,
          158,
          161,
          158,
          159,
          4935,
          4945,
          4942,
          4938,
          4941,
          4939,
          4939,
          4941,
          4930,
          4934,
          2332,
          2331,
          2331,
          2331,
          2331,
          2330,
          2333,
          2333,
          2333,
          2334,
          9227,
          9234,
          9231,
          9230,
          9230,
          9230,
          9227,
          9236,
          9229,
          9229,
          420,
          417,
          419,
          417,
          417,
          419,
          419,
          420,
          418,
          417,
          8265,
          8275,
          8279,
          8279,
          8278,
          8274,
          8268,
          8279,
          8281,
          8277,
          281,
          282,
          279,
          280,
          281,
          282,
          281,
          281,
          281,
          279,
          14359,
          14356,
          14357,
          14351,
          14351,
          14349,
          14357,
          14354,
          14363,
          14351,
          7130,
          7133,
          7138,
          7136,
          7134,
          7134,
          7135,
          7135,
          7135,
          7134,
          5883,
          5885,
          5886,
          5892,
          5887,
          5891,
          5882,
          5891,
          5885,
          5879,
          1159,
          1164,
          1165,
          1161,
          1163,
          1160,
          1166,
          1163,
          1159,
          1165,
          9519,
          9523,
          9524,
          9529,
          9524,
          9528,
          9531,
          9525,
          9522,
          9518,
          997,
          999,
          997,
          997,
          999,
          998,
          997,
          997,
          996,
          995
        ]
      }
    ]
  ],
  "app_os": "macOS 17.7.0",
  "app_name": "PhotosynQ",
  "app_version": "1.1.0",
  "app_device": "x64",
  "location": false,
  "time_offset": "America/New_York"
}
Dave in cap img 4615
Created by

David M. Kramer


Protocol connections:
0
Latest Update:
Jan 2019