~ubuntu-branches/ubuntu/saucy/argyll/saucy

« back to all changes in this revision

Viewing changes to spectro/munki_imp.c

  • Committer: Package Import Robot
  • Author(s): Christian Marillat
  • Date: 2012-04-25 07:46:07 UTC
  • mfrom: (1.2.2) (13.1.15 sid)
  • Revision ID: package-import@ubuntu.com-20120425074607-yjqadetw8kum9skc
Tags: 1.4.0-4
Should Build-Depends on libusb-dev (Closes: #670329).

Show diffs side-by-side

added added

removed removed

Lines of Context:
63
63
#include "sort.h"
64
64
 
65
65
/* Configuration */
66
 
#define USE_THREAD              /* Need to use thread, or there are 1.5 second internal */
 
66
#define USE_THREAD              /* [Def] Need to use thread, or there are 1.5 second internal */
67
67
                                                /* instrument delays ! */
68
 
#define ENABLE_NONVCAL  /* Enable saving calibration state between program runs in a file */
69
 
#define ENABLE_NONLINCOR        /* Enable non-linear correction */
 
68
#define ENABLE_NONVCAL  /* [Def] Enable saving calibration state between program runs in a file */
 
69
#define ENABLE_NONLINCOR        /* [Def] Enable non-linear correction */
70
70
                                                /* NOTE :- high gain scaling will be stuffed if disabled! */
71
 
#define ENABLE_LEDTEMPC /* Enable LED temperature compensation */
72
 
#define ENABLE_SPOS_CHECK       /* Chech the sensor position is reasonable for measurement */
73
 
#define CALTOUT (24 * 60 * 60)  /* Calibration timeout in seconds */
74
 
#define MAXSCANTIME 15.0        /* Maximum scan time in seconds */
75
 
#define SW_THREAD_TIMEOUT (10 * 60.0)   /* Switch read thread timeout */
76
 
//#define SW_THREAD_TIMEOUT (0.1)       /* Switch read thread timeout */
 
71
#define ENABLE_LEDTEMPC /* [Def] Enable LED temperature compensation */
 
72
#define ENABLE_SPOS_CHECK       /* [Def] Chech the sensor position is reasonable for measurement */
 
73
#define CALTOUT (24 * 60 * 60)  /* [24 Hrs] Calibration timeout in seconds */
 
74
#define MAXSCANTIME 15.0        /* [14 Sec] Maximum scan time in seconds */
 
75
#define SW_THREAD_TIMEOUT (10 * 60.0)   /* [10 Min] Switch read thread timeout */
77
76
 
78
 
#define SINGLE_READ             /* Use a single USB read for scan to eliminate latency issues. */
79
 
#define HIGH_RES                /* Enable high resolution spectral mode code. Disable */
 
77
#define SINGLE_READ             /* [Def] Use a single USB read for scan to eliminate latency issues. */
 
78
#define HIGH_RES                /* [Def] Enable high resolution spectral mode code. Disable */
80
79
                                                /* to break dependency on rspl library. */
81
80
 
82
 
/* Debug */
 
81
/* Debug [Und] */
83
82
#undef DEBUG                    /* Turn on debug printfs */
84
83
#undef PLOT_DEBUG               /* Use plot to show readings & processing */
85
84
#undef RAWR_DEBUG               /* Print out raw reading processing values */
273
272
        munkiimp *m;
274
273
 
275
274
        if ((m = (munkiimp *)calloc(1, sizeof(munkiimp))) == NULL) {
276
 
                DBG((dbgo,"add_munkiimp malloc %d bytes failed (1)\n",sizeof(munkiimp)))
277
 
                if (p->verb) printf("Malloc %d bytes failed (1)\n",sizeof(munkiimp));
 
275
                DBG((dbgo,"add_munkiimp malloc %lu bytes failed (1)\n",sizeof(munkiimp)))
 
276
                if (p->verb) printf("Malloc %lu bytes failed (1)\n",sizeof(munkiimp));
278
277
                return MUNKI_INT_MALLOC;
279
278
        }
280
279
        m->p = p;
292
291
                int i;
293
292
                munkiimp *m = (munkiimp *)p->m;
294
293
                munki_state *s;
295
 
                munki_code ev;
296
294
 
297
295
                if (m->th != NULL) {            /* Terminate switch monitor thread by simulating an event */
298
296
                        m->th_term = 1;                 /* Tell thread to exit on error */
454
452
 
455
453
        DBG((dbgo,"munki_init:\n"))
456
454
 
457
 
        if (p->prelim_itype == instColorMunki)
458
 
                p->itype = instColorMunki;
459
 
        else
 
455
        if (p->itype != instColorMunki)
460
456
                return MUNKI_UNKNOWN_MODEL;
461
457
 
462
458
#ifdef ENABLE_SPOS_CHECK
867
863
                        m->mmode = mmode;
868
864
                        m->spec_en = spec_en ? 1 : 0;
869
865
                        return MUNKI_OK;
 
866
                default:
 
867
                        break;
870
868
        }
871
869
        return MUNKI_INT_ILLEGALMODE;
872
870
}
875
873
inst_cal_type munki_imp_needs_calibration(
876
874
        munki *p
877
875
) {
878
 
        munki_code ev = MUNKI_OK;
879
876
        munkiimp *m = (munkiimp *)p->m;
880
877
        munki_state *s = &m->ms[m->mmode];
881
878
        time_t curtime = time(NULL);
897
894
                s->cal_valid = 0;
898
895
        }
899
896
 
900
 
//printf("~1 idark_valid = %d, dark_valid = %d, cal_valid = %d\n",
901
 
//s->idark_valid,s->dark_valid,s->cal_valid); 
902
 
//printf("~1 need_calib = %d, need_dcalib = %d, noautocalib = %d\n",
903
 
