/*************************************************************************** * hptime2timestr: * * Build a time string in filename format from a high precision * epoch time. * * The provided isostimestr must have enough room for the resulting time * string of 24 characters, i.e. '2001.07.29.12.38.00.000' + NULL. * * The 'subseconds' flag controls whether the sub second portion of the * time is included or not. * * Returns a pointer to the resulting string or NULL on error. ***************************************************************************/ char * hptime2timestr(hptime_t hptime, char *timestr, flag subseconds, char* datepath) { struct tm tms; time_t isec; int ifract; int ret; if (timestr == NULL) return NULL; /* Reduce to Unix/POSIX epoch time and fractional seconds */ isec = MS_HPTIME2EPOCH(hptime); ifract = (int) (hptime - (isec * HPTMODULUS)); /* Adjust for negative epoch times */ if (hptime < 0 && ifract != 0) { isec -= 1; ifract = HPTMODULUS - (-ifract); } if (!(gmtime_r(&isec, &tms))) return NULL; if (subseconds) { ifract /= (HPTMODULUS / 1000); // tp milliseconds (assumes HPTMODULUS mulitple of 1000) /* Assuming ifract has millisecond precision */ ret = snprintf(timestr, 24, "%4d.%02d.%02d.%02d.%02d.%02d.%03d", tms.tm_year + 1900, tms.tm_mon + 1, tms.tm_mday, tms.tm_hour, tms.tm_min, tms.tm_sec, ifract); } else { ret = snprintf(timestr, 20, "%4d.%02d.%02d.%02d.%02d.%02d", tms.tm_year + 1900, tms.tm_mon + 1, tms.tm_mday, tms.tm_hour, tms.tm_min, tms.tm_sec); } //printf("DEBUG: timestr= %s\n", timestr); if (ret != 23 && ret != 19) return NULL; ret = snprintf(datepath, 17, "%4d/%02d/%02d/%02d/%02d", tms.tm_year + 1900, tms.tm_mon + 1, tms.tm_mday, tms.tm_hour, tms.tm_min); if (ret != 16) return NULL; return timestr; } /* End of ms_hptime2isotimestr() */
/* * extract the data from the records and fill the arrays in the PPfData structure */ bool StationTrace::concatenateRecordsIntoPDAS(PPfData* ppfDataPtr) { std::list<StationTrace::StationRecord>::iterator rIter; std::list<double>::iterator dIter; double dt = -1.0; bool first = true; int nitems = 0; hptime_t end_time = -1; hptime_t diff; hptime_t span; int samp_add; int i; // sort on startTime records.sort(); for (rIter = records.begin(); rIter != records.end(); rIter++) { // check for gaps in the record diff=rIter->startTime-end_time; if(end_time>0 && abs(diff)>(double)(HPTMODULUS/(2.0*rIter->dt))) { samp_add=((double)MS_HPTIME2EPOCH(diff)*rIter->dt)+0.5; //std::cerr<<"Gap: "<<(double)MS_HPTIME2EPOCH(diff)<<" ==> samples: "<< samp_add<<std::endl; nitems+=samp_add; } span = ((double)(rIter->data.size())/rIter->dt*HPTMODULUS)+0.5; end_time=rIter->startTime+span; // here comes the real trace nitems += rIter->data.size(); if (first) { dt = rIter->dt; first = false; } else { if (dt != rIter->dt) { std::cerr << "inconsistent sample frequency between records for station trace '" << filename << "'" << std::endl; return false; } } } strncpy(ppfDataPtr->pdasFilename, filename.c_str(), PP_MAX_NAME_LEN); ppfDataPtr->dt = dt; ppfDataPtr->ndat = nitems; // get the start time of the first record if (!records.empty()) { ppfDataPtr->start = (double)MS_HPTIME2EPOCH(records.front().startTime); } if ((ppfDataPtr->values = (float *)calloc(nitems, sizeof(float))) == NULL) { std::cerr << "memory allocation error in trace '" << filename << "'" << std::endl; return false; } if ((ppfDataPtr->exists = (unsigned char *)calloc(nitems, sizeof(unsigned char))) == NULL) { std::cerr << "memory allocation error in trace '" << filename << "'" << std::endl; return false; } memset(ppfDataPtr->exists, 0x01, nitems * sizeof(unsigned char)); int count = 0; end_time = -1; for (rIter = records.begin(); rIter != records.end(); rIter++) { // check for gaps in the record diff=rIter->startTime-end_time; if(end_time>0 && abs(diff)>(double)(HPTMODULUS/(2.0*rIter->dt))) { samp_add=((double)MS_HPTIME2EPOCH(diff)*rIter->dt)+0.5; std::cerr<<"...Gap: "<<(double)MS_HPTIME2EPOCH(diff)<<" ==> samples: "<< samp_add<<std::endl; if(samp_add>0) { for(i=0;i<samp_add;i++) { ppfDataPtr->exists[count++]=0; } } else { count-=samp_add; } } span = ((double)(rIter->data.size())/rIter->dt*HPTMODULUS)+0.5; end_time=rIter->startTime+span; for (dIter = rIter->data.begin(); dIter != rIter->data.end(); dIter++) { ppfDataPtr->values[count++] = *dIter; } } ppfDataPtr->user = NULL; return true; }
static str MseedLoadIntern(BAT **bbtime, BAT **bbdata, str targetfile) { str msg = MAL_SUCCEED; MSRecord *msr = 0; BAT *btime, *bdata; int verbose = 1; //int ppackets = 2; int reclen = -1; int dataflag = 1; int retcode; int j; time_t t; struct tm *tm; timestamp ts; char file[BUFSIZ]; date d; daytime dt; tzone tz; int ms,stepsize,minutes=0; snprintf(file,BUFSIZ,"%s%c%s",vaultpath,DIR_SEP,targetfile); if ( access(file,R_OK) ) throw(MAL, "mseed.load", "Cannot access %s\n", file); btime = BATnew(TYPE_void,TYPE_timestamp,0); if ( btime == NULL) throw(MAL,"mseed.load",MAL_MALLOC_FAIL); BATseqbase(btime,0); bdata = BATnew(TYPE_void,TYPE_int,0); if ( bdata == NULL){ BBPreleaseref(btime->batCacheid); throw(MAL,"mseed.load",MAL_MALLOC_FAIL); } BATseqbase(bdata,0); if ( btime == NULL || bdata == NULL ){ if ( btime) BBPreleaseref(btime->batCacheid); if ( bdata) BBPreleaseref(bdata->batCacheid); throw(MAL, "mseed.load", MAL_MALLOC_FAIL); } *bbtime = btime; *bbdata = bdata; MTIMEtzone_create(&tz, &minutes); while ( (retcode = ms_readmsr (&msr, file, reclen, NULL, NULL, 1, dataflag, verbose)) == MS_NOERROR ) { stepsize = 1000000/ msr->samprate; /* collect the statistics */ switch(msr->sampletype){ case 'i': if (msr->datasamples) for ( j=0;j< msr->samplecnt; j++){ t= MS_HPTIME2EPOCH(msr->starttime); tm = gmtime(&t); tm->tm_year += (tm->tm_year > 80?1900:2000); ms = (msr->starttime % HPTMODULUS)/1000; tm->tm_mon++; MTIMEdate_create(&d,&tm->tm_year, &tm->tm_mon, &tm->tm_mday); MTIMEdaytime_create(&dt, &tm->tm_hour, &tm->tm_min, &tm->tm_sec, &ms); MTIMEtimestamp_create(&ts, &d, &dt, &tz); BUNappend(btime, (ptr) &ts , FALSE); BUNappend(bdata, (ptr)(((int*) msr->datasamples)+j) , FALSE); msr->starttime += stepsize; } break; case 'a': case 'f': case 'd': default: msg = createException(MAL,"mseed.load","data type not yet implemented"); goto wrapup; } } wrapup: /* Make sure everything is cleaned up */ ms_readmsr (&msr, NULL, 0, NULL, NULL, 0, 0, 0); if ( retcode != MS_ENDOFFILE ) throw(MAL, "mseed.load", "Cannot read %s: %s\n", targetfile, ms_errorstr(retcode)); return msg; }
str MseedImport(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci) { int *ret = (int*) getArgReference(stk,pci,0); int *vid = (int*) getArgReference(stk,pci,1); str *targetfile = (str*) getArgReference(stk,pci,2); str msg = MAL_SUCCEED; MSRecord *msr = 0; int verbose = 1; //int ppackets = 2; int reclen = -1; int dataflag = 1; int retcode; int j; int sampleindex = 0; time_t t; struct tm *tm; char file[BUFSIZ]; char buf[BUFSIZ], *s= buf; char starttime[BUFSIZ]; int imin = INT_MAX, imax = INT_MIN; /* keep state of a file to detect major deviances */ str network =0, station = 0 , location = 0 , channel = 0; char sampletype = 0; (void) mb; *ret = int_nil; snprintf(file,BUFSIZ,"%s%c%s",vaultpath,DIR_SEP,*targetfile); if ( access(file,R_OK) ) throw(MAL, "mseed.load", "Cannot access %s\n", file); while ( (retcode = ms_readmsr (&msr, file, reclen, NULL, NULL, 1, dataflag, verbose)) == MS_NOERROR ) { if ( network == 0){ network= GDKstrdup(msr->network); station= GDKstrdup(msr->station); location= GDKstrdup(msr->location); channel= GDKstrdup(msr->channel); sampletype = msr->sampletype; } else { if( strcmp(network,msr->network)) msg = createException(MAL,"mseed.import","network name is not stable"); if( strcmp(station,msr->station)) msg = createException(MAL,"mseed.import","station name is not stable"); if( strcmp(location,msr->location)) msg = createException(MAL,"mseed.import","location name is not stable"); if( strcmp(channel,msr->channel)) msg = createException(MAL,"mseed.import","channel name is not stable"); if ( sampletype != msr->sampletype) msg = createException(MAL,"mseed.import","sample type is not stable"); if (msg) goto wrapup; } t= MS_HPTIME2EPOCH(msr->starttime); tm = gmtime(&t); snprintf(starttime,BUFSIZ,"%d-%02d-%02d %02d:%02d:%02d.%06d", tm->tm_year +(tm->tm_year > 80?1900:2000), tm->tm_mon+1,tm->tm_mday, tm->tm_hour, tm->tm_min,tm->tm_sec, (int) (msr->starttime % HPTMODULUS)); /* collect the statistics */ switch(msr->sampletype){ case 'i': imin = INT_MAX, imax = INT_MIN; if (msr->datasamples) for ( j=0;j< msr->samplecnt; j++){ if ( imin > ((int*) msr->datasamples)[j]) imin = ((int*) msr->datasamples)[j]; if ( imax < ((int*) msr->datasamples)[j]) imax = ((int*) msr->datasamples)[j]; } snprintf(buf,BUFSIZ,QRYinsertI, *vid, msr->sequence_number,msr->dataquality,msr->network, msr->station, msr->location, msr->channel, starttime,msr->samprate, sampleindex,(lng)msr->samplecnt,"int",imin,imax); break; case 'a': case 'f': case 'd': default: msg = createException(MAL,"mseed.import","data type not yet implemented"); goto wrapup; } if ( ( msg =SQLstatementIntern(cntxt,&s,"mseed.import",TRUE,FALSE)) != MAL_SUCCEED) break; sampleindex += msr->samplecnt; } wrapup: /* Make sure everything is cleaned up */ ms_readmsr (&msr, NULL, 0, NULL, NULL, 0, 0, 0); if ( network) GDKfree(network); if ( station) GDKfree(station); if ( location) GDKfree(location); if ( channel) GDKfree(channel); if ( msg) return msg; if ( retcode != MS_ENDOFFILE ) throw(MAL, "mseed.dump", "Cannot read %s: %s\n", *targetfile, ms_errorstr(retcode)); *ret = *vid; return msg; }