38 #include "vircam_mods.h"
39 #include "vircam_utils.h"
40 #include "vircam_stats.h"
41 #include "vircam_pfits.h"
42 #include "vircam_channel.h"
47 static double nom_val = 10000;
50 static double linval(
double inval,
double *kfacs,
double tolerance,
51 int niter,
double *b,
int norder);
52 static double getkfac(
long index,
long ncpts,
float reset_time,
53 float read_time,
float delay_time,
float exptime);
54 static void getco(
double *a,
int nord,
int m);
118 double mindit, vir_tfits *chantab,
119 int norder, cpl_table **lchantab,
120 double **lindata,
int *status) {
122 const char *fctid =
"vircam_genlincur";
123 int retval,i,j,nbad,oldnorder,k,ii,nullval;
125 double *meds,sigfit,**aco,c0,lin_nom,*temp,*polyco,pt,*work,kfac;
126 double sum,t10000,*kfacs;
129 cpl_array *exparray,*medsarray,*polyfitco,*workarray;
130 char colname[SZCOLNAME];
135 if (*status != VIR_OK)
140 if (nimages < norder+1) {
142 "Not enought images (%" CPL_SIZE_FORMAT
") for fit order (%" CPL_SIZE_FORMAT
")",
143 (cpl_size)nimages,(cpl_size)norder);
151 if (retval != VIR_OK) {
159 lc = cpl_table_duplicate(ctab);
160 oldnorder = cpl_table_get_int(lc,
"norder",0,&nullval);
161 if (oldnorder > norder) {
162 for (i = norder+1; i <= oldnorder; i++) {
163 snprintf(colname,SZCOLNAME,
"coeff_%d",i);
164 cpl_table_erase_column(lc,colname);
166 }
else if (oldnorder < norder) {
167 for (i = oldnorder+1; i <= norder; i++) {
168 snprintf(colname,SZCOLNAME,
"coeff_%d",i);
169 if (cpl_table_has_column(lc,colname))
171 cpl_table_new_column(lc,colname,CPL_TYPE_DOUBLE);
177 exparray = cpl_array_wrap_double(exps,nimages);
178 medsarray = cpl_array_new((cpl_size)nimages,CPL_TYPE_DOUBLE);
179 meds = cpl_array_get_data_double(medsarray);
180 aco = cpl_malloc(norder*
sizeof(
double *));
181 for (i = 0; i < norder; i++)
182 aco[i] = cpl_malloc(norder*
sizeof(
double));
183 temp = cpl_malloc(norder*
sizeof(
double));
184 kfacs = cpl_malloc(norder*
sizeof(
double));
188 *lindata = cpl_malloc(nimages*np*
sizeof(
double));
193 for (i = 0; i < np; i++) {
198 for (j = 0; j < nimages; j++)
199 meds[j] = fdata[j][i];
203 if (
vircam_polyfit(exparray,medsarray,norder,1,2,2.0,2.0,&polyfitco,
204 &sigfit) != VIR_OK) {
206 cpl_table_set_int(lc,
"norder",(cpl_size)i,norder);
207 cpl_table_set_double(lc,
"coeff_1",(cpl_size)i,1.0);
208 for (k = 1; k < norder; k++) {
209 snprintf(colname,SZCOLNAME,
"coeff_%d",k+1);
210 cpl_table_set_double(lc,colname,(cpl_size)i,0.0);
212 freearray(polyfitco);
215 polyco = cpl_array_get_data_double(polyfitco);
219 for (j = 0; j < nimages; j++)
220 if (meds[j] > nom_val)
222 t10000 = exps[j-1] + (nom_val - meds[j-1])/(meds[j] - meds[j-1]);
224 for (j = 0; j < norder; j++)
225 sum += (
double)(j+1)*polyco[j]*pow(t10000,(
double)j);
226 lin_nom = 100.0*fabs(sum - polyco[0])/polyco[0];
230 for (j = 0; j < norder; j++) {
231 getco(temp,norder,j+1);
232 for (k = 0; k < norder; k++) {
233 pt = pow(mindit,(
double)(j-k));
234 aco[j][k] = pt*temp[k];
242 cpl_table_set_int(lc,
"norder",(cpl_size)i,norder);
243 cpl_table_set_double(lc,
"coeff_1",(cpl_size)i,1.0);
244 for (k = 1; k < norder; k++) {
245 snprintf(colname,SZCOLNAME,
"coeff_%d",k+1);
246 cpl_table_set_double(lc,colname,(cpl_size)i,0.0);
248 freearray(polyfitco);
255 for (j = 0; j < norder; j++) {
256 polyco[j] /= pow(c0,(
double)(j+1));
257 snprintf(colname,SZCOLNAME,
"coeff_%d",j+1);
258 cpl_table_set_double(lc,colname,(cpl_size)i,polyco[j]);
260 cpl_table_set_int(lc,
"norder",(cpl_size)i,norder);
266 workarray = cpl_array_new((cpl_size)nimages,CPL_TYPE_DOUBLE);
267 work = cpl_array_get_data_double(workarray);
268 for (j = 0; j < nimages; j++) {
269 kfac = mindit/exps[j];
271 for (ii = 1; ii < norder; ii++)
272 kfacs[ii] = pow((kfac+1.0),(
double)(ii+1)) -
273 pow(kfac,(
double)(ii+1));
274 work[j] = linval(meds[j],kfacs,0.5,10,polyco,norder);
275 (*lindata)[j*np+i] = work[j];
277 freearray(polyfitco);
280 polyco = cpl_array_get_data_double(polyfitco);
281 sigfit *= 100.0/nom_val;
282 freearray(workarray);
283 freearray(polyfitco);
287 cpl_table_set_double(lc,
"lin_10000_err",(cpl_size)i,sigfit);
288 cpl_table_set_double(lc,
"lin_10000",(cpl_size)i,lin_nom);
293 *lchantab = cpl_table_duplicate(lc);
294 cpl_array_unwrap(exparray);
295 freearray(medsarray);
296 freespace2(aco,norder);
302 cpl_msg_warning(fctid,
303 "%" CPL_SIZE_FORMAT
"channels have a failed solution",
355 int ndit,
int *status) {
356 int retval,i,norder,ii;
357 long naxis[2],j,rind,aind,ncpts,np;
358 float *data,texp,reset_time,read_time,delay_time;
359 double kfac_nom,lkfac,inval,outval,*lbb,dnd,*kfacs;
360 const char *fctid =
"vircam_lincor";
362 cpl_propertylist *plist;
368 if (*status != VIR_OK)
380 if (retval != VIR_OK)
388 cpl_msg_error(fctid,
"Error mapping data in input image");
399 cpl_msg_error(fctid,
"No exposure time in %s",
405 cpl_msg_error(fctid,
"No mindit time in %s",
409 read_time = reset_time;
412 cpl_msg_error(fctid,
"No dit delay time in %s",
419 kfac_nom = (double)(read_time/texp);
427 for (i = 0; i < np; i++) {
429 ncpts = (pp->delta_i)*(pp->delta_j);
442 kfacs = cpl_malloc(norder*
sizeof(
double));
445 for (ii = 1; ii < norder; ii++)
446 kfacs[ii] = pow((kfac_nom+1.0),(
double)(ii+1)) -
447 pow(kfac_nom,(
double)(ii+1));
452 for (j = 0; j < ncpts; j++) {
459 lkfac = getkfac(j,ncpts,reset_time,read_time,delay_time,texp);
461 for (ii = 1; ii < norder; ii++)
462 kfacs[ii] = pow((lkfac+1.0),(
double)(ii+1)) -
463 pow(lkfac,(
double)(ii+1));
468 inval = ((double)data[aind])/dnd;
469 outval = linval(inval,kfacs,0.5,10,lbb,norder);
470 data[aind] = (float)(dnd*outval);
518 static double linval(
double inval,
double *kfacs,
double tolerance,
519 int niter,
double *b,
int norder) {
521 double val_old,val,tol,sum;
525 tol = tolerance + 1.0;
526 while (iter < niter && tol > tolerance) {
530 for (jj = norder - 1; jj >= 1; jj--)
531 sum = (sum + b[jj]*kfacs[jj])*val;
534 tol = fabs(val - val_old);
538 }
else if (val < -1000.0) {
577 static double getkfac(
long index,
long npts,
float reset_time,
578 float read_time,
float delay_time,
float exptime) {
579 double tkfac,dt1,dt2,dt3,dt4,df;
581 df = ((double)index/(
double)npts);
582 dt1 = (double)exptime;
583 dt2 = (double)read_time;
584 dt3 = (double)reset_time;
585 dt4 = (double)delay_time;
586 tkfac = (dt3 + dt4 + (dt2 - dt3)*df)/dt1;
614 static void getco(
double *a,
int nord,
int m) {
617 for (i = 0; i < nord; i++)
622 for (i = start-1; i >= 0; i--) {
624 a[i] = a[i+1]*(double)(m - j + 2)/(double)(j-1);
cpl_table * vircam_tfits_get_table(vir_tfits *p)
int vircam_solve_gauss(double **a, double *b, int m)
int vircam_pfits_get_ditdelay(const cpl_propertylist *plist, float *ditdelay)
Get the value of dit delay time.
long vircam_chan_r2a(parquet *p, long naxis[2], long k)
int vircam_pfits_get_exptime(const cpl_propertylist *plist, float *exptime)
Get the value of exposure time.
int vircam_genlincur(double **fdata, int nimages, double *exps, double mindit, vir_tfits *chantab, int norder, cpl_table **lchantab, double **lindata, int *status)
Generate a linearity curve for each readout channel in a list of images.
int vircam_lincor(vir_fits *infile, vir_tfits *lchantab, int kconst, int ndit, int *status)
Apply linearity curves to data.
char * vircam_fits_get_fullname(vir_fits *p)
cpl_image * vircam_fits_get_image(vir_fits *p)
int vircam_pfits_get_mindit(const cpl_propertylist *plist, float *mindit)
Get the value of mindit time.
int vircam_polyfit(const cpl_array *xarray, const cpl_array *yarray, int ncoefs, int ilim, int niter, float lclip, float hclip, cpl_array **polycf, double *sigfit)
cpl_propertylist * vircam_fits_get_ehu(vir_fits *p)
int vircam_chan_fill(cpl_table *tab, parquet **p, long *np)
char * vircam_tfits_get_filename(vir_tfits *p)
long vircam_chan_d2r(parquet *p, long l)
void vircam_chan_free(int np, parquet **p)