//s->need_calib,s->need_dcalib, m->noautocalib); 
904
 
 
905
897
        if ((s->emiss && s->adaptive && !s->idark_valid)
906
898
         || ((!s->emiss || !s->adaptive) && !s->dark_valid)
907
899
         || (s->need_dcalib && !m->noautocalib)
908
900
         || (s->reflective && !s->cal_valid)
909
901
         || (s->reflective && s->need_calib && !m->noautocalib)) {
910
 
//printf("~1 need cal ref white\n");
911
902
                return inst_calt_ref_white;
912
903
 
913
904
        } else if (   (s->trans && !s->cal_valid)
914
905
                   || (s->trans && s->need_calib && !m->noautocalib)) {
915
 
//printf("~1 need cal trans white\n");
916
906
                return inst_calt_trans_white;
917
907
 
918
908
        } else if (s->emiss && !s->scan && !s->adaptive && !s->done_dintcal) {
919
 
//printf("~1 need cal disp/proj inttime\n");
920
909
                if (s->projector)
921
910
                        return inst_calt_proj_int_time; 
922
911
                else
1001
990
                        *calc = inst_calc_man_cal_smode;
1002
991
                        return MUNKI_CAL_SETUP;
1003
992
                }
1004
 
                if (!m->nosposcheck && spos != mk_spos_calib)
 
993
                if (!m->nosposcheck && spos != mk_spos_calib) {
1005
994
                        return MUNKI_SPOS_CALIB;
 
995
                }
1006
996
        } else if (calt == inst_calt_em_dark) {         /* Emissive Dark calib */
1007
997
                id[0] = '\000';
1008
998
                if (*calc != inst_calc_man_cal_smode) {
1009
999
                        *calc = inst_calc_man_cal_smode;
1010
1000
                        return MUNKI_CAL_SETUP;
1011
1001
                }
1012
 
                if (!m->nosposcheck && spos != mk_spos_calib)
 
1002
                if (!m->nosposcheck && spos != mk_spos_calib) {
1013
1003
                        return MUNKI_SPOS_CALIB;
 
1004
                }
1014
1005
        } else if (calt == inst_calt_trans_dark) {      /* Transmissive dark */
1015
1006
                id[0] = '\000';
1016
1007
                if (*calc != inst_calc_man_cal_smode) {
1017
1008
                        *calc = inst_calc_man_cal_smode;
1018
1009
                        return MUNKI_CAL_SETUP;
1019
1010
                }
1020
 
                if (!m->nosposcheck && spos != mk_spos_calib)
 
1011
                if (!m->nosposcheck && spos != mk_spos_calib) {
1021
1012
                        return MUNKI_SPOS_CALIB;
 
1013
                }
1022
1014
        } else if (calt == inst_calt_trans_white) {     /* Transmissive white */
1023
1015
                id[0] = '\000';
1024
1016
                if (*calc != inst_calc_man_trans_white) {
1025
1017
                        *calc = inst_calc_man_trans_white;
1026
1018
                        return MUNKI_CAL_SETUP;
1027
1019
                }
1028
 
                if (!m->nosposcheck && spos != mk_spos_surf)
 
1020
                if (!m->nosposcheck && spos != mk_spos_surf) {
1029
1021
                        return MUNKI_SPOS_SURF;
 
1022
                }
 
1023
        }
 
1024
 
 
1025
        /* Sanity check scan mode settings, in case something strange */
 
1026
        /* has been restored from the persistence file. */
 
1027
        if (s->scan && s->inttime > (2.1 * m->min_int_time)) {
 
1028
                s->inttime = m->min_int_time;   /* Maximize scan rate */
1030
1029
        }
1031
1030
 
1032
1031
        /* We are now either in inst_calc_man_cal_smode, */ 
1033
1032
        /* inst_calc_man_trans_white, inst_calc_disp_white or inst_calc_proj_white */
1034
 
        /* condition for it. */
 
1033
        /* sequenced in that order, and in the appropriate condition for it. */
1035
1034
 
1036
 
        /* Reflective uses on the fly black, but we need a black for white calib. */
