Esempio n. 1
0
	/*! \brief Add grid dataset
	 *
	 * \param i sub-domain id
	 * \param g Grid to add
	 * \param offset grid offset
	 * \param spacing spacing of the grid
	 * \param dom part of the spacethat is the domain
	 *
	 */
	void add(size_t i, const typename pair::first & g, const Point<pair::first::dims,typename pair::second> & offset, const Point<pair::first::dims,typename pair::second> & spacing, const Box<pair::first::dims,typename pair::second> & dom, const comb<pair::first::dims> & cmb)
	{
		//! Increase the size
		if (i >= vg.size())
			vg.resize(i+1);

		vg.get(i).offset = offset;
		vg.get(i).spacing = spacing;
		vg.get(i).dom = dom;

		// append the grid
		append_grid(i,g,cmb);
	}
Esempio n. 2
0
/*
 * Scan the named file, createing a grid_info struct for each grid.  Store
 * the grid_info structs in the grid data base.
 * Input:  name - name of grads file.
 *         db - the grid data base
 * Return:  number of grids found.
 */
int get_grads_info( char *name, struct grid_db *db )
{
   FILE *f;
   char **token;
   int ntokens;
   int time, var;
   int grids = 0;
   struct grid_info *info;
   int pos = 0;
   int fileheader_size = 0;
   float args[1000];
   struct projection *proj;
   struct vcs *vcs[MAXVARS];

   /* GrADS file info: */
   char dset_name[1000];
   float missing_value;
   int byteswapped = 0;
   int nr, nc, nl[MAXLEVELS], maxnl;
   int vertical;
   float westbound, northbound, bottombound;
   float rowinc, colinc, levinc;
   float height[MAXLEVELS];
   char varname[MAXVARS][100];
   int timestamp[MAXTIMES], datestamp[MAXTIMES];
   int numtimes, numvars;
   int projection_type = PROJ_LINEAR;
   int use_file_template = 0;
   char specific_file_name[TEMPLATE_OUTPUT_LEN];

   /* Initialize args */
   args[0] = args[1] = args[2] = args[3] = args[4] = 0.0f;

   f = fopen( name, "r" );
   if (!f) {
      printf("Error: couldn't open %s\n", name );
      return 0;
   }
   

   while (1) {
      char line[MAXLINE];
      /* read a line of the control file */
      if (!fgets( line, MAXLINE, f ))
         break;

      /* break line into tokens */
      token = tokenize( line, &ntokens );

      if (ntokens==0) continue;

      if (strcasecmp(token[0],"DSET")==0) {
         if (ntokens<2) {
            printf("Error: missing filename argument on DSET line\n");
         }
         else {
            if (token[1][0]=='^') {

               /* skip the ^ (current directory) character */
               /* This is not the current directory, rather it is the same 
                  directory in which the control file is located */
              int i;
              for(i=strlen(name)-1;i>=0;i--){
                if(name[i] == '/'){
                  strncpy(dset_name,name,i+1);
                  i++;
                  break;
                }
              } 
				  if(i<0) i=0; /* No path in ctl file name */
              strcpy( dset_name+i, token[1]+1 );
            }
            else {
               strcpy( dset_name, token[1] );
            }
         }
			if(Debug_i) printf("dset name >%s<\n",dset_name);
      }
      else if (strcasecmp(token[0],"TITLE")==0) {
         /* ignore the title line */
      }
      else if (strcasecmp(token[0],"UNDEF")==0) {
         missing_value = atof(token[1]);
      }
      else if (strcasecmp(token[0],"BYTESWAPPED")==0) {
         /* Is this valid??? Shouldn't it be "OPTIONS BYTESWAPPED" ? */
         byteswapped = 1;
      }
      else if (strcasecmp(token[0],"FORMAT")==0) {
         if (strcasecmp(token[1],"SEQUENTIAL")==0) {
               /* this is the only format currently supported; */
               /* also note: FORMAT keyword has been replaced by OPTIONS */
         }
         else {
            printf("Warning: FORMAT not fully supported\n");
            printf("         only SEQUENTIAL format is allowed.\n");
         }
      }
      else if (strcasecmp(token[0],"OPTIONS")==0) {
         if (strcasecmp(token[1],"SEQUENTIAL")==0) {
            /* Don't need to do anything, supported by default??? */
         }
         else if (strcasecmp(token[1],"BYTESWAPPED")==0) {
            byteswapped=1;
         }
         else if (strcasecmp(token[1],"TEMPLATE")==0) {
            use_file_template=1;
         }
#ifdef WORDS_BIGENDIAN
	      else if (strcasecmp(token[1],"LITTLE_ENDIAN")==0 ) {
           byteswapped=1;
         }
#else
	      else if (strcasecmp(token[1],"BIG_ENDIAN")==0  ) {
           byteswapped=1;
         }
#endif
         else {
            printf("Warning: OPTIONS %s not supported\n", token[1]);
         }
      }
      else if (strcasecmp(token[0],"FILEHEADER")==0) {
         if (ntokens<2) {
            printf("Error: missing position argument on FILEHEADER line\n");
         }
         fileheader_size = atoi( token[1] );
         pos = fileheader_size;
      }
      else if (strcasecmp(token[0],"XDEF")==0) {
         if (ntokens<4) {
            printf("Error: missing arguments to XDEF line\n");
         }
         else {
            nc = atoi( token[1] );
            if (strcasecmp(token[2],"LINEAR")==0) {
               westbound = -atof( token[3] );
               colinc = atof( token[4] );
            }
            else if (strcasecmp(token[2],"LEVELS")==0) {
               printf("Warning: XDEF LEVELS not fully supported\n");
               westbound = -atof( token[3] );
               colinc = fabs( atof(token[3]) - atof(token[4]) );
            }
            else {
               printf("Warning: XDEF %s not fully supported\n", token[2]);
            }
         }
      }
      else if (strcasecmp(token[0],"YDEF")==0) {
         if (ntokens<4) {
            printf("Error: missing arguments to YDEF line\n");
         }
         else {
            nr = atoi( token[1] );
            if (strcasecmp(token[2],"LINEAR")==0) {
               float southbound = atof( token[3] );
               rowinc = atof( token[4] );
               northbound = southbound + rowinc * (nr-1);
            }
            else if (strncmp(token[2],"GAUSR",5)==0
                     || strncmp(token[2],"gausr",5)==0) {
               printf("Warning: YDEF GAUSRnn not supported\n");
            }
            else {
               printf("Warning: YDEF %s not fully supported\n", token[2]);
            }
         }
      }
      else if (strcasecmp(token[0],"PDEF")==0) {
         if (ntokens<4) {
            printf("Error: missing arguments to PDEF line\n");
         }
         else {
            nc = atoi( token[1] );
            nr = atoi( token[2] );
            if (strcasecmp(token[3],"PSE")==0) {
               if (ntokens<11) {
                  printf("Error: missing arguments to PDEF line\n");
                  printf("'PDEF ... pse ...' must have 10 arguments\n");
               }
               else {
                  double pseLat       = atof( token[4] );    /* degrees */
                  double pseLon       = atof( token[5] );    /* degrees */
                  double pseCenterCol = atof( token[6] );    /* grid units */
                  double pseCenterRow = atof( token[7] );    /* grid units */
                  double pseDeltaX    = atof( token[8] );    /* in km */
                  /*double pseDeltaY    = atof( token[9] ); */   /* ignored */
                  int    pseNorthOrSouth = atoi( token[10] );/* +1 or -1 */

                  /* grads documentation describes this format as 
                     "high accuracy polar stereo (eccentric)" while vis5d
                     calls it "azimuthal stereographic". The conversions
                     performed here are somewhat cryptic, and were obtained
                     with some combination of reading the documentation and
                     trial and error. */
                  /* center latitude. NOT TESTED FOR SOUTH POLAR PROJECTION! */
                  args[0] = pseNorthOrSouth * 90.0;

                  /* center longitude. Why minus 270? Seems to work though. */
                  args[1] = pseLon - 270.0;
                  /* put longitude in the range -180 to +180 */
                  args[1] = fmod( args[1], 360.0 );
                  if ( args[1] > 180.0 ) args[1] -= 360.0;
                  if ( args[1] <-180.0 ) args[1] += 360.0;

                  /* center grid row. Why the minus sign and nr-1? */
                  args[2] = nr - ( pseCenterRow + 1 );

                  /* center grid column */
                  args[3] = pseCenterCol;

                  /* column inc. in km, GrADS gives column increment at this
                     lattitude, we need column increment at the pole. */
                  args[4] = pseDeltaX * ( 1.0 + sin( 90/57.29578 ) ) /
                                        ( 1.0 + sin( pseLat/57.29578 ) );

                  /* what to do with token[9] - row inc. in km??? */
                  /* what to do with token[10] - 1 is N pole, -1 is S pole???*/
                  projection_type = PROJ_STEREO;
               }
            }
            else {
               printf("Warning: \"PDEF ... %s ...\" not supported\n", token[3] );
            }
         }
      }
      else if (strcasecmp(token[0],"ZDEF")==0) {
         if (ntokens<3) {
            printf("Error: missing arguments to ZDEF line\n");
         }
         else {
            float pressure[MAXLEVELS];
            int i;
            maxnl = atoi( token[1] );
            if (strcasecmp(token[2],"LINEAR")==0) {
               vertical = VERT_EQUAL_KM;
               bottombound = atof( token[3] );
               levinc = atof( token[4] );
               for (i=0;i<maxnl;i++) {
                  pressure[i] = bottombound + i * levinc;
               }
            }
            else if (strcasecmp(token[2],"LEVELS")==0) {
               vertical = VERT_UNEQUAL_MB ; /*VERT_UNEQUAL_KM;*/
               for (i=0;i<maxnl && i+3<ntokens;i++) {
                  pressure[i] = atof( token[3+i] );
                  height[i] = pressure_to_height(pressure[i]);
               }
            }

         }

      }
      else if (strcasecmp(token[0],"TDEF")==0) {
         if (ntokens!=5) {
            printf("Error: missing arguments to TDEF line\n");
         }
         else {
            int date0, time0, days, seconds;
            int i, it, id, ii;

            numtimes = atoi( token[1] );
            /* token[2]=="LINEAR" */

            if (!parse_time( token[3], &date0, &time0 )) {
               printf("Error reading grads header, bad time: %s\n", token[3] );
            }
            if (!parse_time_inc( token[4], &days, &seconds )) {
               printf("Error reading grads header, bad time increment: %s\n",
                      token[4] );
            }

            id = v5dYYDDDtoDays(date0);
            it = v5dHHMMSStoSeconds(time0);
            for (i=0;i<numtimes&&i<MAXTIMES;i++) {
               timestamp[i] = v5dSecondsToHHMMSS(it);
               datestamp[i] = v5dDaysToYYDDD(id);
               it = it + seconds;
               ii = it / 86400;
               it = it - 86400 * ii;
               id = id + days + ii;
            }
         }
      }
      else if (strcasecmp(token[0],"VARS")==0) {
         /* TODO: variables */
         if (ntokens!=2) {
            printf("Error: wrong number of arguments to VARS line\n");
         }
         else {
            char **vartok;
            int i, ntok;

            numvars = atoi( token[1] );

            for (i=0;i<numvars;i++) {
               fgets( line, MAXLINE, f );
               vartok = tokenize( line, &ntok );
               strcpy( varname[i], vartok[0] );   /* var name */
               nl[i] = atoi( vartok[1] );         /* number of levels */

               /* JPE nl=0 has a special meaning and will create a 
						different vcs below 
					  if (nl[i]==0)  nl[i] = 1; */
					
               /* vartok[2] = units */
               /* vartok[3] = text description */
               free_tokens( vartok );
            }
         }
      }
      else if (strcasecmp(token[0],"ENDVARS")==0){
         /* ignore */
      }
      else {
         printf("Warning: unknown token: %s\n",token[0] );
      }

   } /*while*/


   /*
    * Generate grid_info structs
    */

   if ( projection_type == PROJ_LINEAR ) {

      args[0] = northbound;
      args[1] = westbound;
      args[2] = rowinc;
      args[3] = colinc;
      proj = new_projection( db, PROJ_LINEAR, nr, nc, args );
   }
   else if ( projection_type == PROJ_STEREO ) {
      /* args have already been set properly. */
      proj = new_projection( db, PROJ_STEREO, nr, nc, args );
   }

   /* Potentially different vcs for each grid because number of levels */
   /* can vary per variable. */
   for (var=0;var<numvars;var++) {
      if (vertical==VERT_EQUAL_KM) {
         args[0] = bottombound;
         args[1] = levinc;
      }
      else {
         int i;
         if(nl[var]==0){
			  nl[var]=1;
			  args[0] = 0.0;
			}else{
			  for (i=0;i<maxnl;i++) {
				 args[i] = height[i];
			  }
			}
      }
      vcs[var] = new_vcs( db, vertical, nl[var], 0, args );
   }

   if ( numtimes > MAXTIMES ) {
      printf("Warning: %d is too many time steps, %d is limit.\n",
             numtimes, MAXTIMES );
   }
   for (time=0;time<numtimes&&time<MAXTIMES;time++) {
      if ( use_file_template ) {
         int yr, mo, dy, hr, mn, jday;
         char prev_file_name[1000];

         /* Save the old file name so we can see if it has changed. */
         strcpy( prev_file_name, specific_file_name );

         /* Replace FileName, which may be a format string, with result
            of expanding the file format string. */
         yr = yy2yyyy( datestamp[time] / 1000 );
         jday = datestamp[time] - 1000*(datestamp[time] / 1000);
         julian2mmdd( yr, jday, &mo, &dy );
         hr = timestamp[time] / 10000;
         mn = timestamp[time] / 100 - hr*100;
	 expand_GrADS_file_template(dset_name, specific_file_name,
				    yr, mo, dy, hr, mn,
				    hr, yr, mo, dy, hr, mn);

         if ( strcmp( prev_file_name, specific_file_name ) != 0 ) {
            /* Changing files - reset pos to the beginning of the file */
            pos = fileheader_size;
         }
         printf("In get_grads_info, date:%05d, time:%06d, file:%s\n",
                 datestamp[time], timestamp[time], specific_file_name );
      } else {
         strcpy( specific_file_name, dset_name );
      }

      for (var=0;var<numvars;var++) {

         info = alloc_grid_info();


         info->FileName = strdup( specific_file_name );
         info->Format = FILE_GRADS;
         info->TimeStep = time;
         info->VarNum = var;
         info->Position = pos;         /* pos. of data in binary grid file */
         pos += nr * nc * nl[var] * 4;

         info->Nr = nr;
         info->Nc = nc;
         info->Nl = nl[var];

         info->DateStamp = datestamp[time];
         info->TimeStamp = timestamp[time];
         info->VarName = strdup( varname[var] );

         info->Proj = proj;
         info->Vcs = vcs[var];

         info->MissingValue = missing_value;
         info->byteswapped = byteswapped;

         append_grid( info, db );
         grids++;

      }

   }

   return grids;
}
Esempio n. 3
0
/*
 * Scan the named file, createing a grid_info struct for each grid.  Store
 * the grid_info structs in the grid data base.
 * Input:  name - name of UW VIS file.
 *         db - the grid data base
 * Return:  number of grids found.
 */
