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 #include <jsoc_main.h>
00033 #include <stdio.h>
00034 #include <stdlib.h>
00035 #include <math.h>
00036 #include <sys/time.h>
00037 #include <sys/resource.h>
00038
00039 #define DTOR (M_PI / 180.)
00040
00041 #define ARRLENGTH(ARR) (sizeof(ARR) / sizeof(ARR[0]))
00042 #define DIE(msg) {fflush(stdout); fprintf(stderr, "%s, status=%d\n", msg, status); return(status);}
00043 #define SHOW(msg) {printf("%s", msg); fflush(stdout);}
00044
00045 #include "pfss.h"
00046 #include "hccsss_pkg.h"
00047
00048 #include "timing.c"
00049
00050 char *module_name = "jgh2hccsss";
00051
00052 ModuleArgs_t module_args[] =
00053 {
00054 {ARG_STRING, "in", NULL, "Input data series."},
00055 {ARG_STRING, "out", NULL, "Output data series."},
00056 {ARG_INT, "LMAX", "72", "Maximum l number used below rcp."},
00057 {ARG_INT, "LC", "15", "Maximum l number desired above rcp."},
00058 {ARG_INT, "SINLAT", "0", "Set to zero for latitude grid; lat by default."},
00059 {ARG_INT, "NP", "360", "Number of Grid points in longitude."},
00060 {ARG_INT, "NT", "180", "Number of Grid points in latitude."},
00061 {ARG_INT, "NR", "31", "Number of Grid points in radial direction."},
00062 {ARG_FLOAT, "DR", "0.1", "Step size in radial direction."},
00063 {ARG_FLOAT, "APAR", "0.2", "Parameterized length scale of horizontal current"},
00064 {ARG_INT, "VERB", "1", "Level of verbosity: 0=errors/warnings; 1=all messages"},
00065 {ARG_END}
00066 };
00067
00068
00069
00070
00071
00072 int DoIt(void)
00073 {
00074 int status = DRMS_SUCCESS;
00075 char *inQuery, *outQuery;
00076 DRMS_RecordSet_t *inRS, *outRS;
00077 int irec, nrecs;
00078 DRMS_Record_t *inRec, *outRec, *linkedRec;
00079 DRMS_Segment_t *inSegG, *inSegH;
00080 DRMS_Segment_t *outSegBr, *outSegBt, *outSegBp, *outSegGc, *outSegHc;
00081 DRMS_Array_t *inArrayG, *inArrayH;
00082 DRMS_Array_t *outArrayBr, *outArrayBt, *outArrayBp, *outArrayGc, *outArrayHc;
00083 DRMS_Link_t *synopLink, *ghLink;
00084 float *inDataG, *inDataH;
00085 float *g, *h, *gc, *hc;
00086 float *Br, *Bt, *Bp;
00087
00088 char *inchecklist[] = {"CAR_ROT", "LON0", "LMAX"};
00089 char *outchecklist[] = {"CAR_ROT", "LON0", "LMAX", "LC", "CTYPE2"};
00090 DRMS_Record_t *inRec_tmp, *outRec_tmp;
00091 DRMS_Keyword_t *inkeytest, *outkeytest;
00092
00093 int outDims[3], outDimsGHc[2];
00094 int lmax, lmax1, lc, lc1;
00095 int want_lmax, have_lmax;
00096 int sinlat, car_rot, verbflag;
00097 int np, nt, nr;
00098 float apar, dr;
00099
00100 int i, j, n;
00101 int l, m, itest;
00102 int n0, n1;
00103
00104 struct Grid *grid;
00105
00106
00107 double wt0, wt1, wt;
00108 double ut0, ut1, ut;
00109 double st0, st1, st;
00110 double ct0, ct1, ct;
00111 wt0 = getwalltime();
00112 ct0 = getcputime(&ut0, &st0);
00113
00114
00115 inQuery = (char *)params_get_str(&cmdparams, "in");
00116 outQuery = (char *)params_get_str(&cmdparams, "out");
00117 want_lmax = params_get_int(&cmdparams, "LMAX");
00118 lc = params_get_int(&cmdparams, "LC");
00119 sinlat = params_get_int(&cmdparams, "SINLAT");
00120 np = params_get_int(&cmdparams, "NP");
00121 nt = params_get_int(&cmdparams, "NT");
00122 nr = params_get_int(&cmdparams, "NR");
00123 dr = params_get_float(&cmdparams, "DR");
00124 apar = params_get_float(&cmdparams, "APAR");
00125 verbflag = params_get_int(&cmdparams, "VERB");
00126
00127 outDims[0] = np; outDims[1] = nt; outDims[2] = nr;
00128 lc1 = lc + 1;
00129 outDimsGHc[0] = lc1; outDimsGHc[1] = lc1;
00130
00131
00132 inRS = drms_open_records(drms_env, inQuery, &status);
00133 if (status || inRS->n == 0) DIE("No input data found");
00134 nrecs = inRS->n;
00135
00136
00137 inRec_tmp = inRS->records[0];
00138 for (itest = 0; itest < ARRLENGTH(inchecklist); itest++) {
00139 inkeytest = hcon_lookup_lower(&inRec_tmp->keywords, inchecklist[itest]);
00140 if (!inkeytest) {
00141 fprintf(stderr, "ERROR: required input keyword %s is missing\n", inchecklist[itest]);
00142 return 0;
00143 }
00144 }
00145 have_lmax = drms_getkey_int(inRec_tmp, "LMAX", &status);
00146 if (want_lmax > have_lmax) DIE("Request lmax greater than input lmax");
00147
00148
00149 outRec_tmp = drms_create_record(drms_env, outQuery, DRMS_TRANSIENT, &status);
00150 if (status) DIE("Unable to open record in output series");
00151 for (itest = 0; itest < ARRLENGTH(outchecklist); itest++) {
00152 outkeytest = hcon_lookup_lower(&outRec_tmp->keywords, outchecklist[itest]);
00153 if (!outkeytest || outkeytest->info->islink || outkeytest->info->recscope == 1) {
00154 fprintf(stderr, "Output keyword %s is missing/constant/a link.\n", outchecklist[itest]);
00155 return 0;
00156 }
00157 }
00158 drms_close_record(outRec_tmp, DRMS_FREE_RECORD);
00159
00160
00161 outRS = drms_create_records(drms_env, nrecs, outQuery, DRMS_PERMANENT, &status);
00162 if (status) DIE("Output recordset not created");
00163
00164
00165 grid = (struct Grid *)(malloc(sizeof(struct Grid)));
00166 grid->np = np; grid->nt = nt; grid->nr = nr;
00167 grid->ph = (float *)(calloc(np, sizeof(float)));
00168 grid->th = (float *)(calloc(nt, sizeof(float)));
00169 grid->rr = (float *)(calloc(nr, sizeof(float)));
00170 for (i = 0; i < np; i++)
00171 grid->ph[i] = (i + 0.5) / np * 2 * M_PI;
00172 for (j = 0; j < nt; j++)
00173 grid->th[j] = sinlat ? acos(1.0 - 2.0 * (nt - j - 0.5) / nt) : ((nt - j - 0.5) / nt * M_PI);
00174
00175
00176
00177
00178 if (nr != 1) {
00179 for (n = 0; n < nr; n++)
00180 grid->rr[n] = R0 + dr * n;
00181 } else {
00182 grid->rr[0] = RS;
00183 printf("Only one point specified in radial direction, compute source surface.\n");
00184 }
00185
00186
00187 for (irec = 0; irec < nrecs; irec++) {
00188
00189 if (verbflag) {
00190 wt1 = getwalltime();
00191 ct1 = getcputime(&ut1, &st1);
00192 printf("processing record %d...\n", irec);
00193 }
00194
00195
00196 inRec = inRS->records[irec];
00197
00198 inSegG = drms_segment_lookup(inRec, "g");
00199 inArrayG = drms_segment_read(inSegG, DRMS_TYPE_FLOAT, &status);
00200 if (status) {
00201 printf("No G data file found. \n");
00202 drms_free_array(inArrayG);
00203 continue;
00204 }
00205 inDataG = (float *)inArrayG->data;
00206
00207 inSegH = drms_segment_lookup(inRec, "h");
00208 inArrayH = drms_segment_read(inSegH, DRMS_TYPE_FLOAT, &status);
00209 if (status) {
00210 printf("No H data file found. \n");
00211 drms_free_array(inArrayH);
00212 continue;
00213 }
00214 inDataH = (float *)inArrayH->data;
00215
00216 car_rot = drms_getkey_int(inRec, "CAR_ROT", &status);
00217
00218
00219 n0 = inArrayG->axis[0];
00220 n1 = inArrayG->axis[1];
00221 if (n0 != n1 || (n0 - 1) != have_lmax)
00222 DIE("Wrong input data dimension");
00223 if (want_lmax > have_lmax)
00224 DIE("Request lmax greater than available lmax");
00225 lmax = want_lmax;
00226 lmax1 = lmax + 1;
00227 g = (float *)(calloc(lmax1 * lmax1, sizeof(float)));
00228 h = (float *)(calloc(lmax1 * lmax1, sizeof(float)));
00229 for (int l = 0; l <= lmax; l++) {
00230 for (int m = 0; m <= l; m++) {
00231 g[l * lmax1 + m] = inDataG[l * n0 + m];
00232 h[l * lmax1 + m] = inDataH[l * n0 + m];
00233
00234 }
00235 }
00236 g[0] = 0.0; h[0] = 0.0;
00237 drms_free_array(inArrayG); drms_free_array(inArrayH);
00238
00239
00240 outArrayBr = drms_array_create(DRMS_TYPE_FLOAT, 3, outDims, NULL, &status);
00241 outArrayBt = drms_array_create(DRMS_TYPE_FLOAT, 3, outDims, NULL, &status);
00242 outArrayBp = drms_array_create(DRMS_TYPE_FLOAT, 3, outDims, NULL, &status);
00243 outArrayGc = drms_array_create(DRMS_TYPE_FLOAT, 2, outDimsGHc, NULL, &status);
00244 outArrayHc = drms_array_create(DRMS_TYPE_FLOAT, 2, outDimsGHc, NULL, &status);
00245 Br = (float *)outArrayBr->data;
00246 Bt = (float *)outArrayBt->data;
00247 Bp = (float *)outArrayBp->data;
00248 gc = (float *)outArrayGc->data;
00249 hc = (float *)outArrayHc->data;
00250
00251
00252 if (verbflag) SHOW("start computing coefficient... ");
00253 gh_hccsss(g, h, grid, lmax, gc, hc, lc, apar);
00254 if (verbflag) SHOW("done.\n");
00255 if (verbflag) SHOW("start computing field... ");
00256 hccsss(g, h, gc, hc, grid, Br, Bt, Bp, lmax, lc, apar);
00257 if (verbflag) SHOW("done.\n");
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272 free(g); free(h);
00273
00274
00275 outRec = outRS->records[irec];
00276 outSegBr = drms_segment_lookup(outRec, "Br");
00277 outSegBt = drms_segment_lookup(outRec, "Bt");
00278 outSegBp = drms_segment_lookup(outRec, "Bp");
00279 outSegGc = drms_segment_lookup(outRec, "gc");
00280 outSegHc = drms_segment_lookup(outRec, "hc");
00281
00282 for (i = 0; i < 3; i++) {
00283 outSegBr->axis[i] = outArrayBr->axis[i];
00284 outSegBt->axis[i] = outArrayBt->axis[i];
00285 outSegBp->axis[i] = outArrayBp->axis[i];
00286 }
00287 for (i = 0; i < 2; i++) {
00288 outSegGc->axis[i] = outArrayGc->axis[i];
00289 outSegHc->axis[i] = outArrayHc->axis[i];
00290 }
00291 outArrayBr->parent_segment = outSegBr;
00292 outArrayBt->parent_segment = outSegBt;
00293 outArrayBp->parent_segment = outSegBp;
00294 outArrayGc->parent_segment = outSegGc;
00295 outArrayHc->parent_segment = outSegHc;
00296
00297
00298 status = drms_segment_write(outSegBr, outArrayBr, 0);
00299 if (status) DIE("problem writing Br");
00300 drms_free_array(outArrayBr);
00301 status = drms_segment_write(outSegBt, outArrayBt, 0);
00302 if (status) DIE("problem writing Bt");
00303 drms_free_array(outArrayBt);
00304 status = drms_segment_write(outSegBp, outArrayBp, 0);
00305 if (status) DIE("problem writing Bp");
00306 drms_free_array(outArrayBp);
00307 status = drms_segment_write(outSegGc, outArrayGc, 0);
00308 if (status) DIE("problem writing Gc");
00309 drms_free_array(outArrayGc);
00310 status = drms_segment_write(outSegHc, outArrayHc, 0);
00311 if (status) DIE("problem writing Hc");
00312 drms_free_array(outArrayHc);
00313
00314
00315 drms_setkey_string(outRec, "BLD_VERS", jsoc_version);
00316 drms_setkey_time(outRec, "DATE", CURRENT_SYSTEM_TIME);
00317 drms_copykey(outRec, inRec, "CAR_ROT");
00318 drms_copykey(outRec, inRec, "LON0");
00319 drms_setkey_int(outRec, "LMAX", lmax);
00320 drms_setkey_int(outRec, "LC", lc);
00321 drms_setkey_float(outRec, "RCP", RCP);
00322 drms_setkey_float(outRec, "RSS", RSS);
00323 drms_setkey_float(outRec, "APAR", apar);
00324 drms_setkey_float(outRec, "CDELT1", -360. / np);
00325 drms_setkey_float(outRec, "CRPIX1", 1.0);
00326 drms_setkey_float(outRec, "CRVAL1", car_rot * 360. - 180. / np);
00327 drms_setkey_float(outRec, "CRPIX2", nt / 2.0 + 0.5);
00328 drms_setkey_float(outRec, "CRVAL2", 0.0);
00329 if (sinlat) {
00330 drms_setkey_string(outRec, "CTYPE2", "CRLT-CEA");
00331 drms_setkey_float(outRec, "CDELT2", 2. / nt);
00332 drms_setkey_string(outRec, "CUNIT2", "Sine Latitude");
00333 } else {
00334 drms_setkey_string(outRec, "CTYPE2", "CRLT-CAR");
00335 drms_setkey_float(outRec, "CDELT2", 180. / nt);
00336 drms_setkey_string(outRec, "CUNIT2", "degree");
00337 }
00338 drms_setkey_float(outRec, "CDELT3", dr);
00339 drms_setkey_float(outRec, "CRPIX3", 1.0);
00340 drms_setkey_float(outRec, "CRVAL3", 1.0);
00341
00342
00343 ghLink = hcon_lookup_lower(&outRec->links, "HARMONICS");
00344 if (synopLink) {
00345 drms_setlink_static(outRec, "HARMONICS", inRec->recnum);
00346 linkedRec = drms_link_follow(outRec, "HARMONICS", &status);
00347 }
00348 if (!status) {
00349 synopLink = hcon_lookup_lower(&linkedRec->links, "SYNOP");
00350 if (synopLink) {
00351 drms_setlink_static(outRec, "SYNOP", linkedRec->recnum);
00352 }
00353 }
00354
00355
00356 if (verbflag) {
00357 wt = getwalltime();
00358 ct = getcputime(&ut, &st);
00359 printf("record %d done, %.2f ms wall time, %.2f ms cpu time\n",
00360 irec, wt - wt1, ct - ct1);
00361 }
00362 }
00363
00364 free(grid->rr); free(grid->th); free(grid->ph); free(grid);
00365
00366 drms_close_records(inRS, DRMS_FREE_RECORD);
00367 drms_close_records(outRS, DRMS_INSERT_RECORD);
00368
00369 if (verbflag) {
00370 wt = getwalltime();
00371 ct = getcputime(&ut, &st);
00372 printf("total time spent: %.2f ms wall time, %.2f ms cpu time\n",
00373 wt - wt0, ct - ct0);
00374 }
00375
00376 return(DRMS_SUCCESS);
00377 }