00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053 #include <jsoc_main.h>
00054 #include <fftw3.h>
00055 #include "keystuff.c"
00056
00057 char *module_name = "drms_rebin";
00058 char *version_id = "1.0";
00059 char *module_desc = "rectangular region binning";
00060
00061 ModuleArgs_t module_args[] = {
00062 {ARG_STRING, "in", "", "input data set"},
00063 {ARG_STRING, "out", "", "output data series"},
00064 {ARG_STRING, "seg", "Not Specified", "output data segment"},
00065 {ARG_INTS, "bin", "{1}", "array of per-axis bin widths"},
00066 {ARG_INTS, "start", "{0}", "array of input axis starting pixels"},
00067 {ARG_INTS, "stop", "{-1}", "array of input axis ending pixels"},
00068 {ARG_FLOATS, "wmin", "{NaN}",
00069 "minimum wavelengths per axis for low-pass filtering"},
00070 {ARG_STRING, "copy", "+",
00071 "comma separated list of keys to propagate forward"},
00072 {ARG_STRING, "scale", "Not Specified", "scaling value (number or keyword)"},
00073 {ARG_STRING, "offset", "Not Specified", "offset value (number or keyword)"},
00074 {ARG_INT, "qmask", "0x80000000", "quality bit mask for image rejection"},
00075 {ARG_STRING, "qual_key", "Quality", "keyname for 32-bit input image quality field"},
00076 {ARG_FLAG, "c", "", "collapse rank of output for unit axes"},
00077 {ARG_FLAG, "n", "", "do not save output (for testing)"},
00078 {ARG_FLAG, "o", "",
00079 "remove orbital velocity from signal (radial component only)"},
00080 {ARG_FLAG, "O", "", "remove orbital velocity from signal"},
00081 {ARG_FLAG, "v", "", "run in verbose mode"},
00082 {ARG_END}
00083 };
00084
00085
00086 char *propagate[] = {"T_REC", "T_OBS", "DATE__OBS", "TELESCOP", "INSTRUME"};
00087
00088
00089
00090 char *parse_as_arith_key (const char *str, int *mult, int *add) {
00091 char *parsed = strdup (str);
00092 *mult = *add = 1;
00093 if (parsed[0] == '*') parsed++;
00094 else if (parsed[0] == '/') {
00095 *mult = -1;
00096 parsed++;
00097 }
00098 if (parsed[0] == '+') parsed++;
00099 else if (parsed[0] == '-') {
00100 *add = -1;
00101 parsed++;
00102 }
00103 return parsed;
00104 }
00105
00106 int set_stats_keys (DRMS_Record_t *rec, DRMS_Array_t *v, long long ntot) {
00107 double *vavg = (double *)v->data;
00108
00109 double vmin, vmax, norm, norm2, scale, sig, var;
00110 double sumv1, sum2, sum3, sum4;
00111 long long n;
00112 int sumv0;
00113 int valmin = ntot, valmax = 0;
00114 int kstat = 0;
00115
00116 vmin = HUGE;
00117 vmax = -HUGE;
00118 sumv1 = 0.0;
00119 sumv0 = 0;
00120 for (n = 0; n < ntot; n++) {
00121 if (vavg[n] < vmin) vmin = vavg[n];
00122 if (vavg[n] > vmax) vmax = vavg[n];
00123 if (isfinite (vavg[n])) {
00124 sumv0++;
00125 sumv1 += vavg[n];
00126 }
00127 }
00128
00129 kstat += check_and_set_key_double (rec, "DataMin", vmin);
00130 kstat += check_and_set_key_double (rec, "DataMax", vmax);
00131
00132 if (sumv0) {
00133 scale = 1.0 / sumv0;
00134 sumv1 *= scale;
00135 sum2 = sum3 = sum4 = 0.0;
00136 kstat += check_and_set_key_double (rec, "DataMean", sumv1);
00137 for (n = 0; n < ntot; n++) {
00138 if (isfinite (vavg[n])) {
00139 norm = vavg[n] - sumv1;
00140 norm2 = norm * norm;
00141 sum2 += norm2;
00142 sum3 += norm * norm2;
00143 sum4 += norm2 * norm2;
00144 }
00145 }
00146 kstat += check_and_set_key_double (rec, "DataRMS", sqrt (sum2 / sumv0));
00147 if (sumv0 > 1) {
00148 var = sum2 / (sumv0 - 1);
00149 sig = sqrt (var);
00150 kstat += check_and_set_key_double (rec, "DataSkew",
00151 scale * sum3 / (var * sig));
00152 kstat += check_and_set_key_double (rec, "DataKurt",
00153 scale * sum4 / (var * var) - 3.0);
00154 }
00155 }
00156
00157 return kstat;
00158 }
00159
00160 static int data_filter (DRMS_Array_t *data) {
00161 double *wdata = (double *)data->data;
00162 double norm;
00163 float *xdata = (float *)data->data;
00164 long long n, ntot;
00165 int dp_calc;
00166 int *axes = data->axis;
00167 int rank = data->naxis;
00168 static char *valid = NULL;
00169
00170 fftw_plan fplan, iplan;
00171 fftwf_plan rfplan, riplan;
00172 static fftw_complex *wform = NULL;
00173 static fftwf_complex *xform = NULL;
00174
00175 if (data->type == DRMS_TYPE_DOUBLE) dp_calc = 1;
00176 else if (data->type == DRMS_TYPE_FLOAT) dp_calc = 0;
00177 else {
00178 fprintf (stderr, "Error: filtering of data of type %s not supported\n",
00179 drms_type_names[data->type]);
00180 return 1;
00181 }
00182
00183 ntot = 1;
00184 for (n = 0; n < rank; n++) ntot *= axes[n];
00185 norm = 1.0 / ntot;
00186 valid = (char *)realloc (valid, ntot * sizeof (char));
00187
00188 if (dp_calc) {
00189 wform = (fftw_complex *)realloc (wform, (ntot + 1) * sizeof (fftw_complex));
00190 fplan = fftw_plan_dft_r2c (rank, axes, wdata, wform, FFTW_ESTIMATE);
00191 iplan = fftw_plan_dft_c2r (rank, axes, wform, wdata, FFTW_ESTIMATE);
00192 } else {
00193 xform = (fftwf_complex *)realloc (xform, (ntot + 1) * sizeof (fftwf_complex));
00194 rfplan = fftwf_plan_dft_r2c (rank, axes, xdata, xform, FFTW_ESTIMATE);
00195 riplan = fftwf_plan_dft_c2r (rank, axes, xform, xdata, FFTW_ESTIMATE);
00196 }
00197
00198 if (dp_calc) {
00199 for (n = 0; n < ntot; n++)
00200 if (isnan (wdata[n])) valid[n] = wdata[n] = 0;
00201 else valid[n] = 1;
00202 fftw_execute (fplan);
00203 } else {
00204 for (n = 0; n < ntot; n++)
00205 if (isnan (xdata[n])) valid[n] = xdata[n] = 0;
00206 else valid[n] = 1;
00207 fftwf_execute (rfplan);
00208 }
00209 double rx2, rxfac, ry2, ryfac, rfilt;
00210 int col, hcols, cols = axes[0];
00211 int row, hrows, rows = axes[1];
00212 hrows = (rows + 1) / 2;
00213 hcols = cols / 2;
00214 rxfac = 1.0 / cols;
00215 ryfac = 1.0 / rows;
00216 if (dp_calc) {
00217 for (row = 0, n = 0; row < hrows; row++) {
00218 ry2 = row * ryfac;
00219 ry2 *= ry2;
00220 for (col = 0; col < cols; col++, n+=2) {
00221 rx2 = col * rxfac;
00222 rx2 *= rx2;
00223 rfilt = sqrt (rx2 + ry2);
00224 if (rfilt > 0.1) wform[n] = wform[n+1] = 0.0;
00225 }
00226 }
00227 } else {
00228 for (row = 0, n = 0; row < hrows; row++) {
00229 ry2 = row * ryfac;
00230 ry2 *= ry2;
00231 for (col = 0; col < cols; col++, n+=2) {
00232 rx2 = col * rxfac;
00233 rx2 *= rx2;
00234 rfilt = sqrt (rx2 + ry2);
00235 if (rfilt > 0.1) xform[n] = xform[n+1] = 0.0;
00236 }
00237 }
00238 }
00239
00240 if (dp_calc) {
00241 fftw_execute (iplan);
00242 for (n = 0; n < ntot; n++) {
00243 if (!valid[n]) wdata[n] = NAN;
00244 else wdata[n] *= norm;
00245 }
00246 } else {
00247 fftwf_execute (riplan);
00248 for (n = 0; n < ntot; n++) {
00249 if (!valid[n]) xdata[n] = NAN;
00250 else xdata[n] *= norm;
00251 }
00252 }
00253 return 0;
00254 }
00255
00256 static int check_input_series (char *inds, int *segnum) {
00257
00258
00259
00260
00261
00262
00263 DRMS_RecordSet_t *drs = NULL;
00264 DRMS_Record_t *irec;
00265 DRMS_Segment_t *iseg;
00266 HIterator_t *lastseg = NULL;
00267 int rec_ct;
00268 int status = 0, valid_ct = 0;
00269
00270 *segnum = 0;
00271 drs = drms_open_records (drms_env, inds, &status);
00272 if (!drs) {
00273 fprintf (stderr, "Error: unable to open record set %s\n", inds);
00274 return 1;
00275 }
00276 irec = drs->records[0];
00277
00278
00279 while (iseg = drms_record_nextseg (irec, &lastseg, 1)) {
00280 if (iseg->info->protocol == DRMS_PROTOCOL_INVALID ||
00281 iseg->info->protocol == DRMS_GENERIC) continue;
00282 if (!valid_ct) *segnum = iseg->info->segnum;
00283 valid_ct++;
00284 }
00285 if (valid_ct > 1) {
00286 fprintf (stderr, "Error: input data set %s\n", inds);
00287 fprintf (stderr,
00288 " contains multiple segments of appropriate protocol;\n");
00289 fprintf (stderr, " in segment must be specified\n");
00290 status = 1;
00291 }
00292 if (valid_ct < 1) {
00293 fprintf (stderr, "Error: input data set %s\n", inds);
00294 fprintf (stderr, " contains no segments of appropriate protocol\n");
00295 status = 1;
00296 }
00297 rec_ct = drs->n;
00298 if (rec_ct < 1) {
00299 fprintf (stderr, "No records in selected set %s\n", inds);
00300 status = 1;
00301 }
00302 drms_close_records (drs, DRMS_FREE_RECORD);
00303 return status;
00304 }
00305
00306 static int check_output_series (char *series, char *segname, int *segnum,
00307 int *check) {
00308
00309
00310
00311
00312
00313
00314
00315 DRMS_Record_t *orec;
00316 DRMS_Segment_t *oseg;
00317 int oseg_ct, seg_n;
00318 int status;
00319
00320 orec = drms_create_record (drms_env, series, DRMS_TRANSIENT, &status);
00321 if (!orec) {
00322 fprintf (stderr, "Error: unable to create records in series %s\n", series);
00323 fprintf (stderr, " drms_create_record() returned status %d\n",
00324 status);
00325 return 1;
00326 }
00327
00328 *check = 0;
00329 if (strcmp (segname, "Not Specified")) {
00330
00331 oseg = drms_segment_lookup (orec, segname);
00332 if (!oseg) {
00333 fprintf (stderr, "Error: no such data segment %s in series %s\n", segname,
00334 series);
00335 drms_free_record (orec);
00336 return 1;
00337 }
00338 if (oseg->info->protocol == DRMS_PROTOCOL_INVALID ||
00339 oseg->info->protocol == DRMS_GENERIC) {
00340 fprintf (stderr, "Error: output data segment %s\n", segname);
00341 fprintf (stderr, " is not of appropriate protocol\n");
00342 drms_free_record (orec);
00343 return 1;
00344 }
00345 *segnum = oseg->info->segnum;
00346 } else {
00347 int valid_ct = 0;
00348 oseg_ct = drms_record_numsegments (orec);
00349
00350 for (seg_n = 0; seg_n < oseg_ct; seg_n++) {
00351 oseg = drms_segment_lookupnum (orec, seg_n);
00352 if (oseg->info->protocol == DRMS_PROTOCOL_INVALID ||
00353 oseg->info->protocol == DRMS_GENERIC) continue;
00354 if (!valid_ct) *segnum = seg_n;
00355 valid_ct++;
00356 }
00357 if (valid_ct > 1) *check = 1;
00358 if (valid_ct < 1) {
00359 fprintf (stderr, "Error: output data series %s\n", series);
00360 fprintf (stderr, " contains no segments of appropriate protocol\n");
00361 drms_free_record (orec);
00362 return 1;
00363 }
00364 }
00365 drms_free_record (orec);
00366 return 0;
00367 }
00368
00369 static int check_output_segment (DRMS_Segment_t *seg, int rank, int *axes) {
00370 return 0;
00371 }
00372
00373 static int find_output_segment (char *series, int rank, int *axes) {
00374
00375
00376
00377
00378 DRMS_Record_t *orec;
00379 DRMS_Segment_t *oseg;
00380 int oseg_ct, seg_n, n;
00381 int status;
00382 int valid_ct = 0, segnum = -1;
00383
00384 orec = drms_create_record (drms_env, series, DRMS_TRANSIENT, &status);
00385 oseg_ct = drms_record_numsegments (orec);
00386 for (seg_n = 0; seg_n < oseg_ct; seg_n++) {
00387 oseg = drms_segment_lookupnum (orec, seg_n);
00388 if (oseg->info->protocol == DRMS_PROTOCOL_INVALID ||
00389 oseg->info->protocol == DRMS_GENERIC) continue;
00390 if (oseg->info->naxis != rank) continue;
00391 if (oseg->info->scope != DRMS_VARDIM) {
00392 for (n = 0; n < rank; n++) {
00393
00394 if (axes[n] != oseg->axis[n]) continue;
00395 }
00396 }
00397 if (!valid_ct) segnum = seg_n;
00398 valid_ct++;
00399 }
00400
00401 drms_free_record (orec);
00402 if (valid_ct > 1) {
00403 oseg = drms_segment_lookupnum (orec, segnum);
00404 fprintf (stderr, "Warning: output data series %s\n", series);
00405 fprintf (stderr,
00406 " contains multiple segments of appropriate protocol and dimensions;\n");
00407 fprintf (stderr,
00408 " using first matching segment: %s.\n", oseg->info->name);
00409 fprintf (stderr,
00410 " To use another, seg must be specified\n");
00411 }
00412 drms_free_record (orec);
00413 return segnum;
00414 }
00415
00416 int DoIt (void) {
00417 CmdParams_t *params = &cmdparams;
00418 int propct;
00419 char **copykeylist;
00420 char module_ident[128];
00421 DRMS_RecordSet_t *drs = NULL;
00422 DRMS_Record_t *irec, *orec;
00423 DRMS_Segment_t *iseg, *oseg;
00424 DRMS_Array_t *orig_array, *bind_array;
00425 double *vdat, *vbin;
00426 double crpix, cdelt;
00427 double scale, bias, vr, vw, vn;
00428 float *wmin;
00429 long long *nssub, *ntsub;
00430 long long nn, ntdat, ntbin;
00431 unsigned int qual_inp, qual_out;
00432 int **loc;
00433 int *np;
00434 int *in_axes, *out_axes;
00435 int *bin, *strt, *stop, *strt0, *stop0;
00436 int axis, npmax;
00437 int m, n, key_n, rec_n, rec_ct;
00438 int isegnum, osegnum, rank, crank, axis_check;
00439 int bias_mult, bias_sign, scale_mult, scale_sign;
00440 int prefilter;
00441 int kstat, status = 0;
00442 int keyct = sizeof (propagate) / sizeof (char *);
00443 char *key_scale, *key_bias;
00444 char source[DRMS_MAXQUERYLEN];
00445 char key[256], valuestr[256];
00446
00447 double missing_val = 0.0 / 0.0;
00448
00449 char *inds = strdup (params_get_str (params, "in"));
00450 char *outser = strdup (params_get_str (params, "out"));
00451 char *out_segname = strdup (params_get_str (params, "seg"));
00452 int binvals = params_get_int (params, "bin_nvals");
00453 int strtvals = params_get_int (params, "start_nvals");
00454 int stopvals = params_get_int (params, "stop_nvals");
00455 int wminvals = params_get_int (params, "wmin_nvals");
00456 char *propagate_req = strdup (params_get_str (params, "copy"));
00457 unsigned int qmask = cmdparams_get_int64 (params, "qmask", &status);
00458 char *qual_key = strdup (params_get_str (params, "qual_key"));
00459 int collapse = params_isflagset (params, "c");
00460 int no_save = params_isflagset (params, "n");
00461 int add_orbital_vr = params_isflagset (params, "o");
00462 int add_orbital_full = params_isflagset (params, "O");
00463 int scale_values = strcmp (params_get_str (params, "scale"), "Not Specified");
00464 int bias_values = strcmp (params_get_str (params, "offset"), "Not Specified");
00465 int verbose = params_isflagset (params, "v");
00466 int dispose = (no_save) ? DRMS_FREE_RECORD : DRMS_INSERT_RECORD;
00467
00468 snprintf (module_ident, 128, "%s v %s", module_name, version_id);
00469 if (verbose) printf ("%s:\n", module_ident);
00470
00471
00472 if (check_input_series (inds, &isegnum)) return 1;
00473
00474 if (!strcmp (outser, "in")) {
00475 outser = strdup (inds);
00476 for (n = 0; n < strlen (outser); n++) if (outser[n] == '[') {
00477 outser[n] = '\0';
00478 break;
00479 }
00480 }
00481
00482 if (check_output_series (outser, out_segname, &osegnum, &axis_check)) {
00483 drms_close_records (drs, DRMS_FREE_RECORD);
00484 return 1;
00485 }
00486
00487 drs = drms_open_records (drms_env, inds, &status);
00488 rec_ct = drs->n;
00489 irec = drs->records[0];
00490 iseg = drms_segment_lookupnum (irec, isegnum);
00491 crank = rank = iseg->info->naxis;
00492
00493
00494 bin = (int *)malloc (rank * sizeof (int));
00495 strt = (int *)malloc (rank * sizeof (int));
00496 stop = (int *)malloc (rank * sizeof (int));
00497 strt0 = (int *)malloc (rank * sizeof (int));
00498 stop0 = (int *)malloc (rank * sizeof (int));
00499 wmin = (float *)malloc (rank * sizeof (float));
00500 if (binvals > rank) binvals = rank;
00501 if (strtvals > rank) strtvals = rank;
00502 if (stopvals > rank) stopvals = rank;
00503 if (wminvals > rank) wminvals = rank;
00504 for (n = 0; n < binvals; n++) {
00505 sprintf (key, "bin_%d_value", n);
00506 bin[n] = params_get_int (params, key);
00507 }
00508 while (n < rank) {
00509 bin[n] = bin[n-1];
00510 n++;
00511 }
00512 for (n = 0; n < strtvals; n++) {
00513 sprintf (key, "start_%d_value", n);
00514 strt[n] = params_get_int (params, key);
00515 }
00516 while (n < rank) {
00517 strt[n] = strt[n-1];
00518 n++;
00519 }
00520 for (n = 0; n < stopvals; n++) {
00521 sprintf (key, "stop_%d_value", n);
00522 stop[n] = params_get_int (params, key);
00523 }
00524 while (n < rank) {
00525 stop[n] = stop[n-1];
00526 n++;
00527 }
00528 for (n = 0; n < wminvals; n++) {
00529 sprintf (key, "wmin_%d_value", n);
00530 wmin[n] = params_get_float (params, key);
00531 }
00532 while (n < rank) {
00533 wmin[n] = wmin[n-1];
00534 n++;
00535 }
00536
00537 for (n = 0; n < rank; n++) {
00538 strt0[n] = strt[n];
00539 stop0[n] = stop[n];
00540 }
00541
00542
00543 in_axes = (int *)malloc (rank * sizeof (int));
00544 out_axes = (int *)malloc (rank * sizeof (int));
00545 nssub = (long long *)malloc (rank * sizeof (long long));
00546 ntsub = (long long *)malloc (rank * sizeof (long long));
00547 ntdat = ntbin = npmax = 1;
00548 nssub[0] = ntsub[0] = 1;
00549 for (n = 0; n < rank; n++) {
00550 in_axes[n] = iseg->axis[n];
00551
00552 while (strt[n] < 0) strt[n] += in_axes[n];
00553 while (stop[n] < 0) stop[n] += in_axes[n];
00554 while (strt[n] >= in_axes[n]) strt[n] -= in_axes[n];
00555 while (stop[n] >= in_axes[n]) stop[n] -= in_axes[n];
00556 if (stop[n] < strt[n]) {
00557 int save = strt[n];
00558 strt[n] = stop[n];
00559 stop[n] = save;
00560 }
00561
00562 axis = stop[n] - strt[n] + 1;
00563 out_axes[n] = axis / bin[n];
00564 if (axis % bin[n]) out_axes[n]++;
00565 ntdat *= in_axes[n];
00566 ntbin *= out_axes[n];
00567 npmax *= bin[n];
00568 if (n) {
00569 nssub[n] = nssub[n-1] * in_axes[n-1];
00570 ntsub[n] = ntsub[n-1] * out_axes[n-1];
00571 }
00572 }
00573 if (collapse) {
00574 for (n = 0; n < rank; n++) {
00575 if (out_axes[n] == 1) {
00576 crank--;
00577 for (m = n; m < crank; m++) out_axes[m] = out_axes[m + 1];
00578 }
00579 }
00580 if (crank == rank) collapse = 0;
00581 }
00582
00583
00584 if (axis_check) {
00585 osegnum = find_output_segment (outser, crank, out_axes);
00586 if (osegnum < 0) return 1;
00587 }
00588
00589 orec = drms_create_record (drms_env, outser, DRMS_PERMANENT, &status);
00590 oseg = drms_segment_lookupnum (orec, osegnum);
00591 axis_check = (oseg->info->scope != DRMS_VARDIM);
00592
00593 if (scale_values) {
00594 char *endptr;
00595 scale = strtod (params_get_str (params, "scale"), &endptr);
00596 if (strlen (endptr)) {
00597 key_scale = parse_as_arith_key (params_get_str (params, "scale"),
00598 &scale_mult, &scale_sign);
00599 if (!drms_keyword_lookup (irec, key_scale, 1)) {
00600 fprintf (stderr, "Warning: required keyword %s not found\n", key_scale);
00601 fprintf (stderr, " no scaling applied\n");
00602 scale_values = 0;
00603 }
00604 } else scale_mult = scale_sign = 0;
00605 }
00606 if (bias_values) {
00607 char *endptr;
00608 bias = strtod (params_get_str (params, "offset"), &endptr);
00609 if (strlen (endptr)) {
00610 key_bias = parse_as_arith_key (params_get_str (params, "offset"),
00611 &bias_mult, &bias_sign);
00612 if (!drms_keyword_lookup (irec, key_bias, 1)) {
00613 fprintf (stderr, "Warning: required keyword %s not found\n", key_bias);
00614 fprintf (stderr, " no offset applied\n");
00615 bias_values = 0;
00616 }
00617 } else bias_mult = bias_sign = 0;
00618 }
00619
00620 if (add_orbital_vr || add_orbital_full) {
00621 if (!drms_keyword_lookup (irec, "OBS_VR", 1)) {
00622 fprintf (stderr, "Warning: required keyword %s not found\n", "OBS_VR");
00623 fprintf (stderr, " no correction applied for observer velocity\n");
00624 add_orbital_vr = add_orbital_full = 0;
00625 }
00626 if (add_orbital_full) {
00627 add_orbital_vr = 0;
00628 if (!drms_keyword_lookup (irec, "OBS_VW", 1)) {
00629 fprintf (stderr, "Warning: required keyword %s not found\n", "OBS_VW");
00630 fprintf (stderr, " no correction applied for observer velocity\n");
00631 add_orbital_full = 0;
00632 }
00633 if (!drms_keyword_lookup (irec, "OBS_VW", 1)) {
00634 fprintf (stderr, "Warning: required keyword %s not found\n", "OBS_VN");
00635 fprintf (stderr, " no correction applied for observer velocity\n");
00636 add_orbital_full = 0;
00637 }
00638 if (rank != 2) {
00639 fprintf (stderr, "Warning: input data not image type\n");
00640 fprintf (stderr,
00641 " full correction of orbital velocity not supported\n");
00642 add_orbital_full = 0;
00643 }
00644 fprintf (stderr,
00645 "Warning: full correction of orbital velocity not implemented\n");
00646 add_orbital_full = 0;
00647 }
00648 }
00649 if (!collapse && oseg->info->naxis != rank) {
00650 fprintf (stderr,
00651 "Error: ranks of input and output data segments do not match\n");
00652 drms_free_record (orec);
00653 drms_close_records (drs, DRMS_FREE_RECORD);
00654 return 1;
00655 }
00656 axis_check = (oseg->info->scope != DRMS_VARDIM);
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711 prefilter = isfinite (wmin[0]);
00712 for (n = 1; n < rank; n++) {
00713 if (prefilter && isnan (wmin[n])) {
00714 fprintf (stderr, "Warning: not all wmin values valid\n");
00715 fprintf (stderr, " filtering turned off\n");
00716 prefilter = 0;
00717 break;
00718 }
00719 if (isfinite (wmin[n])) prefilter = 1;
00720 }
00721
00722
00723 in_axes = (int *)malloc (rank * sizeof (int));
00724 out_axes = (int *)malloc (rank * sizeof (int));
00725 nssub = (long long *)malloc (rank * sizeof (long long));
00726 ntsub = (long long *)malloc (rank * sizeof (long long));
00727 ntdat = ntbin = npmax = 1;
00728 nssub[0] = ntsub[0] = 1;
00729 for (n = 0; n < rank; n++) {
00730 in_axes[n] = iseg->axis[n];
00731
00732 while (strt[n] < 0) strt[n] += in_axes[n];
00733 while (stop[n] < 0) stop[n] += in_axes[n];
00734 while (strt[n] >= in_axes[n]) strt[n] -= in_axes[n];
00735 while (stop[n] >= in_axes[n]) stop[n] -= in_axes[n];
00736 if (stop[n] < strt[n]) {
00737 int save = strt[n];
00738 strt[n] = stop[n];
00739 stop[n] = save;
00740 }
00741
00742 axis = stop[n] - strt[n] + 1;
00743 out_axes[n] = axis / bin[n];
00744 if (axis % bin[n]) out_axes[n]++;
00745 ntdat *= in_axes[n];
00746 ntbin *= out_axes[n];
00747 npmax *= bin[n];
00748 if (n) {
00749 nssub[n] = nssub[n-1] * in_axes[n-1];
00750 ntsub[n] = ntsub[n-1] * out_axes[n-1];
00751 }
00752 }
00753
00754 if (axis_check) {
00755
00756 for (n = 0; n < rank; n++) {
00757 if (out_axes[n] != oseg->axis[n]) {
00758 fprintf (stderr,
00759 "Error: array mismatch between output segment definition\n");
00760 fprintf (stderr,
00761 " and desired binning on fixed input segment definition\n");
00762 fprintf (stderr, "axis[%d] = %d, should be %d\n", n, oseg->axis[n],
00763 out_axes[n]);
00764 drms_free_record (orec);
00765 drms_close_records (drs, DRMS_FREE_RECORD);
00766 return 1;
00767 }
00768 }
00769 if (iseg->info->scope != DRMS_VARDIM) axis_check = 0;
00770 }
00771 np = (int *)calloc (ntbin, sizeof (int));
00772 loc = (int **)malloc (ntbin * sizeof (int *));
00773 for (nn = 0; nn < ntbin; nn++) loc[nn] = (int *)malloc (npmax * sizeof (int));
00774
00775 for (nn = 0; nn < ntdat; nn++) {
00776 int trgpix;
00777 int intarget = 1;
00778 int srcpix = (nn % in_axes[0]);
00779 if (srcpix < strt[0] || srcpix > stop[0]) intarget = 0;
00780 trgpix = (srcpix - strt[0]) / bin[0];
00781 for (m = 1; m < rank; m++) {
00782 srcpix = (nn / nssub[m]) % in_axes[m];
00783 if (srcpix < strt[m] || srcpix > stop[m]) {
00784 intarget = 0;
00785 break;
00786 }
00787 trgpix += ((srcpix - strt[m]) / bin[m]) * ntsub[m];
00788 }
00789 if (intarget) {
00790 loc[trgpix][np[trgpix]] = nn;
00791 np[trgpix]++;
00792 }
00793 }
00794
00795 vbin = (double *)malloc (ntbin * sizeof (double));
00796 int *bind_axes = (int *)malloc (rank * sizeof (int));
00797 memcpy (bind_axes, out_axes, rank * sizeof (int));
00798 bind_array = drms_array_create (DRMS_TYPE_DOUBLE, rank, out_axes,
00799 (void *)vbin, &status);
00800 bind_array->bscale = oseg->bscale;
00801 bind_array->bzero = oseg->bzero;
00802 drms_free_record (orec);
00803
00804 propct = construct_stringlist (propagate_req, ',', ©keylist);
00805 if (verbose) {
00806 printf ("propagating %d key(s):\n", propct);
00807 for (n = 0; n < propct; n++) printf (" %s\n", copykeylist[n]);
00808 printf ("\nprocessing %d record(s) in series %s:\n", rec_ct, inds);
00809 }
00810
00811 if (axis_check) {
00812 fprintf (stderr,
00813 "Warning: either input or output segment has protocol vardim\n");
00814 fprintf (stderr,
00815 " not currently supported; results may be garbage!\n");
00816
00817
00818
00819 }
00820
00821 for (rec_n = 0; rec_n < rec_ct; rec_n++) {
00822 if (verbose) printf ("record %d:\n", rec_n);
00823 irec = drs->records[rec_n];
00824 drms_sprint_rec_query (source, irec);
00825 orec = drms_create_record (drms_env, outser, DRMS_PERMANENT, &status);
00826 if (verbose) printf (" processing record %d: %s\n", rec_n, source);
00827 kstat = 0;
00828
00829
00830 kstat += copy_prime_keys (orec, irec);
00831 for (key_n = 0; key_n < propct; key_n++) {
00832 if (strcmp (copykeylist[key_n], "+"))
00833 kstat += check_and_copy_key (orec, irec, copykeylist[key_n]);
00834 else kstat += propagate_keys (orec, irec, propagate, keyct);
00835 }
00836 kstat += check_and_set_key_time (orec, "Date", CURRENT_SYSTEM_TIME);
00837 kstat += check_and_set_key_time (orec, "Created", CURRENT_SYSTEM_TIME);
00838 kstat += check_and_set_key_str (orec, "Module", module_ident);
00839 kstat += check_and_set_key_str (orec, "Input", inds);
00840 kstat += check_and_set_key_str (orec, "Source", source);
00841 kstat += check_and_set_key_str (orec, "BLD_VERS", jsoc_version);
00842
00843 qual_inp = drms_getkey_int (irec, qual_key, &status);
00844 if ((qual_inp & qmask) && !status) {
00845 kstat += check_and_set_key_int (orec, "Quality", 0x80000000);
00846 drms_close_record (orec, dispose);
00847 continue;
00848 }
00849 qual_out = 0x00000000;
00850 iseg = drms_segment_lookupnum (irec, isegnum);
00851 if (!iseg) {
00852 fprintf (stderr, "Warning: could not find segment # %d\n", isegnum);
00853 fprintf (stderr, " in %s; skipped\n", source);
00854 continue;
00855 }
00856
00857
00858 orig_array = drms_segment_read (iseg, DRMS_TYPE_DOUBLE, &status);
00859 if (!orig_array) {
00860 fprintf (stderr, "Warning: could not read segment # %d\n", isegnum);
00861 fprintf (stderr, " in %s; skipped\n", source);
00862 continue;
00863 }
00864 if (prefilter) {
00865
00866 status = data_filter (orig_array);
00867 fprintf (stderr, "Warning: prefiltering not implemented\n");
00868 }
00869 vdat = (double *)orig_array->data;
00870 oseg = drms_segment_lookupnum (orec, osegnum);
00871 if (iseg->info->scope == DRMS_VARDIM) {
00872
00873 int recalc = 0, recok = 1;
00874 for (n = 0; n < rank; n++) {
00875 if (in_axes[n] != iseg->axis[n]) recalc = 1;
00876 in_axes[n] = iseg->axis[n];
00877 }
00878 if (recalc) {
00879
00880 for (n = 0; n < rank; n++) {
00881 strt[n] = strt0[n];
00882 stop[n] = stop0[n];
00883 }
00884 ntdat = ntbin = npmax = 1;
00885 ntsub[0] = nssub[0] = 1;
00886 for (n = 0; n < rank; n++) {
00887
00888 while (strt[n] < 0) strt[n] += in_axes[n];
00889 while (stop[n] < 0) stop[n] += in_axes[n];
00890 while (strt[n] >= in_axes[n]) strt[n] -= in_axes[n];
00891 while (stop[n] >= in_axes[n]) stop[n] -= in_axes[n];
00892 if (stop[n] < strt[n]) {
00893 int save = strt[n];
00894 strt[n] = stop[n];
00895 stop[n] = save;
00896 }
00897 axis = stop[n] - strt[n] + 1;
00898 out_axes[n] = axis / bin[n];
00899 if (axis % bin[n]) out_axes[n]++;
00900 ntdat *= in_axes[n];
00901 ntbin *= out_axes[n];
00902 npmax *= bin[n];
00903 if (n) {
00904 nssub[n] = nssub[n-1] * in_axes[n-1];
00905 ntsub[n] = ntsub[n-1] * out_axes[n-1];
00906 }
00907 }
00908 if (axis_check) {
00909
00910 for (n = 0; n < rank; n++) {
00911 if (out_axes[n] != oseg->axis[n]) {
00912 fprintf (stderr,
00913 "Warning: array mismatch between output segment definition\n");
00914 fprintf (stderr,
00915 " and desired binning on input segment in\n");
00916 fprintf (stderr, " %s; skipped\n", source);
00917 drms_free_record (orec);
00918 recok = 0;
00919 break;
00920 }
00921 }
00922 if (!recok) continue;
00923 }
00924
00925 np = (int *)realloc (np, ntbin * sizeof (int));
00926 for (nn = 0; nn < ntbin; nn++) np[nn] = 0;
00927 loc = (int **)realloc (loc, ntbin * sizeof (int *));
00928 for (nn = 0; nn < ntbin; nn++) {
00929 if (loc[nn]) free (loc[nn]);
00930 loc[nn] = (int *)malloc (npmax * sizeof (int));
00931 }
00932 for (nn = 0; nn < ntdat; nn++) {
00933 int trgpix;
00934 int intarget = 1;
00935 int srcpix = (nn % in_axes[0]);
00936 if (srcpix < strt[0] || srcpix >= stop[0]) intarget = 0;
00937 trgpix = (srcpix - strt[0]) / bin[0];
00938 for (m = 1; m < rank; m++) {
00939 srcpix = (nn / nssub[m]) % in_axes[m];
00940 if (srcpix < strt[m] || srcpix >= stop[m]) {
00941 intarget = 0;
00942 break;
00943 }
00944 trgpix += ((srcpix - strt[m]) / bin[m]) * ntsub[m];
00945 }
00946 if (intarget) {
00947 loc[trgpix][np[trgpix]] = nn;
00948 np[trgpix]++;
00949 }
00950 }
00951 }
00952 }
00953
00954
00955
00956
00957
00958 if (bias_values) {
00959 if (bias_mult) {
00960 bias = drms_getkey_double (irec, key_bias, &status);
00961 if (bias_mult < 0) bias = 1.0 / bias;
00962 bias *= bias_sign;
00963 }
00964 for (nn = 0; nn < ntdat; nn++) if (isfinite (bias)) vdat[nn] += bias;
00965 }
00966 if (scale_values) {
00967 if (scale_mult) {
00968 scale = drms_getkey_double (irec, key_scale, &status);
00969 if (scale_mult < 0) scale = 1.0 / scale;
00970 scale *= scale_sign;
00971 }
00972 for (nn = 0; nn < ntdat; nn++) if (isfinite (scale)) vdat[nn] *= scale;
00973 }
00974 if (add_orbital_vr) {
00975 vr = drms_getkey_double (irec, "OBS_VR", &status);
00976 for (nn = 0; nn < ntdat; nn++) if (isfinite (vr)) vdat[nn] -= vr;
00977 }
00978 if (add_orbital_full) {
00979 vr = drms_getkey_double (irec, "OBS_VR", &status);
00980 vw = drms_getkey_double (irec, "OBS_VW", &status);
00981 vn = drms_getkey_double (irec, "OBS_VN", &status);
00982 }
00983 for (nn = 0; nn < ntbin; nn++) {
00984 vbin[nn] = 0;
00985 for (m = 0; m < np[nn]; m++) {
00986 vbin[nn] += vdat[loc[nn][m]];
00987 }
00988
00989 if (np[nn]) vbin[nn] /= np[nn];
00990 else vbin[nn] = missing_val;
00991 }
00992 drms_free_array (orig_array);
00993
00994 if (collapse) {
00995 DRMS_Array_t *coll_array;
00996 int crank = rank;
00997 for (n = 0; n < rank; n++) {
00998 if (out_axes[n] == 1) {
00999 crank--;
01000 for (m = n; m < crank; m++) out_axes[m] = out_axes[m + 1];
01001 }
01002 }
01003 coll_array = drms_array_create (DRMS_TYPE_DOUBLE, crank, out_axes,
01004 (void *)vbin, &status);
01005 coll_array->bscale = bind_array->bscale;
01006 coll_array->bzero = bind_array->bzero;
01007 drms_segment_write (oseg, coll_array, 0);
01008 } else drms_segment_write (oseg, bind_array, 0);
01009 kstat += check_and_set_key_int (orec, "Quality", qual_out);
01010
01011 for (n = 0; n < rank; n++) {
01012 sprintf (key, "binwdth_%d", n);
01013 kstat += check_and_set_key_int (orec, key, bin[n]);
01014 sprintf (key, "startpx_%d", n);
01015 kstat += check_and_set_key_int (orec, key, strt[n]);
01016 sprintf (key, "stoppx_%d", n);
01017 kstat += check_and_set_key_int (orec, key, stop[n]);
01018 }
01019
01020 for (n = 0; n < rank; n++) {
01021 sprintf (key, "CTYPE%d", n + 1);
01022 kstat += check_and_copy_key (orec, irec, key);
01023 sprintf (key, "CRVAL%d", n + 1);
01024 kstat += check_and_copy_key (orec, irec, key);
01025 sprintf (key, "CRPIX%d", n + 1);
01026 crpix = drms_getkey_double (irec, key, &status);
01027 if (!status) {
01028 crpix -= strt[n];
01029 crpix /= bin[n];
01030 kstat += check_and_set_key_double (orec, key, crpix);
01031 }
01032 sprintf (key, "CDELT%d", n + 1);
01033 cdelt = drms_getkey_double (irec, key, &status);
01034 if (!status) {
01035 cdelt *= bin[n];
01036 kstat += check_and_set_key_double (orec, key, cdelt);
01037 }
01038 sprintf (key, "CROTA%d", n + 1);
01039 kstat += check_and_copy_key (orec, irec, key);
01040 }
01041 if (bias_values) {
01042 if (bias_mult) {
01043 if (bias_mult < 0) {
01044 if (bias_sign < 0) snprintf (valuestr, 256, "1/(-%s)", key_bias);
01045 else snprintf (valuestr, 256, "1/%s", key_scale);
01046 } else {
01047 if (bias_sign < 0) snprintf (valuestr, 256, "-%s", key_bias);
01048 else snprintf (valuestr, 256, "%s", key_bias);
01049 }
01050 } else snprintf (valuestr, 256, "%g", bias);
01051 kstat += check_and_set_key_str (orec, "OffsetBy", valuestr);
01052 if (verbose) {
01053 printf (" offset by ");
01054 if (bias_mult) printf ("%s = ", valuestr);
01055 printf ("%g\n", bias);
01056 }
01057 }
01058 if (scale_values) {
01059 if (scale_mult) {
01060 if (scale_mult < 0) {
01061 if (scale_sign < 0) snprintf (valuestr, 256, "1/(-%s)", key_scale);
01062 else snprintf (valuestr, 256, "1/%s", key_scale);
01063 } else {
01064 if (scale_sign < 0) snprintf (valuestr, 256, "-%s", key_scale);
01065 else snprintf (valuestr, 256, "%s", key_scale);
01066 }
01067 } else snprintf (valuestr, 256, "%g", scale);
01068 kstat += check_and_set_key_str (orec, "ScaledBy", valuestr);
01069 if (verbose) {
01070 printf (" scaled by ");
01071 if (scale_mult) printf ("%s = ", valuestr);
01072 printf ("%g\n", scale);
01073 }
01074 }
01075
01076 kstat += set_stats_keys (orec, bind_array, ntbin);
01077 drms_close_record (orec, dispose);
01078 }
01079 drms_close_records (drs, DRMS_FREE_RECORD);
01080
01081 return 0;
01082 }
01083
01084
01085
01086
01087
01088
01089
01090
01091
01092
01093
01094
01095
01096
01097
01098
01099
01100
01101
01102
01103
01104
01105
01106
01107
01108
01109
01110
01111
01112
01113