1037
 
        if (s->reflective && *calc == inst_calc_man_cal_smode) {
 
1035
        /* Reflective uses on the fly black, even for adaptive. */
 
1036
        /* Emiss and trans can use single black ref only for non-adaptive */
 
1037
        /* using the current inttime & gainmode, while display mode */
 
1038
        /* does an extra fallback black cal for bright displays. */
 
1039
        if ((s->reflective && *calc == inst_calc_man_ref_white)
 
1040
         || (s->emiss && !s->adaptive && !s->scan && *calc == inst_calc_man_cal_smode)
 
1041
         || (s->trans && !s->adaptive && *calc == inst_calc_man_cal_smode)) {
1038
1042
                int stm;
1039
1043
 
1040
1044
                nummeas = munki_comp_nummeas(p, s->dcaltime, s->inttime);
1041
1045
 
1042
 
                DBG((dbgo,"Doing initial reflective black calibration with dcaltime %f, int_time %f, nummeas %d, gainmode %d\n", s->dcaltime, s->inttime, nummeas, s->gainmode))
 
1046
                DBG((dbgo,"Doing initial display black calibration with dcaltime %f, int_time %f, nummeas %d, gainmode %d\n", s->dcaltime, s->inttime, nummeas, s->gainmode))
1043
1047
                stm = msec_time();
1044
1048
                if ((ev = munki_dark_measure(p, s->dark_data, nummeas, &s->inttime, s->gainmode))
1045
1049
                                                                                 != MUNKI_OK) {
1047
1051
                }
1048
1052
                if (p->debug) fprintf(stderr,"Execution time of dark calib time %f sec = %d msec\n",s->inttime,msec_time() - stm);
1049
1053
 
 
1054
                /* Special display mode alternate integration time black measurement */
 
1055
                if (s->emiss && !s->scan && !s->adaptive) {
 
1056
                        nummeas = munki_comp_nummeas(p, s->dcaltime2, s->dark_int_time2);
 
1057
                        DBG((dbgo,"Doing 2nd initial black calibration with dcaltime2 %f, dark_int_time2 %f, nummeas %d, gainmode %d\n", s->dcaltime2, s->dark_int_time2, nummeas, s->gainmode))
 
1058
                        stm = msec_time();
 
1059
                        if ((ev = munki_dark_measure(p, s->dark_data2, nummeas, &s->dark_int_time2,
 
1060
                                                                           s->gainmode)) != MUNKI_OK) {
 
1061
                                return ev;
 
1062
                        }
 
1063
                        if (p->debug) fprintf(stderr,"Execution time of 2nd dark calib time %f sec = %d msec\n",s->inttime,msec_time() - stm);
 
1064
        
 
1065
                        nummeas = munki_comp_nummeas(p, s->dcaltime3, s->dark_int_time3);
 
1066
                        DBG((dbgo,"Doing 3rd initial black calibration with dcaltime3 %f, dark_int_time3 %f, nummeas %d, gainmode %d\n", s->dcaltime3, s->dark_int_time3, nummeas, s->gainmode))
 
1067
                        nummeas = munki_comp_nummeas(p, s->dcaltime3, s->dark_int_time3);
 
1068
                        stm = msec_time();
 
1069
                        if ((ev = munki_dark_measure(p, s->dark_data3, nummeas, &s->dark_int_time3,
 
1070
                                                                                   s->gainmode)) != MUNKI_OK) {
 
1071
                                return ev;
 
1072
                        }
 
1073
                        if (p->debug) fprintf(stderr,"Execution time of 3rd dark calib time %f sec = %d msec\n",s->inttime,msec_time() - stm);
 
1074
        
 
1075
                }
1050
1076
                s->dark_valid = 1;
1051
1077
                s->need_dcalib = 0;
1052
1078
                s->ddate = time(NULL);
1054
1080
                s->dark_gain_mode = s->gainmode;
1055
1081
        }
1056
1082
 
1057
 
        /* Emsissive scan uses the fastest possible scan rate (??) */
 
1083
        /* Emsissive scan (flash) uses the fastest possible scan rate (??) */
1058
1084
        if (s->emiss && !s->adaptive && s->scan && *calc == inst_calc_man_cal_smode) {
1059
1085
                int stm;
1060
1086
 
1061
1087
                nummeas = munki_comp_nummeas(p, s->dcaltime, s->inttime);
1062
1088
 
1063
 
                DBG((dbgo,"Doing display black calibration with dcaltime %f, int_time %f, nummeas %d, gainmode %d\n", s->dcaltime, s->inttime, nummeas, s->gainmode))
 
1089
                DBG((dbgo,"Doing emissive (flash) black calibration with dcaltime %f, int_time %f, nummeas %d, gainmode %d\n", s->dcaltime, s->inttime, nummeas, s->gainmode))
1064
1090
                stm = msec_time();
1065
1091
                if ((ev = munki_dark_measure(p, s->dark_data, nummeas, &s->inttime, s->gainmode))
1066
1092
                                                                                 != MUNKI_OK) {
1093
1119
        }
1094
1120
 
1095
1121
        /* Emmissive adaptive and transmissive black reference. */
1096
 
        /* The integration time and gain needs to be variable. */
 
1122
        /* in non-scan mode, where the integration time and gain may vary. */
1097
1123
        if ((s->emiss && s->adaptive && !s->scan && *calc == inst_calc_man_cal_smode)
1098
1124
         || (s->trans && s->adaptive && !s->scan && *calc == inst_calc_man_cal_smode)) {
1099
1125
                /* Adaptive where we can't measure the black reference on the fly, */
1101
1127
                /* The black reference is probably temperature dependent, but */
1102
1128
                /* there's not much we can do about this. */
1103
1129
 
1104
 
                if (s->scan)
1105
 
                        s->idark_int_time[0] = s->inttime;              /* Use nominal time for scan */
1106
 
                else
1107
 
                        s->idark_int_time[0] = m->min_int_time;
 
1130
                s->idark_int_time[0] = m->min_int_time;
1108
1131
                nummeas = munki_comp_nummeas(p, s->dcaltime, s->idark_int_time[0]);
1109
1132
                DBG((dbgo,"Doing adaptive interpolated black calibration, dcaltime %f, idark_int_time[0] %f, nummeas %d, gainmode %d\n", s->dcaltime, s->idark_int_time[0], nummeas, 0))
1110
1133
                if ((ev = munki_dark_measure(p, s->idark_data[0], nummeas, &s->idark_int_time[0], 0))
1120
1143
                        return ev;
1121
1144
                }
1122
1145
        
1123
 
                if (s->scan)
1124
 
                        s->idark_int_time[2] = s->inttime;              /* Use nominal time for scan */
1125
 
                else
1126
 
                        s->idark_int_time[2] = m->min_int_time;
 
1146
                s->idark_int_time[2] = m->min_int_time;
1127
1147
                nummeas = munki_comp_nummeas(p, s->dcaltime, s->idark_int_time[2]);
1128
1148
                DBG((dbgo,"Doing adaptive interpolated black calibration, dcaltime %f, idark_int_time[2] %f, nummeas %d, gainmode %d\n", s->dcaltime, s->idark_int_time[2], nummeas, 1))
1129
1149
                if ((ev = munki_dark_measure(p, s->idark_data[2], nummeas, &s->idark_int_time[2], 1))
1154
1174
                s->dark_gain_mode = s->gainmode;
1155
1175
 
1156
1176
                /* Save the calib to all similar modes */
 
1177
                DBG((dbgo,"Saving adaptive black calib to similar modes\n"))
1157
1178
                for (i = 0; i < mk_no_modes; i++) {
1158
1179
                        munki_state *ss = &m->ms[i];
1159
1180
                        if (ss == s)
1220
1241
 
1221
1242
        }
1222
1243
 
1223
 
        /* Emiss non-adaptive (display/projector) needs three pre-set black */
1224
 
        /* references, so it has fallback intergration times. */
1225
 
        if (s->emiss && !s->adaptive && !s->scan && *calc == inst_calc_man_cal_smode) {
1226
 
                int stm;
1227
 
 
1228
 
                nummeas = munki_comp_nummeas(p, s->dcaltime, s->inttime);
1229
 
 
1230
 
                DBG((dbgo,"Doing initial display black calibration with dcaltime %f, int_time %f, nummeas %d, gainmode %d\n", s->dcaltime, s->inttime, nummeas, s->gainmode))
1231
 
                stm = msec_time();
1232
 
                if ((ev = munki_dark_measure(p, s->dark_data, nummeas, &s->inttime, s->gainmode))
1233
 
                                                                                 != MUNKI_OK) {
1234
 
                        return ev;
1235
 
                }
1236
 
                if (p->debug) fprintf(stderr,"Execution time of dark calib time %f sec = %d msec\n",s->inttime,msec_time() - stm);
1237
 
 
1238
 
                nummeas = munki_comp_nummeas(p, s->dcaltime2, s->dark_int_time2);
1239
 
                DBG((dbgo,"Doing 2nd initial black calibration with dcaltime2 %f, dark_int_time2 %f, nummeas %d, gainmode %d\n", s->dcaltime2, s->dark_int_time2, nummeas, s->gainmode))
1240
 
                stm = msec_time();
1241
 
                if ((ev = munki_dark_measure(p, s->dark_data2, nummeas, &s->dark_int_time2,
1242
 
                                                                   s->gainmode)) != MUNKI_OK) {
1243
 
                        return ev;
1244
 
                }
1245
 
                if (p->debug) fprintf(stderr,"Execution time of 2nd dark calib time %f sec = %d msec\n",s->inttime,msec_time() - stm);
1246
 
 
1247
 
                nummeas = munki_comp_nummeas(p, s->dcaltime3, s->dark_int_time3);
1248
 
                DBG((dbgo,"Doing 3rd initial black calibration with dcaltime3 %f, dark_int_time3 %f, nummeas %d, gainmode %d\n", s->dcaltime3, s->dark_int_time3, nummeas, s->gainmode))
1249
 
                nummeas = munki_comp_nummeas(p, s->dcaltime3, s->dark_int_time3);
1250
 
                stm = msec_time();
1251
 
                if ((ev = munki_dark_measure(p, s->dark_data3, nummeas, &s->dark_int_time3,
1252
 
                                                                           s->gainmode)) != MUNKI_OK) {
1253
 
                        return ev;
1254
 
                }
1255
 
                if (p->debug) fprintf(stderr,"Execution time of 3rd dark calib time %f sec = %d msec\n",s->inttime,msec_time() - stm);
1256
 
 
 
1244
        /* Deal with an emissive/transmisive adaptive black reference */
 
1245
        /* when in scan mode. */
 
1246
        if ((s->emiss && s->adaptive && s->scan && *calc == inst_calc_man_cal_smode)
 
1247
         || (s->trans && s->adaptive && s->scan && *calc == inst_calc_man_cal_smode)) {
 
1248
                int j;
 
1249
                /* We know scan is locked to the minimum integration time, */
 
1250
                /* so we can measure the dark data at that integration time, */
 
1251
                /* but we don't know what gain mode will be used, so measure both, */
 
1252
                /* and choose the appropriate one on the fly. */
 
1253
        
 
1254
                s->idark_int_time[0] = s->inttime;
 
1255
                nummeas = munki_comp_nummeas(p, s->dcaltime, s->idark_int_time[0]);
 
1256
                DBG((dbgo,"Doing adaptive scan black calibration, dcaltime %f, idark_int_time[0] %f, nummeas %d, gainmode %d\n", s->dcaltime, s->idark_int_time[0], nummeas, s->gainmode))
 
1257
                if ((ev = munki_dark_measure(p, s->idark_data[0], nummeas, &s->idark_int_time[0], 0))
 
1258
                                                                                          != MUNKI_OK)
 
1259
                        return ev;
 
1260
        
 
1261
                s->idark_int_time[2] = s->inttime;
 
1262
                nummeas = munki_comp_nummeas(p, s->dcaltime, s->idark_int_time[2]);
 
1263
                DBG((dbgo,"Doing adaptive scan black calibration, dcaltime %f, idark_int_time[2] %f, nummeas %d, gainmode %d\n", s->dcaltime, s->idark_int_time[2], nummeas, s->gainmode))
 
1264
                if ((ev = munki_dark_measure(p, s->idark_data[2], nummeas, &s->idark_int_time[2], 1))
 
1265
                                                                                          != MUNKI_OK)
 
1266
                        return ev;
 
1267
        
 
1268
                s->idark_valid = 1;
 
1269
                s->iddate = time(NULL);
 
1270
 
 
1271
                if (s->gainmode) {
 
1272
                        for (j = 0; j < m->nraw; j++)
 
1273
                                s->dark_data[j] = s->idark_data[2][j];
 
1274
                } else {
 
1275
                        for (j = 0; j < m->nraw; j++)
 
1276
                                s->dark_data[j] = s->idark_data[0][j];
 
1277
                }
1257
1278
                s->dark_valid = 1;
1258
1279
                s->need_dcalib = 0;
1259
 
                s->ddate = time(NULL);
 
1280
                s->ddate = s->iddate;
1260
1281
                s->dark_int_time = s->inttime;
1261
1282
                s->dark_gain_mode = s->gainmode;
1262
1283
 
 
1284
                DBG((dbgo,"Done adaptive scan black calibration\n"))
 
1285
 
1263
1286
                /* Save the calib to all similar modes */
 
1287
                DBG((dbgo,"Saving adaptive scan black calib to similar modes\n"))
1264
1288
                for (i = 0; i < mk_no_modes; i++) {
1265
1289
                        munki_state *ss = &m->ms[i];
1266
1290
                        if (ss == s)
1267
1291
                                continue;
1268
 
                        if (ss->emiss && !ss->adaptive && !ss->scan) {
1269
 
                                ss->dark_valid = s->dark_valid;
 
1292
                        if ((ss->emiss || ss->trans) && ss->adaptive && s->scan) {
 
1293
                                ss->idark_valid = s->idark_valid;
1270
1294
                                ss->need_dcalib = s->need_dcalib;
1271
 
                                ss->ddate = s->ddate;
 
1295
                                ss->iddate = s->iddate;
1272
1296
                                ss->dark_int_time = s->dark_int_time;
1273
1297
                                ss->dark_gain_mode = s->dark_gain_mode;
1274
 
                                for (k = 0; k < m->nraw; k++) {
1275
 
                                        ss->dark_data[k] = s->dark_data[k];
1276
 
                                        ss->dark_data2[k] = s->dark_data2[k];
1277
 
                                        ss->dark_data3[k] = s->dark_data3[k];
 
1298
                                for (j = 0; j < 4; j++) {
 
1299
                                        ss->idark_int_time[j] = s->idark_int_time[j];
 
1300
                                        for (k = 0; k < m->nraw; k++)
 
1301
                                                ss->idark_data[j][k] = s->idark_data[j][k];
1278
1302
                                }
1279
1303
                        }
1280
1304
                }
1281
1305
        }
1282
1306
 
 
1307
        /* Reflective uses on the fly black, but we need a black for white calib */
 
1308
        /* (because of the way the Munki subtracts the black ??) */
 
1309
        if (s->reflective && *calc == inst_calc_man_cal_smode) {
 
1310
                int stm;
 
1311
 
 
1312
                nummeas = munki_comp_nummeas(p, s->dcaltime, s->inttime);
 
1313
 
 
1314
                DBG((dbgo,"Doing initial reflective black calibration with dcaltime %f, int_time %f, nummeas %d, gainmode %d\n", s->dcaltime, s->inttime, nummeas, s->gainmode))
 
1315
                stm = msec_time();
 
1316
                if ((ev = munki_dark_measure(p, s->dark_data, nummeas, &s->inttime, s->gainmode))
 
1317
                                                                                 != MUNKI_OK) {
 
1318
                        return ev;
 
1319
                }
 
1320
                if (p->debug) fprintf(stderr,"Execution time of dark calib time %f sec = %d msec\n",s->inttime,msec_time() - stm);
 
1321
 
 
1322
                s->dark_valid = 1;
 
1323
                s->need_dcalib = 0;
 
1324
                s->ddate = time(NULL);
 
1325
                s->dark_int_time = s->inttime;
 
1326
                s->dark_gain_mode = s->gainmode;
 
1327
        }
 
1328
 
1283
1329
        /* Now deal with white calibrations */
1284
1330
 
1285
1331
        /* If we are doing a reflective white reference calibrate */
1287
1333
        if ((s->reflective && *calc == inst_calc_man_cal_smode)
1288
1334
         || (s->trans && *calc == inst_calc_man_trans_white)) {
1289
1335
                double dead_time = 0.0;         /* Dead integration time */
1290
 
                int optimal;
1291
1336
                double scale;
1292
1337
                int i;
1293
1338
                double ulimit = m->optsval / m->minsval;        /* Upper scale needed limit */
1295
1340
                double llimit = m->optsval / m->maxsval;        /* Lower scale needed limit */
1296
1341
                double fllimit = sqrt(llimit);                          /* Fast exit limit */
1297
1342
 
1298
 
                DBG((dbgo,"Doing initial reflective white calibration with current inttime %f, gainmode %d\n",
 
1343
                DBG((dbgo,"Doing initial white calibration with current inttime %f, gainmode %d\n",
1299
1344
                                                                   s->inttime, s->gainmode))
1300
1345
                DBG((dbgo,"ulimit %f, llimit %f\n",ulimit,llimit))
1301
1346
                DBG((dbgo,"fulimit %f, fllimit %f\n",fulimit,fllimit))
1311
1356
                        RDBG((dbgo,"Doing a white calibration with trial int_time %f, gainmode %d\n",
1312
1357
                                                                         s->inttime,s->gainmode))
1313
1358
 
1314
 
                        if (s->trans) {
 
1359
                        if (s->trans && s->adaptive) {
1315
1360
                                /* compute interpolated dark refence for chosen inttime & gainmode */
1316
1361
                                RDBG((dbgo,"Interpolate dark calibration reference\n"))
1317
1362
                                if ((ev = munki_interp_dark(p, s->dark_data, s->inttime, s->gainmode))
1561
1606
 
1562
1607
        DBG((dbgo,"munki_imp_measure called\n"))
1563
1608
        if (p->debug)
1564
 
                fprintf(stderr,"Taking %d measurments in %s%s%s%s mode called\n", nvals,
 
1609
                fprintf(stderr,"Taking %d measurments in %s%s%s%s%s mode called\n", nvals,
1565
1610
                        s->emiss ? "Emission" : s->trans ? "Trans" : "Refl", 
1566
1611
                        s->emiss && s->ambient ? " Ambient" : "",
1567
1612
                        s->scan ? " Scan" : "",
1977
2022
}
1978
2023
 
1979
2024
/* Write an array of time_t's to the file. Set the error flag to nz on error */
 
2025
/* (This will cause file checksum fail if different executables on the same */
 
2026
/*  system have different time_t values) */
1980
2027
static void write_time_ts(i1pnonv *x, FILE *fp, time_t *dp, int n) {
1981
2028
 
1982
2029
        if (fwrite((void *)dp, sizeof(time_t), n, fp) != n) {
2018
2065
}
2019
2066
 
2020
2067
/* Read an array of time_t's from the file. Set the error flag to nz on error */
 
2068
/* (This will cause file checksum fail if different executables on the same */
 
2069
/*  system have different time_t values) */
2021
2070
static void read_time_ts(i1pnonv *x, FILE *fp, time_t *dp, int n) {
2022
2071
 
2023
2072
        if (fread((void *)dp, sizeof(time_t), n, fp) != n) {
2031
2080
        munkiimp *m = (munkiimp *)p->m;
2032
2081
        munki_code ev = MUNKI_OK;
2033
2082
        munki_state *s;
2034
 
        int i, j;
 
2083
        int i;
2035
2084
        char nmode[10];
2036
2085
        char cal_name[40+1];            /* Name */
2037
 
        char *cal_path = NULL;          /* Allocated overal path */
 
2086
        char **cal_paths = NULL;
 
2087
        int no_paths = 0;
2038
2088
        FILE *fp;
2039
2089
        i1pnonv x;
2040
2090
        int ss;
2049
2099
#endif
2050
2100
 
2051
2101
        sprintf(cal_name, "color/.mk_%s.cal", m->serno);
2052
 
        if ((cal_path = xdg_bds(NULL, xdg_cache, xdg_write, xdg_user, cal_name)) == NULL)
2053
 
                return MUNKI_INT_CAL_SAVE;
2054
 
 
2055
 
        DBG((dbgo,"munki_save_calibration saving to file '%s'\n",cal_path));
2056
 
 
2057
 
        if (create_parent_directories(cal_path))
2058
 
                return MUNKI_INT_CAL_SAVE;
2059
 
 
2060
 
        if ((fp = fopen(cal_path, nmode)) == NULL) {
 
2102
        if ((no_paths = xdg_bds(NULL, &cal_paths, xdg_cache, xdg_write, xdg_user, cal_name)) < 1)
 
2103
                return MUNKI_INT_CAL_SAVE;
 
2104
 
 
2105
        if (p->debug >= 1)
 
2106
                fprintf(stderr,"munki_save_calibration saving to file '%s'\n",cal_paths[0]);
 
2107
        DBG((dbgo,"munki_save_calibration saving to file '%s'\n",cal_paths[0]));
 
2108
 
 
2109
        if (create_parent_directories(cal_paths[0])
 
2110
         || (fp = fopen(cal_paths[0], nmode)) == NULL) {
2061
2111
                DBG((dbgo,"munki_save_calibration failed to open file for writing\n"));
2062
 
                free(cal_path);
 
2112
                xdg_free(cal_paths, no_paths);
2063
2113
                return MUNKI_INT_CAL_SAVE;
2064
2114
        }
2065
2115
        
2130
2180
        write_ints(&x, fp, (int *)&x.chsum, 1);
2131
2181
 
2132
2182
        if (x.ef != 0) {
 
2183
                if (p->debug >= 1)
 
2184
                        fprintf(stderr,"Writing calibration file failed\n");
2133
2185
                DBG((dbgo,"Writing calibration file failed\n"))
2134
2186
                fclose(fp);
2135
 
                delete_file(cal_path);
 
2187
                delete_file(cal_paths[0]);
2136
2188
        } else {
2137
2189
                fclose(fp);
2138
2190
                DBG((dbgo,"Writing calibration file done\n"))
2139
2191
        }
2140
 
        free(cal_path);
 
2192
        xdg_free(cal_paths, no_paths);
2141
2193
 
2142
2194
        return ev;
2143
2195
}
2150
2202
        int i, j;
2151
2203
        char nmode[10];
2152
2204
        char cal_name[40+1];            /* Name */
2153
 
        char *cal_path;
 
2205
        char **cal_paths = NULL;
 
2206
        int no_paths = 0;
2154
2207
        FILE *fp;
2155
2208
        i1pnonv x;
2156
2209
        int argyllversion;
2163
2216
#endif
2164
2217
 
2165
2218
        sprintf(cal_name, "color/.mk_%s.cal", m->serno);
2166
 
        if ((cal_path = xdg_bds(NULL, xdg_cache, xdg_read, xdg_user, cal_name)) == NULL)
 
2219
        if ((no_paths = xdg_bds(NULL, &cal_paths, xdg_cache, xdg_read, xdg_user, cal_name)) < 1)
2167
2220
                return MUNKI_INT_CAL_RESTORE;
2168
2221
 
2169
 
        DBG((dbgo,"munki_restore_calibration restoring from file '%s'\n",cal_path));
 
2222
        if (p->debug >= 1)
 
2223
                fprintf(stderr,"munki_restore_calibration restoring from file '%s'\n",cal_paths[0]);
 
2224
        DBG((dbgo,"munki_restore_calibration restoring from file '%s'\n",cal_paths[0]));
2170
2225
 
2171
 
        if ((fp = fopen(cal_path, nmode)) == NULL) {
 
2226
        if ((fp = fopen(cal_paths[0], nmode)) == NULL) {
2172
2227
                DBG((dbgo,"munki_restore_calibration failed to open file for reading\n"));
2173
 
                free(cal_path);
 
2228
                xdg_free(cal_paths, no_paths);
2174
2229
                return MUNKI_INT_CAL_RESTORE;
2175
2230
        }
2176
 
        free(cal_path);
 
2231
        xdg_free(cal_paths, no_paths);
2177
2232
        
2178
2233
        x.ef = 0;
2179
2234
        x.chsum = 0;
2268
2323
        
2269
2324
        if (x.ef != 0
2270
2325
         || chsum1 != chsum2) {
2271
 
                if (p->debug >= 2)
 
2326
                if (p->debug >= 1)
2272
2327
                        fprintf(stderr,"Unable to restore previous calibration due to checksum error\n");
2273
2328
                DBG((dbgo,"Checksum didn't verify, got 0x%x, expected 0x%x\n",chsum1, chsum2));
2274
2329
                goto reserr;
2297
2352
 
2298
2353
        /* For each mode, save the calibration if it's valid */
2299
2354
        for (i = 0; i < mk_no_modes; i++) {
2300
 
                double dd, inttime;
2301
2355
                s = &m->ms[i];
2302
2356
 
2303
2357
                /* Mode identification */
2502
2556
) {
2503
2557
        munki_code ev = MUNKI_OK;
2504
2558
        munkiimp *m = (munkiimp *)p->m;
2505
 
        munki_state *s = &m->ms[m->mmode];
2506
2559
        double **multimes;              /* Multiple measurement results */
2507
2560
        double darkthresh;              /* Dark threshold */
2508
2561
        double sensavg;                 /* Overall average of sensor readings */
2580
2633
        munki *p,
2581
2634
        double htime            /* Heat up time */
2582
2635
) {
2583
 
        munki_code ev = MUNKI_OK;
2584
2636
        munkiimp *m = (munkiimp *)p->m;
2585
 
        munki_state *s = &m->ms[m->mmode];
2586
2637
        double inttime = m->cal_int_time;               /* Integration time to use/used */
2587
2638
        int nummeas;
2588
2639
        unsigned char *buf;             /* Raw USB reading buffer */
2756
2807
        double *abswav2,                /* Return array [nwav2] of abswav values (if hr_init, may be NULL) */
2757
2808
        double *absraw                  /* Given array [nraw] of absraw values */
2758
2809
) {
2759
 
        munki_code ev = MUNKI_OK;
2760
2810
        munkiimp *m = (munkiimp *)p->m;
2761
 
        munki_state *s = &m->ms[m->mmode];
2762
2811
 
2763
2812
        /* Convert an absraw array from raw wavelengths to output wavelenths */
2764
2813
        if (abswav1 != NULL) {
2804
2853
        double **multimes;              /* Multiple measurement results */
2805
2854
        double *ledtemp;                /* LED temperature for each measurement */
2806
2855
        double darkthresh;              /* Dark threshold */
2807
 
        int rv;
2808
2856
 
2809
2857
        DBG((dbgo,"munki_ledtemp_whitemeasure called \n"))
2810
2858
 
3020
3068
) {
3021
3069
        munki_code ev = MUNKI_OK;
3022
3070
        munkiimp *m = (munkiimp *)p->m;
3023
 
        munki_state *s = &m->ms[m->mmode];
3024
 
        int rv = 0;
3025
3071
 
3026
3072
        if ((ninvmeas + minnummeas) <= 0)
3027
3073
                return MUNKI_INT_ZEROMEASURES;
3309
3355
        double **multimes;              /* Multiple measurement results */
3310
3356
        double *abssens;                /* Linearsised absolute sensor raw values */
3311
3357
        int nmeasuered;                 /* Number actually measured */
3312
 
        double highest;                 /* Highest of sensor readings */
3313
3358
        double sensavg;                 /* Overall average of sensor readings */
3314
 
        double satthresh;               /* Saturation threshold */
3315
3359
        double darkthresh;              /* Dark threshold */
3316
3360
        double trackmax[2];             /* Track optimum target */
3317
3361
        double maxval;                  /* Maximum multimeas value */
3614
3658
 
3615
3659
        /* Process the "tracked to max" values too */
3616
3660
        if (ntrackmax > 0 && trackmax != NULL)  {
3617
 
                double raw, lval;
3618
3661
                for (i = 0; i < ntrackmax; i++) {
3619
3662
                        double rval, fval, lval;
3620
3663
 
3918
3961
 
3919
3962
                                /* For each window offset, choose the one to use. */
3920
3963
                                bdev = 1e38;
 
3964
                                basl = 0.0;
3921
3965
                                for (k = 0; k < FW; k++) { 
3922
3966
 
3923
3967
                                        /* Choose window average with smallest deviation squared */
4324
4368
                PRDBG((dbgo,"Patch %d: consistency = %f%%, thresh = %f%%\n",pix,100.0 * cons, 100.0 * patch_cons_thr))
4325
4369
                if (cons > patch_cons_thr) {
4326
4370
                        if (p->debug >= 1)
4327
 
                                fprintf(stderr,"Patch recog failed - patch %k is inconsistent (%f%%)\n",cons);
 
4371
                                fprintf(stderr,"Patch recog failed - patch %d is inconsistent (%f%%)\n",pix, cons);
4328
4372
                        rv |= 1;
4329
4373
                }
4330
4374
                pix++;
4368
4412
        double inttime                  /* Integration time (used to compute duration) */
4369
4413
) {
4370
4414
        munkiimp *m = (munkiimp *)p->m;
4371
 
        int i, j, k, pix;
 
4415
        int i, j, k;
4372
4416
        double minval, maxval;          /* min and max input value at wavelength of maximum input */
4373
4417
        double mean;                            /* Mean of the max wavelength band */
4374
4418
        int maxband;                            /* Band of maximum value */
4387
4431
 
4388
4432
        /* Discover the maximum input value for flash dection */
4389
4433
        maxval = -1e6;
 
4434
        maxband = 0;
4390
4435
        for (j = 0; j < m->nraw; j ++) {
4391
4436
                for (i = 0; i < nummeas; i++) {
4392
4437
                        if (multimeas[i][j] > maxval) {
5855
5900
                        /* Create upsampled version */
5856
5901
                        for (i = 0; i < m->nwav2; i++) {                /* Output wavelength */
5857
5902
                                for (j = 0; j < m->nwav2; j++) {        /* Input wavelength */
5858
 
                                        pp.p[0] = XSPECT_WL(m->wl_short2, m->wl_long2, m->nwav2, i);
5859
 
                                        pp.p[1] = XSPECT_WL(m->wl_short2, m->wl_long2, m->nwav2, j);
 
5903
                                        double p0, p1;
 
5904
                                        p0 = XSPECT_WL(m->wl_short2, m->wl_long2, m->nwav2, i);
 
5905
                                        p1 = XSPECT_WL(m->wl_short2, m->wl_long2, m->nwav2, j);
5860
5906
#ifdef SALONEINSTLIB
5861
5907
                                        /* Do linear interp with clipping at ends */
5862
5908
                                        {
5863
5909
                                                int x0, x1, y0, y1;
5864
5910
                                                double xx, yy, w0, w1, v0, v1;
5865
5911
 
5866
 
                                                xx = (m->nwav1-1.0) * (pp.p[0] - m->wl_short1)/(m->wl_long1 - m->wl_short1);
 
5912
                                                xx = (m->nwav1-1.0) * (p0 - m->wl_short1)/(m->wl_long1 - m->wl_short1);
5867
5913
                                                x0 = (int)floor(xx);
5868
5914
                                                if (x0 <= 0)
5869
5915
                                                        x0 = 0;
5873
5919
                                                w1 = xx - (double)x0;
5874
5920
                                                w0 = 1.0 - w1;
5875
5921
 
5876
 
                                                yy = (m->nwav1-1.0) * (pp.p[1] - m->wl_short1)/(m->wl_long1 - m->wl_short1);
 
5922
                                                yy = (m->nwav1-1.0) * (p1 - m->wl_short1)/(m->wl_long1 - m->wl_short1);
5877
5923
                                                y0 = (int)floor(yy);
5878
5924
                                                if (y0 <= 0)
5879
5925
                                                        y0 = 0;
5889
5935
                                                        + w1 * v1 * slp[x1][y1]; 
5890
5936
                                        }
5891
5937
#else /* !SALONEINSTLIB */
 
5938
                                        pp.p[0] = p0;
 
5939
                                        pp.p[1] = p1;
5892
5940
                                        trspl->interp(trspl, &pp);
5893
5941
#endif /* !SALONEINSTLIB */
5894
5942
                                        m->straylight2[i][j] = pp.v[0] * HIGHRES_WIDTH/10.0;
6177
6225
        double wl_short = m->wl_short;  /* Starting wavelegth */
6178
6226
        double sms;                     /* Weighting */
6179
6227
 
6180
 
#ifndef SALONEINSTLIB
6181
6228
        if (s->emiss)
6182
6229
                conv = new_xsp2cie(icxIT_none, NULL, icxOT_CIE_1931_2, NULL, icSigXYZData);
6183
6230
        else
6184
6231
                conv = new_xsp2cie(icxIT_D50, NULL, icxOT_CIE_1931_2, NULL, icSigXYZData);
6185
 
#else /* SALONEINSTLIB */
6186
 
        if (s->emiss)
6187
 
                conv = new_xsp2cie(icxIT_none, NULL, icxOT_CIE_1931_2, NULL);
6188
 
        else
6189
 
                conv = new_xsp2cie(icxIT_D50, NULL, icxOT_CIE_1931_2, NULL);
6190
 
#endif /* SALONEINSTLIB */
6191
6232
        if (conv == NULL)
6192
6233
                return MUNKI_INT_CIECONVFAIL;
6193
6234
 
6646
6687
        int *noeeblocks,        /* Number of EEPROM blocks */
6647
6688
        int *eeblocksize        /* Size of each block */
6648
6689
) {
6649
 
        int rwbytes;                    /* Data bytes read or written */
6650
6690
        unsigned char pbuf[24]; /* status bytes read */
6651
6691
        int _fwrev_maj, _fwrev_min;
6652
6692
        int _tickdur;
6699
6739
        munki *p,
6700
6740
        unsigned char chipid[8]
6701
6741
) {
6702
 
        int rwbytes;                    /* Data bytes read or written */
6703
6742
        int se, rv = MUNKI_OK;
6704
6743
        int isdeb = 0;
6705
6744
 
6734
6773
        munki *p,
6735
6774
        char vstring[37]
6736
6775
) {
6737
 
        int rwbytes;                    /* Data bytes read or written */
6738
6776
        int se, rv = MUNKI_OK;
6739
6777
        int isdeb = 0;
6740
6778
 
6773
6811
        int *dutycycle,         /* Duty Cycle */
6774
6812
        int *ADfeedback         /* A/D converter feedback */
6775
6813
) {
6776
 
        int rwbytes;                    /* Data bytes read or written */
6777
6814
        unsigned char pbuf[16]; /* values read */
6778
6815
        int _ledtrange;
6779
6816
        int _ledtemp;
6824
6861
        mk_spos *spos,          /* Return the sensor position */
6825
6862
        mk_but *but                     /* Return Button state */
6826
6863
) {
6827
 
        int rwbytes;                    /* Data bytes read or written */
6828
6864
        unsigned char pbuf[2];  /* status bytes read */
6829
6865
        mk_spos _spos;
6830
6866
        mk_but _but;
6893
6929
    int p4,                     /* Number of pulses, -1 = max */
6894
6930
    int p5                      /* Ignored ? */
6895
6931
) {
6896
 
        int rwbytes;                    /* Data bytes read or written */
6897
6932
        unsigned char pbuf[20]; /* command bytes written */
6898
6933
        int se, rv = MUNKI_OK;
6899
6934
        int isdeb = 0;
6938
6973
        int holdtempduty        /* Hold temperature duty cycle */
6939
6974
) {
6940
6975
        munkiimp *m = (munkiimp *)p->m;
6941
 
        int rwbytes;                    /* Data bytes read or written */
6942
6976
        unsigned char pbuf[12]; /* command bytes written */
6943
6977
        int se, rv = MUNKI_OK;
6944
6978
        int isdeb = 0;
7026
7060
 
7027
7061
        top = extra + m->c_inttime * nmeas;
7028
7062
 
7029
 
        if (isdeb) fprintf(stderr,"\nmunki: Read measurement results: inummeas %d, scanflag %d, address 0x%x bsize 0x%x, timout %f\n",inummeas, scanflag, buf, bsize, top);
 
7063
        if (isdeb) fprintf(stderr,"\nmunki: Read measurement results: inummeas %d, scanflag %d, address %p bsize 0x%x, timout %f\n",inummeas, scanflag, buf, bsize, top);
7030
7064
 
7031
7065
        for (;;) {
7032
7066
                int size;               /* number of bytes to read */
7172
7206
/* Simulating an event */
7173
7207
munki_code munki_simulate_event(munki *p, mk_eve ecode,  int timestamp) {
7174
7208
        munkiimp *m = (munkiimp *)p->m;
7175
 
        int rwbytes;                    /* Data bytes read or written */
7176
7209
        unsigned char pbuf[8];  /* 8 bytes to write */
7177
7210
        int se, rv = MUNKI_OK;
7178
7211
        int isdeb = 0;
7448
7481
 
7449
7482
        /* Create class to handle EEProm parsing */
7450
7483
        if ((d = m->data = new_mkdata(p, buf, len, p->verb, p->debug)) == NULL)
7451
 
                MUNKI_INT_CREATE_EEPROM_STORE;
 
7484
                return MUNKI_INT_CREATE_EEPROM_STORE;
7452
7485
 
7453
7486
        /* Check out the version */
7454
7487
        if (d->get_u16_ints(d, &calver, 0, 1) == NULL)