From 4b95fb97ec18f2fb6c67618e85c2240997b8cbd9 Mon Sep 17 00:00:00 2001 From: Benjamin Renard Date: Mon, 28 Sep 2015 11:32:50 +0200 Subject: [PATCH] Add TimesUpdate & TimesUpdateNoData --- CMakeLists.txt | 2 ++ scripts/StartServer.in | 2 +- src/TIMESUPDATE/CMakeLists.txt | 24 ++++++++++++++++++++++++ src/TIMESUPDATE/TimesUpdate.c | 431 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/TIMESUPDATENODATA/CMakeLists.txt | 24 ++++++++++++++++++++++++ src/TIMESUPDATENODATA/TimesUpdateNoData.c | 330 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 812 insertions(+), 1 deletion(-) create mode 100644 src/TIMESUPDATE/CMakeLists.txt create mode 100755 src/TIMESUPDATE/TimesUpdate.c create mode 100644 src/TIMESUPDATENODATA/CMakeLists.txt create mode 100644 src/TIMESUPDATENODATA/TimesUpdateNoData.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 3dd747e..eef0f31 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -45,6 +45,8 @@ add_subdirectory(src/DECODERS/themis/esafull2nc) add_subdirectory(src/DECODERS/themis/esamom2nc) add_subdirectory(src/DECODERS/themis/fgm2nc) add_subdirectory(src/DECODERS/themis/sst2nc) +add_subdirectory(src/TIMESUPDATE) +add_subdirectory(src/TIMESUPDATENODATA) add_subdirectory(tests) install(FILES "scripts/StartServer" DESTINATION . PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) diff --git a/scripts/StartServer.in b/scripts/StartServer.in index 3a913a4..2856437 100755 --- a/scripts/StartServer.in +++ b/scripts/StartServer.in @@ -6,7 +6,7 @@ DDBASE=/home/budnik/AMDA-NG.core/DDBASE/DATA DDPATH=/home/budnik/AMDA-NG.core/DDBASE DDLIB=@CMAKE_INSTALL_PREFIX@/lib DDBASEBIN=@CMAKE_INSTALL_PREFIX@/bin -LD_LIBRARY_PATH=$DDLIB/:@NETCDFLIB_DIR@:@USRLIB_DIR@ +LD_LIBRARY_PATH=$DDLIB/:@NETCDFLIB_DIR@:@libcdf_LIBRARIES@:@USRLIB_DIR@ export DDBASE DDPATH DDBASEBIN DDLIB LD_LIBRARY_PATH #$DDBASEBIN/DD_Server 1>/dev/null 2>/dev/null& diff --git a/src/TIMESUPDATE/CMakeLists.txt b/src/TIMESUPDATE/CMakeLists.txt new file mode 100644 index 0000000..04cad02 --- /dev/null +++ b/src/TIMESUPDATE/CMakeLists.txt @@ -0,0 +1,24 @@ + +PROJECT(TimesUpdate) + +include_directories( + ${CMAKE_HOME_DIRECTORY}/src/INCLUDE/ + ${NETCDFINCLUDE_DIR} +) + +#Configuration de l'exécutable +file( + GLOB_RECURSE + source_files + ./* +) + +ADD_EXECUTABLE (TimesUpdate ${source_files} ) + +target_link_libraries( + TimesUpdate + DD_Client + ${NETCDFLIBRARY} +) + +install (TARGETS TimesUpdate DESTINATION bin) diff --git a/src/TIMESUPDATE/TimesUpdate.c b/src/TIMESUPDATE/TimesUpdate.c new file mode 100755 index 0000000..0f02a70 --- /dev/null +++ b/src/TIMESUPDATE/TimesUpdate.c @@ -0,0 +1,431 @@ +/* $Id: TimesUpdate.c,v 1.3 2008/02/19 16:24:58 elena Exp $*/ +/*===================================================================== + * DD SYSTEM base package + * DD_Server library + * TimesUpdate.c + * V.4.6 + * + * usage TimesUpdate -r/-i[-u]/-d nc_times_file nc_data_file[*.gz] nc_data_file[*.gz] .... + * Note that in most of cases at the end of activity you have to run ClearTimes nc_times_file + * + * Versions: + * Apr 23 1997, Usung *.gz files V.2.0 + * Jan 4, 2006, V.3.0 - insert file and check overlaping + * Jan 13,2006, V.3.1 - error is corrected + * Feb 02,2006, V.3.2 - Corrected removing database in case of error + * Sep 20, 2007, V.4.0, Fedorov, from rehash.nc. New NetCDF V.3, syncronization + * Sep 25, 2007 V.4.1 The very first file and first file insert + * Nov 29, 2007 V.4.2 If several first records - bug correction + * Feb 17, 2008 V.4.5 Fedorov: New options , remake, insert, delete + * Feb 19, 2008 V.4.6 delete bugs corrected + *=====================================================================*/ + /*===================================================================== + * Description: + * Program reads list of nc_data_files, probabbly gzipped, reads StartTime and Stop time + * and create or update nc_times_file. The sequence of data files are not important + * -r remove nc_times_file and create new one + * -i insert new file(s) + * -d remove file(s) from nc_times + * + * 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 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 STARTTIME "StartTime" +#define STOPTIME "StopTime" +#define FILENAME "FileName" + +#define TIME_TYPE NC_CHAR + +#define TEMPUNZIP "TimesUpdateTemp.nc\0" +#define NODATA "NODATA\0" + +/*----------- Conditions --------------------------*/ +enum Conditions {ALLLEFT,LEFTOVER,WELLIN,RIGHTOVER,ALLRIGHT,LEFTRIGHTOVER,LEFTIN}; + +/*----------- Modes -------------------------------*/ +enum Modes {REMAKE, INSERT, DELETE}; + +/*----------- 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"; + static int ToZipFlag = 0; + static char UnzipName[NAME_LENGTH]; + +/*======================================================================== + * FUNCTIONS + *=======================================================================*/ +/*======================================================================== + * GetFileInfo + *=======================================================================*/ +t_StartStop *GetFileInfo(char *FileName) +{ + static t_StartStop StartStop; + int dataID; + int DataStartID, DataStopID; + static size_t DataStart[1] = {0}; + static size_t DataCount[1] = {TIME_LENGTH}; + char command[200]; + int Status; + + /*---- Check if this file exist ------------*/ + if(strcmp(FileName+strlen(FileName)-3,".gz") == 0) // Zipped file + { + strcpy(UnzipName, TEMPUNZIP); + sprintf(command,"gunzip -c %s > %s",FileName,UnzipName); + system(command); + ToZipFlag = 0; + strncpy(StartStop.Name,FileName,strlen(FileName)-3); + } else + { + ToZipFlag = 1; + strcpy(UnzipName,FileName); + strcpy(StartStop.Name,FileName); + } + + if((Status = nc_open(UnzipName,NC_NOWRITE,&dataID)) == NC_NOERR) + { + Status = nc_inq_varid(dataID,STARTTIME,&DataStartID); + Status = nc_inq_varid(dataID,STOPTIME, &DataStopID); + + Status = nc_get_vara_text(dataID,DataStartID,DataStart,DataCount,(char *)StartStop.StartS); + Status = nc_get_vara_text(dataID,DataStopID,DataStart,DataCount,(char *)StartStop.StopS); + Status = nc_close(dataID); + } + else if(Status == 2) + { + fprintf(stderr,"File %s does not exist\n",UnzipName); + return NULL; + } + else + { + fprintf(stderr,"File %s is corrupted, Error = %d\n",UnzipName,Status); + sprintf(command,"rm %s*",StartStop.Name); + system(command); + return NULL; + } + + if((isdigit(StartStop.StartS[0]) == 0) || (isdigit(StartStop.StopS[0]) == 0)) + { + fprintf(stderr,"File %s is corrupted\n",UnzipName); + sprintf(command,"rm %s*",StartStop.Name); + system(command); + return NULL; + } + + StartStop.StartD = DD_Time2Double(StartStop.StartS); + StartStop.StopD = DD_Time2Double(StartStop.StopS); + + return &StartStop; +} +/*-----------------------------------------------------------*/ + +/*------------------------------------------------------------ + * RemoveRecord() + *-----------------------------------------------------------*/ +int RemoveRecord(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]; + size_t Crec; + char command[200]; + int status; + char NewName[NAME_LENGTH]; + +/*------- Remove corresponding file -------------------*/ + TimeStart[0] = RecordPos; + nc_get_vara_text(tmID,NameID,TimeStart,NameCount,(char *)CName); + if(StartStop == NULL) NewName[0] = '\0'; else strcpy(NewName,StartStop->Name); + if((strcmp(CName,NODATA) != 0)&&(strcmp(CName,NewName) != 0)) + { // Remove old file which overlap with new one */ + sprintf(command,"rm %s*",CName); + system(command); + } + +/*--- replacing Variable -----------------------*/ + for(Crec = RecordPos + 1; Crec < RecordsNumber; Crec++) + { + TimeStart[0] = 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); + } + +/*----- Set Zero at the end -------------------------*/ + TimeStart[0] = RecordsNumber - 1; + status = nc_put_vara_text(tmID,StartID,TimeStart,TimeCount,(char *)ZeroTime); + status = nc_put_vara_text(tmID,StopID,TimeStart,TimeCount,(char *)ZeroTime); + + RecordsNumber--; + nc_sync(tmID); + return 1; +} +/*-----------------------------------------------------------*/ + +/*------------------------------------------------------------ + * 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; + +/*--- Scrall all wariables 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: TimesUpdate -r/-i[-u]/-d nc_times_file nc_data_file[*.gz] nc_data_file[*.gz]"; + + 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 i, InsertFlag, FindFlag, ihole; + + char command[100]; + char name[100]; + int compress = 0; + int status; + + double LastTime = 0.0, FirstTime = 0.0; // Times of the hall between files + + t_StartStop *CurrentRecord; // pointer to the internal static structure + enum Modes CurrMode; + enum Conditions condition; + +/*================================================================= + * Check arguments and options + *=================================================================*/ + if(argc < 4) {fprintf(stderr,"%s\n",usage); exit(1); } + if((strcmp(argv[1], "-r")) == 0) CurrMode = REMAKE; + else if((strcmp(argv[1], "-i")) == 0) CurrMode = INSERT; + else if((strcmp(argv[1], "-u")) == 0) CurrMode = INSERT; + else if((strcmp(argv[1], "-d")) == 0) CurrMode = DELETE; + else {fprintf(stderr,"Unknown option %s\n",argv[1]); exit(1);} +/*-----------------------------------------------------------------*/ + +/*================================================================= + * Creating Times ncdf file if we have to make a new file + *=================================================================*/ + switch(CurrMode) + { + case REMAKE: /* Create New File */ + if((status = nc_create(argv[2],NC_SHARE,&tmID)) != NC_NOERR) + { + fprintf(stderr,"Can not create file %s\n",argv[2]); + exit(0); + } + status = nc_def_dim(tmID,TIME_LENGTH_NAME,TIME_LENGTH,&TlDimID); + status = nc_def_dim(tmID,NAME_DIM_NAME,NAME_DIM,&NlDimID); + status = nc_def_dim(tmID,REC_DIM_NAME,REC_DIM,&RecDimID); + + DimVector[0] = RecDimID; + DimVector[1] = TlDimID; + status = nc_def_var(tmID, STARTTIME,TIME_TYPE,2,DimVector,&StartID); + status = nc_def_var(tmID, STOPTIME,TIME_TYPE,2,DimVector,&StopID); + DimVector[1] = NlDimID; + status = nc_def_var(tmID, FILENAME,TIME_TYPE,2,DimVector,&NameID); + RecordsNumber = 0; + TimeStart[0] = (size_t)RecordsNumber; + status = nc_enddef(tmID); + break; +/*====== Or just open existing file ===================*/ + case INSERT: + case DELETE: /* Open existing file */ + if((status = nc_open(argv[2],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); + break; + } +/*==========================================================================*/ + + /*========================================================================== + * For Each file in the argument list + *=========================================================================*/ + for(i = 3; i < argc; i++) + { + switch(CurrMode) + { + case DELETE: + TimeStart[0] = 0; + FindFlag = 0; + while((FindFlag == 0) && (TimeStart[0] < RecordsNumber)) + { + status = nc_get_vara_text(tmID,NameID,TimeStart,NameCount,(char *)tmName); + + if(strncmp(tmName, argv[i], strlen(tmName)) == 0) + { /* Record is found */ + FindFlag = 1; + RemoveRecord((size_t)TimeStart[0],(t_StartStop *)NULL); + } + else TimeStart[0]++; + } + break; + case REMAKE: + case INSERT: + if((CurrentRecord = GetFileInfo(argv[i])) != NULL) /* Read current file information */ + { + /*----------------- The very first file in VI DIR -------------------*/ + if (RecordsNumber == 0) + { + TimeStart[0] = (size_t)0; + status = nc_put_vara_text(tmID,StartID,TimeStart,TimeCount,(char *)CurrentRecord->StartS); + status = nc_put_vara_text(tmID,StopID,TimeStart,TimeCount,(char *)CurrentRecord->StopS); + status = nc_put_vara_text(tmID,NameID,TimeStart,NameCount,(char *)CurrentRecord->Name); + RecordsNumber++; + } else + { + /*--------------------------------------------------------- + * Searchig the same file or a hole to insert + *-------------------------------------------------------*/ + InsertFlag = 0; + ihole = 0; + while((InsertFlag == 0) && (ihole <= RecordsNumber)) + { + if(ihole > 0) /* Get the Left Time of the hole */ + { + TimeStart[0] = (size_t)(ihole-1); + status = nc_get_vara_text (tmID,StopID,TimeStart,TimeCount,(char *)Stop); + FirstTime = DD_Time2Double(Stop); + } else FirstTime = 0.0; + + if(ihole < RecordsNumber) /* Get the Right Time of the hole */ + { + TimeStart[0] = (size_t)ihole; + status = nc_get_vara_text(tmID,StartID,TimeStart,TimeCount,(char *)Start); + LastTime = DD_Time2Double(Start); + } + else LastTime = 1.0e16; + + /*--------- Look the conditions ---------------*/ + condition = ALLRIGHT; + if((CurrentRecord->StartD < FirstTime - 60.0) && + (CurrentRecord->StopD > LastTime + 60.0)) condition = LEFTRIGHTOVER; + else if((CurrentRecord->StartD < FirstTime - 60.0) && + (CurrentRecord->StopD < FirstTime + 60.0)) condition = ALLLEFT; + else if((CurrentRecord->StartD < FirstTime - 60.0) && + (CurrentRecord->StopD > FirstTime) && + (CurrentRecord->StopD < LastTime + 60.0)) condition = LEFTOVER; + else if((CurrentRecord->StartD >= FirstTime - 60.0) && + (CurrentRecord->StopD <= LastTime + 60.0)) condition = WELLIN; + else if((CurrentRecord->StartD >= FirstTime - 60.0) && + (CurrentRecord->StartD < LastTime) && + (CurrentRecord->StopD > LastTime + 60.0))condition = RIGHTOVER; + else if((CurrentRecord->StartD > LastTime - 60.0) && (CurrentRecord->StopD > LastTime + 60.0)) + condition = ALLRIGHT; + + /* What to do with these conditions ----------------*/ + switch(condition) + { + case WELLIN : InsertRecord((size_t)ihole, CurrentRecord); InsertFlag = 1; break; + case ALLLEFT : RemoveRecord((size_t)(ihole-1),CurrentRecord); ihole--; break; + case ALLRIGHT : ihole++; break; + case LEFTOVER : RemoveRecord((size_t)(ihole-1),CurrentRecord); ihole--; break; + case RIGHTOVER : RemoveRecord((size_t)ihole,CurrentRecord); break; + case LEFTRIGHTOVER : RemoveRecord((size_t)(ihole-1),CurrentRecord); + RemoveRecord((size_t)(ihole-1),CurrentRecord); + ihole--; break; + } + } // While InsertFlag + } // if RecordsNumber > 0 + /*---------- Zip or remove new nc file -----------------*/ + if(ToZipFlag) sprintf(command,"gzip -f %s",CurrentRecord->Name); + else sprintf(command,"rm %s",UnzipName); + system(command); + } // If current argument file is OK + } // CASE + } // For several arguments + status = nc_close(tmID); + return(0); +} +/*=========================================================================================================*/ diff --git a/src/TIMESUPDATENODATA/CMakeLists.txt b/src/TIMESUPDATENODATA/CMakeLists.txt new file mode 100644 index 0000000..0628c35 --- /dev/null +++ b/src/TIMESUPDATENODATA/CMakeLists.txt @@ -0,0 +1,24 @@ + +PROJECT(TimesUpdateNoData) + +include_directories( + ${CMAKE_HOME_DIRECTORY}/src/INCLUDE/ + ${NETCDFINCLUDE_DIR} +) + +#Configuration de l'exécutable +file( + GLOB_RECURSE + source_files + ./* +) + +ADD_EXECUTABLE (TimesUpdateNoData ${source_files} ) + +target_link_libraries( + TimesUpdateNoData + DD_Client + ${NETCDFLIBRARY} +) + +install (TARGETS TimesUpdateNoData DESTINATION bin) diff --git a/src/TIMESUPDATENODATA/TimesUpdateNoData.c b/src/TIMESUPDATENODATA/TimesUpdateNoData.c new file mode 100644 index 0000000..f881b1b --- /dev/null +++ b/src/TIMESUPDATENODATA/TimesUpdateNoData.c @@ -0,0 +1,330 @@ +/** +* @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); +} +/*=========================================================================================================*/ -- libgit2 0.21.2