/** * @file TimesUpdateNoData.c * @version $Id: TimesUpdateNoData.c,v 1.6 2009/07/07 11:37:40 budnik Exp $ * @brief Program reads StartTime and StopTime and add to nc_times_file NODATA intervals * * @arg nc_times_file OrderedStartTime OrderedStopTime */ /*===================================================================== * DD SYSTEM base package * DD_Server library * TimesUpdateNoData.c * V.1.5 * * usage TimesUpdateNoData nc_times_file OrderedStartTime OrderedStopTime * *=====================================================================*/ /*===================================================================== * Description: * Program reads StartTime and StopTime and add to nc_times_file NODATA intervals * * * * Dimensions: * TimeLingth TIMELENGTH * NameLength NAME_DIM * Record Unlimited * Variables: * * char StartTime[TIMELENGTH] * char EndTime[TIMELENGTH] * * Attributes: * none *======================================================================*/ #include #include #include #include #include #include #include #include /* Global Constant definitions */ #define ISOTIMER "%d-%d-%dT%d:%d:%d.%dZ" /* Format to READ time in ISO format */ #define TIME_LENGTH_NAME "TimeLength" #define TIME_LENGTH 17L #define REC_DIM_NAME "record" #define REC_DIM NC_UNLIMITED #define NAME_DIM_NAME "NameLength" #define NAME_DIM 32L #define NAME_LENGTH 100 #define ISO_LENGTH 25 #define STARTTIME "StartTime" #define STOPTIME "StopTime" #define FILENAME "FileName" #define TIME_TYPE NC_CHAR #define DATAGAP 7200 #define NODATA "NODATA\0" /*----------- Type definition ------------------------------*/ typedef struct { char Name[NAME_LENGTH]; // current data file char StartS[TIME_LENGTH]; // Start Time String char StopS[TIME_LENGTH]; // Stop Time String double StartD; // Start double double StopD; // Stop double } t_StartStop; /*---------- Global variables (IDs) of open times file -------------*/ int tmID; /* nc file descriptor */ int StartID, StopID, NameID; size_t RecordsNumber = 0; // Records Number of the existing times file static char ZeroTime[TIME_LENGTH] = "0000000000000000\0"; /*======================================================================== * FUNCTIONS *=======================================================================*/ /*===================================================================== * ISOTime2Double() * Covert double time to ISO time to Double * *=====================================================================*/ double ISOTime2Double(char* ISO) { unsigned UT[7]; dd_tmstr_t *Time; sscanf(ISO, ISOTIMER, &UT[0], &UT[1], &UT[2], &UT[3], &UT[4], &UT[5], &UT[6]); Time = (dd_tmstr_t *)UT2double(UT); return Time->times; } /*-----------------------------------------------------------*/ /*------------------------------------------------------------ * InsertRecord() *-----------------------------------------------------------*/ int InsertRecord(size_t RecordPos, t_StartStop *StartStop) { static size_t TimeStart[2] = {0,0}; static size_t TimeCount[2] = {1,TIME_LENGTH}; static size_t NameCount[2] = {1, NAME_DIM}; char CStart[TIME_LENGTH],CStop[TIME_LENGTH], CName[NAME_DIM]; int Crec; int status; /*--- Scroll all variables down-----------------------*/ for(Crec = RecordsNumber - 1; Crec >= (int)RecordPos; Crec--) { TimeStart[0] = (size_t)Crec; status = nc_get_vara_text (tmID,StartID,TimeStart,TimeCount,(char *)CStart); status = nc_get_vara_text (tmID,StopID,TimeStart,TimeCount,(char *)CStop); status = nc_get_vara_text (tmID,NameID,TimeStart,NameCount,(char *)CName); TimeStart[0]++; status = nc_put_vara_text(tmID,StartID,TimeStart,TimeCount,(char *)CStart); status = nc_put_vara_text(tmID,StopID,TimeStart,TimeCount,(char *)CStop); status = nc_put_vara_text(tmID,NameID,TimeStart,NameCount,(char *)CName); } /*------ Put the new record to empty space -----------------*/ TimeStart[0] = RecordPos; status = nc_put_vara_text(tmID,StartID,TimeStart,TimeCount,(char *)StartStop->StartS); status = nc_put_vara_text(tmID,StopID,TimeStart,TimeCount,(char *)StartStop->StopS); status = nc_put_vara_text(tmID,NameID,TimeStart,NameCount,(char *)StartStop->Name); RecordsNumber++; nc_sync(tmID); return 1; } /*==================================================================================*/ /*================================================================================== * MAIN *==================================================================================*/ main(int argc, char **argv) { static char usage[] = "usage: TimesUpdateNoData nc_times_file StartTime StopTime"; char Start[TIME_LENGTH], Stop[TIME_LENGTH], Name[NAME_DIM]; /* NC definitions */ int TlDimID,RecDimID, NlDimID; /* ID of dimensions */ static size_t TimeStart[2] = {0,0}; static size_t TimeCount[2] = {1,TIME_LENGTH}; static size_t NameCount[2] = {1, NAME_DIM}; int DimVector[2]; char tmName[NAME_DIM]; int InsertFlag; int i, hi, lo = 0; double StartD0, StartD1 = 0.0, StopD0, StopD1, STARTD, STOPD, CurrentStart; int StartRecord, StopRecord; char command[100]; char name[100]; int status; double LastTime = 0.0, FirstTime = 0.0; // Times of the hole between files t_StartStop CurrentRecord; // /*================================================================= * Check arguments and options *=================================================================*/ if(argc < 4) {fprintf(stderr,"%s\n",usage); exit(1); } /*-----------------------------------------------------------------*/ /* Open existing file */ if((status = nc_open(argv[1],NC_WRITE|NC_SHARE,&tmID)) != NC_NOERR) { fprintf(stderr,"Can not open file %s to write\n",argv[2]); exit(0); } status = nc_inq_dimid(tmID,REC_DIM_NAME,&RecDimID); status = nc_inq_varid(tmID, STARTTIME,&StartID); status = nc_inq_varid(tmID, STOPTIME,&StopID); status = nc_inq_varid(tmID, FILENAME,&NameID); status = nc_inq_dimlen(tmID,RecDimID, &RecordsNumber); /*==========================================================================*/ hi = RecordsNumber; STARTD = ISOTime2Double(argv[2]); STOPD = ISOTime2Double(argv[3]); while (lo <= hi) { i = (lo+hi)/2; TimeStart[0] = i + 1; status = nc_get_vara_text(tmID,StartID,TimeStart,TimeCount,(char *)Start); StartD1 = DD_Time2Double(Start); if (StartD1 > STARTD) hi--; TimeStart[0] = i; status = nc_get_vara_text(tmID,StartID,TimeStart,TimeCount,(char *)Start); StartD0 = DD_Time2Double(Start); if (StartD0 < STARTD) lo++; if (StartD1 <= STARTD && StartD0 >= STARTD) break; } StartRecord = i; status = nc_get_vara_text(tmID,StopID,TimeStart,TimeCount,(char *)Stop); StopD0 = DD_Time2Double(Stop); while (STOPD > StopD0 && TimeStart[0] <= RecordsNumber) { status = nc_get_vara_text(tmID,StopID,TimeStart,TimeCount,(char *)Stop); if (status != NC_NOERR) fprintf(stderr," %s\n", nc_strerror(status)); StopD0 = DD_Time2Double(Stop); TimeStart[0]++; } StopRecord = TimeStart[0]-1; // if NODATA is the very FIRST - insert NODATA if (StartRecord == 0 && (StartD0 - STARTD) > DATAGAP) { TimeStart[0] = 0; status = nc_get_vara_text(tmID, NameID, TimeStart, NameCount,(char *)Name); if (strcmp(Name,NODATA) == 0 && (StartD0 - STOPD) < DATAGAP) { status = nc_put_vara_text(tmID,StartID, TimeStart, TimeCount, Double2DD_Time(STARTD)); } else { strncpy(CurrentRecord.Name, NODATA, 7); strncpy(CurrentRecord.StartS,Double2DD_Time(STARTD),TIMELENGTH); if ((StartD0 - STOPD) < DATAGAP) strncpy(CurrentRecord.StopS,Start,TIMELENGTH); else strncpy(CurrentRecord.StopS,Double2DD_Time(STOPD),TIMELENGTH); InsertRecord((size_t)(0), &CurrentRecord); } } for (i = StartRecord; i < StopRecord ; i++) { InsertFlag = 0; TimeStart[0] = i; status = nc_get_vara_text(tmID,StopID, TimeStart, TimeCount,(char *)Stop); StopD0 = DD_Time2Double(Stop); TimeStart[0] = i+1; status = nc_get_vara_text(tmID,StartID, TimeStart, TimeCount, (char *)Start); StartD1 = DD_Time2Double(Start); // Data Gap -> NODATA if ((StartD1 - StopD0) > DATAGAP) { strncpy(CurrentRecord.Name, NODATA,7); TimeStart[0] = i; status = nc_get_vara_text(tmID, NameID, TimeStart, NameCount,(char *)Name); if (strcmp(Name,NODATA) == 0) { strncpy(Stop,Start,TIMELENGTH); status = nc_get_vara_text(tmID,StartID, TimeStart, TimeCount, (char *)Start); status = nc_put_vara_text(tmID,StartID, TimeStart, TimeCount, (char *)Start); if ((StartD1 - STOPD) < DATAGAP) status = nc_put_vara_text(tmID,StopID,TimeStart,TimeCount,(char *)Stop); else status = nc_put_vara_text(tmID,StopID,TimeStart,TimeCount,Double2DD_Time(STOPD)); status = nc_put_vara_text(tmID,NameID,TimeStart,NameCount,(char *)CurrentRecord.Name); InsertFlag = 1; } if (!InsertFlag) { if ((i == StartRecord) && (StopD0 < STARTD)) strncpy(CurrentRecord.StartS,Double2DD_Time(STARTD),TIMELENGTH); else strncpy(CurrentRecord.StartS,Stop,TIMELENGTH); if ((i == StopRecord-1) && (StartD1 > STOPD)) strncpy(CurrentRecord.StopS,Double2DD_Time(STOPD),TIMELENGTH); else strncpy(CurrentRecord.StopS,Start,TIMELENGTH); if ((DD_Time2Double(CurrentRecord.StopS) - DD_Time2Double(CurrentRecord.StartS)) > DATAGAP) InsertRecord((size_t)(i+1), &CurrentRecord); } } } // if NODATA is the very LAST - add NODATA if (StopRecord == RecordsNumber) { TimeStart[0] = StopRecord-1; status = nc_get_vara_text(tmID,StopID, TimeStart, TimeCount, (char *)Stop); StopD0 = DD_Time2Double(Stop); if (STOPD > StopD0) { status = nc_get_vara_text(tmID, NameID, TimeStart, NameCount,(char *)Name); if (strcmp(Name,NODATA) == 0 && (STARTD - StopD0) < DATAGAP) { status = nc_get_vara_text(tmID,StartID, TimeStart, TimeCount, (char *)Start); strncpy(Stop,Start,TIMELENGTH); } else { strncpy(Name, NODATA, 7); TimeStart[0]++; } if ((STARTD - StopD0) < DATAGAP) CurrentStart = DD_Time2Double(Stop); else CurrentStart = STARTD; if ((STOPD - CurrentStart) > DATAGAP) { status = nc_put_vara_text(tmID,StartID,TimeStart,TimeCount, Double2DD_Time(CurrentStart)); status = nc_put_vara_text(tmID,StopID,TimeStart,TimeCount, Double2DD_Time(STOPD)); status = nc_put_vara_text(tmID,NameID,TimeStart,NameCount,(char *)Name); } } } nc_sync(tmID); status = nc_close(tmID); exit(0); } /*=========================================================================================================*/