UpdateTimeInfo.c 6.55 KB
/*=====================================================================
 *                  DD SYSTEM base package
 *                   DD_Server library
 *                    UpdateTimeInfo.c
 *                        V.1.1
 *  Functions to updete time constant in the DD_Var structure and 
 *  auxial functions to search in the "times" file.
 *
 *  Versions:
 *  Sep 20, 2007, V.1.0, Fedorov
 *  Sep 23, 2007, V.1.1, Fedorov, SHARE MODE
 *=====================================================================*/

#include <netcdf.h>
#include "DD.h"
#include "DD_comm.h"

extern int Verbose;
/*---------------------------------------------------------
 *            SearchRight()
 *---------------------------------------------------------*/
int SearchRight(DD_Var_t *DD_VarL, size_t Rmin, size_t Rmax)
{
  static size_t start[2] = {0,0};
  static size_t TimeCount[2] = {1,TIMELENGTH};
  static size_t FileCount[2] = {1,MAXFILENAME};
  char TimeIntName[MAXSETLENGTH]; /* File name associated with the given time interval */
  int NoDataFlag;
  int status;
  
  start[0] = DD_VarL->TimeRecNumber;
  
  NoDataFlag = 1;
  while(NoDataFlag)
  {
     status = nc_get_vara_text(DD_VarL->tmID, DD_VarL->NameID,start,FileCount,TimeIntName);
     if(strcmp(TimeIntName,NODATASTR) == 0) /* No data for this time interval */
     {
        start[0]++; /* Go right */
        if(start[0] > Rmax)  return REACHRIGHT; /* End of alowed interval is reached */
     }
     else 
     {
        DD_VarL->TimeRecNumber = start[0];
        NoDataFlag = 0;
     }
  }
  return OKRIGHT;
}

/*---------------------------------------------------------
 *            SearchLeft()
 *---------------------------------------------------------*/
int SearchLeft(DD_Var_t *DD_VarL, size_t Rmin, size_t Rmax)
{
  static size_t start[2] = {0,0};
  static size_t TimeCount[2] = {1,TIMELENGTH};
  static size_t FileCount[2] = {1,MAXFILENAME};
  char TimeIntName[MAXSETLENGTH]; /* File name associated with the given time interval */
  int NoDataFlag;
  int status;
  
  start[0] = DD_VarL->TimeRecNumber;
  
  NoDataFlag = 1;
  while(NoDataFlag)
  {
     status = nc_get_vara_text(DD_VarL->tmID, DD_VarL->NameID,start,FileCount,TimeIntName);
     if(strcmp(TimeIntName,NODATASTR) == 0) /* No data for this time interval */
     {
        if(start[0] > 0) start[0]--; else return REACHLEFT; /* Go left */
        if(start[0] < Rmin)  return REACHLEFT;              /* End of alowed interval is reached */
     }
     else 
     {
        DD_VarL->TimeRecNumber = start[0];
        NoDataFlag = 0;
     }
  }
  return OKLEFT;
}
/*-----------------------------------------------------------------*/

/*---------------------------------------------------------
 *            UpdateTimeInfo()
 *---------------------------------------------------------*/
