114
118
time_t cfdate; /* Date/time of last cal factor calibration */
115
119
double *cal_factor; /* [nwav] of calibration scale factor for this mode */
116
120
double *cal_factor1, *cal_factor2; /* (Underlying tables for two resolutions) */
117
double *white_data; /* [nraw] linear absolute dark subtracted white data */
121
double *white_data; /* [-1 nraw] linear absolute dark subtracted white data */
118
122
/* used to compute cal_factors (at reftemp) */
119
double **iwhite_data; /* [nraw][2] LED temperature data to interpolate white_data from */
123
double **iwhite_data; /* [-1 nraw][2] LED temperature data to interpolate white_data from */
120
124
double reftemp; /* Reference temperature to correct to */
122
126
/* Adaptive emission/transparency black data */
123
127
int idark_valid; /* idark calibration factors valid */
124
128
time_t iddate; /* Date/time of last dark idark calibration */
125
129
double idark_int_time[4];
126
double **idark_data; /* [4][nraw] of dark level for inttime/gains of : */
130
double **idark_data; /* [4][-1 nraw] of dark level for inttime/gains of : */
127
131
/* 0.01 norm, 1.0 norm, 0.01 high, 1.0 high */
128
132
/* then it's converted to base + increment with inttime */
130
int need_calib; /* White calibration needed anyway */
131
int need_dcalib; /* Dark Calibration needed anyway */
134
int want_calib; /* Initial White calibration wanted */
135
int want_dcalib; /* Initial Dark Calibration wanted */
133
137
/* Display mode calibration state (emmis && !scan && !adaptive) */
134
138
int dispswap; /* 0 = default time, 1 = dark_int_time2, 2 = dark_int_time3 */
135
double done_dintcal; /* A display integration time cal has been done */
139
double done_dintsel; /* A display integration time selection has been done */
140
time_t diseldate; /* Date/time of last display integration time selection */
136
141
double dcaltime2; /* Target dark calibration time - sets number of readings */
137
142
double dark_int_time2; /* Integration time used for dark data 2 */
138
double *dark_data2; /* [nraw] of dark level to subtract for dark_int_time2. */
143
double *dark_data2; /* [-1 nraw] of dark level to subtract for dark_int_time2. */
139
144
double dcaltime3; /* Target dark calibration time - sets number of readings */
140
145
double dark_int_time3; /* Integration time used for dark data 3 */
141
double *dark_data3; /* [nraw] of dark level to subtract for dark_int_time3. */
146
double *dark_data3; /* [-1 nraw] of dark level to subtract for dark_int_time3. */
143
148
}; typedef struct _munki_state munki_state;
148
153
struct _munkiimp {
156
/* Misc. and top level */
151
157
struct _mkdata *data; /* EEProm data container */
152
158
athread *th; /* Switch monitoring thread (NULL if not used) */
153
159
volatile int switch_count; /* Incremented in thread */
154
void *hcancel; /* Context for canceling outstandin I/O */
160
volatile int hide_switch; /* Set to supress switch event during read */
161
usb_cancelt cancelt; /* Token to allow cancelling an outstanding I/O */
155
162
volatile int th_term; /* Thread terminate on error rather than retry */
156
163
volatile int th_termed; /* Thread has terminated */
157
inst_opt_mode trig; /* Reading trigger mode */
158
int trig_return; /* Emit "\n" after trigger */
159
int noautocalib; /* Disable automatic calibration if not essential */
164
inst_opt_type trig; /* Reading trigger mode */
165
int noinitcalib; /* Disable initial calibration if not essential */
160
166
int nosposcheck; /* Disable checking the sensor position */
161
167
int highres; /* High resolution mode */
162
168
int hr_inited; /* High resolution has been initialized */
217
223
double max_int_time; /* Maximum integration time (secs) (fixed in sw) */
219
225
/* Underlying calibration information */
220
int nraw; /* Raw sample bands stored = 133 */
221
/* Only 128 starting at offset 6 are actually valid. */
222
// ~~99 change this to rnwav, rwl_short, rwl_long, enwav, ewl_short, ewl_long ?? */
226
int nsen; /* There are 137 provided from the device, with */
227
/* 6 skipped at the start, and 3 at the end. */
228
/* The first 4 are photo shielded. */
229
/* The last reading is the LED voltage drop */
230
/* 2 at the start and 2 at the end are unused. */
231
int nraw; /* Raw sample bands stored = 128 (Must be signed!) */
223
232
int nwav; /* Current cooked spectrum bands stored, usually = 36 */
224
233
double wl_short; /* Cooked spectrum bands short wavelength, usually 380 */
225
234
double wl_long; /* Cooked spectrum bands short wavelength, usually 730 */
264
273
double highgain; /* High gain mode gain */
265
274
double scan_toll_ratio; /* Modifier of scan tollerance */
267
/* Trigger houskeeping */
276
/* Trigger houskeeping & diagnostics */
277
int transwarn; /* Transmission calibration warning state */
278
int lo_secs; /* Seconds since last opened (from calibration file mod time) */
268
279
int tr_t1, tr_t2, tr_t3, tr_t4, tr_t5, tr_t6, tr_t7; /* Trigger/read timing diagnostics */
269
280
/* 1->2 = time to execute trigger */
270
281
/* 2->3 = time to between end trigger and start of first read */
292
303
#define MUNKI_COMS_FAIL 0x72 /* Communication failure */
293
304
#define MUNKI_UNKNOWN_MODEL 0x73 /* Not an munki */
294
305
#define MUNKI_DATA_PARSE_ERROR 0x74 /* Read data parsing error */
295
#define MUNKI_USER_ABORT 0x75 /* User hit abort */
296
#define MUNKI_USER_TERM 0x76 /* User hit terminate */
297
#define MUNKI_USER_TRIG 0x77 /* User hit trigger */
298
#define MUNKI_USER_CMND 0x78 /* User hit command */
307
#define MUNKI_USER_ABORT 0x75 /* uicallback returned abort */
308
#define MUNKI_USER_TRIG 0x76 /* uicallback retuned trigger */
300
310
#define MUNKI_UNSUPPORTED 0x79 /* Unsupported function */
301
311
#define MUNKI_CAL_SETUP 0x7A /* Cal. retry with correct setup is needed */
332
341
#define MUNKI_RD_NOTENOUGHSAMPLES 0x3D /* Not enough samples per patch */
333
342
#define MUNKI_RD_NOFLASHES 0x3E /* No flashes recognized */
334
343
#define MUNKI_RD_NOAMBB4FLASHES 0x3F /* No ambient before flashes found */
344
#define MUNKI_RD_NOREFR_FOUND 0x40 /* Unable to measure refresh rate */
336
#define MUNKI_SPOS_PROJ 0x40 /* Sensor needs to be in projector position */
337
#define MUNKI_SPOS_SURF 0x41 /* Sensor needs to be in surface position */
338
#define MUNKI_SPOS_CALIB 0x42 /* Sensor needs to be in calibration position */
339
#define MUNKI_SPOS_AMB 0x43 /* Sensor needs to be in ambient position */
346
#define MUNKI_SPOS_PROJ 0x48 /* Sensor needs to be in projector position */
347
#define MUNKI_SPOS_SURF 0x49 /* Sensor needs to be in surface position */
348
#define MUNKI_SPOS_CALIB 0x4A /* Sensor needs to be in calibration position */
349
#define MUNKI_SPOS_AMB 0x4B /* Sensor needs to be in ambient position */
341
351
/* Internal errors */
342
352
#define MUNKI_INT_NO_COMS 0x50
343
#define MUNKI_INT_EEOUTOFRANGE 0x51 /* EEProm access is out of range */
344
#define MUNKI_INT_CALTOOSMALL 0x52 /* Calibration EEProm size is too small */
345
#define MUNKI_INT_CALTOOBIG 0x53 /* Calibration EEProm size is too big */
346
#define MUNKI_INT_CALBADCHSUM 0x54 /* Calibration has a bad checksum */
347
#define MUNKI_INT_ODDREADBUF 0x55 /* Measurment read buffer is not mult 274 */
348
#define MUNKI_INT_INTTOOBIG 0x56 /* Integration time is too big */
349
#define MUNKI_INT_INTTOOSMALL 0x57 /* Integration time is too small */
350
#define MUNKI_INT_ILLEGALMODE 0x58 /* Illegal measurement mode selected */
351
#define MUNKI_INT_ZEROMEASURES 0x59 /* Number of measurements requested is zero */
352
#define MUNKI_INT_WRONGPATCHES 0x5A /* Number of patches to match is wrong */
353
#define MUNKI_INT_MEASBUFFTOOSMALL 0x5B /* Measurement read buffer is too small */
354
#define MUNKI_INT_NOTIMPLEMENTED 0x5C /* Support not implemented */
355
#define MUNKI_INT_NOTCALIBRATED 0x5D /* Unexpectedely invalid calibration */
356
#define MUNKI_INT_THREADFAILED 0x5E /* Creation of thread failed */
357
#define MUNKI_INT_BUTTONTIMEOUT 0x5F /* Switch status read timed out */
358
#define MUNKI_INT_CIECONVFAIL 0x60 /* Creating spectral to CIE converted failed */
359
#define MUNKI_INT_MALLOC 0x61 /* Error in mallocing memory */
360
#define MUNKI_INT_CREATE_EEPROM_STORE 0x62 /* Error in creating EEProm store */
361
#define MUNKI_INT_NEW_RSPL_FAILED 0x63 /* Creating RSPL object faild */
362
#define MUNKI_INT_CAL_SAVE 0x64 /* Unable to save calibration to file */
363
#define MUNKI_INT_CAL_RESTORE 0x65 /* Unable to restore calibration from file */
353
#define MUNKI_INT_EESIZE 0x51 /* EEProm read size is too big */
354
#define MUNKI_INT_EEOUTOFRANGE 0x52 /* EEProm size is unexpected */
355
#define MUNKI_INT_CALTOOSMALL 0x53 /* Calibration EEProm size is too small */
356
#define MUNKI_INT_CALTOOBIG 0x54 /* Calibration EEProm size is too big */
357
#define MUNKI_INT_CALBADCHSUM 0x55 /* Calibration has a bad checksum */
358
#define MUNKI_INT_ODDREADBUF 0x56 /* Measurment read buffer is not mult 274 */
359
#define MUNKI_INT_INTTOOBIG 0x57 /* Integration time is too big */
360
#define MUNKI_INT_INTTOOSMALL 0x58 /* Integration time is too small */
361
#define MUNKI_INT_ILLEGALMODE 0x59 /* Illegal measurement mode selected */
362
#define MUNKI_INT_ZEROMEASURES 0x5A /* Number of measurements requested is zero */
363
#define MUNKI_INT_WRONGPATCHES 0x5B /* Number of patches to match is wrong */
364
#define MUNKI_INT_MEASBUFFTOOSMALL 0x5C /* Measurement read buffer is too small */
365
#define MUNKI_INT_NOTIMPLEMENTED 0x5D /* Support not implemented */
366
#define MUNKI_INT_NOTCALIBRATED 0x5E /* Unexpectedely invalid calibration */
367
#define MUNKI_INT_THREADFAILED 0x5F /* Creation of thread failed */
368
#define MUNKI_INT_BUTTONTIMEOUT 0x60 /* Switch status read timed out */
369
#define MUNKI_INT_CIECONVFAIL 0x61 /* Creating spectral to CIE converted failed */
370
#define MUNKI_INT_MALLOC 0x62 /* Error in mallocing memory */
371
#define MUNKI_INT_CREATE_EEPROM_STORE 0x63 /* Error in creating EEProm store */
372
#define MUNKI_INT_NEW_RSPL_FAILED 0x64 /* Creating RSPL object faild */
373
#define MUNKI_INT_CAL_SAVE 0x65 /* Unable to save calibration to file */
374
#define MUNKI_INT_CAL_RESTORE 0x66 /* Unable to restore calibration from file */
375
#define MUNKI_INT_CAL_TOUCH 0x67 /* Unable to touch calibration file */
378
#define MUNKI_INT_ASSERT 0x6F /* Internal assert */
381
int icoms2munki_err(int se);
365
383
/* ============================================================ */
366
384
/* High level implementatation */
377
395
mk_mode mmode, /* munki mode to use */
378
396
int spec_en); /* nz to enable reporting spectral */
380
/* Determine if a calibration is needed. */
381
inst_cal_type munki_imp_needs_calibration(munki *p);
398
/* Implement get_n_a_cals */
399
munki_code munki_imp_get_n_a_cals(munki *p, inst_cal_type *pn_cals, inst_cal_type *pa_cals);
383
401
/* Calibrate for the current mode. */
384
402
/* Request an instrument calibration of the current mode. */
385
403
munki_code munki_imp_calibrate(
387
inst_cal_type calt, /* Calibration type. inst_calt_all for all neeeded */
405
inst_cal_type *calt, /* Calibration type to do/remaining */
388
406
inst_cal_cond *calc, /* Current condition/desired condition */
389
407
char id[100] /* Condition identifier (ie. white reference ID) */
471
496
double *abswav1, /* Return array [nwav1] of abswav values (may be NULL) */
472
497
double *abswav2, /* Return array [nwav2] of abswav values (if hr_init, may be NULL) */
473
double *absraw /* Given array [nraw] of absraw values */
498
double *absraw /* Given array [-1 nraw] of absraw values */
476
501
/* Take a reflective white reference measurement, */
477
502
/* subtracts black and decompose into base + LED temperature components */
478
503
munki_code munki_ledtemp_whitemeasure(
480
double *white, /* Return [nraw] of temperature compensated white reference */
481
double **iwhite, /* Return array [nraw][2] of absraw base and scale values */
505
double *white, /* Return [-1 nraw] of temperature compensated white reference */
506
double **iwhite, /* Return array [-1 nraw][2] of absraw base and scale values */
482
507
double *reftemp, /* Return a reference temperature to normalize to */
483
508
int nummeas, /* Number of readings to take */
484
509
double inttime, /* Integration time to use */
519
544
double *abswav1, /* Return array [nwav1] of abswav values (may be NULL) */
520
545
double *abswav2, /* Return array [nwav2] of abswav values (if hr_init, may be NULL) */
521
double *absraw, /* Return array [nraw] of absraw values */
546
double *absraw, /* Return array [-1 nraw] of absraw values */
522
547
double inttime, /* Integration time to used */
523
548
int gainmode, /* Gain mode to use, 0 = normal, 1 = high */
524
549
unsigned char *buf /* Raw buffer */
583
608
/* ============================================================ */
584
609
/* lower level reading processing */
586
/* Take a buffer full of raw readings, and convert them to */
587
/* directly to floating point sensor values. Return nz if any is saturated */
588
int munki_meas_to_sens(
611
/* Take a buffer full of sensor readings, and convert them to */
612
/* directly to floating point raw values. */
613
/* Return MUNKI_RD_SENSORSATURATED if any is saturated */
614
munki_code munki_sens_to_raw(
590
double **abssens, /* Array of [nummeas-ninvalid][nraw] value to return */
616
double **raw, /* Array of [nummeas-ninvalid][-1 nraw] value to return */
591
617
double *ledtemp, /* Optional array [nummeas-ninvalid] LED temperature values to return */
592
unsigned char *buf, /* Raw measurement data must be 274 * nummeas */
618
unsigned char *buf, /* Sensor measurement data must be 274 * nummeas */
593
619
int nummeas, /* Number of readings measured */
594
620
int ninvalid, /* Number of initial invalid readings to skip */
595
621
double satthresh, /* Sauration threshold in raw units */
596
622
double *darkthresh /* Return a dark threshold value */
599
/* Subtract the black from sensor values and convert to */
625
/* Subtract the black from raw values and convert to */
600
626
/* absolute (integration & gain scaled), zero offset based, */
601
627
/* linearized sensor values. */
602
void munki_sub_sens_to_abssens(
628
void munki_sub_raw_to_absraw(
604
630
int nummeas, /* Return number of readings measured */
605
631
double inttime, /* Integration time used */
606
632
int gainmode, /* Gain mode, 0 = normal, 1 = high */
607
double **abssens, /* Source/Desination array [nraw] */
608
double *sub, /* Value to subtract [nraw] */
609
double *trackmax, /* abssens values that should be offset the same as max */
633
double **absraw, /* Source/Desination array [-1 nraw] */
634
double *sub, /* Value to subtract [-1 nraw] */
635
double *trackmax, /* absraw values that should be offset the same as max */
610
636
int ntrackmax, /* Number of trackmax values */
611
637
double *maxv /* If not NULL, return the maximum value */
618
644
/* Return the overall average. */
619
645
int munki_average_multimeas(
621
double *avg, /* return average [nraw] */
622
double **multimeas, /* Array of [nummeas][nraw] value to average */
647
double *avg, /* return average [-1 nraw] */
648
double **multimeas, /* Array of [nummeas][-1 nraw] value to average */
623
649
int nummeas, /* number of readings to be averaged */
624
650
double *poallavg, /* If not NULL, return overall average of bands and measurements */
625
651
double darkthresh /* Dark threshold (used for consistency check scaling) */
632
658
munki_code munki_extract_patches_multimeas(
634
660
int *flags, /* return flags */
635
double **pavg, /* return patch average [naptch][nraw] */
661
double **pavg, /* return patch average [naptch][-1 nraw] */
636
662
int npatch, /* number of patches to recognise */
637
double **multimeas, /* Array of [nummeas][nraw] value to extract from */
663
double **multimeas, /* Array of [nummeas][-1 nraw] value to extract from */
638
664
int nummeas, /* number of readings to recognise them from */
639
665
double inttime /* Integration time (used to adjust consistency threshold) */
647
673
int *flags, /* return flags */
648
674
double *duration, /* return duration */
649
double *pavg, /* return patch average [nraw] */
650
double **multimeas, /* Array of [nummeas][nraw] value to extract from */
675
double *pavg, /* return patch average [-1 nraw] */
676
double **multimeas, /* Array of [nummeas][-1 nraw] value to extract from */
651
677
int nummeas, /* number of readings made */
652
678
double inttime /* Integration time (used to compute duration) */
655
/* Convert an abssens array from raw wavelengths to output wavelenths */
681
/* Convert an absraw array from raw wavelengths to output wavelenths */
656
682
/* for the current resolution */
657
void munki_abssens_to_abswav(
683
void munki_absraw_to_abswav(
659
685
int nummeas, /* Return number of readings measured */
660
686
double **abswav, /* Desination array [nwav] */
661
double **abssens /* Source array [nraw] */
687
double **absraw /* Source array [-1 nraw] */
664
/* Convert an abssens array from raw wavelengths to output wavelenths */
690
/* Convert an absraw array from raw wavelengths to output wavelenths */
665
691
/* for the standard resolution */
666
void munki_abssens_to_abswav1(
692
void munki_absraw_to_abswav1(
668
694
int nummeas, /* Return number of readings measured */
669
695
double **abswav, /* Desination array [nwav1] */
670
double **abssens /* Source array [nraw] */
696
double **absraw /* Source array [-1 nraw] */
673
/* Convert an abssens array from raw wavelengths to output wavelenths */
699
/* Convert an absraw array from raw wavelengths to output wavelenths */
674
700
/* for the high resolution */
675
void munki_abssens_to_abswav2(
701
void munki_absraw_to_abswav2(
677
703
int nummeas, /* Return number of readings measured */
678
704
double **abswav, /* Desination array [nwav2] */
679
double **abssens /* Source array [nraw] */
705
double **absraw /* Source array [-1 nraw] */
682
708
/* Convert an abswav array of output wavelengths to scaled output readings. */
756
783
/* Create Reflective if ref nz, else create Emissive */
757
784
munki_code munki_create_hr(munki *p, int ref);
759
/* Set the noautocalib mode */
760
void munki_set_noautocalib(munki *p, int v);
786
/* Set the noinitcalib mode */
787
void munki_set_noinitcalib(munki *p, int v, int losecs);
762
789
/* Set the trigger config */
763
void munki_set_trig(munki *p, inst_opt_mode trig);
790
void munki_set_trig(munki *p, inst_opt_type trig);
765
792
/* Return the trigger config */
766
inst_opt_mode munki_get_trig(munki *p);
793
inst_opt_type munki_get_trig(munki *p);
768
795
/* Set the trigger return */
769
796
void munki_set_trigret(munki *p, int val);