int get_uwvis_info( char *name, struct grid_db *db )
{
   static int init_flag = 0;
   FILE *f;
   int grids = 0;
   int var, numvars, nr, nc, nl;
   float height[MAXLEVELS];
   char ch;
   int i, vcs;

   if (init_flag==0) {
      init_visreader();
      init_flag = 1;
   }


   /* Open the file */
   f = fopen( name, "r" );
   if (!f) {
      return 0;
   }

   fscanf( f, "%d", &numvars );
   if (numvars>MAXVARS) {
      printf("ERROR: %s contains too many variables, limit is %d\n",
             name, MAXVARS );
   }

   /* grid size */
   fscanf( f, "%d", &nc );
   fscanf( f, "%d", &nr );
   fscanf( f, "%d", &nl );
   (void) getc(f);  /* get '\n' */

   /* this is tricky:
    * We look at the next character:
    * if it's a letter then
    *     we read the variable name and extract the height info from header
    * else
    *     read the height values for each grid level (variable delta Z).
    * endif
    */
   ch = getc(f);
   ungetc(ch, f);

   if (isalpha(ch)) {
      vcs = 1;
   }
   else {
      /* Read the height (in meters) of each grid level */
      for (i=0;i<nl;i++) {
         fscanf( f, "%8f", &height[i] );
         height[i] /= 1000.0;    /* convert from meters to km */
      }
      (void) getc(f);  /* get '\n' */
      vcs = 2;
   }


   for (var=0;var<numvars;var++) {
      int *header, header_size;
      char varname[100];
      struct grid_info *info;
      float args[100];

      /* read variable name */
      fgets( varname, 40, f );
      for (i=7;i>=0 && varname[i]==' ';i--) {
         varname[i] = '\0';
      }
      varname[8] = 0;

      /* read data header */
      header = read_int_block( f, &header_size );


      /*
       * Allocate grid info struct and initialize it.
       */
      info = alloc_grid_info();

      info->FileName = strdup( name );
      info->Format = FILE_UWVIS;
      info->Position = ftell(f);    /* save position of data in file */

      info->Nr = nr;
      info->Nc = nc;
      info->Nl = nl;

      info->DateStamp = header[5];
      info->TimeStamp = header[6];
      info->VarName = strdup( varname );

      args[0] = (float) header[22] / 10000.0;
      args[1] = (float) header[23] / 10000.0;
      args[2] = (float) header[24] / 10000.0;
      args[3] = (float) header[25] / 10000.0;
      info->Proj = new_projection( db, PROJ_LINEAR, nr, nc, args );

      if (vcs==1) {
         /* equally spaced km */
         float tophgt = (float) header[31] / 1000.0;
         float hgtinc = (float) header[32] / 1000.0;
         args[0] = tophgt - hgtinc*(nl-1);
         args[1] = hgtinc;
      }
      else {
         /* vcs==2 */
         /* unequally spaced km */
         memcpy( args, height, sizeof(float)*nl );
      }
      info->Vcs = new_vcs( db, vcs, nl, 0, args );

      /*
       * done with this grid
       */
      append_grid( info, db );
      grids++;

      free( header );

#ifdef LEAVEOUT
      {
         float *data;
         int data_size;
         /* read and skip data */
         data = read_float_block( f, &data_size );
         free( data );
      }
#else
      skip_float_block( f );
#endif
   }

   fclose(f);

   return grids;
}