int UpdateTimeInfo(DD_Var_t *DD_VarL)
{
  static char StartName[] =  "StartTime";
  static char StopName[] =   "StopTime";
  static char FileName[] =   "FileName"; /* Variable IDs */
  static char RecDimName[] = "record";
  static int  RecDimID;
  static size_t start[2] = {0,0};
  static size_t TimeCount[2] = {1,TIMELENGTH};
  char TimeS[TIMELENGTH];
  size_t Rmin,Rmax;
  int SearchStatus;
  int status;  
  /*---- Close file if it is open ---------------------------*/
  if(DD_VarL->tmID > -1) status = nc_close(DD_VarL->tmID);
  
  if(Verbose) fprintf(stderr,"UpdateTimeInfo(%s): Start\n",DD_VarL->TimesFileName);
  
  /*---- Reopen times file ----------------------------------*/
  status = nc_open(DD_VarL->TimesFileName, NC_NOWRITE|NC_SHARE,&(DD_VarL->tmID)); 
  if(status != NC_NOERR)
   {
      if(Verbose) fprintf(stderr,"UpdateTimeInfo(%s): open file: message: %s\n",DD_VarL->TimesFileName,nc_strerror(status));
      return(NOTIMESFILE);
   }
   /*
    * Init corresponding constants
    */
    status =  nc_inq_varid(DD_VarL->tmID,FileName, &(DD_VarL->NameID));
    status =  nc_inq_varid(DD_VarL->tmID,StartName,&(DD_VarL->StartID));
    status =  nc_inq_varid(DD_VarL->tmID,StopName, &(DD_VarL->StopID));
    if (status != NC_NOERR)
    {
        if(Verbose) fprintf(stderr,"UpdateTimeInfo(%s): Get parameters times file %s\n",DD_VarL->TimesFileName,nc_strerror(status));
        return(NOTIMESFILE);
    }

     /* Get MaxRecord Number */
     status = nc_inq_dimid(DD_VarL->tmID,RecDimName, &RecDimID);
     if (status != NC_NOERR)
     {
        if(Verbose) fprintf(stderr,"UpdateTimeInfo(%s): Get Max records in Times file %s\n",DD_VarL->TimesFileName,nc_strerror(status));
        return(NOTIMESFILE);
     }
     status = nc_inq_dimlen(DD_VarL->tmID,RecDimID, &(DD_VarL->MaxTimeRecNum));

/* -----------------------------------------------------------------
 * Search the extreme left and right valid intervals
 * -----------------------------------------------------------------*/
   Rmin = 0; Rmax = DD_VarL->MaxTimeRecNum - 1;
   DD_VarL->TimeRecNumber = 0;
   switch(SearchRight(DD_VarL,Rmin,Rmax))
   {
      case REACHRIGHT: SearchStatus = NOONEDATA;  
                       DD_VarL->RValidMin = -1; 
                       DD_VarL->RValidMax = -1; 
                       DD_VarL->MinValidTime = -1.0;
                       break;
      case OKRIGHT: DD_VarL->RValidMin = DD_VarL->TimeRecNumber;SearchStatus = IDLE;
   }
 
   if(SearchStatus != NOONEDATA) /* Ther is something in the right */
   {
     DD_VarL->TimeRecNumber = Rmax;
     switch(SearchLeft(DD_VarL,Rmin,Rmax))
     {
        case REACHLEFT: DD_VarL->RValidMin = -1; 
                        DD_VarL->RValidMax = -1;  
                        DD_VarL->MaxValidTime = -1.0;
                        break; /* Impossible */
        case OKLEFT: DD_VarL->RValidMax = (int)DD_VarL->TimeRecNumber;
     }
   }
   
   /*------ Define min and max valid times ------------------------*/
   if(DD_VarL->RValidMin >= 0)
   {
     start[0] = (size_t)DD_VarL->RValidMin;
     status = nc_get_vara_text(DD_VarL->tmID, DD_VarL->StartID,start,TimeCount,TimeS);
     DD_VarL->MinValidTime = DD_Time2Double(TimeS);
   }
   else DD_VarL->MinValidTime = -1.0;
   if(DD_VarL->RValidMax >= 0)
   {
     start[0] = (size_t)DD_VarL->RValidMax;
     status = nc_get_vara_text(DD_VarL->tmID, DD_VarL->StopID,start,TimeCount,TimeS);
     DD_VarL->MaxValidTime = DD_Time2Double(TimeS);
   }
   else DD_VarL->MaxValidTime = -1.0;

   
   /*------- Init other values ------------------------------------*/
   DD_VarL->CurrRmin = -1;
   DD_VarL->CurrRmax = -1;
  /*-----------------------------------------------------------------------*/
   if(Verbose) fprintf(stderr,"UpdateTimeInfo(%s): OK\n",DD_VarL->TimesFileName);
   return OK;
}
/*====================================================================================*/