00001 #define CVSVERSION "$Id: hmi_limbdark.c,v 1.11 2017/07/17 16:56:21 kehcheng Exp $"
00002
00043 #include "jsoc.h"
00044 #include "jsoc_main.h"
00045 #include "fstats.h"
00046 #include <math.h>
00047 #include <stdlib.h>
00048 #include <time.h>
00049
00050 char *module_name = "hmi_limbdark";
00051
00052 #define DIE(msg) {fflush(stdout);fprintf(stderr,"%s, status=%d\n",msg,status); return(status);}
00053
00054 #define Deg2Rad (M_PI/180.0)
00055 #define Rad2arcsec (3600.0/Deg2Rad)
00056 #define arcsec2Rad (Deg2Rad/3600.0)
00057 #define Rad2Deg (180.0/M_PI)
00058
00059 struct ObsInfo_struct
00060 {
00061
00062 TIME t_obs;
00063 double rsun_obs, obs_vr, obs_vw, obs_vn;
00064 double crpix1, crpix2, cdelt1, cdelt2, crota2;
00065 double crval1, crval2;
00066 double cosa, sina;
00067 double obs_b0;
00068
00069 int i,j;
00070
00071 double x,y,r;
00072 double rho;
00073 double lon;
00074 double lat;
00075 double sinlat, coslat;
00076 double sig;
00077 double mu;
00078 double chi;
00079 double obs_v;
00080 };
00081
00082 typedef struct ObsInfo_struct ObsInfo_t;
00083
00084 ObsInfo_t *GetObsInfo(DRMS_Segment_t *seg, ObsInfo_t *ObsLoc, int *status);
00085
00086 int GetObsLocInfo(DRMS_Segment_t *seg, int i, int j, ObsInfo_t *ObsLoc);
00087
00088 int rm_limbdark(DRMS_Array_t *arr, DRMS_Array_t *outarr, ObsInfo_t *ObsLoc, double *coefs, int *ncrop, int do_reverse, int do_norm, double crop_limit2);
00089
00090 int fit_limbdark(DRMS_Array_t *arr, ObsInfo_t *ObsLoc, double* coefs);
00091
00092 int upNcenter(DRMS_Array_t *data, ObsInfo_t *ObsLoc);
00093
00094
00095 int lsqfitd(double y[],double x[],double a[],int n,int np);
00096 double imprvd(double a[], double lu[], double x[], double b[], int n);
00097 int ludcmpd(double a[], int n);
00098 void bkslvd(double lu[], double b[], int n);
00099 int matinvd(double a[], int n);
00100 int matsold(double a[], double x[], double b[], int n);
00101
00102 ModuleArgs_t module_args[] =
00103 {
00104 {ARG_STRING, "in", "NOT SPECIFIED", "Input data series."},
00105 {ARG_STRING, "out", "NOT SPECIFIED", "Output data series."},
00106 {ARG_FLAG, "l", "0", "disable limb darkening removal, implied by -r"},
00107 {ARG_FLAG, "r", "0", "Restore limb darkening"},
00108 {ARG_FLAG, "f", "0", "Fit limb darkening before applying"},
00109 {ARG_FLAG, "n", "0", "Normalize the final image by dividing by the mean"},
00110 {ARG_FLAG, "c", "0", "Supress center and flip 180 degrees if CROTA~180."},
00111 {ARG_FLAG, "x", "0", "Exclude pixels that deviate from the default LD, <0.875 or >1.25."},
00112 {ARG_FLAG, "h", "0", "Include full headers, set when requestid is present"},
00113 {ARG_DOUBLES, "coefs", "0.0", "Limb darkening coeficients, 5 needed"},
00114 {ARG_FLOAT, "croplimit", "1.0", "crop limit for removing limbdarkening"},
00115 {ARG_STRING, "requestid", "NA", "JSOC export identifier"},
00116 {ARG_END}
00117 };
00118
00119 int DoIt(void)
00120 {
00121 int noLD = cmdparams_isflagset(&cmdparams, "l");
00122 int noFlip = cmdparams_isflagset(&cmdparams, "c");
00123 int restoreLD = cmdparams_isflagset(&cmdparams, "r");
00124 int do_fit = cmdparams_isflagset(&cmdparams, "f");
00125 int do_normalize = cmdparams_isflagset(&cmdparams, "n");
00126 int do_exclude = cmdparams_isflagset(&cmdparams, "x");
00127 const char *inQuery = params_get_str(&cmdparams, "in");
00128 const char *outSeries = params_get_str(&cmdparams, "out");
00129 const char *requestid = params_get_str(&cmdparams, "requestid");
00130 int full_headers = cmdparams_isflagset(&cmdparams, "h") || strcmp(requestid, "NA");
00131 float crop_limit = params_get_float(&cmdparams, "croplimit");
00132 double crop_limit2 = crop_limit*crop_limit;
00133 char *p;
00134 int status = 0;
00135 ObsInfo_t *ObsLoc;
00136
00137
00138
00139
00140 static double defaultcoefs[] = {1.0, 0.459224, 0.132395, 0.019601, 0.000802, -4.31934E-05 };
00141 char *CoefVersion = "2";
00142
00143 double use_coefs[6];
00144 double n_user_coefs = cmdparams_get_int(&cmdparams, "coefs_nvals", &status);
00145
00146 int nrecs, irec;
00147 DRMS_RecordSet_t *inRS, *outRS;
00148
00149 if (strcmp(inQuery, "NOT SPECIFIED") == 0)
00150 DIE("Must have input series");;
00151 if (strcmp(outSeries, "NOT SPECIFIED") == 0)
00152 DIE("Must have output series");;
00153
00154 printf("FitLimbDark\n");
00155 if (n_user_coefs == 6)
00156 {
00157 double *cmdcoefs;
00158 int i;
00159 CoefVersion = "user given";
00160 cmdparams_get_dblarr(&cmdparams, "coefs", &cmdcoefs, &status);
00161 for (i=0; i<6; i++)
00162 {
00163 use_coefs[i] = cmdcoefs[i];
00164 printf(" Coef%d = %0.6f\n", i, use_coefs[i]);
00165 }
00166 }
00167 else
00168 {
00169 int i;
00170 for (i=0; i<6; i++)
00171 use_coefs[i] = defaultcoefs[i];
00172 printf(" Use default coefs\n");
00173 }
00174
00175 if (restoreLD) noLD = 1;
00176 if (noLD)
00177 printf(" Supress limb darkening removal\n");
00178
00179 inRS = drms_open_records(drms_env, inQuery, &status);
00180 if (status || !inRS || (nrecs = inRS->n) == 0)
00181 DIE("No input records found");
00182
00183 outRS = drms_create_records(drms_env, nrecs, (char *)outSeries, DRMS_PERMANENT, &status);
00184 if (status || !outRS)
00185 DIE("Failed to create output recordset");
00186
00187 for (irec=0; irec<nrecs; irec++)
00188 {
00189 DRMS_Record_t *inRec = inRS->records[irec];
00190 DRMS_Record_t *outRec;
00191 int quality = drms_getkey_int(inRec, "QUALITY", NULL);
00192 ObsInfo_t *ObsLoc;
00193
00194 outRec = outRS->records[irec];
00195 drms_copykeys(outRec, inRec, 0, kDRMS_KeyClass_Explicit);
00196 drms_copykey(outRec, inRec, "T_REC");
00197 drms_copykey(outRec, inRec, "T_OBS");
00198 drms_copykey(outRec, inRec, "QUALITY");
00199 drms_setkey_time(outRec, "DATE", time(0) + UNIX_EPOCH);
00200 drms_setkey_string(outRec, "RequestID", requestid);
00201 drms_setkey_string(outRec, "CODEVER4", CVSVERSION);
00202
00203 if (quality >= 0)
00204 {
00205 double mean=1.0;
00206 double coefs[6];
00207 DRMS_Segment_t *inSeg, *outSeg;
00208 DRMS_Array_t *inArray, *outArray;
00209 int ncropped = 0;
00210 inSeg = drms_segment_lookupnum(inRec, 0);
00211 inArray = drms_segment_read(inSeg, DRMS_TYPE_FLOAT, &status);
00212 if (status)
00213 {
00214 printf(" No data file found but QUALITY not bad, status=%d\n", status);
00215 drms_free_array(inArray);
00216 continue;
00217 }
00218
00219 ObsLoc = GetObsInfo(inSeg, NULL, &status);
00220 if (status)
00221 DIE("Failed to get observatory location.");
00222
00223
00224 if (do_fit)
00225 {
00226 if (do_exclude )
00227 {
00228 DRMS_Array_t *xArray = drms_array_create(DRMS_TYPE_FLOAT, inArray->naxis, inArray->axis, NULL, &status);
00229 DRMS_Array_t *inxArray = drms_array_create(DRMS_TYPE_FLOAT, inArray->naxis, inArray->axis, NULL, &status);
00230 float *iv = (float*)inArray->data;
00231 float *v = (float*)xArray->data;
00232 float *nv = (float*)inxArray->data;
00233 int i, n = inArray->axis[0] * inArray->axis[1];
00234 int nskip = 0;
00235 float missval = DRMS_MISSING_FLOAT;
00236 rm_limbdark(inArray, xArray, ObsLoc, use_coefs, &ncropped, 0, 1, crop_limit2);
00237 for (i=0; i<n; i++, v++, iv++)
00238 if (!isnan(*v) && *v > 0.850 && *v < 1.150)
00239 *nv++ = *iv;
00240 else
00241 {
00242 *nv++ = missval;
00243 if (!isnan(*v))
00244 nskip++;
00245 }
00246 printf("exclude %d pixels\n", nskip);
00247 fit_limbdark(inxArray, ObsLoc, coefs);
00248 drms_free_array(xArray);
00249 drms_free_array(inxArray);
00250 }
00251 else
00252 fit_limbdark(inArray, ObsLoc, coefs);
00253 }
00254
00255 outSeg = drms_segment_lookupnum(outRec, 0);
00256 outArray = drms_array_create(DRMS_TYPE_FLOAT, inArray->naxis, inArray->axis, NULL, &status);
00257
00258 if (rm_limbdark(inArray, outArray, ObsLoc, (do_fit ? coefs : use_coefs), &ncropped, restoreLD, do_normalize, crop_limit2) == DRMS_SUCCESS)
00259 {
00260 int totvals, datavals;
00261
00262 if (drms_keyword_lookup(outRec, "COEF_VER", 0))
00263 {
00264 drms_setkey_string(outRec, "COEF_VER", CoefVersion);
00265 drms_setkey_float(outRec, "LDCoef0", (float)(do_fit ? coefs[0] : use_coefs[0]));
00266 drms_setkey_float(outRec, "LDCoef1", (float)(do_fit ? coefs[1] : use_coefs[1]));
00267 drms_setkey_float(outRec, "LDCoef2", (float)(do_fit ? coefs[2] : use_coefs[2]));
00268 drms_setkey_float(outRec, "LDCoef3", (float)(do_fit ? coefs[3] : use_coefs[3]));
00269 drms_setkey_float(outRec, "LDCoef4", (float)(do_fit ? coefs[4] : use_coefs[4]));
00270 drms_setkey_float(outRec, "LDCoef5", (float)(do_fit ? coefs[5] : use_coefs[5]));
00271 }
00272 else
00273 {
00274 char LDhistory[1000];
00275 sprintf(LDhistory, "hmi_limbdark: COEF_VER=%s", CoefVersion);
00276 drms_appendhistory(outRec, LDhistory, 0);
00277 sprintf(LDhistory, "LDCoefs=%0.6f,%0.6f,%0.6f,%0.6f,%0.6f,%0.6f",
00278 (float)(do_fit ? coefs[0] : use_coefs[0]),
00279 (float)(do_fit ? coefs[1] : use_coefs[1]),
00280 (float)(do_fit ? coefs[2] : use_coefs[2]),
00281 (float)(do_fit ? coefs[3] : use_coefs[3]),
00282 (float)(do_fit ? coefs[4] : use_coefs[4]),
00283 (float)(do_fit ? coefs[5] : use_coefs[5]));
00284 drms_appendhistory(outRec, LDhistory, 1);
00285 }
00286 if (!noFlip)
00287 upNcenter(outArray, ObsLoc);
00288 drms_setkey_double(outRec, "CRPIX1", ObsLoc->crpix1);
00289 drms_setkey_double(outRec, "CRPIX2", ObsLoc->crpix2);
00290 drms_setkey_double(outRec, "CROTA2", ObsLoc->crota2);
00291
00292 if (do_normalize)
00293 {
00294 outArray->bzero = 1.0;
00295 outArray->bscale= 1.0/30000.0;
00296 }
00297 else
00298 {
00299 outArray->bzero = 32768.0;
00300 outArray->bscale=1.5;
00301 }
00302
00303 set_statistics(outSeg, outArray, 1);
00304 totvals = drms_getkey_int(outRec, "TOTVALS", &status);
00305 if (!status)
00306 {
00307 datavals = drms_getkey_int(outRec, "DATAVALS", &status);
00308 totvals -= ncropped;
00309 drms_setkey_int(outRec, "TOTVALS", totvals);
00310 drms_setkey_int(outRec, "MISSVALS", totvals - datavals);
00311 }
00312
00313 if (full_headers)
00314 drms_segment_writewithkeys(outSeg, outArray, 0);
00315 else
00316 drms_segment_write(outSeg, outArray, 0);
00317 drms_free_array(inArray);
00318 drms_free_array(outArray);
00319 }
00320
00321 }
00322 else
00323 printf("Skip Rec %d, Quality=%#08x\n", irec, quality);
00324 }
00325 drms_close_records(outRS, DRMS_INSERT_RECORD);
00326 drms_close_records(inRS, DRMS_FREE_RECORD);
00327 return (DRMS_SUCCESS);
00328 }
00329
00330 int fit_limbdark(DRMS_Array_t *arr, ObsInfo_t *ObsLoc, double* coefs)
00331 {
00332 int status = 0;
00333 double x0 = ObsLoc->crpix1 - 1;
00334 double y0 = ObsLoc->crpix2 - 1;
00335 double rsun = ObsLoc->rsun_obs/ObsLoc->cdelt1;
00336
00337 int ix, iy;
00338 int nx = arr->axis[0];
00339 int ny = arr->axis[1];
00340 double scale;
00341 double crop_limit2;
00342 float *data = (float*)arr->data;
00343 float missval = DRMS_MISSING_FLOAT;
00344 int n;
00345 int ord;
00346 double *f = (double *)malloc(nx*ny*sizeof(double));
00347 double *c = (double *)malloc(6*nx*ny*sizeof(double));
00348 double fitcoefs[6];
00349
00350 if (!f || !c) DIE("malloc problem");
00351
00352 scale = 1.0/rsun;
00353 crop_limit2 = 0.99975;
00354
00355 n = 0;
00356 for (iy=0; iy<ny; iy++)
00357 for (ix=0; ix<nx; ix++)
00358 {
00359 double costheta2;
00360 double xi, mu, z, ld;
00361 double x, y, R2;
00362 float *Ip = data + iy*nx + ix;
00363
00364 if (drms_ismissing_float(*Ip))
00365 continue;
00366
00367
00368 x = ((double)ix - x0) * scale;
00369 y = ((double)iy - y0) * scale;
00370
00371
00372 R2 = x*x + y*y;
00373
00374 if (R2 >= crop_limit2)
00375 continue;
00376
00377 costheta2 = 1.0 - R2;
00378 mu = sqrt(costheta2);
00379 xi = log(mu);
00380 z = 1.0;
00381 f[n] = *Ip;
00382 c[6*n + 0] = 1.0;
00383 for (ord=1; ord<6; ord++)
00384 {
00385 z *= xi;
00386 c[6*n + ord] = z;
00387 }
00388 n++;
00389 }
00390 if (!lsqfitd(f, c, fitcoefs, 5, n))
00391 {
00392 fprintf(stderr,"lsqfit failure\n");
00393 fitcoefs[0] = fitcoefs[1] = fitcoefs[2] = fitcoefs[3] = fitcoefs[4] = fitcoefs[5] = DRMS_MISSING_DOUBLE;
00394 }
00395 printf("Fit %d points, Coefs = %0.6f", n, fitcoefs[0]);
00396 for (ord=0; ord<6; ord++)
00397 {
00398 coefs[ord] = fitcoefs[ord]/fitcoefs[0];
00399 printf(", %8.6f", coefs[ord]);
00400 }
00401 printf("\n");
00402 coefs[0] = fitcoefs[0];
00403 free(f);
00404 free(c);
00405 return(0);
00406 }
00407
00408 int rm_limbdark(DRMS_Array_t *arr, DRMS_Array_t *outarr, ObsInfo_t *ObsLoc, double *coefs, int *ncrop, int do_reverse, int do_norm, double crop_limit2)
00409 {
00410 double x0 = ObsLoc->crpix1 - 1;
00411 double y0 = ObsLoc->crpix2 - 1;
00412 double rsun = ObsLoc->rsun_obs/ObsLoc->cdelt1;
00413
00414 int ix, iy;
00415 int nx = arr->axis[0];
00416 int ny = arr->axis[1];
00417 double scale;
00418 float *data = (float *)arr->data;
00419 float *odata = (float *)outarr->data;
00420 float missval = DRMS_MISSING_FLOAT;
00421 int ncropped = 0;
00422
00423 scale = 1.0/rsun;
00424
00425 for (iy=0; iy<ny; iy++)
00426 for (ix=0; ix<nx; ix++)
00427 {
00428 double costheta2;
00429 double xi, mu, z, ld;
00430 double x, y, R2;
00431 int ord;
00432 float *Ip = data + iy*nx + ix;
00433 float *Op = odata + iy*nx + ix;
00434
00435 if (drms_ismissing_float(*Ip))
00436 {
00437 *Op = missval;
00438 continue;
00439 }
00440
00441
00442 x = ((double)ix - x0) * scale;
00443 y = ((double)iy - y0) * scale;
00444
00445
00446 R2 = x*x + y*y;
00447
00448 if (R2 >= crop_limit2)
00449 {
00450 *Op = missval;
00451 ncropped++;
00452 continue;
00453 }
00454
00455 if (R2 < 0.99975)
00456 costheta2 = 1.0 - R2;
00457 else
00458 costheta2 = 1.0 - 0.99975;
00459
00460 mu = sqrt(costheta2);
00461 xi = log(mu);
00462 z = 1.0;
00463 ld = 1.0;
00464 for (ord=1; ord<6; ord++)
00465 {
00466 z *= xi;
00467 ld += coefs[ord] * z;
00468 }
00469 if (ld <= 0.0)
00470 {
00471 *Op = missval;
00472 ncropped++;
00473 }
00474 else if (do_reverse)
00475 *Op = *Ip * ld;
00476 else
00477 *Op = *Ip / ld;
00478 }
00479 *ncrop = ncropped;
00480 if (do_norm)
00481 {
00482 double mean;
00483 float *v = odata;
00484 int i, n = outarr->axis[0] * outarr->axis[1];
00485 if (coefs[0] == 1.0)
00486 {
00487 int nok=0;
00488 v = odata;
00489 for (i=0; i<n; i++, v++)
00490 if (!isnan(*v))
00491 { nok++; mean += *v; }
00492 if (nok)
00493 mean /= nok;
00494 else
00495 mean = 1.0;
00496 }
00497 else
00498 mean = coefs[0];
00499 v = odata;
00500 for (i=0; i<n; i++, v++)
00501 if (!isnan(*v))
00502 *v /= mean;
00503 }
00504 return(0);
00505 }
00506
00507 #define CHECK(keyname) {if (status) {fprintf(stderr,"Keyword failure to find: %s, status=%d\n",keyname,status); *rstatus=status; return(NULL);}}
00508
00509 ObsInfo_t *GetObsInfo(DRMS_Segment_t *seg, ObsInfo_t *pObsLoc, int *rstatus)
00510 {
00511 TIME t_prev;
00512 DRMS_Record_t *rec;
00513 TIME t_obs;
00514 double dv;
00515 ObsInfo_t *ObsLoc;
00516 int status;
00517
00518 if (!seg || !(rec = seg->record))
00519 { *rstatus = 1; return(NULL); }
00520
00521 ObsLoc = (pObsLoc ? pObsLoc : (ObsInfo_t *)malloc(sizeof(ObsInfo_t)));
00522 if (!pObsLoc)
00523 memset(ObsLoc, 0, sizeof(ObsInfo_t));
00524
00525 t_prev = ObsLoc->t_obs;
00526 t_obs = drms_getkey_time(rec, "T_OBS", &status); CHECK("T_OBS");
00527
00528 if (t_obs <= 0.0)
00529 { *rstatus = 2; return(NULL); }
00530
00531 if (t_obs != t_prev)
00532 {
00533 ObsLoc->crpix1 = drms_getkey_double(rec, "CRPIX1", &status); CHECK("CRPIX1");
00534 ObsLoc->crpix2 = drms_getkey_double(rec, "CRPIX2", &status); CHECK("CRPIX2");
00535 ObsLoc->crval1 = drms_getkey_double(rec, "CRVAL1", &status); CHECK("CRVAL1");
00536 ObsLoc->crval2 = drms_getkey_double(rec, "CRVAL2", &status); CHECK("CRVAL2");
00537 ObsLoc->cdelt1 = drms_getkey_double(rec, "CDELT1", &status); CHECK("CDELT1");
00538 ObsLoc->cdelt2 = drms_getkey_double(rec, "CDELT2", &status); CHECK("CDELT1");
00539 ObsLoc->crota2 = drms_getkey_double(rec, "CROTA2", &status); CHECK("CROTA2");
00540 ObsLoc->sina = sin(ObsLoc->crota2*Deg2Rad);
00541 ObsLoc->cosa = sqrt (1.0 - ObsLoc->sina*ObsLoc->sina);
00542 ObsLoc->rsun_obs = drms_getkey_double(rec, "RSUN_OBS", &status);
00543 if (status)
00544 {
00545 double dsun_obs = drms_getkey_double(rec, "DSUN_OBS", &status); CHECK("DSUN_OBS");
00546 ObsLoc->rsun_obs = asin(696000000.0/dsun_obs)/arcsec2Rad;
00547 }
00548 ObsLoc->obs_vr = drms_getkey_double(rec, "OBS_VR", &status); CHECK("OBS_VR");
00549 ObsLoc->obs_vw = drms_getkey_double(rec, "OBS_VW", &status); CHECK("OBS_VW");
00550 ObsLoc->obs_vn = drms_getkey_double(rec, "OBS_VN", &status); CHECK("OBS_VN");
00551 ObsLoc->obs_b0 = drms_getkey_double(rec, "CRLT_OBS", &status); CHECK("CRLT_OBS");
00552 ObsLoc->t_obs = t_obs;
00553 }
00554 *rstatus = 0;
00555 return(ObsLoc);
00556 }
00557
00558
00559 int upNcenter(DRMS_Array_t *arr, ObsInfo_t *ObsLoc)
00560 {
00561 int nx, ny, ix, iy, i, j, xoff, yoff;
00562 double rot, x0, y0, mid;
00563 float *data;
00564 if (!arr || !ObsLoc)
00565 return(1);
00566 data = (float *)arr->data;
00567 nx = arr->axis[0];
00568 ny = arr->axis[1];
00569 x0 = ObsLoc->crpix1 - 1;
00570 y0 = ObsLoc->crpix2 - 1;
00571 mid = (nx-1.0)/2.0;
00572 if ((rot = fabs(ObsLoc->crota2)) > 179 && rot < 181)
00573 {
00574
00575 float val;
00576 int half = ny / 2;
00577 int odd = ny & 1;
00578 for (iy=0; iy<half; iy++)
00579 {
00580 for (ix=0; ix<nx; ix++)
00581 {
00582 i = iy*nx + ix;
00583 j = (ny - 1 - iy)*nx + (nx - 1 - ix);
00584 val = data[i];
00585 data[i] = data[j];
00586 data[j] = val;
00587 }
00588 }
00589
00590 if (odd) {
00591 for (ix=0; ix<nx/2; ++ix) {
00592 i = nx*half + ix;
00593 j = nx*half + nx - ix - 1;
00594 val = data[i];
00595 data[i] = data[j];
00596 data[j] = val;
00597 }
00598 }
00599 x0 = nx - x0;
00600 y0 = ny - y0;
00601 rot = ObsLoc->crota2 - 180.0;
00602 if (rot < -90.0) rot += 360.0;
00603 ObsLoc->crota2 = rot;
00604 }
00605 xoff = round(x0 - mid);
00606 yoff = round(y0 - mid);
00607 if (abs(xoff) > 1.0)
00608 {
00609 for (iy=0; iy<ny; iy++)
00610 {
00611 float valarr[nx];
00612 for (ix=0; ix<nx; ix++)
00613 {
00614 int jx = ix - xoff;
00615 if (jx >= nx) jx -= nx;
00616 if (jx < 0) jx += nx;
00617 valarr[jx] = data[iy*nx + ix];
00618 }
00619 for (ix=0; ix<nx; ix++)
00620 data[iy*nx + ix] = valarr[ix];
00621 }
00622 x0 -= xoff;
00623 }
00624 if (abs(yoff) > 1.0)
00625 {
00626 for (ix=0; ix<nx; ix++)
00627 {
00628 float valarr[ny];
00629 for (iy=0; iy<ny; iy++)
00630 {
00631 int jy = iy - yoff;
00632 if (jy >= ny) jy -= ny;
00633 if (jy < 0) jy += ny;
00634 valarr[jy] = data[iy*nx + ix];
00635 }
00636 for (iy=0; iy<ny; iy++)
00637 data[iy*nx + ix] = valarr[iy];
00638 }
00639 y0 -= yoff;
00640 }
00641 ObsLoc->crpix1 = x0 + 1;
00642 ObsLoc->crpix2 = y0 + 1;
00643 return(0);
00644 }
00645
00646
00647
00648 #define ITMAX 7
00649 #define EPS 2.8e-17
00650
00651
00652
00653
00654
00655
00656
00657
00658 int matsold(double a[], double x[], double b[], int n)
00659 {
00660 double *lu, err, wrk, wrk1;
00661 extern double imprvd();
00662 int k;
00663
00664
00665
00666
00667
00668 lu = (double *)malloc( (n*n*8) );
00669
00670
00671
00672
00673
00674 {
00675 double *src = &a[0];
00676 double *dest = lu;
00677 int i = (n*n);
00678
00679 do
00680 {
00681 *(dest++) = *(src++);
00682 } while(--i);
00683 }
00684
00685
00686
00687
00688
00689 if(ludcmpd(lu, n) == 0)
00690 {
00691 free(lu);
00692 return(0);
00693 }
00694
00695
00696
00697
00698
00699
00700 {
00701 int i;
00702 double *dest = x;
00703 double *src = b;
00704
00705
00706
00707
00708
00709 i = n;
00710 do
00711 {
00712 *(dest++) = *(src++);
00713 }while(--i);
00714
00715
00716
00717
00718
00719 bkslvd(lu, x, n);
00720
00721 for(k=0;k<ITMAX;k++)
00722 {
00723 err = imprvd(a,lu,x,b,n);
00724 wrk = 0.0;
00725 src = x;
00726 i = n;
00727 do
00728 {
00729 wrk1 = (*src < 0.0) ? -(*src++) : *(src++);
00730 wrk = (wrk < wrk1) ? wrk1 : wrk;
00731 }while(--i);
00732 wrk1 = err/wrk;
00733 if(wrk1 < EPS)break;
00734 }
00735
00736 }
00737
00738
00739
00740
00741
00742 free(lu);
00743 return(1);
00744 }
00745
00746
00747
00748
00749
00750
00751
00752 int matinvd(double a[], int n)
00753 {
00754 double *ainv, *lu, *x, *b, err, wrk, wrk1;
00755 extern double imprvd();
00756 int j, k;
00757
00758
00759
00760
00761
00762
00763 ainv = (double *)malloc( (n*n*8) );
00764 lu = (double *)malloc( (n*n*8) );
00765 x = (double *)malloc( (n*8) );
00766 b = (double *)malloc( (n*8) );
00767
00768
00769
00770
00771
00772 {
00773 double *src = &a[0];
00774 double *dest = lu;
00775 int i = (n*n);
00776
00777 do
00778 {
00779 *(dest++) = *(src++);
00780 } while(--i);
00781 }
00782
00783
00784
00785
00786
00787 if(ludcmpd(lu, n) == 0)
00788 {
00789 free(ainv);
00790 free(lu);
00791 free(x);
00792 free(b);
00793 return(0);
00794 }
00795
00796
00797
00798
00799
00800
00801 for(j = 0;j<n;j++)
00802 {
00803 int i;
00804 double *dest = b;
00805 double *src = x;
00806
00807
00808
00809
00810
00811
00812 i = n;
00813 do
00814 {
00815 *(dest++) = 0.0;
00816 *(src++) = 0.0;
00817 }while(--i);
00818 b[j] = x[j] = 1.0;
00819
00820
00821
00822
00823
00824 bkslvd(lu, x, n);
00825
00826 for(k=0;k<ITMAX;k++)
00827 {
00828 err = imprvd(a,lu,x,b,n);
00829 wrk = 0.0;
00830 src = x;
00831 i = n;
00832 do
00833 {
00834 wrk1 = (*src < 0.0) ? -(*src++) : *(src++);
00835 wrk = (wrk < wrk1) ? wrk1 : wrk;
00836 }while(--i);
00837 wrk1 = err/wrk;
00838 if(wrk1 < EPS)break;
00839 }
00840
00841
00842
00843
00844
00845 src = x;
00846 dest = &ainv[j];
00847 i = n;
00848 do
00849 {
00850 *dest = *(src++);
00851 dest += n;
00852 }while(--i);
00853 }
00854 {
00855 int i = n*n;
00856 double *src = ainv;
00857 double *dest = &a[0];
00858
00859
00860
00861
00862
00863 do
00864 {
00865 *(dest++) = *(src++);
00866 }while(--i);
00867 }
00868
00869
00870
00871
00872
00873 free(ainv);
00874 free(lu);
00875 free(x);
00876 free(b);
00877 return(1);
00878 }
00879
00880
00881
00882
00883
00884
00885 void bkslvd(double lu[], double b[], int n)
00886 {
00887 int i, k;
00888
00889
00890
00891
00892
00893 for(i=0;i<(n-1);i++)
00894 {
00895 int j = n-1-i;
00896 double *lower = &lu[i*(n+1)+n];
00897 double *current = &b[i+1];
00898 double first = b[i];
00899
00900 do
00901 {
00902
00903 *(current++) -= first*(*lower);
00904 lower += n;
00905 } while(--j);
00906 }
00907
00908
00909
00910
00911
00912 for(i = n-1;i >= 0;i--)
00913 {
00914 double *factor = &lu[n*i + i + 1];
00915 double *vector = &b[i+1];
00916 double *current = &b[i];
00917
00918 for(k=i;k<n-1;k++)
00919 {
00920 *current -= *(factor++)*(*(vector++));
00921 }
00922 *current /= lu[n*i+i];
00923 }
00924 return;
00925 }
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935 int ludcmpd(double a[], int n)
00936 {
00937 double wrk;
00938 int i, j;
00939
00940 for(i=0;i<(n-1);i++)
00941 {
00942 if(a[i+n*i] != 0.0)wrk = 1.0/a[i+n*i];
00943 else return(0);
00944 for(j=i+1;j<n;j++)
00945 {
00946 double *first = &a[i+1+n*i];
00947 double *row = &a[i+1+n*j];
00948 int k = n-(i+1);
00949 double elim = a[i+n*j]*wrk;
00950
00951
00952 a[i+n*j] = elim;
00953
00954
00955
00956
00957
00958
00959
00960
00961 do
00962 {
00963 *(row++) -= *(first++)*elim;
00964 }while(--k);
00965 }
00966 }
00967 return(1);
00968 }
00969
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979 double imprvd(double a[], double lu[], double x[], double b[], int n)
00980 {
00981 double *berr, err;
00982 int i;
00983
00984 berr = (double *)malloc( (n*8) );
00985 err = 0.0;
00986
00987
00988
00989
00990 for(i=0;i<n;i++)
00991 {
00992 int j = n;
00993 double *vector = &x[0];
00994 double *row = &a[n*i];
00995 double accum = 0.0;
00996
00997 do
00998 {
00999 accum += (*(vector++))*(*(row++));
01000 }while(--j);
01001 berr[i] = b[i] - accum;
01002
01003 accum = (berr[i] < 0) ? -berr[i] : berr[i];
01004 err = (err < accum) ? accum : err;
01005 }
01006
01007 bkslvd(lu, berr, n);
01008 for(i=0;i<n;i++)x[i] += berr[i];
01009 free(berr);
01010 return(err);
01011 }
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022
01023
01024
01025
01026
01027
01028
01029
01030
01031
01032
01033
01034
01035
01036
01037
01038
01039
01040
01041
01042
01043 int lsqfitd(double y[],double x[],double a[],int n,int np)
01044 {
01045 double *ar, *lu, *sx, *xm, *r;
01046 int i, k;
01047 double f1, ym, sum, s, wmi;
01048 extern double sqrt(), imprvd();
01049
01050
01051
01052
01053
01054
01055
01056
01057
01058
01059
01060
01061
01062
01063
01064
01065 if (np < 3)
01066 return(0);
01067 ar = (double *)malloc( n*n*8 );
01068 lu = (double *)malloc( n*n*8 );
01069 sx = (double *)malloc( n*8 );
01070 xm = (double *)malloc( n*8 );
01071 r = (double *)malloc( n*8 );
01072
01073 sum = ym = s = 0.0;
01074
01075 for(i=0;i<n;i++)
01076 {
01077 double *dp = &ar[i*n];
01078 int j = n;
01079
01080 r[i] = 0.0;
01081 do
01082 {
01083 *(dp)++ = 0.0;
01084 }while(--j);
01085 }
01086 {
01087
01088 double *dp1 = &sx[0];
01089 double *dp2 = &xm[0];
01090 int j = n;
01091
01092 do
01093 {
01094 *(dp1++) = 0.0;
01095 *(dp2++) = 0.0;
01096 }while(--j);
01097 }
01098
01099
01100
01101
01102 for(i=0;i<np;i++)
01103 {
01104 double *dp1 = &xm[0];
01105 double *dp2 = &x[(n+1)*i];
01106 int j = n;
01107 double wi;
01108
01109 wi = *(dp2++);
01110 sum += wi;
01111 ym += wi*y[i];
01112 do
01113 {
01114 *(dp1++) += wi*(*(dp2++));
01115 }while(--j);
01116 }
01117
01118 if(sum == 0.0)
01119 {
01120 free(ar);
01121 free(lu);
01122 free(sx);
01123 free(xm);
01124 free(r);
01125 return(0);
01126 }
01127
01128
01129 ym /= sum;
01130 wmi = ((double)np)/sum;
01131 for(i=0;i<n;i++)xm[i] /= sum;
01132
01133
01134
01135
01136 for(i=0;i<np;i++)
01137 {
01138 double fy, wi;
01139
01140 wi = x[i*(n+1)]*wmi;
01141 fy = y[i] - ym;
01142 s += wi*fy*fy;
01143 for(k=0;k<n;k++)
01144 {
01145 double *dp1 = &ar[k];
01146 double *dp2 = &ar[n*k];
01147 double *dp3 = &xm[0];
01148 double *dp4 = &x[i*(n+1)+1];
01149 int j;
01150 double fx;
01151
01152 fx = *(dp4+k) - *(dp3+k);
01153 sx[k]+= wi*fx*fx;
01154 r[k] += wi*fx*fy;
01155
01156 for(j=0;j<=k;j++)
01157 {
01158 *dp2 += wi*fx*(*(dp4++) - *(dp3++));
01159 *dp1 = *(dp2++);
01160 dp1 += n;
01161 }
01162 }
01163 }
01164
01165
01166
01167
01168
01169 f1 = np - 1.0;
01170 s = sqrt(s/f1);
01171 for(i=0;i<n;i++)
01172 {
01173 double *dp1 = &ar[i];
01174 double *dp2 = &ar[i*n];
01175 double *dp3 = &sx[i];
01176 int j;
01177 double sxj;
01178
01179 *dp3 = sqrt(*dp3/f1);
01180 sxj = *dp3;
01181 r[i] /= f1*(*dp3)*s;
01182 dp3 = &sx[0];
01183
01184 for(j=0;j<=i;j++)
01185 {
01186 if (*dp3 == 0.0)
01187 return(0);
01188 *dp2 /= f1*(*(dp3++))*sxj;
01189 *dp1 = *(dp2++);
01190 dp1 += n;
01191 }
01192 }
01193
01194
01195
01196
01197
01198
01199 {
01200 double *dp1 = &ar[0];
01201 double *dp2 = &lu[0];
01202 int j = n*n;
01203
01204 do
01205 {
01206 *(dp2++) = *(dp1++);
01207 }while(--j);
01208 }
01209
01210 if(ludcmpd(lu, n) == 0)
01211 {
01212 free(ar);
01213 free(lu);
01214 free(sx);
01215 free(xm);
01216 free(r);
01217 return(0);
01218 }
01219
01220
01221
01222 {
01223 double *dp1 = &a[1];
01224 double *dp2 = &r[0];
01225 int j = n;
01226
01227 do
01228 {
01229 *(dp1++) = *(dp2++);
01230 }while(--j);
01231 }
01232
01233
01234
01235 bkslvd(lu, &a[1], n);
01236
01237
01238
01239 for(i=0;i<ITMAX;i++)
01240 if(imprvd(ar, lu, &a[1], r, n) < EPS)break;
01241
01242
01243
01244 {
01245 double *dp1 = &a[0];
01246 double *dp2 = &sx[0];
01247 double *dp3 = &xm[0];
01248 int j;
01249
01250 *(dp1++) = ym;
01251 for(j=0;j<n;j++)
01252 {
01253 *dp1 *= s;
01254 *dp1 /= *(dp2++);
01255 a[0] -= (*(dp1++))*(*(dp3++));
01256 }
01257 }
01258
01259
01260 free(ar);
01261 free(lu);
01262 free(sx);
01263 free(xm);
01264 free(r);
01265
01266 return(1);
01267 }
01268
01269
01270
01271
01272
01273
01274
01275
01276
01277
01278
01279
01280
01281
01282
01283
01284
01285
01286
01287
01288
01289
01290
01291
01292
01293
01294
01295
01296
01297
01298
01299
01300
01301
01302
01303
01304
01305
01306
01307
01308
01309
01310
01311
01312
01313
01314
01315
01316
01317
01318
01319
01320
01321
01322
01323
01324
01325
01326
01327
01328
01329
01330
01331
01332
01333
01334
01335
01336
01337
01338