Source code for jii_multispeq_protocols.protocols.calibrations.electronic_offsets_calibration

"""
Electronic Offsets Calibration
==============================

new electronic offsets calibration

2230
"""

import numpy as np
from scipy import stats
import warnings
from jii_multispeq.analysis import GetProtocolByLabel

_protocol = [
  {
    "v_arrays": [
      [
        -120,
        -150,
        -180,
        -200,
        -300,
        -400
      ],
      [
        -30,
        -40,
        -60,
        -100,
        -120
      ]
    ],
    "set_repeats": 1,
    "_protocol_set_": [
      {
        "label": "test"
      },
      {
        "label": "test",
        "alert": "Clamp panel #1 (white) of the Chlorophyll calibration cards",
        "set_detector_offsets": [
          [
            1,
            0
          ],
          [
            3,
            0
          ]
        ],
        "bleed_correction": 0,
        "do_once": 1
      },
      {
        "autogain": [
          [
            1,
            6,
            1,
            10,
            10000
          ],
          [
            2,
            6,
            1,
            20,
            20000
          ],
          [
            3,
            6,
            1,
            20,
            30000
          ],
          [
            4,
            6,
            1,
            40,
            40000
          ],
          [
            5,
            1,
            3,
            40,
            5000
          ],
          [
            6,
            1,
            3,
            40,
            10000
          ],
          [
            7,
            1,
            3,
            40,
            15000
          ],
          [
            8,
            1,
            3,
            40,
            20000
          ]
        ]
      },
      {
        "label": "card_1",
        "pulses": [
          10,
          10,
          10,
          10
        ],
        "nonpulsed_lights": [
          [
            2
          ],
          [
            2
          ],
          [
            2
          ],
          [
            2
          ]
        ],
        "pulse_distance": [
          4000,
          4000,
          4000,
          4000
        ],
        "nonpulsed_lights_brightness": [
          [
            0
          ],
          [
            0
          ],
          [
            0
          ],
          [
            0
          ]
        ],
        "pulsed_lights": [
          [
            6,
            1
          ],
          [
            6,
            1
          ],
          [
            6,
            1
          ],
          [
            6,
            1
          ]
        ],
        "detectors": [
          [
            1,
            3
          ],
          [
            1,
            3
          ],
          [
            1,
            3
          ],
          [
            1,
            3
          ]
        ],
        "pulsed_lights_brightness": [
          [
            "a_b1",
            "a_b5"
          ],
          [
            "a_b2",
            "a_b6"
          ],
          [
            "a_b3",
            "a_b7"
          ],
          [
            "a_b4",
            "a_b8"
          ]
        ],
        "pulse_length": [
          [
            "a_d1",
            "a_d5"
          ],
          [
            "a_d2",
            "a_d6"
          ],
          [
            "a_d3",
            "a_d7"
          ],
          [
            "a_d4",
            "a_d8"
          ]
        ],
        "protocol_averages": 1,
        "protocol_repeats": 1
      },
      {
        "label": "test",
        "alert": "Clamp panel #9 (white) of the Chlorophyll calibration cards"
      },
      {
        "label": "card_9",
        "pulses": [
          10,
          10,
          10,
          10
        ],
        "nonpulsed_lights": [
          [
            2
          ],
          [
            2
          ],
          [
            2
          ],
          [
            2
          ]
        ],
        "pulse_distance": [
          4000,
          4000,
          4000,
          4000
        ],
        "nonpulsed_lights_brightness": [
          [
            0
          ],
          [
            0
          ],
          [
            0
          ],
          [
            0
          ]
        ],
        "pulsed_lights": [
          [
            6,
            1
          ],
          [
            6,
            1
          ],
          [
            6,
            1
          ],
          [
            6,
            1
          ]
        ],
        "detectors": [
          [
            1,
            3
          ],
          [
            1,
            3
          ],
          [
            1,
            3
          ],
          [
            1,
            3
          ]
        ],
        "pulsed_lights_brightness": [
          [
            "a_b1",
            "a_b5"
          ],
          [
            "a_b2",
            "a_b6"
          ],
          [
            "a_b3",
            "a_b7"
          ],
          [
            "a_b4",
            "a_b8"
          ]
        ],
        "pulse_length": [
          [
            "a_d1",
            "a_d5"
          ],
          [
            "a_d2",
            "a_d6"
          ],
          [
            "a_d3",
            "a_d7"
          ],
          [
            "a_d4",
            "a_d8"
          ]
        ],
        "protocol_averages": 1,
        "protocol_repeats": 1
      },
      {
        "label": "test",
        "alert": "Clamp panel #1 (white) and #9 (white) of BOTH Chlorophyll calibration cards"
      },
      {
        "label": "cards_1_9",
        "pulses": [
          10,
          10,
          10,
          10
        ],
        "nonpulsed_lights": [
          [
            2
          ],
          [
            2
          ],
          [
            2
          ],
          [
            2
          ]
        ],
        "pulse_distance": [
          4000,
          4000,
          4000,
          4000
        ],
        "nonpulsed_lights_brightness": [
          [
            0
          ],
          [
            0
          ],
          [
            0
          ],
          [
            0
          ]
        ],
        "pulsed_lights": [
          [
            6,
            1
          ],
          [
            6,
            1
          ],
          [
            6,
            1
          ],
          [
            6,
            1
          ]
        ],
        "detectors": [
          [
            1,
            3
          ],
          [
            1,
            3
          ],
          [
            1,
            3
          ],
          [
            1,
            3
          ]
        ],
        "pulsed_lights_brightness": [
          [
            "a_b1",
            "a_b5"
          ],
          [
            "a_b2",
            "a_b6"
          ],
          [
            "a_b3",
            "a_b7"
          ],
          [
            "a_b4",
            "a_b8"
          ]
        ],
        "pulse_length": [
          [
            "a_d1",
            "a_d5"
          ],
          [
            "a_d2",
            "a_d6"
          ],
          [
            "a_d3",
            "a_d7"
          ],
          [
            "a_d4",
            "a_d8"
          ]
        ],
        "protocol_averages": 1,
        "protocol_repeats": 1
      }
    ]
  }
]

