00001
00002
00003 #include <stdio.h>
00004 #include <stdlib.h>
00005 #include <time.h>
00006 #include <math.h>
00007 #include <sys/time.h>
00008 #include <sys/resource.h>
00009 #include "jsoc_main.h"
00010 #include "astro.h"
00011 #include "drms_dsdsapi.h"
00012 #include "soi_ephem.h"
00013 #include "/home/wso/src/libastro.d/solephem.c"
00014 #include "fstats.h"
00015
00016 #define C1 0.0757644
00017 #define C2 92353.9357
00018 #define RADSINDEG (PI/180)
00019
00020
00021 #define kRecSetIn "in"
00022 #define kSeriesOut "out"
00023 #define kSegIn "segin"
00024 #define kSegOut "segout"
00025 #define kNOTSPECIFIED "not specified"
00026
00027 #define EQPOINTS "EQPOINTS"
00028 #define HALFWIN "HALFWIN"
00029 #define LOSFLAG "l"
00030 #define FORCEFLAG "f"
00031 #define DLOGFLAG "d"
00032 #define NOISESIGMA "NOISESIGMA"
00033 #define MAXNOISEADJ "MAXNOISEADJ"
00034
00035
00036 #define MINOUTLIERPTS "MINOUTLIERPTS"
00037
00038
00039
00040 #define DPC_OBSR "DPC_OBSR"
00041 #define FD_Magnetogram_Sum "FD_Magnetogram_Sum"
00042 #define FD_Magnetogram "FD_Magnetogram"
00043 #define HWNWIDTH "HWNWIDTH"
00044
00045
00046 #define kCARSTRCH "CARSTRCH"
00047 #define kDIFROT_A "DIFROT_A"
00048 #define kDIFROT_B "DIFROT_B"
00049 #define kDIFROT_C "DIFROT_C"
00050 #define CR "CR"
00051
00052 const float kOutScale = 0.1;
00053 const int kOutBPP = 16;
00054 const float kNOISE_EQ = 20.0;
00055 const float sensAdjVal = 1.8;
00056
00057 enum MagAggregate_t
00058 {
00059 kOneMinuteValue = 0,
00060 kFiveMinuteValue = 1
00061 };
00062
00063 float gMagAgg[] =
00064 {
00065 1.0,
00066 2.75
00067 };
00068
00069 char *module_name = "mdisynop";
00070
00071 #define DIE(msg) {fflush(stdout); fprintf(stderr,"%s, status=%d\n", msg, status); return(status);}
00072
00073
00074
00075
00076
00077
00078
00079 typedef struct MagCol_struct
00080 {
00081 float dist;
00082 float *datacol;
00083 float equivPts;
00084 int ds;
00085 int sn;
00086 int col;
00087 char valid;
00088 } MagCol_t;
00089
00090
00091
00092
00093
00094 int CalcSynCols(int start,
00095 int end,
00096 int incr,
00097 MagCol_t **smc,
00098 float *synop,
00099 int *wt,
00100 char *ww,
00101 float *epts,
00102 float *losSynop,
00103 int *len,
00104 float center,
00105 float nEquivPtsReq,
00106 int los,
00107 int radialFound,
00108 float sensAdj,
00109 float noiseS,
00110 float nsig,
00111 float maxNoiseAdj,
00112 int minOutPts,
00113 int dlog);
00114
00115 int magStats(float **val, int npts, double sum, int outThreshold, double *avg, float *med);
00116 void SortMagCols(MagCol_t *mc, int nelem);
00117 void FreeMagColsData(int start, int end, int incr, int *n, MagCol_t **mc);
00118 TIME CarringtonTime(int crot, double L);
00119
00120 ModuleArgs_t module_args[] =
00121 {
00122 {ARG_STRING, kRecSetIn, "", "Input data records."},
00123 {ARG_STRING, kSeriesOut, "", "Output data series."},
00124 {ARG_STRING, kSegIn, kNOTSPECIFIED, ""},
00125 {ARG_STRING, kSegOut, kNOTSPECIFIED, ""},
00126 {ARG_INT, CR, "", "", ""},
00127 {ARG_FLOAT, "nsig", "3.0", "", ""},
00128 {ARG_INT, "MAPMMAX", "1800", "", ""},
00129 {ARG_INT, "SINBDIVS", "720", "", ""},
00130 {ARG_FLOAT, "MAPLGMAX", "90.0", "", ""},
00131 {ARG_FLOAT, "MAPLGMIN", "-90.0", "", ""},
00132 {ARG_FLOAT, EQPOINTS, "20.0", "", ""},
00133 {ARG_FLOAT, HALFWIN, "30.0", "", ""},
00134 {ARG_FLOAT, "center", "0.0", "", ""},
00135 {ARG_INT, "checkqual", "1", "", ""},
00136 {ARG_STRING, "qualmask", "0x0", ""},
00137 {ARG_FLAG, LOSFLAG, "0", "-1", "1"},
00138 {ARG_FLAG, FORCEFLAG, "0", "-1", "1"},
00139 {ARG_FLAG, DLOGFLAG, "0", "-1", "1"},
00140 {ARG_FLOAT, NOISESIGMA, "2.0", "", ""},
00141 {ARG_FLOAT, MAXNOISEADJ, "3.0", "", ""},
00142 {ARG_INT, MINOUTLIERPTS, "4", "", ""},
00143 {ARG_END}
00144 };
00145
00146 int DoIt(void)
00147 {
00148
00149 int newstat = 0;
00150 int status = DRMS_SUCCESS;
00151 float *synop;
00152 int *wt;
00153 char *ww;
00154 float *epts = NULL;
00155 float *losSynop = NULL;
00156 float *ps, *pm;
00157 char *odir;
00158 struct stat stbuf;
00159 float nsig;
00160 int cr, mapmmax, sinbdivs;
00161 int checkqual;
00162 unsigned int quality, qualvld, qualmask, qualmask1, qualmask2, qualmask3;
00163 float lgmax, lgmin;
00164 float center;
00165 float halfWindow;
00166 int len[2];
00167 int ngood, idx;
00168 int started, ended;
00169 int firstidx, lastidx;
00170 int mapmidcol, synmidcol;
00171 int cols2right, cols2left;
00172 int mrc, mlc, src, slc;
00173 int mapcols, col, row, syncol;
00174 double maprightct, mapleftct;
00175 double synleftct, synrightct;
00176 double synstart;
00177 double synend;
00178 double synstep;
00179 char tstr[64];
00180 int mag_num = 0;
00181 TIME tstart, tstop, trot, tearth;
00182 TIME tdiff, magtime;
00183 double r,b,l,vr,vn,vw;
00184 int y,m,d;
00185 TIME tmod, delta_T = 0.0;
00186 double bearth;
00187 double carrtime;
00188 char dsname[1024], key[1024], logfn[1024], synfn[1024], wtfn[1024], losFn[1024];
00189 char eptsfn[1024];
00190 int ds, nds, noutRec;
00191 int fsn, lsn, sn;
00192 int i,j;
00193 double statMin, statMax, statMedn, statMean, statSig, statSkew, statKurt;
00194 int statNgood;
00195 double eph[30];
00196
00197 struct {
00198 int recno;
00199 double mapct;
00200 double mapCM;
00201 float mapdev;
00202 float tmin;
00203 float tmax;
00204 TIME tobs;
00205 } imrec[1024];
00206
00207 int nStackMags;
00208 float nEquivPtsReq;
00209 MagCol_t **sortedMagCol = NULL;
00210
00211 long long modVers = soi_vers_num;
00212 long long imgVers = 0;
00213 int radialFound = 0;
00214 int losFound = 0;
00215 int carrStretch = -1;
00216 float diffrotA = DRMS_MISSING_FLOAT;
00217 float diffrotB = DRMS_MISSING_FLOAT;
00218 float diffrotC = DRMS_MISSING_FLOAT;
00219
00220 const char *synopFileName = NULL;
00221 const char *wtFileName = NULL;
00222 const char *eptsFileName = NULL;
00223
00224 int los;
00225 int force;
00226 int dlog;
00227 float noiseS = cmdparams_get_float(&cmdparams, NOISESIGMA, &status);
00228 float maxNoiseAdj = cmdparams_get_float(&cmdparams, MAXNOISEADJ, &status);
00229
00230
00231 int minOutPts = cmdparams_get_int(&cmdparams, MINOUTLIERPTS, &status);
00232
00233
00234
00235 int sensAdjDone = -1;
00236 float sensAdj;
00237
00238 int nxtSyncol = -1;
00239 int calcsynret = 0;
00240 delta_T = sscan_time("1977.01.01_00:00:00_TAI") - sscan_time("1601.01.01_00:00:00_UT");
00241
00242
00243
00244
00245
00246 cr = cmdparams_get_int(&cmdparams, CR, &status);
00247 nsig = cmdparams_get_float(&cmdparams, "nsig", &status);
00248 mapmmax = cmdparams_get_int(&cmdparams, "MAPMMAX", &status);
00249 sinbdivs = cmdparams_get_int(&cmdparams, "SINBDIVS", &status);
00250 checkqual = cmdparams_get_int(&cmdparams, "checkqual", &status);
00251 qualmask = strtoul(cmdparams_get_str(&cmdparams, "qualmask", &status), (char **) 0, 0);
00252 center = cmdparams_get_float(&cmdparams, "center", &status);
00253 halfWindow = cmdparams_get_float(&cmdparams, HALFWIN, &status);
00254 lgmax = cmdparams_get_float(&cmdparams, "MAPLGMAX", &status);
00255 lgmin = cmdparams_get_float(&cmdparams, "MAPLGMIN", &status);
00256
00257 qualmask3 = strtoul("0x00000200", (char **) 0, 0);
00258 qualmask2 = strtoul("0x00000201", (char **) 0, 0);
00259 qualmask1 = strtoul("0x00000000", (char **) 0, 0);
00260
00261 if (lgmax <= lgmin)
00262 {
00263 printf("MAPLGMAX must be greater than MAPLGMIN\n");
00264 DIE("MAKES_NO_SENSE");
00265 }
00266
00267 nEquivPtsReq = cmdparams_get_float(&cmdparams, EQPOINTS, &status);
00268
00269
00270 len[0] = rint(360.0 / (lgmax - lgmin) * mapmmax);
00271 len[1] = 2 * sinbdivs;
00272
00273 synstep = 360.0 / len[0];
00274 synstart = (cr - 1) * 360.0;
00275 synend = cr * 360.0 - synstep;
00276
00277 nStackMags = rint(2 * halfWindow * 1.5);
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290 tstart = CarringtonTime(cr, 360.0);
00291 tstop = CarringtonTime(cr, 0.0);
00292 trot = CarringtonTime(cr, 180.0);
00293
00294
00295
00296
00297
00298
00299 los = (cmdparams_isflagset(&cmdparams, LOSFLAG) != 0);
00300 force = (cmdparams_isflagset(&cmdparams, FORCEFLAG) != 0);
00301 dlog = (cmdparams_isflagset(&cmdparams, DLOGFLAG) != 0);
00302
00303 printf("\n######### FIRST PASS here #################\n");
00304
00305
00306
00307
00308 if (modVers < 0)
00309 {
00310 modVers = -modVers;
00311 }
00312 char *inRecQuery, *outRecQuery;
00313 inRecQuery = (char *)params_get_str(&cmdparams, kRecSetIn);
00314 outRecQuery = (char *)params_get_str(&cmdparams, kSeriesOut);
00315
00316
00317 DRMS_RecordSet_t *inRD, *outRD;
00318
00319 DRMS_Record_t *outRec;
00320
00321 inRD = drms_open_records(drms_env, inRecQuery, &status);
00322 if (status || inRD->n == 0)
00323 DIE("No input data found");
00324 nds = inRD->n;
00325 idx = 0;
00326 for (ds=0; ds < nds; ds++)
00327 {
00328 double clong;
00329 double cmLong;
00330 double mapct = 0.0;
00331 double mapctnew;
00332 double mapCM = 0.0;
00333 double mapCMnew;
00334 double remapLgmax = 0.0;
00335 double remapLgmin = 0.0;
00336 int orot;
00337 char t_obs[64];
00338 char *imgVersStr = NULL;
00339 int rkey = 0;
00340 int csKey = 0;
00341 float csCoeffKey;
00342 int sensAdjKey;
00343 DRMS_Record_t *inRec;
00344 inRec = inRD->records[ds];
00345
00346 if (checkqual)
00347 {
00348 quality = drms_getkey_int(inRec, "QUALITY", &status);
00349 if (drms_ismissing_int(quality))
00350 {
00351 printf(" Can't find QUALITY in log file; quality check disabled\n");
00352 continue;
00353 }
00354 else if ((quality != qualmask1) & (quality != qualmask2) & (quality != qualmask3))
00355 {
00356 printf(" Bad QUALITY = 0x%08x; rejected\n", quality);
00357
00358 continue;
00359 }
00360 }
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378 if (!force)
00379 {
00380 imgVers = 0;
00381 imgVersStr = drms_getkey_string(inRec, "BLDVER18", &status);
00382
00383 if (imgVersStr)
00384 {
00385 char *endptr = NULL;
00386 imgVers = strtoll(imgVersStr, &endptr, 10);
00387 if (*endptr != '\0' || endptr == imgVersStr)
00388 {
00389
00390 printf(" Invalid build version information.\n");
00391 printf(" Rejecting ds=%d.\n", ds);
00392 continue;
00393 }
00394 }
00395 else
00396 {
00397
00398 printf(" Rejecting ds=%d \n", ds);
00399 continue;
00400 }
00401
00402 if (imgVers < 0)
00403 {
00404 imgVers = -imgVers;
00405 }
00406
00407 if (imgVers < modVers)
00408 {
00409 printf(" Attempt to use obsolete image (img lev18 vers %lld, mod lev18 vers %lld).\n",
00410 imgVers, modVers);
00411 printf(" Rejecting ds=%d.\n", ds);
00412 continue;
00413 }
00414 }
00415
00416
00417
00418 rkey = drms_getkey_int(inRec, "FDRADIAL", &status);
00419 if (rkey > 0)
00420 {
00421 printf(" Found radial keyword %d, ds=%d.\n", rkey, ds);
00422 if (losFound)
00423 {
00424 printf(" Attempt to use a mixture of radial and line-of-sight images.\n");
00425 printf(" Rejecting ds=%d.\n", ds);
00426 continue;
00427 }
00428 else
00429 {
00430 radialFound = 1;
00431 }
00432 }
00433 else
00434 {
00435 if (radialFound)
00436 {
00437 printf(" Attempt to use a mixture of radial and line-of-sight images.\n");
00438 printf(" Rejecting ds=%d.\n", ds);
00439 continue;
00440 }
00441 else
00442 {
00443 losFound = 1;
00444 }
00445 }
00446
00447 csKey = drms_getkey_int(inRec, kCARSTRCH, &status);
00448 csKey = (drms_ismissing_int(csKey)) ? 0 : csKey;
00449
00450 if (idx == 0)
00451 {
00452 carrStretch = csKey;
00453 }
00454 else
00455 {
00456 if (csKey != carrStretch)
00457 {
00458 printf(" Attempt to mix carr-streched and non-carr-stretched images.\n");
00459 printf(" Rejecting ds=%d.\n", ds);
00460 continue;
00461 }
00462 }
00463
00464 if (carrStretch > 0)
00465 {
00466 csCoeffKey = (float)drms_getkey_double(inRec, kDIFROT_A, &status);
00467 if (idx == 0)
00468 {
00469 diffrotA = (float)csCoeffKey;
00470 }
00471 else
00472 {
00473 if (fabsf(csCoeffKey - diffrotA) > 0.001)
00474 {
00475 printf(" Attempt to use inconsistent carr stretch parameters.\n");
00476 printf(" Rejecting ds=%d.\n", ds);
00477 continue;
00478 }
00479 }
00480
00481 csCoeffKey = (float)drms_getkey_double(inRec, kDIFROT_B, &status);
00482 if (idx == 0)
00483 {
00484 diffrotB = (float)csCoeffKey;
00485 }
00486 else
00487 {
00488 if (fabsf(csCoeffKey - diffrotB) > 0.001)
00489 {
00490 printf(" Attempt to use inconsistent carr stretch parameters.\n");
00491 printf(" Rejecting ds=%d.\n", ds);
00492 continue;
00493 }
00494 }
00495
00496 csCoeffKey = (float)drms_getkey_double(inRec, kDIFROT_C, &status);
00497 if (idx == 0)
00498 {
00499 diffrotC = (float)csCoeffKey;
00500 }
00501 else
00502 {
00503 if (fabsf(csCoeffKey - diffrotC) > 0.001)
00504 {
00505 printf(" Attempt to use inconsistent carr stretch parameters.\n");
00506 printf(" Rejecting ds=%d.\n", ds);
00507 continue;
00508 }
00509 }
00510 }
00511
00512 sensAdjKey = drms_getkey_int(inRec, "SENSADJ", &status);
00513 if (sensAdjKey < 0)
00514 {
00515 sensAdjKey = 0;
00516 }
00517
00518 if (sensAdjDone == -1)
00519 {
00520 sensAdjDone = sensAdjKey;
00521 sensAdj = sensAdjDone ? sensAdjVal : 1.0;
00522 }
00523 else
00524 {
00525
00526 if (sensAdjKey != sensAdjDone)
00527 {
00528 printf(" Attempt to use a mixture of sensitivity adjusted and non-adj imgs.\n");
00529 printf(" Rejecting ds=%d.\n", ds);
00530 continue;
00531 }
00532 }
00533
00534 clong = drms_getkey_double(inRec, "CRVAL1", &status);
00535 cmLong = drms_getkey_double(inRec, "CRLN_OBS", &status);
00536 orot = drms_getkey_int(inRec, "CAR_ROT", &status);
00537 if (drms_ismissing_float(clong) || drms_ismissing_int(orot))
00538 {
00539 printf(" Bad MAP_L0 or OBS_CR in header; skipped");
00540 continue;
00541 }
00542
00543 mapctnew = (double)(orot) * 360.0 - clong - center;
00544 mapCMnew = (double)(orot) * 360.0 - cmLong - center;
00545 if (mapCMnew < mapCM)
00546 {
00547 printf(" Source image (ds=%d) has a smaller CT than previous img; skipped.\n", ds);
00548 continue;
00549 }
00550 else
00551 {
00552 mapct = mapctnew;
00553 mapCM = mapCMnew;
00554 }
00555
00556 remapLgmax = drms_getkey_double(inRec, "MAPLGMAX", &status);
00557 remapLgmin = drms_getkey_double(inRec, "MAPLGMIN", &status);
00558 imrec[idx].mapdev = (remapLgmax - remapLgmin) / 2.0;
00559 imrec[idx].recno = drms_getkey_int(inRec, "I_DREC", &status);
00560 imrec[idx].mapct = mapct;
00561 imrec[idx].mapCM = mapCM;
00562
00563 strcpy(t_obs, drms_getkey_string(inRec, "T_OBS", &status));
00564 imrec[idx].tobs = sscan_time(t_obs);
00565
00566
00567 ++idx;
00568
00569 }
00570
00571
00572
00573
00574 ngood = idx;
00575
00576 for (idx = 0; idx < ngood; ++idx)
00577 {
00578 imrec[idx].tmin = MAX(imrec[idx].mapCM - halfWindow, imrec[idx].mapct + center - imrec[idx].mapdev);
00579 imrec[idx].tmax = MIN(imrec[idx].mapCM + halfWindow, imrec[idx].mapct + center + imrec[idx].mapdev);
00580 }
00581
00582 printf("\n######### SECOND PASS #################\n");
00583
00584 if (!(wt = (int *) calloc(len[0],4)))
00585 DIE("MALLOC_FAILED");
00586 if (!(ww = (char *) malloc(len[0]*len[1]*2)))
00587 DIE("MALLOC_FAILED");
00588 if (!(epts = (float *) malloc(len[0] * len[1] * sizeof(float))))
00589 DIE("MALLOC_FAILED");
00590 if (!(synop = (float *) malloc(len[0]*len[1]*4)))
00591 DIE("MALLOC_FAILED");
00592 if (los && radialFound && !(losSynop = (float *)malloc(len[0] * len[1] * sizeof(float))))
00593 {
00594 DIE("MALLOC_FAILED");
00595 }
00596 sortedMagCol = (MagCol_t **)malloc(sizeof(MagCol_t *) * len[0]);
00597 if (!sortedMagCol)
00598 {
00599 DIE("MALLOC_FAILED");
00600 }
00601 memset(sortedMagCol, 0, sizeof(MagCol_t *) * len[0]);
00602 idx = 0;
00603 started = 0;
00604 ended = 0;
00605 nxtSyncol = len[0] - 1;
00606
00607
00608
00609
00610
00611 for (ds=0; ds < nds; ds++)
00612 {
00613 int recno;
00614 int col;
00615 float magtype = 0.0;
00616 char *mType = NULL;
00617 float equivPts = 0.0;
00618 char t_mag[64];
00619 TIME tmag;
00620 DRMS_Record_t *inRec;
00621 DRMS_Segment_t *inSeg = NULL;
00622 DRMS_Array_t *inArray;
00623 inRec = inRD->records[ds];
00624
00625 strcpy(t_mag, drms_getkey_string(inRec, "T_OBS", &status));
00626 tmag = sscan_time(t_mag);
00627 if (tmag != imrec[idx].tobs) continue;
00628
00629
00630
00631 if (imrec[idx].tmax < synstart)
00632 {
00633 ++idx;
00634 continue;
00635 }
00636
00637 if (imrec[idx].tmin > synend)
00638 {
00639 if (!ended)
00640 {
00641 ended = 1;
00642 lastidx = idx;
00643 }
00644 ++idx;
00645 continue;
00646 }
00647
00648 if (!started)
00649 {
00650 started = 1;
00651 firstidx = idx;
00652 }
00653
00654
00655
00656 maprightct = MAX(synstart, imrec[idx].tmin);
00657 mapleftct = MIN(synend, imrec[idx].tmax);
00658 mapcols = drms_getkey_int(inRec, "MAPMMAX", &status) + 1;
00659 mapmidcol = rint((mapcols - 1.0) / 2 + center / synstep);
00660 cols2right = rint((imrec[idx].mapct - maprightct) / synstep);
00661 cols2left = rint((imrec[idx].mapct - mapleftct) / synstep);
00662 mrc = mapmidcol + cols2right;
00663 mlc = mapmidcol + cols2left;
00664 synmidcol = rint((synend - imrec[idx].mapct) / synstep);
00665
00666
00667
00668
00669
00670
00671
00672 src = synmidcol + cols2right;
00673 slc = synmidcol + cols2left;
00674
00675
00676
00677
00678 if (src < nxtSyncol)
00679 {
00680 calcsynret = CalcSynCols(nxtSyncol,
00681 src + 1,
00682 -1,
00683 sortedMagCol,
00684 synop,
00685 wt,
00686 ww,
00687 epts,
00688 losSynop,
00689 len,
00690 center,
00691 nEquivPtsReq,
00692 los,
00693 radialFound,
00694 sensAdj,
00695 noiseS,
00696 nsig,
00697 maxNoiseAdj,
00698 minOutPts,
00699 dlog);
00700 FreeMagColsData(nxtSyncol, src + 1, -1, wt, sortedMagCol);
00701
00702 nxtSyncol = src;
00703 if (calcsynret) DIE("Fail to sort data");
00704 }
00705
00706
00707
00708
00709
00710
00711
00712
00713 magtype = drms_getkey_float(inRec, "EXPTIME", &status);
00714 equivPts = 0.0;
00715
00716 if (magtype == 300.0)
00717 {
00718 equivPts = gMagAgg[kFiveMinuteValue];
00719 }
00720 else if (magtype == 30.0)
00721 {
00722 equivPts = gMagAgg[kOneMinuteValue];
00723 }
00724 else
00725 {
00726 equivPts = gMagAgg[kOneMinuteValue];
00727 }
00728
00729 inSeg = drms_segment_lookupnum(inRec, 0);
00730 inArray = drms_segment_read(inSeg, DRMS_TYPE_FLOAT, &status);
00731
00732 if (status)
00733 {
00734 printf(" No data file found, status=%d\n", status);
00735 drms_free_array(inArray);
00736 continue;
00737 }
00738
00739 for (col = mlc; col <= mrc; ++col)
00740 {
00741 MagCol_t mMagCol;
00742
00743 mMagCol.dist = ((col - mapmidcol) * synstep + imrec[idx].mapct) - imrec[idx].mapCM;
00744 mMagCol.datacol = (float *)malloc(sizeof(float) * len[1]);
00745 mMagCol.equivPts = equivPts;
00746 mMagCol.ds = ds;
00747 mMagCol.col = col;
00748 mMagCol.valid = 1;
00749
00750 pm = (float *)inArray->data + col;
00751 ps = mMagCol.datacol;
00752
00753 for (row = 0; row < len[1]; ++row)
00754 {
00755 *ps = *pm;
00756 pm += mapcols;
00757 ps++;
00758 }
00759
00760 syncol = col + slc - mlc;
00761
00762 if (!sortedMagCol[syncol])
00763 {
00764 sortedMagCol[syncol] = (MagCol_t *)malloc(sizeof(MagCol_t) * nStackMags);
00765 if (!sortedMagCol[syncol]) DIE("MALLOC_FAILED");
00766 memset(sortedMagCol[syncol], 0, sizeof(MagCol_t) * nStackMags);
00767 }
00768
00769 if (wt[syncol] > 0 && (wt[syncol] % nStackMags == 0))
00770 {
00771 int frames = 1 + (wt[syncol] / nStackMags);
00772 MagCol_t *mc = (MagCol_t *)malloc(sizeof(MagCol_t) * frames * nStackMags);
00773 memcpy(mc,
00774 sortedMagCol[syncol],
00775 sizeof(MagCol_t) * (frames - 1) * nStackMags);
00776 free(sortedMagCol[syncol]);
00777 sortedMagCol[syncol] = mc;
00778 }
00779
00780 sortedMagCol[syncol][wt[syncol]] = mMagCol;
00781 wt[syncol]++;
00782
00783 }
00784 drms_free_array(inArray);
00785 ++idx;
00786 }
00787
00788
00789 if (nxtSyncol >= 0)
00790 {
00791 calcsynret = CalcSynCols(nxtSyncol,
00792 0,
00793 -1,
00794 sortedMagCol,
00795 synop,
00796 wt,
00797 ww,
00798 epts,
00799 losSynop,
00800 len,
00801 center,
00802 nEquivPtsReq,
00803 los,
00804 radialFound,
00805 sensAdj,
00806 noiseS,
00807 nsig,
00808 maxNoiseAdj,
00809 minOutPts,
00810 dlog);
00811
00812 FreeMagColsData(nxtSyncol, 0, -1, wt, sortedMagCol);
00813 nxtSyncol = -1;
00814 if (calcsynret) DIE("Fail to sort data");
00815 }
00816
00817 if (!ended) lastidx = ngood-1;
00818 magtime = imrec[(int)(ngood/2)].tobs;
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832 if (fstats(len[0]*len[1], synop, &statMin, &statMax, &statMedn, &statMean, &statSig,
00833 &statSkew, &statKurt, &statNgood)) printf("\n Statistics computation failed...\n");
00834
00835 outRD = drms_create_records(drms_env, 1, outRecQuery, DRMS_PERMANENT, &status);
00836 if (status)
00837 DIE("Output record not created");
00838 DRMS_Segment_t *outSeg;
00839 DRMS_Array_t *outArray;
00840 int outDims[2] = {len[0], len[1]};
00841 outRec = outRD->records[0];
00842
00843
00844 outSeg = drms_segment_lookupnum(outRec, 0);
00845 outArray = drms_array_create(DRMS_TYPE_CHAR, 2, outDims, ww, &status);
00846 status = drms_segment_write(outSeg, outArray, 0);
00847 if (status)
00848 DIE("problem writing file");
00849 drms_free_array(outArray);
00850
00851
00852
00853 outSeg = drms_segment_lookupnum(outRec, 1);
00854 outArray = drms_array_create(DRMS_TYPE_FLOAT, 2, outDims, synop, &status);
00855 status = drms_segment_write(outSeg, outArray, 0);
00856 if (status)
00857 DIE("problem writing file");
00858 drms_free_array(outArray);
00859
00860
00861 outSeg = drms_segment_lookupnum(outRec, 2);
00862 outArray = drms_array_create(DRMS_TYPE_FLOAT, 2, outDims, epts, &status);
00863 status = drms_segment_write(outSeg, outArray, 0);
00864 if (status)
00865 DIE("problem writing file");
00866 drms_free_array(outArray);
00867
00868
00869
00870
00871
00872 sprint_ut(tstr, CURRENT_SYSTEM_TIME);
00873 sscanf(tstr, "%d.%d.%d", &y, &m, &d);
00874 sprintf(tstr, "%04d-%02d-%02d", y, m, d);
00875 drms_setkey_string(outRec, "DATE", tstr);
00876 drms_setkey_string(outRec, "BUNIT", "Gauss");
00877
00878
00879
00880 drms_setkey_string(outRec, "CTYPE1", "CRLN-CEA");
00881 drms_setkey_string(outRec, "CTYPE2", "CRLT-CEA");
00882 i=len[0]/2+0.0;
00883 drms_setkey_double(outRec, "CRPIX1", i);
00884
00885 l=len[1]/2+0.0;
00886 drms_setkey_double(outRec, "CRPIX2", l);
00887
00888 carrtime = (cr-1)*360.0 + 180.0 - 0.5 * 360.0/len[0];;
00889 drms_setkey_double(outRec, "CRVAL1", carrtime);
00890 i=0.0;
00891 drms_setkey_double(outRec, "CRVAL2", i);
00892 l=-360.0/len[0];
00893 drms_setkey_double(outRec, "CDELT1", l);
00894 drms_setkey_double(outRec, "CDELT2", 1.0/sinbdivs);
00895 drms_setkey_string(outRec, "CUNIT1", "degree");
00896 drms_setkey_string(outRec, "CUNIT2", "Sine Latitude");
00897
00898
00899 sprint_at(tstr, trot - delta_T);
00900
00901
00902
00903 i = len[0]*len[1];
00904 drms_setkey_int(outRec, "TOTVALS", i);
00905 drms_setkey_int(outRec, "DATAVALS", statNgood);
00906 i = len[0]*len[1]-statNgood;
00907 drms_setkey_int(outRec, "MISSVALS", i);
00908 drms_setkey_double(outRec, "DATAMIN", statMin);
00909 drms_setkey_double(outRec, "DATAMAX", statMax);
00910 drms_setkey_double(outRec, "DATAMEDN", statMedn);
00911 drms_setkey_double(outRec, "DATAMEAN", statMean);
00912 drms_setkey_double(outRec, "DATARMS", statSig);
00913 drms_setkey_double(outRec, "DATASKEW", statSkew);
00914 drms_setkey_double(outRec, "DATAKURT", statKurt);
00915
00916
00917 drms_setkey_string(outRec, "T_OBS", tstr);
00918 drms_setkey_string(outRec, "T_ROT", tstr);
00919 sprint_at(tstr, tstart - delta_T);
00920 drms_setkey_string(outRec, "T_START", tstr);
00921 sprint_at(tstr, tstop - delta_T);
00922 drms_setkey_string(outRec, "T_STOP", tstr);
00923
00924
00925 drms_setkey_int(outRec, "CAR_ROT", cr);
00926 drms_setkey_double(outRec, "CARRTIME", carrtime);
00927 solephem(trot, eph);
00928
00929 drms_setkey_double(outRec, "B0_ROT", eph[9]/RADSINDEG);
00930 solephem(tstart, eph);
00931
00932 drms_setkey_double(outRec, "B0_FRST", eph[9]/RADSINDEG);
00933 solephem(tstop, eph);
00934
00935 drms_setkey_double(outRec, "B0_LAST", eph[9]/RADSINDEG);
00936
00937 l=(cr-1)*360.0;
00938 drms_setkey_double(outRec, "LON_FRST", l);
00939 l=cr*360.0-360.0/len[0];
00940 drms_setkey_double(outRec, "LON_LAST", l);
00941 l=-360.0/len[0];
00942 drms_setkey_double(outRec, "LON_STEP", l);
00943 l=center;
00944 drms_setkey_double(outRec, "W_OFFSET", l);
00945 drms_setkey_string(outRec, "W_WEIGHT", "Even");
00946 i=lastidx-firstidx+1;
00947 drms_setkey_int(outRec, "IMG_NUM", i);
00948 sprint_at(tstr, imrec[firstidx].tobs);
00949 drms_setkey_string(outRec, "IMG_FRST", tstr);
00950 sprint_at(tstr, imrec[lastidx].tobs);
00951 drms_setkey_string(outRec, "IMG_LAST", tstr);
00952 sprint_at(tstr, magtime);
00953 drms_setkey_string(outRec, "IMG_ROT", tstr);
00954 drms_setkey_float(outRec, HWNWIDTH, halfWindow);
00955 drms_setkey_float(outRec, EQPOINTS, nEquivPtsReq);
00956 drms_setkey_float(outRec, "NSIGMA", nsig);
00957
00958
00959 if (carrStretch > 0)
00960 {
00961 drms_setkey_int(outRec, kCARSTRCH, carrStretch);
00962 drms_setkey_float(outRec, kDIFROT_A, diffrotA);
00963 drms_setkey_float(outRec, kDIFROT_B, diffrotB);
00964 drms_setkey_float(outRec, kDIFROT_C, diffrotC);
00965 }
00966
00967
00968
00969
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985
00986
00987
00988
00989
00990
00991
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009
01010
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
01044
01045
01046
01047
01048
01049
01050
01051
01052
01053
01054 if (sortedMagCol)
01055 {
01056 for (i = 0; i < len[0]; i++)
01057 {
01058 if (sortedMagCol[i])
01059 {
01060 free(sortedMagCol[i]);
01061 }
01062 }
01063
01064 free(sortedMagCol);
01065 }
01066 drms_close_records(inRD, DRMS_FREE_RECORD);
01067 drms_close_records(outRD, DRMS_INSERT_RECORD);
01068 return 0;
01069 }
01070
01071 int CalcSynCols(int start,
01072 int end,
01073 int incr,
01074 MagCol_t **smc,
01075 float *synop,
01076 int *wt,
01077 char *ww,
01078 float *epts,
01079 float *losSynop,
01080 int *len,
01081 float center,
01082 float nEquivPtsReq,
01083 int los,
01084 int radialFound,
01085 float sensAdj,
01086 float noiseS,
01087 float nsig,
01088 float maxNoiseAdj,
01089 int minOutPts,
01090 int dlog)
01091 {
01092 float midSynRow;
01093 float cosrho;
01094
01095
01096
01097
01098
01099 float cosCenter;
01100 char *rejDescFormat;
01101 int col;
01102 int row;
01103 int i;
01104 int j;
01105 static int nrej = 0;
01106 int marked;
01107 float nEquivPts;
01108
01109 midSynRow = (float)(len[1] - 1) / 2.0;
01110 cosCenter = cos(center * M_PI / 180);
01111 rejDescFormat = " magnetogram: ds=%d, sn=%d, magcol=%d, magrow=%d\n";
01112 if (minOutPts < 2) minOutPts = 2;
01113
01114
01115 for (col = start; incr > 0 ? col <= end : col >= end; col += incr)
01116 {
01117 float *val = (float *)malloc(sizeof(float) * wt[col]);
01118 float *ept = (float *)malloc(sizeof(float) * wt[col]);
01119 MagCol_t *pcols = NULL;
01120 marked = 0;
01121
01122 if (dlog)
01123 {
01124 pcols = (MagCol_t *)malloc(sizeof(MagCol_t) * wt[col]);
01125 memset(pcols, 0, sizeof(MagCol_t) * wt[col]);
01126 }
01127
01128 if (!val || !ept) printf("MALLOC FAILED");
01129
01130
01131 SortMagCols(smc[col], wt[col]);
01132
01133
01134
01135
01136
01137
01138
01139
01140
01141
01142
01143
01144
01145
01146
01147
01148
01149
01150 for (row = 0; row < len[1]; ++row)
01151 {
01152 float sinLat = (row - midSynRow) / midSynRow;
01153 float cosLat = sqrt(1 - sinLat * sinLat);
01154 float sum;
01155 int npts;
01156 float sumfinal = 0.0;
01157 int nptsfinal = 0;
01158 float eptfinal = 0.0;
01159 int Maxnepts = nEquivPtsReq + 10;
01160
01161 if (radialFound) cosrho = cosLat * cosCenter;
01162 sum = 0.0;
01163 npts = 0;
01164 j = 0;
01165 nEquivPts = 0.0;
01166
01167
01168
01169
01170
01171 for (i = 0; i < wt[col] && nEquivPts < Maxnepts; i++)
01172 {
01173 float magVal = *(smc[col][i].datacol + row);
01174 if (!drms_ismissing_float(magVal))
01175 {
01176 nEquivPts += smc[col][i].equivPts;
01177 sum += magVal;
01178 val[j] = magVal;
01179 ept[j] = smc[col][i].equivPts;
01180
01181 if (dlog && pcols) pcols[j] = smc[col][i];
01182 j++;
01183 npts++;
01184 }
01185 }
01186
01187
01188 if (npts > 1 && nsig > 0.0) {
01189 double avg = 0.0;
01190 double ssqr = 0.0;
01191 double sig;
01192 float med;
01193 int nStatPts = 0;
01194 float *statVals;
01195 float noiseLevel;
01196 float *outlier = NULL;
01197 int statsDone = 0;
01198 int sIdx = 0;
01199 float dev = 0.0;
01200 int nPtsB4Rej = npts;
01201
01202
01203
01204 noiseLevel = kNOISE_EQ * noiseS * sensAdj;
01205 if (radialFound) noiseLevel = noiseLevel * MIN(1 / cosrho, maxNoiseAdj);
01206
01207 statVals = (float *)malloc(sizeof(float) * npts);
01208 if (!statVals) printf("MALLOC_FAILED");
01209
01210 memcpy(statVals, val, sizeof(float) * npts);
01211 nStatPts = magStats(&statVals, npts, sum, minOutPts, &avg, &med);
01212
01213 for (j = 0; j < nPtsB4Rej; ++j)
01214 {
01215 if (!statsDone)
01216 {
01217 for (sIdx = 0; sIdx < nStatPts; sIdx++)
01218 {
01219 ssqr += statVals[sIdx] * statVals[sIdx];
01220 }
01221
01222 sig = sqrt((ssqr - nStatPts * avg * avg) / (nStatPts - 1));
01223 statsDone = 1;
01224 }
01225
01226 dev = fabs(val[j] - med);
01227 if (nptsfinal >= nEquivPtsReq) break;
01228 if (dev < nsig * sig)
01229 {
01230 sumfinal += val[j];
01231 nptsfinal += 1;
01232 eptfinal += ept[j];
01233 --npts;
01234 ++nrej;
01235 if (dlog)
01236 {
01237 char rejDescBuf[128];
01238
01239 snprintf(rejDescBuf,
01240 sizeof(rejDescBuf),
01241 rejDescFormat,
01242 pcols[j].ds,
01243 pcols[j].col,
01244 row);
01245
01246 }
01247
01248 }
01249 }
01250
01251 free(statVals);
01252 }
01253
01254
01255
01256 if (nptsfinal)
01257 {
01258
01259 float synVal = sumfinal/nptsfinal;
01260
01261
01262
01263 synop[row * len[0] + col] = synVal;
01264 }
01265 else
01266 {
01267 synop[row * len[0] + col] = DRMS_MISSING_FLOAT;
01268 }
01269
01270
01271
01272 ww[row * len[0] + col] = nptsfinal;
01273 epts[row * len[0] + col] = eptfinal;
01274 if (los && radialFound)
01275 {
01276 int offset = row * len[0] + col;
01277 if (drms_ismissing_float(synop[offset]))
01278 {
01279 losSynop[offset] = DRMS_MISSING_FLOAT;
01280 }
01281 else
01282 {
01283 losSynop[offset] = synop[offset] * cosLat;
01284 }
01285 }
01286 }
01287
01288 free(val);
01289 val = NULL;
01290 free(ept);
01291 ept = NULL;
01292
01293 if (pcols)
01294 {
01295 free(pcols);
01296 pcols = NULL;
01297 }
01298 }
01299 return 0;
01300 }
01301
01302 int cmp(const void *a, const void *b)
01303 {
01304 float aa = *(float *)a;
01305 float bb = *(float *)b;
01306 return (aa<bb) ? -1 : (aa==bb) ? 0 : 1;
01307 }
01308
01309
01310 int magStats(float **val, int npts, double sum, int outThreshold, double *avg, float *med)
01311 {
01312 int actPts = npts;
01313 float *out = NULL;
01314 float *in = *val;
01315 int idx = 0;
01316 int iOut = 0;
01317 float medianInt = 0.0;
01318 float first;
01319 float last;
01320
01321 qsort((void *)in, npts, sizeof(float), cmp);
01322
01323 if (npts > outThreshold && npts > 1)
01324 {
01325 actPts = npts - 1;
01326 out = malloc(sizeof(float) * actPts);
01327
01328 medianInt = in[npts/2];
01329
01330 first = in[0];
01331 last = in[npts - 1];
01332
01333 if (fabs(first - medianInt) <= fabs(last - medianInt))
01334 {
01335 idx = 0;
01336 sum -= last;
01337 }
01338 else
01339 {
01340 idx = 1;
01341 sum -= first;
01342 }
01343
01344 for (iOut = 0; idx < npts && iOut < actPts; idx++, iOut++)
01345 {
01346 out[iOut] = in[idx];
01347 }
01348
01349 free(in);
01350 *val = out;
01351 in = *val;
01352 }
01353
01354 *avg = sum / actPts;
01355 *med = in[actPts / 2];
01356
01357 return actPts;
01358 }
01359
01360 int CmpMagCol(const void *a, const void *b)
01361 {
01362 MagCol_t *aa = (MagCol_t *)a;
01363 MagCol_t *bb = (MagCol_t *)b;
01364
01365 if (aa->valid && bb->valid)
01366 {
01367 return (fabsf(aa->dist) < fabsf(bb->dist)) ? -1 :
01368 ((fabsf(aa->dist) == fabsf(bb->dist)) ? 0 : 1);
01369 }
01370 else if (aa->valid)
01371 {
01372 return -1;
01373 }
01374 else if (bb->valid)
01375 {
01376 return 1;
01377 }
01378 else
01379 {
01380 return 0;
01381 }
01382 }
01383
01384 void SortMagCols(MagCol_t *mc, int nelem)
01385 {
01386
01387
01388
01389 int topNeg = -1;
01390 int topPos = -1;
01391 MagCol_t *res = NULL;
01392 int idx;
01393
01394 for (idx = 0; idx < nelem; idx++)
01395 {
01396 if (mc[idx].dist >= 0)
01397 {
01398 topPos = idx;
01399 break;
01400 }
01401 }
01402
01403 if (idx == nelem)
01404 {
01405
01406 topNeg = nelem - 1;
01407 }
01408 else if (topPos > 0)
01409 {
01410
01411 topNeg = topPos - 1;
01412 }
01413
01414 if (topNeg >= 0 || topPos >= 0)
01415 {
01416 res = (MagCol_t *)malloc(sizeof(MagCol_t) * nelem);
01417 memset(res, 0, sizeof(MagCol_t) * nelem);
01418 }
01419
01420 if (res)
01421 {
01422 idx = 0;
01423 while (topNeg >=0 && topPos >= 0 && topPos < nelem)
01424 {
01425 if (fabsf(mc[topNeg].dist) < fabsf(mc[topPos].dist))
01426 {
01427 res[idx] = mc[topNeg];
01428 topNeg--;
01429 }
01430 else
01431 {
01432 res[idx] = mc[topPos];
01433 topPos++;
01434 }
01435
01436 idx++;
01437 }
01438
01439 while (topNeg >= 0)
01440 {
01441 res[idx] = mc[topNeg];
01442 topNeg--;
01443 idx++;
01444 }
01445
01446 while (topPos >= 0 && topPos < nelem)
01447 {
01448 res[idx] = mc[topPos];
01449 topPos++;
01450 idx++;
01451 }
01452
01453 memcpy(mc, res, sizeof(MagCol_t) * nelem);
01454 }
01455 }
01456
01457 void FreeMagColsData(int start, int end, int incr, int *n, MagCol_t **mc)
01458 {
01459 if (mc)
01460 {
01461 float *data = NULL;
01462 int cIdx;
01463 int idx;
01464
01465 for (cIdx = start; incr > 0 ? cIdx <= end : cIdx >= end; cIdx += incr)
01466 {
01467 for (idx = 0; idx < n[cIdx]; idx++)
01468 {
01469 data = mc[cIdx][idx].datacol;
01470 if (data)
01471 {
01472 free(data);
01473 mc[cIdx][idx].datacol = NULL;
01474 mc[cIdx][idx].valid = 0;
01475 }
01476 }
01477 }
01478 }
01479 }
01480
01481 TIME CarringtonTime(int crot, double L)
01482 {
01483 double eph[30];
01484 double CT, clong=0.0;
01485 double err, CTp50m, CTm50m;
01486 TIME t;
01487 char *stime;
01488 char tstr[64];
01489 CT = 0.0;
01490 static TIME T1853 = 0.0, delta_T = 0.0;
01491 T1853 = sscan_time("1853.11.09_22:27:24_UTC");
01492
01493 delta_T = sscan_time("1977.01.01_00:00:00_TAI") - sscan_time("1601.01.01_00:00:00_UT");
01494
01495 CT = 360.0 * crot - L;
01496 t = (C2 + CT * C1) * SID;
01497
01498
01499 solephem(t, eph);
01500 err = CT - eph[8];
01501 solephem(t+6*3600.0, eph);
01502 CTp50m = eph[8];
01503 solephem(t-6*3600.0, eph);
01504 CTm50m = eph[8];
01505
01506 t += 12*3600 * (err/(CTp50m - CTm50m));
01507 solephem(t, eph);
01508 err = CT - eph[8];
01509 solephem(t+300.0, eph);
01510 CTp50m = eph[8];
01511 solephem(t-300.0, eph);
01512 CTm50m = eph[8];
01513
01514 t += 600 * (err/(CTp50m - CTm50m));
01515
01516
01517
01518
01519
01520
01521
01522
01523
01524
01525
01526
01527
01528 return(t);
01529 }
01530
01531
01532
01533
01534
01535
01536
01537
01538
01539
01540
01541
01542
01543
01544
01545
01546
01547
01548
01549
01550
01551
01552
01553
01554
01555
01556
01557
01558
01559
01560
01561
01562
01563
01564
01565
01566
01567
01568
01569
01570
01571
01572
01573
01574
01575
01576
01577
01578
01579
01580
01581
01582
01583
01584
01585
01586
01587
01588
01589
01590
01591
01592
01593
01594
01595
01596
01597
01598
01599
01600
01601
01602
01603
01604
01605
01606
01607
01608
01609
01610
01611
01612
01613
01614
01615
01616
01617
01618
01619
01620
01621
01622
01623
01624
01625
01626
01627
01628
01629
01630
01631
01632
01633
01634
01635
01636
01637
01638
01639
01640
01641
01642
01643
01644
01645
01646
01647
01648
01649
01650
01651