00001 #include "jsoc_main.h"
00002 #include "drms.h"
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 #define NOT_SPECIFIED "NOT_SPECIFIED"
00060
00061 #define DATA_OK ('\0')
00062 #define DATA_MISS ('\1')
00063 #define DATA_UNK ('\2')
00064
00065
00066 char primestr[100];
00067
00068 char *primevalstr(TIME prime, DRMS_Type_t type, char *unit, char *format)
00069 {
00070 if (type==DRMS_TYPE_TIME)
00071 sprint_time(primestr, prime, unit, atoi(format));
00072 else
00073 sprintf(primestr, (type <= DRMS_TYPE_LONGLONG ? "%.0f" : "%f"), prime);
00074 return(primestr);
00075 }
00076
00077 void printprime(FILE *fp, TIME prime, DRMS_Type_t type, char *unit, char *format)
00078 {
00079 fprintf(fp, primevalstr(prime, type, unit, format));
00080 }
00081
00082 ModuleArgs_t module_args[] =
00083 {
00084 {ARG_STRING, "ds", NOT_SPECIFIED, "Input data series."},
00085 {ARG_STRING, "low", NOT_SPECIFIED, "Low limit for coverage map."},
00086 {ARG_STRING, "high", NOT_SPECIFIED, "High limit for coverage map."},
00087 {ARG_STRING, "key", NOT_SPECIFIED, "Prime key name to use, default is first prime"},
00088 {ARG_FLAG, "i", "0", "Index - Print index values instead of prime slot values"},
00089 {ARG_FLAG, "q", "0", "Quiet - omit series header info"},
00090 {ARG_END}
00091 };
00092
00093 #define DIE(msg) {fprintf(stderr,"%s\n",msg);exit(1);}
00094
00095
00096 char *module_name = "show_coverage";
00097
00098
00099 int DoIt(void)
00100 {
00101 FILE *out;
00102 int status = 0;
00103 int slotted;
00104 long long lowslot, highslot, serieslowslot, serieshighslot;
00105 DRMS_RecordSet_t *rs;
00106 DRMS_Record_t *rec, *template;
00107 DRMS_Keyword_t *skey, *pkey;
00108 DRMS_Type_t ptype;
00109 char name[DRMS_MAXNAMELEN];
00110 int npkeys;
00111 char *pname;
00112 char *piname;
00113 char *punit;
00114 char *pformat;
00115 char *seriesname;
00116 TIME step, epoch;
00117 TIME series_low, series_high, low, high;
00118 char in[DRMS_MAXQUERYLEN];
00119 char *inbracket;
00120 char otherkeys[20*DRMS_MAXQUERYLEN];
00121 const char *ds = cmdparams_get_str (&cmdparams, "ds", NULL);
00122 const char *lowstr = cmdparams_get_str (&cmdparams, "low", NULL);
00123 const char *highstr = cmdparams_get_str (&cmdparams, "high", NULL);
00124 const char *skeyname = cmdparams_get_str (&cmdparams, "key", NULL);
00125 int quiet = cmdparams_get_int (&cmdparams, "q", NULL) != 0;
00126 int useindex = cmdparams_get_int (&cmdparams, "i", NULL) != 0;
00127 char *map;
00128 long long islot, jslot, nslots;
00129 char *qualkey;
00130 int qualkind;
00131 int ikey;
00132 int nOtherPrimes;
00133 struct OtherKeyStruct
00134 {
00135 char *name;
00136 char *value;
00137 } *OtherPrimes;
00138
00139
00140 if (strcmp(ds, NOT_SPECIFIED) == 0 )
00141 DIE("No files: at least ds must be specified");
00142 out = stdout;
00143
00144
00145
00146 strcpy(in,ds);
00147 inbracket = index(in, '[');
00148 if (inbracket)
00149 *inbracket = '\0';
00150 else
00151 inbracket = in + strlen(in);
00152 template = drms_template_record (drms_env, in, &status);
00153 if (!template || status)
00154 DIE("Series not found or empty");
00155
00156 npkeys = template->seriesinfo->pidx_num;
00157 if (npkeys < 1)
00158 DIE("Series has no prime keys");
00159 if (strcmp(skeyname, NOT_SPECIFIED) != 0)
00160 {
00161 for (ikey=0; ikey < npkeys; ikey++)
00162 {
00163 pkey = template->seriesinfo->pidx_keywords[ikey];
00164 if (pkey->info->recscope > 1)
00165 skey = drms_keyword_slotfromindex(pkey);
00166 if (strcmp(skeyname, skey->info->name) == 0)
00167 break;
00168 }
00169 if (ikey == template->seriesinfo->pidx_num)
00170 DIE("name in key command line arg is not a prime key of this series");
00171 }
00172 else
00173 {
00174 skey = pkey = template->seriesinfo->pidx_keywords[0];
00175 }
00176 if (pkey->info->recscope > 1)
00177 {
00178 skey = drms_keyword_slotfromindex(pkey);
00179 slotted = 1;
00180 }
00181 else
00182 slotted = 0;
00183
00184
00185 ptype = skey->info->type;
00186 pname = strdup(skey->info->name);
00187 piname = strdup(pkey->info->name);
00188 punit = strdup(skey->info->unit);
00189 pformat = strdup(skey->info->format);
00190 seriesname = strdup(template->seriesinfo->seriesname);
00191
00192 otherkeys[0] = '\0';
00193 OtherPrimes = (struct OtherKeyStruct *)malloc(npkeys * sizeof(struct OtherKeyStruct));
00194 nOtherPrimes = 0;
00195 for (ikey=0; ikey < npkeys; ikey++)
00196 {
00197 DRMS_Keyword_t *tmppkey = template->seriesinfo->pidx_keywords[ikey];
00198 if (tmppkey->info->recscope > 1)
00199 tmppkey = drms_keyword_slotfromindex(pkey);
00200 if (cmdparams_exists(&cmdparams, tmppkey->info->name))
00201 {
00202 const char *value;
00203 char tmp[DRMS_MAXQUERYLEN];
00204 if (strcmp(tmppkey->info->name, pname) == 0)
00205 DIE("Can not have main prime key listed explicitly");
00206 value = cmdparams_get_str(&cmdparams, tmppkey->info->name, NULL);
00207 sprintf(tmp, "[%s=%s]", tmppkey->info->name, value);
00208 strcat(otherkeys, tmp);
00209 OtherPrimes[nOtherPrimes].name = strdup(tmppkey->info->name);
00210 OtherPrimes[nOtherPrimes].value = strdup(value);
00211 nOtherPrimes += 1;
00212 }
00213 }
00214
00215
00216 DRMS_Keyword_t *qualitykeyword = drms_keyword_lookup(template, "QUALITY", 1);
00217 if (qualitykeyword && qualitykeyword->info->type == DRMS_TYPE_INT)
00218 {
00219 qualkey = "QUALITY";
00220 qualkind = 1;
00221 }
00222 else if (drms_keyword_lookup(template, "DATAVALS", 1))
00223 {
00224 qualkey = "DATAVALS";
00225 qualkind = 2;
00226 }
00227 else
00228 {
00229 qualkey = NULL;
00230 qualkind = 0;
00231 }
00232
00233 if (slotted == 0 && ( ptype != DRMS_TYPE_SHORT && ptype != DRMS_TYPE_INT && ptype != DRMS_TYPE_LONGLONG))
00234 DIE("Must be slotted or integer type first prime key");
00235 if (ptype == DRMS_TYPE_TIME)
00236 {
00237 strcpy(name, pname);
00238 strcat(name, "_epoch");
00239 epoch = drms_getkey_time(template, name, &status);
00240 strcpy(name, pname);
00241 strcat(name, "_step");
00242 step = drms_getkey_double(template, name, &status);
00243 }
00244 else if (slotted)
00245 {
00246 strcpy(name, pname);
00247 strcat(name, "_base");
00248 epoch = (TIME)drms_getkey_double(template, name, &status);
00249 strcpy(name, pname);
00250 strcat(name, "_step");
00251 step = (TIME)drms_getkey_double(template, name, &status);
00252 }
00253 else
00254 {
00255 epoch = (TIME)0.0;
00256 step = (TIME)1.0;
00257 }
00258
00259 sprintf(in, "%s[%s=^]", seriesname, pname);
00260
00261 rs = drms_open_records (drms_env, in, &status);
00262 if (status || !rs || rs->n == 0)
00263 DIE("Series is empty");
00264 rec = rs->records[0];
00265 if (ptype == DRMS_TYPE_TIME)
00266 series_low = drms_getkey_time(rec, pname, &status);
00267 else if (slotted)
00268 series_low = (TIME)drms_getkey_double(rec, pname, &status);
00269 else
00270 series_low = (TIME)drms_getkey_longlong(rec, pname, &status);
00271 if (slotted)
00272 serieslowslot = drms_getkey_longlong(rec, piname, &status);
00273 else
00274 serieslowslot = series_low;
00275 drms_close_records(rs, DRMS_FREE_RECORD);
00276 if (strcmp(lowstr, NOT_SPECIFIED) == 0)
00277 low = series_low;
00278 else
00279 {
00280 if (ptype == DRMS_TYPE_TIME)
00281 low = sscan_time((char *)lowstr);
00282 else
00283 low = (TIME)atof(lowstr);
00284 }
00285
00286 sprintf(in, "%s[%s=$]", seriesname, pname);
00287
00288 rs = drms_open_records (drms_env, in, &status);
00289 rec = rs->records[0];
00290 if (ptype == DRMS_TYPE_TIME)
00291 series_high = drms_getkey_time(rec, pname, &status);
00292 else if (slotted)
00293 series_high = (TIME)drms_getkey_double(rec, pname, &status);
00294 else
00295 series_high = (TIME)drms_getkey_longlong(rec, pname, &status);
00296 if (slotted)
00297 serieshighslot = drms_getkey_longlong(rec, piname, &status);
00298 else
00299 serieshighslot = series_high;
00300 drms_close_records(rs, DRMS_FREE_RECORD);
00301 if (strcmp(highstr, NOT_SPECIFIED) == 0)
00302 high = series_high;
00303 else
00304 {
00305 if (ptype == DRMS_TYPE_TIME)
00306 high = sscan_time((char *)highstr);
00307 else
00308 high = atof(highstr);
00309 }
00310
00311
00312 if (slotted)
00313 {
00314 DRMS_Value_t indexval;
00315 DRMS_Value_t inval;
00316 inval.value.double_val = low;
00317 inval.type = skey->info->type;
00318 drms_keyword_slotval2indexval(skey, &inval, &indexval, NULL);
00319 lowslot = indexval.value.longlong_val;
00320
00321 inval.value.double_val = high;
00322 inval.type = pkey->info->type;
00323 drms_keyword_slotval2indexval(skey, &inval, &indexval, NULL);
00324 highslot = indexval.value.longlong_val;
00325 }
00326 else
00327 {
00328 lowslot = low;
00329 highslot = high;
00330 }
00331
00332
00333 nslots = highslot - lowslot + 1;
00334 map = (char *)malloc(sizeof(char) * nslots);
00335 for (islot=0; islot<nslots; islot++)
00336 map[islot] = DATA_UNK;
00337 islot = 0;
00338 while (islot < nslots)
00339 {
00340 DRMS_Array_t *data;
00341 int nrecs, irec;
00342 char query[DRMS_MAXQUERYLEN];
00343 char keylist[DRMS_MAXQUERYLEN];
00344 int qualindex=0;
00345 jslot = islot + 1000000;
00346 if (jslot >= nslots) jslot = nslots - 1;
00347 sprintf(query, "%s[%s=#%lld-#%lld]%s", seriesname, pname, lowslot+islot, lowslot+jslot,otherkeys);
00348 strcpy(keylist, piname);
00349 if (qualkind)
00350 {
00351 strcat(keylist, ",");
00352 strcat(keylist, qualkey);
00353 qualindex = 1;
00354 }
00355 data = drms_record_getvector(drms_env, query, keylist, DRMS_TYPE_LONGLONG, 0, &status);
00356 if (!data || status)
00357 {
00358 fprintf(stderr, "getkey_vector failed status=%d\n", status);
00359 DIE("getkey_vector failure");
00360 }
00361 nrecs = data->axis[1];
00362 for (irec = 0; irec < nrecs; irec++)
00363 {
00364 long long thisslot = *((long long *)data->data + irec);
00365 long long qualval;
00366 char val = DATA_OK;
00367 if (qualkind)
00368 {
00369 qualval = *((long long *)data->data + qualindex*nrecs + irec);
00370 if ((qualkind == 1 && qualval < 0) || (qualkind == 2 && qualval == 0))
00371 val = DATA_MISS;
00372 }
00373 map[thisslot - lowslot] = val;
00374 }
00375 islot = jslot + 1;
00376 drms_free_array(data);
00377 }
00378
00379
00380
00381 if (!quiet)
00382 {
00383 fprintf(out, "series=%s\n", seriesname);
00384 fprintf(out, "key=%s\n", pname);
00385 fprintf(out, "type=%s\n", drms_type2str(ptype));
00386 fprintf(out, "slotted=%s\n", (slotted ? "T" : "F"));
00387 fprintf(out, "epoch="); printprime(out, epoch, ptype, punit, pformat); fprintf(out, "\n");
00388 fprintf(out, "step=%f\n", step);
00389 fprintf(out, "low="); printprime(out, low, ptype, punit, pformat); fprintf(out, "\n");
00390 fprintf(out, "high="); printprime(out, high, ptype, punit, pformat); fprintf(out, "\n");
00391 fprintf(out, "series_low="); printprime(out, series_low, ptype, punit, pformat); fprintf(out, "\n");
00392 fprintf(out, "series_high="); printprime(out, series_high, ptype, punit, pformat); fprintf(out, "\n");
00393 fprintf(out, "qualkey=%s\n", qualkey);
00394 }
00395
00396
00397 islot = 0;
00398 while (islot < nslots)
00399 {
00400 long long startslot = islot;
00401 char pval[DRMS_MAXQUERYLEN];
00402 char primeval[DRMS_MAXQUERYLEN];
00403 int nsame = 1;
00404 if (useindex)
00405 sprintf(pval, "%lld", lowslot + islot);
00406 else
00407 sprintf(pval, "%s",
00408 primevalstr(epoch + (lowslot + islot) * step, ptype, punit, pformat));
00409 char thisval = map[islot], nval = 0;
00410 for (islot += 1; islot < nslots && map[islot] == thisval; islot++)
00411 nsame += 1;
00412
00413
00414 if (thisval == DATA_UNK)
00415 {
00416 int irec;
00417 DRMS_RecordSet_t *rs = drms_create_records(drms_env, nsame, seriesname, DRMS_PERMANENT, &status);
00418 if (status || !rs)
00419 DIE("Can not create records.");
00420 fprintf(stderr,"setting %d records missing.\n",nsame);
00421 for (irec = 0; irec<nsame; irec++)
00422 {
00423 int iother;
00424 DRMS_Record_t *rec = rs->records[irec];
00425 sprintf(primeval, "%s",
00426 primevalstr(epoch + (lowslot + startslot + irec) * step, ptype, punit, pformat));
00427 drms_setkey_string(rec, pname, primeval);
00428 for (iother=0; iother<nOtherPrimes; iother++)
00429 drms_setkey_string(rec, OtherPrimes[iother].name, OtherPrimes[iother].value);
00430 if (qualkind == 1)
00431 drms_setkey_int(rec, qualkey, 0XC0000000);
00432 else if (qualkind == 2)
00433 drms_setkey_int(rec, qualkey, 0);
00434 if (qualitykeyword && qualitykeyword->info->type == DRMS_TYPE_STRING)
00435 drms_setkey_string(rec, "QUALITY", "0XC0000000");
00436 }
00437 if (drms_close_records(rs, DRMS_INSERT_RECORD))
00438 DIE("Failed at close new records\n");
00439 }
00440 fprintf(out, "%12s %s %d\n",
00441 (thisval == DATA_OK ? "OK" :
00442 (thisval == DATA_MISS ? "MISS" : "NOWMISSING")),
00443 pval, nsame );
00444 }
00445 return(0);
00446 }
00447
00448