From c6739b6427261ac2682a9fca3b23c98df0dc9f60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Frings-F=C3=BCrst?= Date: Fri, 6 Nov 2015 07:40:42 +0100 Subject: New upstream release --- spectro/i1pro_imp.c | 123 +++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 93 insertions(+), 30 deletions(-) (limited to 'spectro/i1pro_imp.c') diff --git a/spectro/i1pro_imp.c b/spectro/i1pro_imp.c index 0b6fc69..8577f8c 100644 --- a/spectro/i1pro_imp.c +++ b/spectro/i1pro_imp.c @@ -149,6 +149,8 @@ /* Should be good up to 275 cd/m^2 */ #define DISP_INTT3 0.3 /* High brightness display spot mode seconds per reading, */ /* Should be good up to 700 cd/m^2 */ +#define DISP_INTT4 0.1 /* Very high brightness display spot mode seconds per reading, */ + /* Should be good up to 2000 cd/m^2 ? */ #define ADARKINT_MAX 2.0 /* Max cal time for adaptive dark cal */ #define ADARKINT_MAX2 4.0 /* Max cal time for adaptive dark cal Rev E or no high gain */ @@ -398,6 +400,7 @@ void del_i1proimp(i1pro *p) { free_dvector(s->dark_data, -1, m->nraw-1); free_dvector(s->dark_data2, -1, m->nraw-1); free_dvector(s->dark_data3, -1, m->nraw-1); + free_dvector(s->dark_data4, -1, m->nraw-1); free_dvector(s->white_data, -1, m->nraw-1); free_dmatrix(s->idark_data, 0, 3, -1, m->nraw-1); @@ -958,6 +961,7 @@ i1pro_code i1pro_imp_init(i1pro *p) { s->dark_data = dvectorz(-1, m->nraw-1); s->dark_data2 = dvectorz(-1, m->nraw-1); s->dark_data3 = dvectorz(-1, m->nraw-1); + s->dark_data4 = dvectorz(-1, m->nraw-1); s->cal_valid = 0; /* Scale cal invalid */ s->cal_factor[0] = dvectorz(0, m->nwav[0]-1); @@ -972,6 +976,7 @@ i1pro_code i1pro_imp_init(i1pro *p) { s->dark_int_time = DISP_INTT; /* 2.0 */ s->dark_int_time2 = DISP_INTT2; /* 0.8 */ s->dark_int_time3 = DISP_INTT3; /* 0.3 */ + s->dark_int_time4 = DISP_INTT4; /* 0.1 */ s->idark_int_time[0] = s->idark_int_time[2] = m->min_int_time; if (p->itype == instI1Pro2) { @@ -1057,12 +1062,14 @@ i1pro_code i1pro_imp_init(i1pro *p) { s->dark_int_time = s->inttime; s->dark_int_time2 = DISP_INTT2; /* Alternate disp integration time (ie. 0.8) */ s->dark_int_time3 = DISP_INTT3; /* Alternate disp integration time (ie. 0.3) */ + s->dark_int_time4 = DISP_INTT4; /* Alternate disp integration time (ie. 0.1) */ s->dadaptime = 0.0; s->wadaptime = 0.10; s->dcaltime = DISP_INTT; /* ie. determines number of measurements */ s->dcaltime2 = DISP_INTT2 * 2; /* Make it 1.6 seconds (ie, 2 x 0.8 seconds) */ s->dcaltime3 = DISP_INTT3 * 3; /* Make it 0.9 seconds (ie, 3 x 0.3 seconds) */ + s->dcaltime4 = DISP_INTT4 * 3; /* Make it 0.3 seconds (ie, 3 x 0.1 seconds) */ s->wcaltime = 0.0; s->dreadtime = 0.0; s->wreadtime = DISP_INTT; @@ -1620,10 +1627,10 @@ i1pro_code i1pro_imp_calibrate( || (s->emiss && !s->adaptive && !s->scan) || (s->trans && !s->adaptive))) { int stm; - int usesdct23 = 0; /* Is a mode that uses dcaltime2 & 3 */ + int usesdct234 = 0; /* Is a mode that uses dcaltime2, 3 & 4 */ if (s->emiss && !s->adaptive && !s->scan) - usesdct23 = 1; + usesdct234 = 1; nummeas = i1pro_comp_nummeas(p, s->dcaltime, s->inttime); @@ -1637,7 +1644,7 @@ i1pro_code i1pro_imp_calibrate( a1logd(p->log,2,"Execution time of dark calib time %f sec = %d msec\n",s->inttime,msec_time() - stm); /* Special display mode alternate integration time black measurement */ - if (usesdct23) { + if (usesdct234) { nummeas = i1pro_comp_nummeas(p, s->dcaltime2, s->dark_int_time2); a1logd(p->log,2,"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); stm = msec_time(); @@ -1658,6 +1665,17 @@ i1pro_code i1pro_imp_calibrate( return ev; } a1logd(p->log,2,"Execution time of 3rd dark calib time %f sec = %d msec\n",s->inttime,msec_time() - stm); + + nummeas = i1pro_comp_nummeas(p, s->dcaltime4, s->dark_int_time4); + a1logd(p->log,2,"Doing 4th initial black calibration with dcaltime4 %f, dark_int_time4 %f, nummeas %d, gainmode %d\n", s->dcaltime4, s->dark_int_time4, nummeas, s->gainmode); + nummeas = i1pro_comp_nummeas(p, s->dcaltime4, s->dark_int_time4); + stm = msec_time(); + if ((ev = i1pro_dark_measure(p, s->dark_data4, + nummeas, &s->dark_int_time4, s->gainmode)) != I1PRO_OK) { + m->mmode = mmode; /* Restore actual mode */ + return ev; + } + a1logd(p->log,2,"Execution time of 4rd dark calib time %f sec = %d msec\n",s->inttime,msec_time() - stm); } s->dark_valid = 1; s->want_dcalib = 0; @@ -1686,13 +1704,15 @@ i1pro_code i1pro_imp_calibrate( ss->dark_gain_mode = s->dark_gain_mode; for (k = -1; k < m->nraw; k++) ss->dark_data[k] = s->dark_data[k]; - /* If this is a mode with dark_data2/3, tranfer it too */ - if (usesdct23 && ss->emiss && !ss->adaptive && !ss->scan) { + /* If this is a mode with dark_data2/3/4, tranfer it too */ + if (usesdct234 && ss->emiss && !ss->adaptive && !ss->scan) { ss->dark_int_time2 = s->dark_int_time2; - ss->dark_int_time3 = s->dark_int_time2; + ss->dark_int_time3 = s->dark_int_time3; + ss->dark_int_time4 = s->dark_int_time4; for (k = -1; k < m->nraw; k++) { ss->dark_data2[k] = s->dark_data2[k]; ss->dark_data3[k] = s->dark_data3[k]; + ss->dark_data4[k] = s->dark_data4[k]; } } } @@ -2276,6 +2296,9 @@ i1pro_code i1pro_imp_calibrate( } else if (s->dispswap == 2) { tv = s->inttime; s->inttime = s->dark_int_time3; s->dark_int_time3 = tv; tt = s->dark_data; s->dark_data = s->dark_data3; s->dark_data3 = tt; + } else if (s->dispswap == 3) { + tv = s->inttime; s->inttime = s->dark_int_time4; s->dark_int_time4 = tv; + tt = s->dark_data; s->dark_data = s->dark_data4; s->dark_data4 = tt; } s->dispswap = 0; @@ -2284,30 +2307,43 @@ i1pro_code i1pro_imp_calibrate( nummeas = i1pro_comp_nummeas(p, s->wreadtime, s->inttime); ev = i1pro_whitemeasure(p, NULL, NULL, data , &scale, nummeas, &s->inttime, s->gainmode, s->targoscale, 0); - /* Switch to the alternate if things are too bright */ - /* We do this simply by swapping the alternate values in. */ if (ev == I1PRO_RD_SENSORSATURATED || scale < 1.0) { - a1logd(p->log,2,"Switching to alternate display integration time %f seconds\n",s->dark_int_time2); + a1logd(p->log,2,"Switching to 2nd display integration time %f seconds\n",s->dark_int_time2); + /* swap in 2nd display integration time */ tv = s->inttime; s->inttime = s->dark_int_time2; s->dark_int_time2 = tv; tt = s->dark_data; s->dark_data = s->dark_data2; s->dark_data2 = tt; s->dispswap = 1; /* Do another measurement of the full display white, and if it's close to */ - /* saturation, switch to the 3rd alternate display integration time */ + /* saturation, switch to the 3rd display integration time */ nummeas = i1pro_comp_nummeas(p, s->wreadtime, s->inttime); ev = i1pro_whitemeasure(p, NULL, NULL, data , &scale, nummeas, &s->inttime, s->gainmode, s->targoscale, 0); - /* Switch to the 3rd alternate if things are too bright */ - /* We do this simply by swapping the alternate values in. */ if (ev == I1PRO_RD_SENSORSATURATED || scale < 1.0) { - a1logd(p->log,2,"Switching to 3rd alternate display integration time %f seconds\n",s->dark_int_time3); + a1logd(p->log,2,"Switching to 3rd display integration time %f seconds\n",s->dark_int_time3); /* Undo previous swap */ tv = s->inttime; s->inttime = s->dark_int_time2; s->dark_int_time2 = tv; tt = s->dark_data; s->dark_data = s->dark_data2; s->dark_data2 = tt; - /* swap in 2nd alternate */ + /* swap in 3rd time */ tv = s->inttime; s->inttime = s->dark_int_time3; s->dark_int_time3 = tv; tt = s->dark_data; s->dark_data = s->dark_data3; s->dark_data3 = tt; s->dispswap = 2; + + /* Do another measurement of the full display white, and if it's close to */ + /* saturation, switch to the 4th display integration time */ + nummeas = i1pro_comp_nummeas(p, s->wreadtime, s->inttime); + ev = i1pro_whitemeasure(p, NULL, NULL, data , &scale, nummeas, + &s->inttime, s->gainmode, s->targoscale, 0); + if (ev == I1PRO_RD_SENSORSATURATED || scale < 1.0) { + a1logd(p->log,2,"Switching to 4th display integration time %f seconds\n",s->dark_int_time3); + /* Undo previous swap */ + tv = s->inttime; s->inttime = s->dark_int_time3; s->dark_int_time3 = tv; + tt = s->dark_data; s->dark_data = s->dark_data3; s->dark_data3 = tt; + /* swap in 4th time */ + tv = s->inttime; s->inttime = s->dark_int_time4; s->dark_int_time4 = tv; + tt = s->dark_data; s->dark_data = s->dark_data4; s->dark_data4 = tt; + s->dispswap = 3; + } } } free_dvector(data, -1, m->nraw-1); @@ -2947,16 +2983,16 @@ i1pro_code i1pro_imp_measure( /* and try again. */ if (s->emiss && !s->scan && !s->adaptive && ev == I1PRO_RD_SENSORSATURATED - && s->dispswap < 2) { + && s->dispswap < 3) { double *tt, tv; if (s->dispswap == 0) { - a1logd(p->log,2,"Switching to alternate display integration time %f seconds\n",s->dark_int_time2); + a1logd(p->log,2,"Switching to 2nd display integration time %f seconds\n",s->dark_int_time2); tv = s->inttime; s->inttime = s->dark_int_time2; s->dark_int_time2 = tv; tt = s->dark_data; s->dark_data = s->dark_data2; s->dark_data2 = tt; s->dispswap = 1; } else if (s->dispswap == 1) { - a1logd(p->log,2,"Switching to 2nd alternate display integration time %f seconds\n",s->dark_int_time3); + a1logd(p->log,2,"Switching to 3rd display integration time %f seconds\n",s->dark_int_time3); /* Undo first swap */ tv = s->inttime; s->inttime = s->dark_int_time2; s->dark_int_time2 = tv; tt = s->dark_data; s->dark_data = s->dark_data2; s->dark_data2 = tt; @@ -2964,6 +3000,15 @@ i1pro_code i1pro_imp_measure( tv = s->inttime; s->inttime = s->dark_int_time3; s->dark_int_time3 = tv; tt = s->dark_data; s->dark_data = s->dark_data3; s->dark_data3 = tt; s->dispswap = 2; + } else if (s->dispswap == 2) { + a1logd(p->log,2,"Switching to 4th display integration time %f seconds\n",s->dark_int_time4); + /* Undo 2nd swap */ + tv = s->inttime; s->inttime = s->dark_int_time3; s->dark_int_time3 = tv; + tt = s->dark_data; s->dark_data = s->dark_data3; s->dark_data3 = tt; + /* Do 3rd swap */ + tv = s->inttime; s->inttime = s->dark_int_time4; s->dark_int_time4 = tv; + tt = s->dark_data; s->dark_data = s->dark_data4; s->dark_data4 = tt; + s->dispswap = 3; } /* Recompute number of measurements and realloc measurement buffer */ free(mbuf); @@ -4145,6 +4190,8 @@ i1pro_code i1pro_save_calibration(i1pro *p) { write_doubles(&x, fp, s->dark_data2-1, m->nraw+1); write_doubles(&x, fp, &s->dark_int_time3, 1); write_doubles(&x, fp, s->dark_data3-1, m->nraw+1); + write_doubles(&x, fp, &s->dark_int_time4, 1); + write_doubles(&x, fp, s->dark_data4-1, m->nraw+1); write_ints(&x, fp, &s->dark_gain_mode, 1); if (!s->emiss) { @@ -4288,7 +4335,10 @@ i1pro_code i1pro_restore_calibration(i1pro *p) { read_doubles(&x, fp, &dd, 1); for (j = -1; j < m->nraw; j++) read_doubles(&x, fp, &dd, 1); - read_doubles(&x, fp, &dd, 1); + read_doubles(&x, fp, &dd, 1); /* dark_data3 */ + for (j = -1; j < m->nraw; j++) + read_doubles(&x, fp, &dd, 1); + read_doubles(&x, fp, &dd, 1); /* dark_data4 */ for (j = -1; j < m->nraw; j++) read_doubles(&x, fp, &dd, 1); read_ints(&x, fp, &di, 1); @@ -4338,6 +4388,7 @@ i1pro_code i1pro_restore_calibration(i1pro *p) { ts.dark_data = dvectorz(-1, m->nraw-1); ts.dark_data2 = dvectorz(-1, m->nraw-1); ts.dark_data3 = dvectorz(-1, m->nraw-1); + ts.dark_data4 = dvectorz(-1, m->nraw-1); ts.cal_factor[0] = dvectorz(0, m->nwav[0]-1); ts.cal_factor[1] = dvectorz(0, m->nwav[1]-1); ts.white_data = dvectorz(-1, m->nraw-1); @@ -4384,6 +4435,8 @@ i1pro_code i1pro_restore_calibration(i1pro *p) { read_doubles(&x, fp, ts.dark_data2-1, m->nraw+1); read_doubles(&x, fp, &ts.dark_int_time3, 1); read_doubles(&x, fp, ts.dark_data3-1, m->nraw+1); + read_doubles(&x, fp, &ts.dark_int_time4, 1); + read_doubles(&x, fp, ts.dark_data4-1, m->nraw+1); read_ints(&x, fp, &ts.dark_gain_mode, 1); if (!ts.emiss) { @@ -4419,6 +4472,7 @@ i1pro_code i1pro_restore_calibration(i1pro *p) { && (s->adaptive || fabs(s->dark_int_time - ts.dark_int_time) < 0.01) && (s->adaptive || fabs(s->dark_int_time2 - ts.dark_int_time2) < 0.01) && (s->adaptive || fabs(s->dark_int_time3 - ts.dark_int_time3) < 0.01) + && (s->adaptive || fabs(s->dark_int_time4 - ts.dark_int_time4) < 0.01) && (!s->adaptive || fabs(s->idark_int_time[0] - ts.idark_int_time[0]) < 0.01) && (!s->adaptive || fabs(s->idark_int_time[1] - ts.idark_int_time[1]) < 0.01) && (!s->adaptive || fabs(s->idark_int_time[2] - ts.idark_int_time[2]) < 0.01) @@ -4451,6 +4505,9 @@ i1pro_code i1pro_restore_calibration(i1pro *p) { s->dark_int_time3 = ts.dark_int_time3; for (j = -1; j < m->nraw; j++) s->dark_data3[j] = ts.dark_data3[j]; + s->dark_int_time4 = ts.dark_int_time4; + for (j = -1; j < m->nraw; j++) + s->dark_data4[j] = ts.dark_data4[j]; s->dark_gain_mode = ts.dark_gain_mode; if (!ts.emiss) { s->cal_valid = ts.cal_valid; @@ -4480,7 +4537,7 @@ i1pro_code i1pro_restore_calibration(i1pro *p) { a1logd(p->log,2,"emis = %d : %d, trans = %d : %d, ref = %d : %d\n",s->emiss,ts.emiss,s->trans,ts.trans,s->reflective,ts.reflective); a1logd(p->log,2,"scan = %d : %d, flash = %d : %d, ambi = %d : %d, adapt = %d : %d\n",s->scan,ts.scan,s->flash,ts.flash,s->ambient,ts.ambient,s->adaptive,ts.adaptive); a1logd(p->log,2,"inttime = %f : %f\n",s->inttime,ts.inttime); - a1logd(p->log,2,"darkit1 = %f : %f, 2 = %f : %f, 3 = %f : %f\n",s->dark_int_time,ts.dark_int_time,s->dark_int_time2,ts.dark_int_time2,s->dark_int_time3,ts.dark_int_time3); + a1logd(p->log,2,"darkit1 = %f : %f, 2 = %f : %f, 3 = %f : %f, 4 = %f : %f\n",s->dark_int_time,ts.dark_int_time,s->dark_int_time2,ts.dark_int_time2,s->dark_int_time3,ts.dark_int_time3,s->dark_int_time4,ts.dark_int_time4); a1logd(p->log,2,"idarkit0 = %f : %f, 1 = %f : %f, 2 = %f : %f, 3 = %f : %f\n",s->idark_int_time[0],ts.idark_int_time[0],s->idark_int_time[1],ts.idark_int_time[1],s->idark_int_time[2],ts.idark_int_time[2],s->idark_int_time[3],ts.idark_int_time[3]); } } @@ -4489,6 +4546,7 @@ i1pro_code i1pro_restore_calibration(i1pro *p) { free_dvector(ts.dark_data, -1, m->nraw-1); free_dvector(ts.dark_data2, -1, m->nraw-1); free_dvector(ts.dark_data3, -1, m->nraw-1); + free_dvector(ts.dark_data4, -1, m->nraw-1); free_dvector(ts.white_data, -1, m->nraw-1); free_dmatrix(ts.idark_data, 0, 3, -1, m->nraw-1); @@ -4549,6 +4607,8 @@ i1pro_establish_high_power(i1pro *p) { if ((ev = i1pro_getmisc(p, &m->fwrev, NULL, &m->maxpve, NULL, &m->powmode)) != I1PRO_OK) return ev; + a1logd(p->log,2,"CPLD rev = %d\n",m->cpldrev); + if (m->powmode != 8) { /* In high power mode */ if ((ev = i1pro_reset(p, 0x1f)) != I1PRO_OK) return ev; @@ -10724,14 +10784,14 @@ i1pro_readEEProm( 0xC4, 0, 0, pbuf, len, 2.0); if ((rv = icoms2i1pro_err(se)) != I1PRO_OK) { - a1logd(p->log,1,"i1pro_readEEProm: read failed with ICOM err 0x%x\n",se); + a1logd(p->log,1,"i1pro_readEEProm: read failed with ICOM err 0x%x (%d msec)\n",se, msec_time()-stime); return rv; } /* Now read the bytes */ se = p->icom->usb_read(p->icom, NULL, 0x82, buf, size, &rwbytes, 5.0); if ((rv = icoms2i1pro_err(se)) != I1PRO_OK) { - a1logd(p->log,1,"i1pro_readEEProm: read failed with ICOM err 0x%x\n",se); + a1logd(p->log,1,"i1pro_readEEProm: read failed with ICOM err 0x%x (%d msec)\n",se, msec_time()-stime); return rv; } @@ -10812,7 +10872,7 @@ i1pro_writeEEProm( 0xC3, 0, 0, pbuf, len, 2.0); if ((rv = icoms2i1pro_err(se)) != I1PRO_OK) { - a1logd(p->log,2,"i1pro_writeEEProm: write failed with ICOM err 0x%x\n",se); + a1logd(p->log,2,"i1pro_writeEEProm: write failed with ICOM err 0x%x (%d msec)\n",se, msec_time()-stime); return rv; } @@ -10820,7 +10880,7 @@ i1pro_writeEEProm( se = p->icom->usb_write(p->icom, NULL, 0x03, buf, size, &rwbytes, 5.0); if ((rv = icoms2i1pro_err(se)) != I1PRO_OK) { - a1logd(p->log,1,"i1pro_writeEEProm: failed with ICOM err 0x%x\n",se); + a1logd(p->log,1,"i1pro_writeEEProm: failed with ICOM err 0x%x (%d msec)\n",se, msec_time()-stime); return rv; } @@ -10837,7 +10897,7 @@ i1pro_writeEEProm( se = p->icom->usb_write(p->icom, NULL, 0x03, pbuf, 1, &rwbytes, 5.0); if ((rv = icoms2i1pro_err(se)) != I1PRO_OK) { - a1logd(p->log,1,"i1pro_writeEEProm: write failed with ICOM err 0x%x\n",se); + a1logd(p->log,1,"i1pro_writeEEProm: write failed with ICOM err 0x%x (%d msec)\n",se, msec_time()-stime); return rv; } @@ -10889,7 +10949,7 @@ i1pro_getmisc( 0xC9, 0, 0, pbuf, 8, 2.0); if ((rv = icoms2i1pro_err(se)) != I1PRO_OK) { - a1logd(p->log,1,"i1pro_getmisc: failed with ICOM err 0x%x\n",se); + a1logd(p->log,1,"i1pro_getmisc: failed with ICOM err 0x%x (%d msec)\n",se, msec_time()-stime); return rv; } @@ -10937,7 +10997,7 @@ i1pro_getmeasparams( 0xC2, 0, 0, pbuf, 8, 2.0); if ((rv = icoms2i1pro_err(se)) != I1PRO_OK) { - a1logd(p->log,1,"i1pro_getmeasparams: failed with ICOM err 0x%x\n",se); + a1logd(p->log,1,"i1pro_getmeasparams: failed with ICOM err 0x%x (%d msec)\n",se, msec_time()-stime); return rv; } @@ -11002,7 +11062,7 @@ i1pro_setmeasparams( 0xC1, 0, 0, pbuf, 8, 2.0); if ((rv = icoms2i1pro_err(se)) != I1PRO_OK) { - a1logd(p->log,1,"i1pro_setmeasparams: failed with ICOM err 0x%x\n",se); + a1logd(p->log,1,"i1pro_setmeasparams: failed with ICOM err 0x%x (%d msec)\n",se, msec_time()-stime); return rv; } @@ -11318,10 +11378,13 @@ i1pro_setmcmode( 0xCF, 0, 0, pbuf, 1, 2.0); if ((rv = icoms2i1pro_err(se)) != I1PRO_OK) { - a1logd(p->log,1,"i1pro_setmcmode: failed with ICOM err 0x%x\n",se); + a1logd(p->log,1,"i1pro_setmcmode: failed with ICOM err 0x%x (%d msec)\n",se, msec_time()-stime); return rv; } + /* Hmm. Give the instrument a little time to reconfigure itself. */ + msec_sleep(10); + a1logd(p->log,2,"i1pro_setmcmode: done, ICOM err 0x%x (%d msec)\n", se, msec_time()-stime); return rv; @@ -11358,7 +11421,7 @@ i1pro_getmcmode( 0xD1, 0, 0, pbuf, 6, 2.0); if ((rv = icoms2i1pro_err(se)) != I1PRO_OK) { - a1logd(p->log,1,"i1pro_getmcmode: failed with ICOM err 0x%x\n",se); + a1logd(p->log,1,"i1pro_getmcmode: failed with ICOM err 0x%x (%d msec)\n",se, msec_time()-stime); return rv; } @@ -11403,7 +11466,7 @@ i1pro_code i1pro_waitfor_switch(i1pro *p, double top) { } if ((rv = icoms2i1pro_err(se)) != I1PRO_OK) { - a1logd(p->log,1,"i1pro_waitfor_switch: failed with ICOM err 0x%x\n",se); + a1logd(p->log,1,"i1pro_waitfor_switch: failed with ICOM err 0x%x (%d msec)\n",se, msec_time()-stime); return rv; } -- cgit v1.2.3