[docs] def _analyze( _data ): """ * Macro for data evaluation on PhotosynQ.org * by: David M. Kramer * created: May 31, 2020 9:31 AM This protocol tests for offsets in detectors 1 and 3 by comparing measured transmission values usingtaken with the same settings, but with three different transmission card setups. Plotting these against the first should give a series of lines that intersect at the data offset point. The protocol sends the offset values back to the toDevice to be used in subtracting off offsets. """ print_vals = 2 ## Define the output object here output = {} ## Check if the key time exists in json if "time" in _data: ## Add key time and value to output output["time"] = _data["time"] card_1 = GetProtocolByLabel("card_1", _data, True) card_1_data = card_1[0]["data_raw"] card_1_data_det_1 = card_1_data[0::2] card_1_data_det_3 = card_1_data[1::2] output["card_1_data_det_3"] = card_1_data_det_3 if print_vals > 0: output["det3"] = "[%s" % repr(card_1_data_det_3) card_9 = GetProtocolByLabel("card_9", _data, True) card_9_data = card_9[0]["data_raw"] card_9_data_det_1 = card_9_data[0::2] card_9_data_det_3 = card_9_data[1::2] if print_vals > 0: output["det3"] += ", %s" % repr(card_9_data_det_3) cards_1_9 = GetProtocolByLabel("cards_1_9", _data, True) cards_1_9_data = cards_1_9[0]["data_raw"] cards_1_9_data_det_1 = cards_1_9_data[0::2] cards_1_9_data_det_3 = cards_1_9_data[1::2] if print_vals > 0: output["det3"] += ", %s]" % repr(cards_1_9_data_det_3) ## detector 1 ## card 1 v card 9 output["card_1_data_det_1"] = card_1_data_det_1 output["card_9_data_det_1"] = card_9_data_det_1 slope, intercept, r_value, p_value, std_err = stats.linregress(card_1_data_det_1, card_9_data_det_1) slope_det_1_1_v_9 = slope y_int_det_1_1_v_9 = intercept r2_det_1_1_v_9 = r_value**2 output["r2_det_1_1_v_9"] = np.round(r2_det_1_1_v_9, 7) ## card 1 v cards 1+9 slope, intercept, r_value, p_value, std_err = stats.linregress(card_1_data_det_1, cards_1_9_data_det_1) slope_det_1_1_v_1_9 = slope y_int_det_1_1_v_1_9 = intercept r2_det_1_1_v_1_9 = r_value**2 output["r2_det_1_1_v_1_9"] = np.round(r2_det_1_1_v_1_9,7) ## now calculate the intersection point between the two lines ## y1 = m1*x + b1 ## y2 = m2*x + b2 ## There should be an intersection point where y1=y2 ## at which point x should be our offset. ## m1*x - m2*x + b1 - b2 = 0 ## x (m1-m2) = b2 - b1 ## x = (b2-b1)/(m1-m2) offset_det_1 = (y_int_det_1_1_v_1_9 - y_int_det_1_1_v_9)/(slope_det_1_1_v_9-slope_det_1_1_v_1_9) output["offset_det_1"] = np.round(offset_det_1,0) ## now do the same for detector 3 slope, intercept, r_value, p_value, std_err = stats.linregress(card_1_data_det_3, card_9_data_det_3) slope_det_3_1_v_9 = slope y_int_det_3_1_v_9 = intercept r2_det_3_1_v_9 = r_value**2 output["r2_det_3_1_v_9"] = np.round(r2_det_3_1_v_9,7) slope, intercept, r_value, p_value, std_err = stats.linregress(card_1_data_det_3, cards_1_9_data_det_3) slope_det_3_1_v_1_9 = slope y_int_det_3_1_v_1_9 = intercept r2_det_3_1_v_1_9 = r_value**2 output["r2_det_3_1_v_1_9"] = np.round(r2_det_3_1_v_1_9,7) offset_det_3 = (y_int_det_3_1_v_1_9 - y_int_det_3_1_v_9)/(slope_det_3_1_v_9-slope_det_3_1_v_1_9) output["offset_det_3"] = np.round(offset_det_3,0) output["toDevice"] = "set_detector_offset+1+" output["toDevice"] += str(np.round(offset_det_1, 0)) output["toDevice"] += "+" output["toDevice"] += "set_detector_offset+3+" output["toDevice"] += str(np.round(offset_det_3, 0)) output["toDevice"] += "+" if ((r2_det_1_1_v_9 < 0.99) or (r2_det_1_1_v_1_9 < 0.99) or (r2_det_3_1_v_9 < 0.99 ) or (r2_det_3_1_v_1_9 < 0.99)): warnings.warn("Low r² value(s) for the linear regession. This could be caused by the card moving. Repeat the offset calibration.") if ((offset_det_1>400) or (offset_det_1 < -300)): warnings.warn("High offset value for detector 1 (%s). Consider repeating the offset calibration." % np.round(offset_det_1,1)) if ((offset_det_3 > 400) or (offset_det_3 < -300)): warnings.warn("High offset value for detector 3 (%s). Consider repeating the offset calibration." % np.round(offset_det_3,0)) ## Return data return output
_example = { "time": 1600105494848, "device_name": "MultispeQ", "device_version": "2", "device_id": "52:00:06:f0", "device_battery": 100, "device_firmware": 2.3433, "sample": [ [ { "time": 1600105494848, "v_arrays": [ [ -120, -150, -180, -200, -300, -400 ], [ -30, -40, -60, -100, -120 ] ], "set_repeats": 1, "protocol_id": 1, "set": [ { "time": 1600105494864, "label": "test", "data_raw": [ ] }, { "time": 1600105494864, "set_detector_offsets": [ [ 1, 0 ], [ 3, 0 ] ], "bleed_correction": 0, "message": [ "alert", "Clamp panel #1 (white) of the Chlorophyll calibration cards", "ok" ], "label": "test", "data_raw": [ ] }, { "time": 1600105499075, "autogain": [ [ 1, 6, 1, 10, -4294, 28 ], [ 2, 6, 1, 20, -1342, 34 ], [ 3, 6, 1, 20, -1342, 35 ], [ 4, 6, 1, 40, -1342, 43 ], [ 5, 1, 3, 40, -83, 4991 ], [ 6, 1, 3, 40, -109, 9069 ], [ 7, 1, 3, 40, -143, 14445 ], [ 8, 1, 3, 40, -176, 19625 ] ], "data_raw": [ ] }, { "time": 1600105507127, "label": "card_1", "data_raw": [ 30, 4991, 23, 4991, 25, 4993, 23, 4991, 27, 4983, 23, 4982, 25, 4989, 28, 4996, 29, 5001, 30, 4989, 31, 9078, 30, 9085, 35, 9075, 36, 9077, 31, 9082, 33, 9081, 34, 9079, 29, 9081, 37, 9081, 29, 9070, 36, 14447, 29, 14445, 37, 14441, 27, 14450, 31, 14461, 31, 14455, 31, 14447, 31, 14451, 29, 14446, 36, 14454, 41, 19610, 44, 19599, 45, 19611, 47, 19615, 50, 19606, 42, 19607, 39, 19614, 43, 19609, 42, 19605, 41, 19616 ] }, { "time": 1600105507468, "message": [ "alert", "Clamp panel #9 (white) of the Chlorophyll calibration cards", "ok" ], "label": "test", "data_raw": [ ] }, { "time": 1600105512454, "label": "card_9", "data_raw": [ 31, 883, 25, 879, 29, 883, 25, 880, 28, 883, 31, 877, 25, 879, 26, 885, 30, 880, 21, 879, 31, 1654, 30, 1653, 32, 1655, 31, 1650, 31, 1650, 33, 1652, 34, 1649, 33, 1655, 35, 1651, 30, 1655, 35, 2685, 35, 2682, 31, 2683, 34, 2682, 29, 2681, 29, 2685, 31, 2686, 29, 2682, 31, 2683, 31, 2681, 47, 3685, 44, 3686, 43, 3689, 42, 3685, 46, 3682, 42, 3688, 46, 3685, 43, 3690, 45, 3687, 41, 3687 ] }, { "time": 1600105512770, "message": [ "alert", "Clamp panel #1 (white) and #9 (white) of BOTH Chlorophyll calibration cards", "ok" ], "label": "test", "data_raw": [ ] }, { "time": 1600105519121, "label": "cards_1_9", "data_raw": [ 26, 271, 27, 274, 27, 270, 27, 271, 25, 275, 29, 273, 26, 270, 28, 275, 25, 270, 25, 271, 27, 539, 31, 544, 32, 538, 37, 541, 29, 542, 31, 538, 33, 539, 33, 543, 31, 538, 35, 539, 36, 899, 31, 903, 31, 905, 29, 903, 35, 899, 28, 898, 30, 900, 29, 899, 35, 902, 31, 900, 47, 1252, 45, 1251, 41, 1251, 45, 1251, 47, 1255, 43, 1249, 46, 1252, 47, 1255, 43, 1251, 43, 1251 ] } ], "data_raw": [ ] } ] ], "app_os": "macOS 17.7.0", "app_name": "PhotosynQ", "app_version": "1.8.4", "app_device": "x64", "location": False, "time_offset": "America/Detroit" }