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
00054
00055
00056
00057
00058
00059 #include <jsoc_main.h>
00060 #include <fftw3.h>
00061
00062 char *module_name = "pspec3";
00063 char *module_desc = "3-d power spectrum";
00064 char *version_id = "1.1";
00065
00066 ModuleArgs_t module_args[] = {
00067 {ARG_DATASET, "in", "", "Input data set"},
00068 {ARG_STRING, "segment", "Not Specified",
00069 "input data series segment; ignored if series only has one 3-d segment"},
00070 {ARG_DATASERIES, "pspec", "", "Ouput data series"},
00071 {ARG_FLOAT, "mask_in", "0.9375", "inner radial apodization edge", "[0.0,)"},
00072 {ARG_FLOAT, "mask_ex", "1.0", "outer radial apodization edge", "[0.0,)"},
00073 {ARG_FLOAT, "apodize", "0.96875", "temporal apodization edge",
00074 "[0.0,1.0]"},
00075 {ARG_INT, "fbin", "0", "output frequency fbins (0-> none)"},
00076 {ARG_STRING, "copy", "+",
00077 "comma separated list of keys to propagate forward"},
00078 {ARG_FLAG, "l", "",
00079 "output direct power spectrum rather than scaled log"},
00080 {ARG_FLAG, "n", "0", "do not save output record (diagnostics only)"},
00081 {ARG_FLAG, "x", "", "use double-precision calculation"},
00082 {ARG_FLAG, "v", "", "verbose mode"},
00083 {}
00084 };
00085
00086 char *propagate[] = {"CarrTime", "CarrRot", "CMLon", "LonHG", "LatHG", "LonCM",
00087 "MidTime", "Duration", "LonSpan", "T_START", "T_STOP", "Coverage",
00088 "ZonalTrk", "ZonalVel", "MeridTrk", "MeridVel", "MapScale", "MAI", "Ident",
00089 "Width", "Height", "Size", "MapProj", "Map_PA", "PosAng", "RSunRef"};
00090
00091 #include "keystuff.c"
00092
00093 static int cleanup (int error, DRMS_RecordSet_t *irecs, DRMS_Record_t *orec,
00094 DRMS_Array_t *orig, DRMS_Array_t *pspec, int dispose) {
00095 if (orig) drms_free_array (orig);
00096 if (pspec) drms_free_array (pspec);
00097 if (irecs) drms_close_records (irecs, DRMS_FREE_RECORD);
00098 if (orec) {
00099 if (error) drms_close_record (orec, DRMS_FREE_RECORD);
00100 else drms_close_record (orec, dispose);
00101 }
00102 return error;
00103 }
00104
00105 int read_from_big_cube (DRMS_Segment_t *seg, int dp_calc, void *rdata,
00106 double *avg, double *var, double apode_edge, double *apodization,
00107 int xcols) {
00108 DRMS_Array_t *tmp;
00109 DRMS_Type_t type;
00110 void *data;
00111 double *wdata;
00112 double dval, dataavg, datavar, weight;
00113 float *xdata;
00114 float fval;
00115 long long n;
00116 int *start, *stop;
00117 int m, col, cols, row, rows, area, plane, planes, rank, size;
00118 int status;
00119
00120 if (dp_calc) {
00121 size = sizeof (double);
00122 type = DRMS_TYPE_DOUBLE;
00123 wdata = (double *)rdata;
00124 } else {
00125 size = sizeof (float);
00126 type = DRMS_TYPE_FLOAT;
00127 xdata = (float *)rdata;
00128 }
00129 dataavg = datavar = 0.0;
00130
00131 rank = seg->info->naxis;
00132 cols = seg->axis[0];
00133 rows = seg->axis[1];
00134 planes = seg->axis[rank-1];
00135 start = (int *)malloc (rank * sizeof (int));
00136 stop = (int *)malloc (rank * sizeof (int));
00137 area = 1;
00138 for (n = 0; n < rank-1; n++) {
00139 start[n] = 0;
00140 stop[n] = seg->axis[n] - 1;
00141 area *= seg->axis[n];
00142 }
00143 size *= area;
00144 n = 0;
00145 for (plane = 0; plane < planes; plane++) {
00146 m = 0;
00147 start[rank-1] = stop[rank-1] = plane;
00148 tmp = drms_segment_readslice (seg, type, start, stop, &status);
00149 if (status) {
00150 fprintf (stderr, "Error reading data plane %d\n", plane);
00151 return 1;
00152 }
00153 data = tmp->data;
00154 if (apode_edge < 1.0) {
00155 double t = (2.0 * plane) / (planes - 1.0);
00156 if (t > 1.0) t = 2.0 - t;
00157 t = 1.0 - t;
00158 if (t > apode_edge) {
00159 t = (t - apode_edge) / (1.0 - apode_edge);
00160 t *= t;
00161 weight = (1.0 - t);
00162 weight *= weight;
00163 } else weight = 1.0;
00164 } else weight = 1.0;
00165 if (dp_calc) {
00166 for (row = 0; row < rows; row++) {
00167 for (col = 0; col < cols; col++) {
00168 dval = ((double *)data)[m];
00169 if (isnan (dval)) dval = 0.0;
00170 dval *= weight * apodization[m++];
00171 dataavg += dval;
00172 datavar += dval * dval;
00173 wdata[n++] = dval;
00174 }
00175 n += xcols - cols;
00176 }
00177 } else {
00178 for (row = 0; row < rows; row++) {
00179 for (col = 0; col < cols; col++) {
00180 fval = ((float *)data)[m];
00181 if (isnan (fval)) fval = 0.0;
00182 fval *= weight * apodization[m++];
00183 dataavg += fval;
00184 datavar += fval * fval;
00185 xdata[n++] = fval;
00186 }
00187 n += xcols - cols;
00188 }
00189 }
00190 drms_free_array (tmp);
00191 }
00192 return 0;
00193 }
00194
00195 DRMS_Array_t *read_big_cube (DRMS_Segment_t *seg, DRMS_Type_t type, int *status) {
00196 DRMS_Array_t *arr, *tmp;
00197 int *start, *stop;
00198 int n, plane, pln, plen, rank, size;
00199 void *data;
00200
00201 size = drms_sizeof (type);
00202 rank = seg->info->naxis;
00203 plen = seg->axis[rank-1];
00204 arr = drms_array_create (type, rank, seg->axis, NULL, status);
00205 if (*status) return NULL;
00206
00207 start = (int *)malloc (rank * sizeof (int));
00208 stop = (int *)malloc (rank * sizeof (int));
00209 plane = 1;
00210 for (n = 0; n < rank-1; n++) {
00211 start[n] = 0;
00212 stop[n] = seg->axis[n] - 1;
00213 plane *= seg->axis[n];
00214 }
00215 size *= plane;
00216 data = arr->data;
00217 for (pln = 0; pln < plen; pln++) {
00218 start[rank-1] = stop[rank-1] = pln;
00219 tmp = drms_segment_readslice (seg, type, start, stop, status);
00220 if (*status) return NULL;
00221 memcpy (data, tmp->data, size);
00222 drms_free_array (tmp);
00223 (char *)data += size;
00224 }
00225 if (*status) return NULL;
00226 return arr;
00227 }
00228
00229 int DoIt (void) {
00230 CmdParams_t *params = &cmdparams;
00231 DRMS_RecordSet_t *irecs = NULL;
00232 DRMS_Record_t *irec, *orec = NULL;
00233 DRMS_Segment_t *iseg, *oseg;
00234 DRMS_Array_t *orig = NULL, *pspec = NULL;
00235
00236 double *apodization;
00237 double *wdata;
00238 double crpix, crval = 0.0;
00239 double dnu, domega, dval, r, r2, ra, ra2, rx, ry, r0x, r0y, t, tstep;
00240 double dataavg, datavar, powrint, normal, weight;
00241 double bzero, bscale, scale_range;
00242 float *data, *xdata;
00243 float ftrb, ftib, fval, vmin, vmax, vmin2;
00244 long long cube, ntot, l, m, n;
00245 int axes[3];
00246 int rank, col, cols, row, rows, plane, planes, area;
00247 int hcols, hrows, hplanes, opln, xcols, cols_even, rows_even;
00248 int rgn, rgnct, segs, isegnum, osegnum, found;
00249 int bin, is, js;
00250 int key_n, kstat, propct, status;
00251 int bigcube;
00252 char **copykeylist;
00253 char *inser;
00254 char module_ident[64];
00255 char pathname[2*DRMS_MAXPATHLEN+1];
00256 char source[DRMS_MAXQUERYLEN], recid[DRMS_MAXQUERYLEN];
00257 void *val;
00258
00259 int keyct = sizeof (propagate) / sizeof (char *);
00260
00261 char *inds = strdup (params_get_str (params, "in"));
00262 char *out_series = strdup (params_get_str (params, "pspec"));
00263 double apode_edge = params_get_double (params, "apodize");
00264 double edge_inner = params_get_double (params, "mask_in");
00265 double edge_outer = params_get_double (params, "mask_ex");
00266 int fbins = params_get_int (params, "fbin");
00267 char *seg_name = strdup (params_get_str (params, "segment"));
00268 char *propagate_req = strdup (params_get_str (params, "copy"));
00269 int log_out = params_isflagset (params, "l") ? 0 : 1;
00270 int dp_calc = params_isflagset (params, "x");
00271 int verbose = params_isflagset (params, "v");
00272 int no_save = params_isflagset (params, "n");
00273 int dispose = (no_save) ? DRMS_FREE_RECORD : DRMS_INSERT_RECORD;
00274
00275 fftwf_plan fplan;
00276 fftw_plan plan;
00277
00278 snprintf (module_ident, 64, "%s v %s", module_name, version_id);
00279 if (verbose) {
00280 printf ("%s:\n", module_ident);
00281 if (fbins > 1)
00282 printf (" output binned by %d frequencies per plane\n", fbins);
00283 if (no_save)
00284 printf ("(diagnostic run only, no records will be written to DRMS)\n");
00285 }
00286
00287 orec = drms_create_record (drms_env, out_series, DRMS_TRANSIENT, &status);
00288 if (status) {
00289 fprintf (stderr,
00290 "Error: drms_create_record returned %d for data series:\n", status);
00291 fprintf (stderr, " %s\n", out_series);
00292 return cleanup (1, irecs, orec, orig, pspec, dispose);
00293 }
00294 if ((segs = orec->segments.num_total) < 1) {
00295 fprintf (stderr, "Error: no data segments in output data series:\n");
00296 fprintf (stderr, " %s\n", out_series);
00297 return cleanup (1, irecs, orec, orig, pspec, dispose);
00298 }
00299 found = 0;
00300 for (n = 0; n < segs; n++) {
00301 oseg = drms_segment_lookupnum (orec, n);
00302 if (oseg->info->naxis != 3) continue;
00303 if (!found) osegnum = n;
00304 found++;
00305 }
00306 if (!found) {
00307 fprintf (stderr, "Error: no segment of rank 3 in output data series:\n");
00308 fprintf (stderr, " %s\n", out_series);
00309 return cleanup (1, irecs, orec, orig, pspec, dispose);
00310 }
00311 oseg = drms_segment_lookupnum (orec, osegnum);
00312 if (found > 1) {
00313 fprintf (stderr,
00314 "Warning: multiple segments of rank 3 in output data series:\n");
00315 fprintf (stderr, " %s\n", out_series);
00316 fprintf (stderr, " using %s\n", oseg->info->name);
00317 }
00318 switch (oseg->info->type) {
00319 case DRMS_TYPE_CHAR:
00320 scale_range = 250.0;
00321 break;
00322 case DRMS_TYPE_SHORT:
00323 scale_range = 65000.0;
00324 break;
00325 case DRMS_TYPE_INT:
00326 scale_range = 4.2e9;
00327 break;
00328 case DRMS_TYPE_LONGLONG:
00329 scale_range = 1.8e19;
00330 break;
00331 default:
00332 scale_range = 1.0;
00333 }
00334 drms_close_record (orec, DRMS_FREE_RECORD);
00335
00336 irecs = drms_open_records (drms_env, inds, &status);
00337 if (status) {
00338 fprintf (stderr, "Error (%s): drms_open_records() returned %d for dataset:\n",
00339 module_ident, status);
00340 fprintf (stderr, " %s\n", inds);
00341 return cleanup (1, irecs, orec, orig, pspec, dispose);
00342 }
00343
00344 rgnct = irecs->n;
00345 if (rgnct < 1) {
00346 fprintf (stderr, "No records found in input data set %s\n", inds);
00347 return cleanup (1, irecs, orec, orig, pspec, dispose);
00348 }
00349 irec = irecs->records[0];
00350 inser = strdup (inds);
00351 if ((segs = drms_record_numsegments (irec)) < 1) {
00352 fprintf (stderr, "Error: no data segments in input data series:\n");
00353 fprintf (stderr, " %s\n", inser);
00354 return cleanup (1, irecs, orec, orig, pspec, dispose);
00355 }
00356 found = 0;
00357 for (n = 0; n < segs; n++) {
00358 iseg = drms_segment_lookupnum (irec, n);
00359 if (iseg->info->naxis != 3) continue;
00360 if (!found) isegnum = n;
00361 found++;
00362 }
00363 if (!found) {
00364 fprintf (stderr, "Error: no segment of rank 3 in input data series:\n");
00365 fprintf (stderr, " %s\n", inser);
00366 return cleanup (1, irecs, orec, orig, pspec, dispose);
00367 }
00368 if (found > 1) {
00369 if (strcmp (seg_name, "Not Specified")) {
00370 iseg = drms_segment_lookup (irec, seg_name);
00371 if (!iseg) {
00372 fprintf (stderr,
00373 "Warning: requested segment %s not found in input data series:\n",
00374 seg_name);
00375 fprintf (stderr, " %s\n", inser);
00376 iseg = drms_segment_lookupnum (irec, isegnum);
00377 fprintf (stderr, " using segement %s\n", iseg->info->name);
00378 } else if (iseg->info->naxis != 3) {
00379 fprintf (stderr,
00380 "Warning: requested segment %s in input data series:\n", seg_name);
00381 fprintf (stderr, " %s is not 3-dimensional", inser);
00382 iseg = drms_segment_lookupnum (irec, isegnum);
00383 fprintf (stderr, " using segment %s\n", iseg->info->name);
00384 } else isegnum = iseg->info->segnum;
00385 } else {
00386 fprintf (stderr,
00387 "Warning: multiple segments of rank 3 in input data series:\n");
00388 fprintf (stderr, " %s\n", inser);
00389 fprintf (stderr, " using %s\n", iseg->info->name);
00390 }
00391 }
00392 propct = construct_stringlist (propagate_req, ',', ©keylist);
00393 if (verbose) {
00394 printf ("propagating %d key(s):\n", propct);
00395 for (key_n = 0; key_n < propct; key_n++) printf (" %s\n",
00396 copykeylist[key_n]);
00397 printf ("\nprocessing %d record(s) in series %s:\n", rgnct, inser);
00398 }
00399
00400
00401 for (rgn = 0; rgn < rgnct; rgn++) {
00402 irec = irecs->records[rgn];
00403 drms_sprint_rec_query (source, irec);
00404
00405 if (!(iseg = drms_segment_lookupnum (irec, isegnum))) {
00406 fprintf (stderr, "Warning: could not find segment \"V\" or \"Vtrack\"\n");
00407 fprintf (stderr, " in %s; skipped\n", source);
00408 continue;
00409 }
00410 if (iseg->info->naxis != 3) {
00411 fprintf (stderr, "Error: rank of data cube (%d) != 3\n", iseg->info->naxis);
00412 return cleanup (1, irecs, orec, orig, pspec, dispose);
00413 }
00414 if (drms_wcs_timestep (irec, 3, &tstep)) {
00415 dval = (double)drms_getkey_time (irec, "T_STOP", &status);
00416 tstep = dval - (double)drms_getkey_time (irec, "T_START", &status);
00417 if (tstep <= 0.0) {
00418 fprintf (stderr,
00419 "Error: insufficient key information for frequency determination\n");
00420 fprintf (stderr,
00421 " in record %s; skipped\n", source);
00422 continue;
00423 }
00424 tstep /= planes - 1.0;
00425 }
00426
00427 orec = drms_create_record (drms_env, out_series, DRMS_PERMANENT, &status);
00428 if (status) {
00429 fprintf (stderr,
00430 "Error: drms_create_record returned %d for data series:\n", status);
00431 fprintf (stderr, " %s\n", out_series);
00432 return cleanup (1, irecs, orec, orig, pspec, dispose);
00433 }
00434 cols = iseg->axis[0];
00435 rows = iseg->axis[1];
00436 planes = iseg->axis[2];
00437 area = cols * rows;
00438 cube = planes * area;
00439 xcols = 2 * ((cols + 2) / 2);
00440 hcols = cols / 2;
00441 hrows = rows / 2;
00442 cols_even = (cols % 2) ? 0 : 1;
00443 rows_even = (rows % 2) ? 0 : 1;
00444 hplanes = planes / 2;
00445 if (planes % 2) hplanes++;
00446
00447 apodization = (double *)malloc (area * sizeof (double));
00448 if (edge_outer == 0.0) {
00449 for (n = 0; n < area; n++) apodization[n] = 1.0;
00450 } else {
00451 r0x = hcols + 0.5 * cols_even;
00452 r0y = hrows + 0.5 * rows_even;
00453 for (row=0, n=0; row<rows; row++) {
00454 ry = (row - hrows + 0.5 * rows_even) / r0y;
00455 for (col=0; col<cols; col++) {
00456 rx = (col - hcols + 0.5 * cols_even) / r0x;
00457 r2 = rx * rx + ry * ry;
00458 r = sqrt (r2);
00459 if (edge_inner >= edge_outer)
00460 ra = (r < edge_outer) ? 0.0 : 1.0;
00461 else
00462 ra = (r - edge_inner) / (edge_outer - edge_inner);
00463 ra2 = 1.0 - ra * ra;
00464 apodization[n++] = (ra >= 1.0) ? 0.0 : (ra <= 0.0) ? 1.0 : ra2 * ra2;
00465 }
00466 }
00467 }
00468
00469 if (dp_calc) {
00470 wdata = (double *)malloc (planes * rows * xcols * sizeof (double));
00471 plan = fftw_plan_dft_r2c_3d (planes, rows, cols, wdata,
00472 (fftw_complex *)wdata, FFTW_ESTIMATE);
00473 } else {
00474 xdata = (float *)malloc (planes * rows * xcols * sizeof (float));
00475 fplan = fftwf_plan_dft_r2c_3d (planes, rows, cols, xdata,
00476 (fftwf_complex *)xdata, FFTW_ESTIMATE);
00477 }
00478
00479 if (planes < 2) apode_edge = 2.0;
00480 bigcube = 0;
00481 if (cube > 838860800) {
00482 fprintf (stderr,
00483 "Warning: call to drms_segment_read() may fail for %lld values\n",
00484 cube);
00485 fprintf (stderr, " or results may be garbage\n");
00486 bigcube = 1;
00487
00488
00489
00490 if (dp_calc)
00491 read_from_big_cube (iseg, dp_calc, wdata, &dataavg, &datavar,
00492 apode_edge, apodization, xcols);
00493 else
00494 read_from_big_cube (iseg, dp_calc, xdata, &dataavg, &datavar,
00495 apode_edge, apodization, xcols);
00496 } else {
00497 orig = drms_segment_read (iseg, DRMS_TYPE_FLOAT, &status);
00498 if (status) {
00499 fprintf (stderr, "Error on drms_segment_read in\n");
00500 fprintf (stderr, " %s\n", source);
00501 return cleanup (1, irecs, orec, orig, pspec, dispose);
00502 }
00503 l = m = n = 0;
00504 dataavg = datavar = 0.0;
00505 data = (float *)orig->data;
00506 for (plane = 0; plane < planes; plane++) {
00507 if (apode_edge < 1.0) {
00508 t = (2.0 * plane) / (planes - 1.0);
00509 if (t > 1.0) t = 2.0 - t;
00510 t = 1.0 - t;
00511 if (t > apode_edge) {
00512 t = (t - apode_edge) / (1.0 - apode_edge);
00513 t *= t;
00514 weight = (1.0 - t);
00515 weight *= weight;
00516 } else weight = 1.0;
00517 } else weight = 1.0;
00518 if (dp_calc) {
00519 for (row = 0; row < rows; row++) {
00520 for (col = 0; col < cols; col++) {
00521 dval = data[m++];
00522 if (isnan (dval)) dval = 0.0;
00523 dval *= weight * apodization[l++];
00524 dataavg += dval;
00525 datavar += dval * dval;
00526 wdata[n++] = dval;
00527 }
00528 n += xcols - cols;
00529 }
00530 } else {
00531 for (row = 0; row < rows; row++) {
00532 for (col = 0; col < cols; col++) {
00533 fval = data[m++];
00534 if (isnan (fval)) fval = 0.0;
00535 fval *= weight * apodization[l++];
00536 dataavg += fval;
00537 datavar += fval * fval;
00538 xdata[n++] = fval;
00539 }
00540 n += xcols - cols;
00541 }
00542 }
00543 l = 0;
00544 }
00545 drms_free_array (orig);
00546 }
00547
00548 orig = NULL;
00549 dataavg /= m;
00550 datavar /= m;
00551 datavar -= dataavg * dataavg;
00552
00553 if (dp_calc) fftw_execute (plan);
00554 else fftwf_execute (fplan);
00555
00556 axes[0] = cols;
00557 axes[1] = rows;
00558 opln = (fbins > 1) ? hplanes / fbins : hplanes;
00559 if (fbins > 1 && hplanes % fbins) opln++;
00560 axes[2] = opln;
00561 ntot = cols * rows * opln;
00562 data = (float *)malloc (ntot * sizeof (float));
00563
00564 kstat = 0;
00565 for (key_n = 0; key_n < propct; key_n++) {
00566 if (strcmp (copykeylist[key_n], "+"))
00567 kstat += check_and_copy_key (orec, irec, copykeylist[key_n]);
00568 else kstat += propagate_keys (orec, irec, propagate, keyct);
00569 }
00570
00571
00572
00573 dval = drms_getkey_double (irec, "CDELT3", &status);
00574 if (!status) kstat += check_and_set_key_float (orec, "Cadence", dval);
00575
00576 crpix = 0.5 * (cols + 1);
00577 kstat += check_and_set_key_float (orec, "CRPIX1", crpix);
00578 if (cols != rows) crpix = 0.5 * (rows + 1);
00579 kstat += check_and_set_key_float (orec, "CRPIX2", crpix);
00580 crpix = 1.0;
00581 kstat += check_and_set_key_float (orec, "CRPIX3", crpix);
00582 kstat += check_and_set_key_float (orec, "CRVAL1", crval);
00583 kstat += check_and_set_key_float (orec, "CRVAL2", crval);
00584 kstat += check_and_set_key_float (orec, "CRVAL3", crval);
00585 kstat += check_and_set_key_str (orec, "CTYPE1", "WAVE-NUM");
00586 kstat += check_and_set_key_str (orec, "CTYPE2", "WAVE-NUM");
00587 kstat += check_and_set_key_str (orec, "CTYPE3", "FREQ-ANG");
00588 kstat += check_and_set_key_float (orec, "Apode_k_min", edge_inner);
00589 kstat += check_and_set_key_float (orec, "APOD_MIN", edge_inner);
00590 kstat += check_and_set_key_float (orec, "Apode_k_max", edge_outer);
00591 kstat += check_and_set_key_float (orec, "APOD_MAX", edge_outer);
00592 kstat += check_and_set_key_float (orec, "Apode_f", apode_edge);
00593 if (kstat) {
00594 fprintf (stderr, "Error writing key value(s) to record in series %s:\n",
00595 out_series);
00596 fprintf (stderr, " series may not have appropriate structure;\n");
00597 fprintf (stderr, " record %d skipped\n", rgn);
00598 continue;
00599 }
00600
00601 dval = drms_getkey_double (irec, "MapScale", &status);
00602 if (!status) {
00603
00604 dval = 360.0 / dval / cols;
00605 dval /= 696.0;
00606 kstat += check_and_set_key_double (orec, "CDELT1", dval);
00607 if (cols == rows) {
00608 kstat += check_and_set_key_double (orec, "CDELT2", dval);
00609 kstat += check_and_set_key_double (orec, "Delta_k", dval);
00610 } else {
00611 kstat += check_and_set_key_double (orec, "Delta_kx", dval);
00612 dval *= (double)cols / (double)rows;
00613 kstat += check_and_set_key_double (orec, "CDELT2", dval);
00614 kstat += check_and_set_key_double (orec, "Delta_ky", dval);
00615 }
00616 if (kstat) {
00617 fprintf (stderr, "Error writing key value(s) to record in series %s\n",
00618 out_series);
00619 fprintf (stderr, " series may not have appropriate structure\n");
00620 fprintf (stderr, " record %d skipped\n", rgn);
00621 continue;
00622 }
00623 }
00624 dnu = 1.0e6 / planes / tstep;
00625 if (fbins > 1) dnu *= fbins;
00626 kstat += check_and_set_key_double (orec, "Delta_nu", dnu);
00627 domega = dnu * 2.0e-6 * M_PI;
00628 kstat += check_and_set_key_double (orec, "D_OMEGA", domega);
00629 kstat += check_and_set_key_double (orec, "CDELT3", domega);
00630 if (kstat) {
00631 fprintf (stderr, "Error writing key value(s) to record in series %s\n",
00632 out_series);
00633 fprintf (stderr, " series may not have appropriate structure\n");
00634 fprintf (stderr, " record %d skipped\n", rgn);
00635 continue;
00636 }
00637
00638 normal = 1.0 / ntot;
00639 normal *= normal;
00640 powrint = 0.0;
00641 if (fbins > 1) {
00642 double nfac = normal / fbins / fbins;
00643 for (plane = 0, n = 0; plane < hplanes; plane += fbins) {
00644 for (row = 0; row < rows; row++) {
00645 for (col = 0; col < cols; col++, n++) {
00646 js = (row == row % hrows) ? row + hrows : row - hrows;
00647 is = (col == col % hcols) ? col + hcols : col - hcols;
00648 ftrb = ftib = 0.0;
00649 for (bin = 0; bin < fbins; bin++) {
00650 m = (plane + bin) * xcols * rows + js * xcols + 2 * is;
00651 if (is >= hcols) {
00652 m = 2 * (cols - is);
00653 if (js != 0) m += (rows - js) * xcols;
00654 if ((plane + bin) != 0)
00655 m += (planes - plane - bin) * xcols * rows;
00656 }
00657 if (dp_calc) {
00658 ftrb += wdata[m];
00659 ftib += wdata[m+1];
00660 } else {
00661 ftrb += xdata[m];
00662 ftib += xdata[m+1];
00663 }
00664 }
00665 data[n] = nfac * (ftrb*ftrb + ftib*ftib);
00666 if (n == 0) vmax = vmin = vmin2 = data[n];
00667 if (data[n] > vmax) vmax = data[n];
00668 if (data[n] < vmin) {
00669 vmin2 = vmin;
00670 vmin = data[n];
00671 }
00672 powrint += data[n];
00673 }
00674 }
00675 }
00676 if (n > ntot) {
00677 fprintf (stderr, "Error: data written beyond output array bounds\n");
00678 return cleanup (1, irecs, orec, orig, pspec, dispose);
00679 }
00680 } else {
00681 for (plane = 0, n = 0; plane < hplanes; plane++) {
00682 for (row = 0; row < rows; row++) {
00683 for (col = 0; col < cols; col++, n++) {
00684 js = (row == row % hrows) ? row + hrows : row - hrows;
00685 is = (col == col % hcols) ? col + hcols : col - hcols;
00686 m = plane * xcols * rows + js * xcols + 2 * is;
00687 if (is >= hcols) {
00688 m = 2 * (cols - is);
00689 if (js != 0) m += (rows - js) * xcols;
00690 if (plane != 0) m += (planes - plane) * xcols * rows;
00691 }
00692 data[n] = (dp_calc) ?
00693 wdata[m]*wdata[m] + wdata[m+1]*wdata[m+1] :
00694 xdata[m]*xdata[m] + xdata[m+1]*xdata[m+1];
00695 data[n] *= normal;
00696 if (n == 0) vmax = vmin = vmin2 = data[n];
00697 if (data[n] > vmax) vmax = data[n];
00698 if (data[n] < vmin) {
00699 vmin2 = vmin;
00700 vmin = data[n];
00701 }
00702 powrint += data[n];
00703 }
00704 }
00705 }
00706 }
00707 if (dp_calc) free (wdata);
00708 else free (xdata);
00709
00710 if (verbose) {
00711 printf (" P[0] = %11.4e (cf. apodized data mean = %11.4e)\n",
00712 data[cols * hrows + hcols], dataavg);
00713 printf (" S(P) = %11.4e (cf. apodized data var. = %11.4e)\n", powrint, datavar);
00714 }
00715
00716 oseg = drms_segment_lookupnum (orec, osegnum);
00717 if (verbose) printf (" values range from %.3e to %.3e\n", vmin, vmax);
00718 if (log_out) {
00719
00720
00721
00722
00723
00724 if (vmin < 0.1 * vmin2) {
00725 fprintf (stderr,
00726 "** Warning: minimum value = %.2e; value = log (%.2e + data)\n",
00727 vmin, vmin2);
00728 for (n = 0; n < ntot; n++) data[n] = log (vmin2 + data[n]);
00729 vmin = log (vmin2 + vmin);
00730 vmax = log (vmin2 + vmax);
00731 } else {
00732 for (n = 0; n < ntot; n++) data[n] = log (data[n]);
00733 vmin = log (vmin);
00734 vmax = log (vmax);
00735 }
00736 if (verbose) printf (" logs scaled between %f and %f\n", vmin, vmax);
00737 kstat += check_and_set_key_double (orec, "LOG_BASE", exp (1.0));
00738 }
00739
00740 kstat += check_and_set_key_float (orec, "DataMin", vmin);
00741 kstat += check_and_set_key_float (orec, "DataMax", vmax);
00742 kstat += check_and_set_key_str (orec, "Module", module_ident);
00743 kstat += check_and_set_key_str (orec, "BLD_VERS", jsoc_version);
00744 kstat += check_and_set_key_str (orec, "Source", source);
00745 kstat += check_and_set_key_str (orec, "Input", inser);
00746 kstat += check_and_set_key_time (orec, "Created", CURRENT_SYSTEM_TIME);
00747 if (kstat) {
00748 fprintf (stderr, "Error writing key value(s) to record in series %s\n",
00749 out_series);
00750 fprintf (stderr, " series may not have appropriate structure\n");
00751 fprintf (stderr, " record %d skipped\n", rgn);
00752 continue;
00753 }
00754 bscale = (vmax - vmin) / scale_range;
00755 bzero = 0.5 * (vmax + vmin);
00756 pspec = drms_array_create (DRMS_TYPE_FLOAT, 3, axes, data, &status);
00757 if (status) {
00758 fprintf (stderr, "Error: couldn't create output array\n");
00759 return cleanup (1, irecs, orec, orig, pspec, dispose);
00760 }
00761 pspec->bscale = bscale;
00762 pspec->bzero = bzero;
00763 if (bigcube) {
00764 fprintf (stderr,
00765 "Warning: call to drms_segment_write() may fail for %lld values\n",
00766 ntot);
00767 fprintf (stderr, " or results may be garbage\n");
00768 }
00769 status = drms_segment_write (oseg, pspec, 0);
00770 if (status) {
00771 drms_sprint_rec_query (recid, orec);
00772 fprintf (stderr, "Error writing data to record %s\n", recid);
00773 fprintf (stderr, " series may not have appropriate structure\n");
00774 return cleanup (1, irecs, orec, orig, pspec, dispose);
00775 }
00776 drms_free_array (pspec);
00777 pspec = NULL;
00778
00779 if (verbose) {
00780 drms_sprint_rec_query (recid, orec);
00781 if (no_save)
00782 printf ("output data record would be %s\n", recid);
00783 else {
00784 drms_segment_filename (oseg, pathname);
00785 printf ("output data record is %s\n", recid);
00786 printf ("output data cube at %s\n", pathname);
00787 }
00788 }
00789 drms_close_record (orec, dispose);
00790 }
00791
00792 fftwf_destroy_plan (fplan);
00793
00794 return cleanup (0, irecs, NULL, orig, pspec, dispose);
00795 }
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838