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 #include "jsoc_main.h"
00034 #include "astro.h"
00035
00036 char *module_name = "Image Regrid";
00037
00038 #define kRecSetIn "recsin"
00039 #define kSeriesOut "dsout"
00040 #define kCols "cols"
00041 #define kRows "rows"
00042 #define kNotSpecified "NotSpecified"
00043 #define kXSCALE "XSCALE"
00044 #define kYSCALE "YSCALE"
00045 #define kX0 "XO"
00046 #define kY0 "YO"
00047 #define kR_SUN "R_SUN"
00048 #define kMAGNIFY "MAGNIFY"
00049 #define kIM_SCALE "IM_SCALE"
00050 #define kQUALITY "QUALITY"
00051
00052
00053 ModuleArgs_t module_args[] =
00054 {
00055 {ARG_STRING, kRecSetIn, "", "Input data series."},
00056 {ARG_STRING, kSeriesOut, "", "Output data series."},
00057 {ARG_INT, kCols, "0", "Number of output columns (default to original)"},
00058 {ARG_INT, kRows, "0", "Number of output rows (default to original)"},
00059 {ARG_NUME, "3", "0", "Cubic-convolution interpolation (default to bilinear).", "bilinear, cubic"},
00060 {ARG_FLAG, "e", "0", "Embed rectangular data in enclosing square.", "-1:1"},
00061
00062
00063
00064
00065 {ARG_END}
00066 };
00067
00068
00069
00070
00071
00072 int update_scale_loc(DRMS_Record_t *rec, double xmag, double ymag)
00073 {
00074
00075 double dval;
00076 double new;
00077 int platform, instrument;
00078 int status = 0;
00079 int error = 0;
00080
00081 if (xmag == 1.0 && ymag == 1.0) return 0;
00082
00083 dval = drms_getkey_double(rec, kXSCALE, &status);
00084 if (status == DRMS_SUCCESS)
00085 {
00086 new = dval / xmag;
00087 error = (status = drms_setkey_double(rec, kXSCALE, new)) == DRMS_SUCCESS;
00088 }
00089
00090 dval = drms_getkey_double(rec, kYSCALE, &status);
00091 if (status == DRMS_SUCCESS)
00092 {
00093 new = dval / ymag;
00094 status = drms_setkey_double(rec, kYSCALE, new);
00095 if (!error)
00096 {
00097 error = (status == DRMS_SUCCESS);
00098 }
00099 }
00100
00101 dval = drms_getkey_double(rec, kX0, &status);
00102 if (status == DRMS_SUCCESS)
00103 {
00104 new = dval * xmag;
00105 status = drms_setkey_double(rec, kX0, new);
00106
00107 if (!error)
00108 {
00109 error = (status == DRMS_SUCCESS);
00110 }
00111 }
00112
00113 dval = drms_getkey_double(rec, kY0, &status);
00114 if (status == DRMS_SUCCESS)
00115 {
00116 new = dval * ymag;
00117 status = drms_setkey_double(rec, kY0, new);
00118
00119 if (!error)
00120 {
00121 error = (status == DRMS_SUCCESS);
00122 }
00123 }
00124
00125 if (xmag == ymag)
00126 {
00127 dval = drms_getkey_double(rec, kR_SUN, &status);
00128 if (status == DRMS_SUCCESS)
00129 {
00130 new = dval * xmag;
00131 status = drms_setkey_double(rec, kR_SUN, new);
00132
00133 if (!error)
00134 {
00135 error = (status == DRMS_SUCCESS);
00136 }
00137 }
00138
00139 new = xmag;
00140
00141 dval = drms_getkey_double(rec, kMAGNIFY, &status);
00142 if (status == DRMS_SUCCESS)
00143 {
00144 new *= dval;
00145 status = drms_setkey_double(rec, kMAGNIFY, new);
00146
00147 if (!error)
00148 {
00149 error = (status == DRMS_SUCCESS);
00150 }
00151 }
00152
00153 dval = drms_getkey_double(rec, kIM_SCALE, &status);
00154 if (status == DRMS_SUCCESS)
00155 {
00156 new = dval / xmag;
00157 status = drms_setkey_double(rec, kIM_SCALE, new);
00158
00159 if (!error)
00160 {
00161 error = (status == DRMS_SUCCESS);
00162 }
00163 }
00164 }
00165
00166 return error;
00167 }
00168
00169 static int ValidateSeries(DRMS_Env_t *drmsEnv,
00170 const char *inSeriesName,
00171 const char *seriesOutParam,
00172 char *outSeriesName,
00173 int size,
00174 int cols,
00175 int rows,
00176 HContainer_t **matchSegNames)
00177 {
00178 int status = DRMS_SUCCESS;
00179
00180 if (strcmp(seriesOutParam, kNotSpecified) == 0)
00181 {
00182
00183
00184
00185
00186
00187 fprintf(stderr, "Must specify an output series.\n");
00188 status = DRMS_ERROR_INVALIDDATA;
00189 }
00190 else if (drms_series_exists(drmsEnv, inSeriesName, &status))
00191 {
00192 char **segNames = NULL;
00193 HContainer_t *segProtoI = NULL;
00194 int idx = 0;
00195 int nNames;
00196
00197
00198 DRMS_Record_t *sourceRec = drms_template_record(drms_env, inSeriesName, &status);
00199 DRMS_Record_t *prototype = drms_create_recproto(sourceRec, &status);
00200
00201 if (status == DRMS_SUCCESS)
00202 {
00203
00204 int bArchive = 0;
00205 int nDaysRetention = 7;
00206 char *description = "regrid module output series";
00207 drms_recproto_setseriesinfo(prototype,
00208 NULL,
00209 &bArchive,
00210 &nDaysRetention,
00211 NULL,
00212 description);
00213
00214
00215 DRMS_SegmentDimInfo_t dims;
00216 dims.naxis = 2;
00217 dims.axis[0] = cols;
00218 dims.axis[1] = rows;
00219
00220
00221 segProtoI = drms_segment_createinfocon(drmsEnv, inSeriesName, &status);
00222 nNames = hcon_size(segProtoI);
00223 segNames = (char **)malloc(sizeof(char *) * nNames);
00224
00225
00226 HIterator_t hiter;
00227 DRMS_SegmentInfo_t *aSegInfo = NULL;
00228
00229 idx = 0;
00230 hiter_new_sort(&hiter, segProtoI, drms_segment_ranksort);
00231 while (status == DRMS_SUCCESS && (aSegInfo = hiter_getnext(&hiter)) != NULL)
00232 {
00233 segNames[idx] = (char *)malloc(sizeof(char) * DRMS_MAXSEGNAMELEN);
00234 strncpy(segNames[idx], aSegInfo->name, DRMS_MAXSEGNAMELEN);
00235 segNames[idx][DRMS_MAXSEGNAMELEN - 1] = '\0';
00236
00237 DRMS_Segment_t *segproto = drms_segment_lookup(prototype, segNames[idx]);
00238 status = drms_segment_setdims(segproto, &dims);
00239 idx++;
00240 }
00241
00242 snprintf(outSeriesName, size, seriesOutParam);
00243 if (drms_series_exists(drms_env, outSeriesName, &status))
00244 {
00245
00246
00247
00248 *matchSegNames = (HContainer_t *)malloc(sizeof(HContainer_t));
00249 XASSERT(*matchSegNames != NULL);
00250 int nMatch = 0;
00251 int compat = drms_series_checkrecordcompat(drms_env,
00252 outSeriesName,
00253 prototype,
00254 *matchSegNames,
00255 &status);
00256
00257 if (compat != 1)
00258 {
00259 fprintf(stderr, "Output series %s is not compatible with output data.\n", outSeriesName);
00260 status = DRMS_ERROR_INVALIDDATA;
00261 }
00262 }
00263 else
00264 {
00265
00266 status = drms_create_series_fromprototype(&prototype, outSeriesName, 0);
00267 if (status != DRMS_SUCCESS)
00268 {
00269 fprintf(stderr, "Couldn't create new series %s.\n", outSeriesName);
00270 }
00271 else
00272 {
00273
00274 *matchSegNames = hcon_create(DRMS_MAXSEGNAMELEN,
00275 DRMS_MAXSEGNAMELEN,
00276 NULL,
00277 NULL,
00278 (void **)segNames,
00279 segNames,
00280 nNames);
00281 }
00282 }
00283 }
00284
00285 if (segNames)
00286 {
00287 for (idx = 0; idx < nNames; idx++)
00288 {
00289 free(segNames[idx]);
00290 }
00291
00292 free(segNames);
00293 }
00294 }
00295 else
00296 {
00297 fprintf(stderr, "Specified input series %s does not exist.\n", inSeriesName);
00298 }
00299
00300 return status;
00301 }
00302
00303 static int DoMain(DRMS_Array_t **dataArr,
00304 int naxis,
00305 int *dims,
00306 int *length,
00307 int embed,
00308 LIBASTRO_Interpolation_t scheme,
00309 int *status)
00310 {
00311 int error = 0;
00312 *status = DRMS_SUCCESS;
00313
00314 if (embed)
00315 {
00316 float *dat = (float *)((*dataArr)->data);
00317 float fill = F_NAN;
00318 int oc = dims[0];
00319 int or = dims[1];
00320 int c, r, liml;
00321
00322 length[0] = length[1] = (oc > or) ? oc : or;
00323
00324
00325
00326
00327 float *rdat = (float *)malloc(drms_array_size(*dataArr));
00328
00329 if (oc > or) {
00330 liml = (oc - or) / 2;
00331 for (r = 0; r < or; r++)
00332 for (c = 0; c < oc; c++)
00333 rdat[c + oc * (r + liml)] = dat[c + oc * r];
00334 }
00335 else
00336 {
00337 liml = (or - oc) / 2;
00338 for (r = 0; r < or; r++)
00339 for (c = 0; c < oc; c++)
00340 rdat[c + liml + oc * r] = dat[c + oc * r];
00341 }
00342
00343 drms_free_array(*dataArr);
00344 *dataArr = drms_array_create(DRMS_TYPE_FLOAT,
00345 naxis,
00346 dims,
00347 rdat,
00348 status);
00349 }
00350
00351 if (*status == DRMS_SUCCESS)
00352 {
00353
00354 error = (Regrid(dataArr, length, scheme) != kLIBASTRO_Success);
00355 }
00356
00357 return error;
00358 }
00359
00360 int DoIt(void)
00361 {
00362 int error = 0;
00363 int status = 0;
00364
00365 double xmag, ymag;
00366 int length[3];
00367
00368 const char *inRecQuery = cmdparams_get_str(&cmdparams, kRecSetIn, NULL);
00369 const char *seriesOut = cmdparams_get_str(&cmdparams, kSeriesOut, NULL);
00370 int cols = cmdparams_get_int(&cmdparams, kCols, NULL);
00371 int rows = cmdparams_get_int(&cmdparams, kRows, NULL);
00372 LIBASTRO_Interpolation_t scheme = (LIBASTRO_Interpolation_t)(cmdparams_get_int(&cmdparams,
00373 "3",
00374 NULL));
00375 int embed = cmdparams_get_int(&cmdparams, "e", NULL);
00376
00377 char inSeriesName[DRMS_MAXSERIESNAMELEN];
00378 char outSeriesName[DRMS_MAXSERIESNAMELEN];
00379 HContainer_t *matchSegNames = NULL;
00380
00381
00382
00383 snprintf(inSeriesName, sizeof(inSeriesName), inRecQuery);
00384 char *pChar = strchr(inSeriesName, '[');
00385 if (pChar != NULL)
00386 {
00387 *pChar = '\0';
00388 }
00389
00390
00391
00392 status = ValidateSeries(drms_env,
00393 inSeriesName,
00394 seriesOut,
00395 outSeriesName,
00396 sizeof(outSeriesName),
00397 cols,
00398 rows,
00399 &matchSegNames);
00400 error = (status != DRMS_SUCCESS);
00401
00402 if (!error)
00403 {
00404 int nInRecs = 0;
00405 DRMS_RecordSet_t *inRecSet = drms_open_records(drms_env, inRecQuery, &status);
00406 error = (status != DRMS_SUCCESS);
00407
00408 if (!error)
00409 {
00410 nInRecs = inRecSet->n;
00411 }
00412
00413 int quality;
00414
00415 int iRec = 0;
00416 DRMS_Record_t *inRec = NULL;
00417 DRMS_Record_t *outRec = NULL;
00418
00419
00420 for (; !error && iRec < nInRecs; iRec++)
00421 {
00422 inRec = inRecSet->records[iRec];
00423
00424 quality = drms_getkey_int(inRec, kQUALITY, &status);
00425 if (status == DRMS_SUCCESS)
00426 {
00427 if (quality == kALLDATAMISSING)
00428 {
00429 continue;
00430 }
00431 }
00432
00433 outRec = drms_create_record(drms_env, outSeriesName, DRMS_PERMANENT, &status);
00434 error = (status != DRMS_SUCCESS);
00435
00436
00437
00438
00439
00440 DRMS_Keyword_t *inKey = NULL;
00441 DRMS_Keyword_t *outKey = NULL;
00442
00443 HIterator_t *hit = hiter_create(&(inRec->keywords));
00444 error = (hit == NULL);
00445
00446 while (!error && (inKey = (DRMS_Keyword_t *)hiter_getnext(hit)) != NULL)
00447 {
00448 outKey = drms_keyword_lookup(outRec, inKey->info->name, 1);
00449 if (outKey != NULL)
00450 {
00451 status = drms_setkey(outRec,
00452 outKey->info->name,
00453 outKey->info->type,
00454 &(inKey->value));
00455
00456 error = (status != DRMS_SUCCESS);
00457 }
00458 }
00459
00460 if (hit)
00461 {
00462 hiter_destroy(&hit);
00463 }
00464
00465 hit = hiter_create(matchSegNames);
00466 char *oneSegName = NULL;
00467 DRMS_Array_t *dataArr = NULL;
00468 int naxis = 0;
00469 int *dims = NULL;
00470 DRMS_Segment_t *inSeg = NULL;
00471 DRMS_Segment_t *outSeg = NULL;
00472
00473 error = (hit == NULL);
00474
00475 while (!error && NULL != (oneSegName = (char *)hiter_getnext(hit)))
00476 {
00477 inSeg = drms_segment_lookup(inRec, oneSegName);
00478 XASSERT(inSeg != NULL);
00479 outSeg = drms_segment_lookup(outRec, oneSegName);
00480 XASSERT(outSeg != NULL);
00481
00482 if (inSeg != NULL && outSeg != NULL)
00483 {
00484 naxis = inSeg->info->naxis;
00485 dims = inSeg->axis;
00486
00487 if (naxis != 2)
00488 {
00489 continue;
00490 }
00491
00492 length[0] = (cols) ? cols : dims[0];
00493 length[1] = (rows) ? rows : dims[1];
00494
00495 int doEmbed = 0;
00496
00497 if (embed && dims[0] != dims[1])
00498 {
00499 doEmbed = 1;
00500
00501
00502
00503 dataArr = drms_segment_read(inSeg, DRMS_TYPE_FLOAT, &status);
00504 error = (status == DRMS_SUCCESS);
00505 }
00506 else
00507 {
00508
00509 dataArr = drms_segment_read(inSeg, DRMS_TYPE_RAW, &status);
00510 error = (status != DRMS_SUCCESS);
00511 }
00512
00513 if (!error)
00514 {
00515 error = DoMain(&dataArr, naxis, dims, length, doEmbed, scheme, &status);
00516
00517
00518 if (!error)
00519 {
00520 drms_segment_write(outSeg, dataArr, 0);
00521 }
00522
00523
00524
00525
00526
00527
00528
00529 xmag = cols / (double) dims[0];
00530 ymag = rows / (double) dims[1];
00531 update_scale_loc(outRec, xmag, ymag);
00532 }
00533
00534 if (dataArr)
00535 {
00536 drms_free_array(dataArr);
00537 }
00538 }
00539 }
00540
00541 if (hit)
00542 {
00543 hiter_destroy(&hit);
00544 }
00545
00546
00547 if (!error)
00548 {
00549 drms_close_record(outRec, DRMS_INSERT_RECORD);
00550 }
00551 else
00552 {
00553 drms_close_record(outRec, DRMS_FREE_RECORD);
00554 }
00555 }
00556 }
00557
00558 hcon_destroy(&matchSegNames);
00559
00560 return error;
00561 }