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 #include <jsoc_main.h>
00057 #include <stdio.h>
00058 #include <stdlib.h>
00059 #include <math.h>
00060 #include <sys/time.h>
00061 #include <sys/resource.h>
00062
00063 #define DTOR (M_PI / 180.)
00064
00065 #define ARRLENGTH(ARR) (sizeof(ARR) / sizeof(ARR[0]))
00066 #define DIE(msg) {fflush(stdout); fprintf(stderr, "%s, status=%d\n", msg, status); return(status);}
00067 #define SHOW(msg) {printf("%s", msg); fflush(stdout);}
00068
00069 #include "pfss.h"
00070 #include "pfss_pkg.h"
00071 #include "glbhs4gh.c"
00072 #include "timing.c"
00073
00074 char *module_name = "jsynop2gh";
00075
00076 ModuleArgs_t module_args[] =
00077 {
00078 {ARG_STRING, "in", NULL, "Input data series."},
00079 {ARG_STRING, "out", NULL, "Output data series."},
00080 {ARG_INT, "LMAX", "200", "Maximum l number desired."},
00081 {ARG_INT, "FFT", "1", "Set to one for FFT, numerical integration by default"},
00082 {ARG_FLOAT, "DPH0", "0.1", "Original longitude resolution."},
00083 {ARG_INT, "VERB", "1", "Level of verbosity: 0=errors/warnings; 1=all messages"},
00084 {ARG_END}
00085 };
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098 void ylm2gh(ylm, g, h, lmax)
00099 float *ylm, *g, *h;
00100 int lmax;
00101 {
00102 int l, m;
00103 int lmax1 = lmax + 1;
00104 float *gl, *hl, *yl, *ym;
00105 float kl[lmax1], km[lmax1];
00106
00107 for (l = 0; l <= lmax; l++) kl[l] = sqrt(2.0 * l + 1.0);
00108 km[0] = 0.5;
00109 for (m = 1; m <= lmax; m++) km[m] = sqrt(0.5);
00110
00111 for (l = 0; l <= lmax; l++) {
00112 gl = g + l * lmax1;
00113 hl = h + l * lmax1;
00114 yl = ylm + l * (l + 1);
00115 for (m = 0; m <= l; m++) {
00116 ym = yl + m * 2;
00117 gl[m] = ym[0] * kl[l] * km[m];
00118 hl[m] = ym[1] * kl[l] * km[m];
00119 }
00120 hl[0] = 0.0;
00121 }
00122 }
00123
00124
00125
00126
00127 int DoIt(void)
00128 {
00129 int status = DRMS_SUCCESS;
00130 char *inQuery, *outQuery;
00131 DRMS_RecordSet_t *inRS, *outRS;
00132 int irec, nrecs;
00133 DRMS_Record_t *inRec, *outRec;
00134 DRMS_Segment_t *inSeg, *outSeg_g, *outSeg_h;
00135 DRMS_Array_t *inArray, *outArray_g, *outArray_h;
00136 DRMS_Link_t *srcLink;
00137 float *inData, *g, *h;
00138
00139 char *inchecklist[] = {"CAR_ROT", "CDELT1", "CDELT2", "CTYPE2",
00140 "LON_FRST"};
00141 char *outchecklist[] = {"CAR_ROT", "LON0", "LMAX"};
00142 DRMS_Record_t *inRec_tmp, *outRec_tmp;
00143 DRMS_Keyword_t *inkeytest, *outkeytest;
00144
00145 int verbflag;
00146 int outDims[2];
00147 int lmax, lmax1, lmax2;
00148 int fft, sinlat;
00149 int map_lmax;
00150 int car_rot;
00151 float lon_frst, lon0, dph0;
00152 double cdelt1, cdelt2;
00153 float sinBdelta;
00154 char *ctype2;
00155
00156 int i, l, m, itest;
00157 int np, nt, npnt;
00158
00159 struct Grid *grid;
00160
00161
00162 double wt0, wt1, wt;
00163 double ut0, ut1, ut;
00164 double st0, st1, st;
00165 double ct0, ct1, ct;
00166 wt0 = getwalltime();
00167 ct0 = getcputime(&ut0, &st0);
00168
00169
00170 float *map_mlat, *ylm;
00171
00172
00173 inQuery = (char *)params_get_str(&cmdparams, "in");
00174 outQuery = (char *)params_get_str(&cmdparams, "out");
00175 lmax = params_get_int(&cmdparams, "LMAX");
00176 fft = params_get_int(&cmdparams, "FFT");
00177 dph0 = params_get_float(&cmdparams, "DPH0");
00178 verbflag = params_get_int(&cmdparams, "VERB");
00179
00180 lmax1 = lmax + 1; lmax2 = lmax + 2;
00181 outDims[0] = outDims[1] = lmax1;
00182
00183
00184 inRS = drms_open_records(drms_env, inQuery, &status);
00185 if (status || inRS->n == 0) DIE("No input data found");
00186 nrecs = inRS->n;
00187
00188
00189 inRec_tmp = inRS->records[0];
00190 for (itest = 0; itest < ARRLENGTH(inchecklist); itest++) {
00191 inkeytest = hcon_lookup_lower(&inRec_tmp->keywords, inchecklist[itest]);
00192 if (!inkeytest) {
00193 fprintf(stderr, "ERROR: required input keyword %s is missing\n", inchecklist[itest]);
00194 return 0;
00195 }
00196 }
00197
00198
00199 outRec_tmp = drms_create_record(drms_env, outQuery, DRMS_TRANSIENT, &status);
00200 if (status) DIE("Unable to open record in output series");
00201 for (itest = 0; itest < ARRLENGTH(outchecklist); itest++) {
00202 outkeytest = hcon_lookup_lower(&outRec_tmp->keywords, outchecklist[itest]);
00203 if (!outkeytest || outkeytest->info->islink || outkeytest->info->recscope == 1) {
00204 fprintf(stderr, "Output keyword %s is missing/constant/a link.\n", outchecklist[itest]);
00205 return 0;
00206 }
00207 }
00208 drms_close_record(outRec_tmp, DRMS_FREE_RECORD);
00209
00210
00211 outRS = drms_create_records(drms_env, nrecs, outQuery, DRMS_PERMANENT, &status);
00212 if (status) DIE("Output recordset not created");
00213
00214
00215 for (irec = 0; irec < nrecs; irec++)
00216 {
00217 if (verbflag) {
00218 wt1 = getwalltime();
00219 ct1 = getcputime(&ut1, &st1);
00220 printf("processing record %d...\n", irec);
00221 }
00222
00223
00224 inRec = inRS->records[irec];
00225 inSeg = drms_segment_lookupnum(inRec, 0);
00226 inArray = drms_segment_read(inSeg, DRMS_TYPE_FLOAT, &status);
00227 if (status) {
00228 printf("No data file found. \n");
00229 drms_free_array(inArray);
00230 continue;
00231 }
00232 inData = (float *)inArray->data;
00233 np = inArray->axis[0]; nt = inArray->axis[1];
00234
00235
00236 ctype2 = drms_getkey_string(inRec_tmp, "CTYPE2", &status);
00237 sinlat = (strcmp(ctype2, "Sine Latitude") == 0 || strcmp(ctype2, "CRLT-CEA") == 0) ? 1 : 0;
00238 if (!sinlat && fft)
00239 DIE("Input not in sine latitude, can't use FFT");
00240 cdelt1 = fabs(drms_getkey_double(inRec_tmp, "CDELT1", &status));
00241 cdelt2 = fabs(drms_getkey_double(inRec_tmp, "CDELT2", &status));
00242 map_lmax = (int)(180. / cdelt1);
00243 if (lmax > map_lmax) DIE("Request lmax greater than input lmax");
00244 sinBdelta = cdelt2;
00245
00246 if ((fabs(cdelt1 - dph0) >= 0.1 * dph0) && fft)
00247 DIE("Not original data resolution, can't use FFT");
00248
00249
00250 npnt = np * nt;
00251 for (i = 0; i < npnt; i++) if (isnan(inData[i])) break;
00252 if (i < npnt && isnan(inData[i])) {
00253 printf("Missing points in data. \n");
00254 drms_free_array(inArray);
00255 continue;
00256 }
00257
00258
00259 g = (float *)calloc(lmax1 * lmax1, sizeof(float));
00260 h = (float *)calloc(lmax1 * lmax1, sizeof(float));
00261 outArray_g = drms_array_create(DRMS_TYPE_FLOAT, 2, outDims, g, &status);
00262 outArray_h = drms_array_create(DRMS_TYPE_FLOAT, 2, outDims, h, &status);
00263
00264
00265 if (fft) {
00266
00267 if (verbflag) SHOW("starting FFT method... ");
00268
00269 printf("%d, %d\n", nt, lmax1);
00270
00271
00272
00273 map_mlat = (float *)(malloc(nt * 2 * lmax1 * sizeof(float)));
00274 SHOW("0");
00275 helio2mlat(inData, map_mlat, np, nt, lmax, map_lmax);
00276 SHOW("1");
00277
00278 ylm = (float *)(malloc(lmax1 * lmax2 * sizeof(float)));
00279 qdotprod(map_mlat, ylm, nt, 0, lmax, sinBdelta);
00280 SHOW("2");
00281
00282 ylm2gh(ylm, g, h, lmax);
00283 free(map_mlat); free(ylm);
00284 if (verbflag) SHOW("done.\n");
00285
00286 } else {
00287
00288
00289 grid = (struct Grid *)(malloc(sizeof(struct Grid)));
00290 grid->np = np; grid->nt = nt;
00291 grid->ph = (float *)(calloc(np, sizeof(float)));
00292 grid->th = (float *)(calloc(nt, sizeof(float)));
00293 for (int i = 0; i < np; i++)
00294 grid->ph[i] = (i + 0.5) / np * 2 * M_PI - dph0 / 2.0 * DTOR;
00295 for (int j = 0; j < nt; j++)
00296 grid->th[j] = sinlat ? acos(1.0 - 2.0 * (nt - j - 0.5) / nt) :
00297 ((nt - j - 0.5) / nt * M_PI);
00298
00299 if (verbflag) SHOW("starting Mag method... ");
00300 gh_pfss(inData, g, h, grid, lmax, sinlat);
00301 if (verbflag) SHOW("done.\n");
00302 free(grid);
00303
00304 }
00305
00306
00307 for (l = 0; l <= lmax; l++) {
00308 for (m = l + 1; m <= lmax; m++) {
00309 g[l * lmax1 + m] = DRMS_MISSING_FLOAT;
00310 h[l * lmax1 + m] = DRMS_MISSING_FLOAT;
00311 }
00312 }
00313
00314 drms_free_array(inArray);
00315
00316
00317 outRec = outRS->records[irec];
00318 outSeg_g = drms_segment_lookup(outRec, "g");
00319 outSeg_h = drms_segment_lookup(outRec, "h");
00320 for (i = 0; i < 2; i++) {
00321 outSeg_g->axis[i] = outArray_g->axis[i];
00322 outSeg_h->axis[i] = outArray_h->axis[i];
00323 }
00324 outArray_g->parent_segment = outSeg_g;
00325 outArray_h->parent_segment = outSeg_h;
00326
00327
00328 status = drms_segment_write(outSeg_g, outArray_g, 0);
00329 if (status) DIE("Problem writing g file");
00330
00331 status = drms_segment_write(outSeg_h, outArray_h, 0);
00332 if (status) DIE("Problem writing h file");
00333
00334 free(g); free(h);
00335
00336
00337 drms_setkey_string(outRec, "BLD_VERS", jsoc_version);
00338 drms_setkey_time(outRec, "DATE", CURRENT_SYSTEM_TIME);
00339 drms_copykey(outRec, inRec, "T_REC");
00340 drms_copykey(outRec, inRec, "T_OBS");
00341 car_rot = drms_getkey_int(inRec, "CAR_ROT", NULL);
00342 lon_frst = drms_getkey_float(inRec, "LON_FRST", NULL);
00343 lon0 = car_rot * 360. - (lon_frst + 360.);
00344 drms_copykey(outRec, inRec, "CAR_ROT");
00345 drms_setkey_float(outRec, "LON0", lon0);
00346 drms_setkey_int(outRec, "LMAX", lmax);
00347 drms_setkey_int(outRec, "FFT", fft);
00348 drms_setkey_int(outRec, "SINLAT", sinlat);
00349 drms_setkey_int(outRec, "NP", np);
00350 drms_setkey_int(outRec, "NT", nt);
00351
00352
00353 srcLink = hcon_lookup_lower(&outRec->links, "SYNOP");
00354 if (srcLink) {
00355 drms_setlink_static(outRec, "SYNOP", inRec->recnum);
00356 }
00357
00358
00359 if (verbflag) {
00360 wt = getwalltime();
00361 ct = getcputime(&ut, &st);
00362 printf("record %d done, %.2f ms wall time, %.2f ms cpu time\n",
00363 irec, wt - wt1, ct - ct1);
00364 }
00365 }
00366
00367 drms_close_records(inRS, DRMS_FREE_RECORD);
00368 drms_close_records(outRS, DRMS_INSERT_RECORD);
00369
00370 if (verbflag) {
00371 wt = getwalltime();
00372 ct = getcputime(&ut, &st);
00373 printf("total time spent: %.2f ms wall time, %.2f ms cpu time\n",
00374 wt - wt0, ct - ct0);
00375 }
00376
00377 return(DRMS_SUCCESS);
00378 }