Пример #1
0
Файл: gaexpr.c Проект: cjg/grads
char *stnvar (char *ch, char *vnam, struct gafile *pfi,
              struct gavar *pvar, struct gastat *pst) {
struct gastn *stn;
gadouble dmin[5],dmax[5],d,radius;
gaint id[6],dim,size,i,rc,rflag,sflag;
char *pos;
char stid[10];

  rflag = 0;
  sflag = 0;
  radius = 0;

  /* We want to finish parsing the variable name by looking at
     any dimension settings by the user.  First initialize the
     request environment to that found in the pst.             */

  for (i=0;i<3;i++) {
    dmin[i] = pst->dmin[i];
    dmax[i] = pst->dmax[i];
  }
  dmin[3] = t2gr(pfi->abvals[3],&(pst->tmin));
  dmax[3] = t2gr(pfi->abvals[3],&(pst->tmax));

  /* Check for user provided dimension expressions */
  if (*ch=='(') {
    ch++;
    for (i=0;i<6;i++) id[i] = 0;
    while (*ch!=')') {
      if (!cmpch(ch,"stid=",5)) {   /* special stid= arg */
        for (i=0; i<8; i++) stid[i] = ' ';
        stid[8] = '\0';
        pos = ch+5;
        i=0;
        while (*pos!=',' && *pos!=')' && i<8) {
          stid[i] = *pos;
          pos++;
          i++;
        }
        if (i==0) {
          gaprnt (0,"Dimension Expression Error: No stid provided\n");
          pos=NULL;
        }
        if (i>8) {
          gaprnt (0,"Dimension Expression Error: stid too long\n");
          pos=NULL;
        }
	dim=11; 
      } else {
        pos = dimprs(ch, pst, pfi, &dim, &d, 0, &rc);
      }
      if (pos==NULL) {
        sprintf (pout,"  Variable name = %s\n",vnam);
        gaprnt (0,pout);
        return (NULL);
      }
      if (dim<6 && id[dim]>1) {
        gaprnt (0,"Syntax Error: Invalid dimension expression\n");
        gaprnt (0,"  Same dimension specified more than twice ");
        sprintf (pout,"for variable = %s\n",vnam);
        gaprnt (0,pout);
        return (NULL);
      }
      if ( dim==pst->idim || dim==pst->jdim ||
           ( dim>3 && (pst->idim==0 || pst->idim==1 || pst->jdim==1))) {
        gaprnt (0,"Data Request Error: Invalid dimension expression\n");
        gaprnt (0,"  Attempt to set or modify varying dimension\n");
        sprintf (pout,"  Variable = %s, Dimension = %i \n",vnam,dim);
        gaprnt (0,pout);
        return (NULL);
      }
      if (dim==10) {
        rflag = 1;
        radius = d;
      } else if (dim==11) {
        sflag = 1;
      } else {
        if (id[dim]==0) dmin[dim] = d;
        dmax[dim] = d;
      }
      ch = pos;
      if (*ch == ',') ch++;
      id[dim]++;
    }
    ch++;
  }

  /* Verify that dmin is less than or equal to dmax for all our dims */
  for (i=0; i<4; i++) {
    if ((i!=2 && dmin[i]>dmax[i]) || (i==2 && dmax[i]>dmin[i])) {
      gaprnt (0,"Data Request Error: Invalid grid coordinates\n");
      sprintf (pout,"  Varying dimension %i decreases: %g to %g \n",i,dmin[i],dmax[i]);
      gaprnt (0,pout);
      sprintf (pout,"  Error ocurred getting variable '%s'\n",vnam);
      gaprnt (0,pout);
      return (NULL);
    }
  }

  /* Looks like the user specified good stuff, and we are ready to
     try to get some data.  Allocate and fill in a gastn block.     */

  size = sizeof(struct gastn);
  stn = (struct gastn *)galloc(size,"stn");
  if (stn==NULL) {
    gaprnt (0,"Memory Allocation Error:  Station Request Block \n");
    return (NULL);
  }
 
  stn->rnum = 0;
  stn->rpt = NULL;
  stn->pfi = pfi;
  stn->idim = pst->idim;
  stn->jdim = pst->jdim;
  stn->undef = pfi->undef;
  stn->tmin = dmin[3];
  stn->tmax = dmax[3];
  stn->ftmin = dmin[3];
  stn->ftmax = dmax[3];
  stn->pvar = pvar;
  for (i=0; i<3; i++) {
    stn->dmin[i] = dmin[i];
    stn->dmax[i] = dmax[i];
  }
  stn->rflag = rflag;
  stn->radius = radius;
  stn->sflag = sflag;
  if (sflag) {
    for (i=0; i<8; i++) stn->stid[i] = stid[i];
  }
  stn->tvals = (gadouble *)galloc(sizeof(gadouble)*8,"stntvals");
  if (stn->tvals==NULL) {
    gree(stn,"f170");
    gaprnt (0,"Memory Allocation Error:  Station Request Block \n");
    return (NULL);
  }
  for (i=0; i<8; i++) *(stn->tvals+i) = *(pfi->grvals[3]+i);

  rc = gagstn (stn);

  if (rc) {
    sprintf (pout,"Data Request Error:  Variable is '%s'\n",vnam);
    gaprnt (0,pout);
    gree(stn,"f171");
    return (NULL);
  }
  pst->result.stn = stn;
  pst->type = 0;
  return (ch);
}
Пример #2
0
Файл: gaexpr.c Проект: cjg/grads
struct gastn *gastop (struct gastn *stn1, struct gastn *stn2,
                      gaint op, gaint rel) {
struct gastn *stn;
struct garpt *rpt1,*rpt2;
gaint swap,i,j,flag,dimtyp;

  /* Verify dimension environment */

  if (stn1->idim==0 && stn1->jdim==1 && 
      stn2->idim==0 && stn2->jdim==1) 
    dimtyp = 1;                                 /* X and Y are varying */
  else if (stn1->idim==2 && stn1->jdim==-1 && 
	   stn2->idim==2 && stn2->jdim==-1) 
    dimtyp = 2;                                 /* Z is varying */
  else if (stn1->idim==3 && stn1->jdim==-1 && 
	   stn2->idim==3 && stn2->jdim==-1) 
    dimtyp = 3;                                 /* T is varying */
  else {
    gaprnt (0,"Invalid dimension environment for station data");
    gaprnt (0," operation\n");
    return (NULL);
  }

  /* Set it up so first stn set has fewer stations */

  swap=0;
  if (stn1->rnum > stn2->rnum) {
    stn=stn1;
    stn1=stn2;
    stn2=stn;
    swap=1;
  }

  /* Loop through stations of 1st station set.  Find matching
     stations in 2nd station set.  If a match, perform operation.
     Any duplicates in the 2nd station set get ignored.      */

  rpt1 = stn1->rpt;
  for (i=0; i<stn1->rnum; i++,rpt1=rpt1->rpt) {
    if (rpt1->umask == 0) continue;
    flag = 0;
    rpt2 = stn2->rpt;
    for (j=0; j<stn2->rnum; j++,rpt2=rpt2->rpt) {
      if (rpt2->umask == 0) continue;
      if (dimtyp==1 && dequal(rpt1->lat,rpt2->lat,1e-08)!=0) continue;
      if (dimtyp==1 && dequal(rpt1->lon,rpt2->lon,1e-08)!=0) continue;
      if (dimtyp==2 && dequal(rpt1->lev,rpt2->lev,1e-08)!=0) continue;
      if (dimtyp==3 && dequal(rpt1->tim,rpt2->tim,1e-08)!=0) continue;
      if (op==2) 
	rpt1->val = rpt1->val + rpt2->val;
      else if (op==0) 
	rpt1->val = rpt1->val * rpt2->val;
      else if (op==1) {
        if (swap) {
          if (dequal(rpt1->val,0.0,1e-08)==0) rpt1->umask = 0;
          else rpt1->val = rpt2->val / rpt1->val;
        } else {
          if (dequal(rpt2->val,0.0,1e-08)==0) rpt1->umask = 0;
          else rpt1->val = rpt1->val / rpt2->val;
        }
      } 
      else if (op==10) {
        if (swap) rpt1->val = pow(rpt2->val,rpt1->val);
        else rpt1->val = pow(rpt1->val,rpt2->val);
      } 
      else if (op==11)  
	rpt1->val = hypot(rpt1->val,rpt2->val);
      else if (op==12) {
        if ((dequal(rpt1->val,0.0,1e-08)==0) && (dequal(rpt2->val,0.0,1e-08)==0)) 
	  rpt1->val = 0.0;
        else rpt1->val = atan2(rpt1->val,rpt2->val);
      } 
      else if (op==13) {
        if (swap) {
          if (rpt1->val<0.0) rpt1->umask = 0;
          else rpt1->val = rpt2->val;
        } else {
          if (rpt2->val<0.0) rpt1->umask = 0;
        }
      }
      else {
        gaprnt (0,"Internal logic check 57: invalid oper value\n");
        return (NULL);
      }
      flag=1;
      break;
    }
    if (!flag) rpt1->umask = 0;
  }

  /* Release storage if requested then return */

  if (rel) {
    for (i=0; i<BLKNUM; i++) {
      if (stn2->blks[i] != NULL) gree(stn2->blks[i],"f168");
    }
    gree(stn2,"f169");
  }
  return (stn1);
}
Пример #3
0
void *Importbinary(void *argument)
{
  int streamID;
  int gridID = -1, zaxisID, zaxisIDsfc, taxisID, vlistID;
  int i;
  int nmiss = 0, n_nan;
  int ivar;
  int varID = -1, levelID, tsID;
  int gridsize;
  int  status;
  int datatype;
  dsets_t pfi;
  int vdate, vtime;
  int tcur, told,fnum;
  int tmin=0,tmax=0;
  char *ch = NULL;
  int nvars, nlevels, nrecs;
  int recID;
  int e, flag;
  size_t rc, recsize;
  int recoffset;
  char *rec = NULL;
  struct gavar *pvar;
  struct dt dtim, dtimi;
  double missval;
  double fmin, fmax;
  double *array;
  double sfclevel = 0;
  int *recVarID, *recLevelID;
  int *var_zaxisID;
  int *var_dfrm = NULL;
  char vdatestr[32], vtimestr[32];	  

  cdoInitialize(argument);

  dsets_init(&pfi);

  status = read_gradsdes(cdoStreamName(0)->args, &pfi);
  if ( cdoVerbose ) fprintf(stderr, "status %d\n", status);
  //if ( status ) cdoAbort("Open failed on %s!", pfi.name);
  if ( status ) cdoAbort("Open failed!");

  nrecs = pfi.trecs;
  nvars = pfi.vnum;
  pvar  = pfi.pvar1;

  if ( nvars == 0 ) cdoAbort("No variables found!");

  gridID = define_grid(&pfi);
  if ( cdoVerbose ) gridPrint(gridID, gridID, 1);

  zaxisID = define_level(&pfi, 0);
  if ( cdoVerbose ) zaxisPrint(zaxisID, zaxisID);

  zaxisIDsfc = zaxisCreate(ZAXIS_SURFACE, 1);
  zaxisDefLevels(zaxisIDsfc, &sfclevel);

  vlistID = vlistCreate();

  var_zaxisID = (int*) malloc(nvars*sizeof(int));
  recVarID    = (int*) malloc(nrecs*sizeof(int));
  recLevelID  = (int*) malloc(nrecs*sizeof(int));
  var_dfrm    = (int*) malloc(nrecs*sizeof(int));

  recID = 0;
  for ( ivar = 0; ivar < nvars; ++ivar )
    {
      /*
      if ( cdoVerbose )
	fprintf(stderr, "1:%s 2:%s %d %d %d %d 3:%s %d \n", 
		pvar->abbrv, pvar->longnm, pvar->offset, pvar->recoff, pvar->levels, 
		pvar->nvardims, pvar->varnm, pvar->var_t);
      */
      nlevels = pvar->levels;
      
      if ( nlevels == 0 )
	{
	  nlevels = 1;
	  varID = vlistDefVar(vlistID, gridID, zaxisIDsfc, TSTEP_INSTANT);
	}
      else
	{
	  if ( nlevels > zaxisInqSize(zaxisID) )
	    cdoAbort("Variable %s has too many number of levels!", pvar->abbrv);
	  else if ( nlevels < zaxisInqSize(zaxisID) )
	    {
	      int vid, zid = -1, nlev;
	      for ( vid = 0; vid < ivar; ++vid )
		{
		  zid = var_zaxisID[vid];
		  nlev = zaxisInqSize(zid);
		  if ( nlev == nlevels ) break;
		}

	      if ( vid == ivar ) zid = define_level(&pfi, nlevels);
	      varID = vlistDefVar(vlistID, gridID, zid, TSTEP_INSTANT);
	    }
	  else
	    varID = vlistDefVar(vlistID, gridID, zaxisID, TSTEP_INSTANT);
	}

      var_zaxisID[varID] = vlistInqVarZaxis(vlistID, varID);

      vlistDefVarName(vlistID, varID, pvar->abbrv);
      {
	size_t len = strlen(pvar->varnm);
	char *longname = pvar->varnm;
	if ( longname[0] == '\'' && longname[len-1] == '\'' )
	  {
	    longname[len-1] = 0;
	    longname++;
	  }
	vlistDefVarLongname(vlistID, varID, longname);
      }

      missval  = pfi.undef;
      datatype = DATATYPE_FLT32;

      if      ( pvar->dfrm ==  1 ) {
	datatype = DATATYPE_UINT8;
	if ( missval < 0 || missval > 255 ) missval = 255;
      }
      else if ( pvar->dfrm ==  2 )  {
	datatype = DATATYPE_UINT16;
	if ( missval < 0 || missval > 65535 ) missval = 65535;
      }
      else if ( pvar->dfrm == -2 )  {
	datatype = DATATYPE_INT16;
	if ( missval < -32768 || missval > 32767 ) missval = -32768;
      }
      else if ( pvar->dfrm ==  4 )  {
	datatype = DATATYPE_INT32;
	if ( missval < -2147483648 || missval > 2147483647 ) missval = -2147483646;
      }
      else if ( pfi.flt64 )
	datatype = DATATYPE_FLT64;
      
      vlistDefVarDatatype(vlistID, varID, datatype);
      vlistDefVarMissval(vlistID, varID, missval);

      for ( levelID = 0; levelID < nlevels; ++levelID )
	{
	  if ( recID >= nrecs ) cdoAbort("Internal problem with number of records!");
	  recVarID[recID]   = varID;
	  recLevelID[recID] = levelID;
          var_dfrm[recID]   = pvar->dfrm;
	  recID++;
	}

      pvar++;
    }

  taxisID = taxisCreate(TAXIS_RELATIVE);

  taxisDefCalendar(taxisID, CALENDAR_STANDARD);

  vlistDefTaxis(vlistID, taxisID);

  streamID = streamOpenWrite(cdoStreamName(1), cdoFiletype());

  streamDefVlist(streamID, vlistID);


  gridsize = pfi.dnum[0]*pfi.dnum[1];
  if ( pfi.flt64 )
    recoffset = pfi.xyhdr*8;
  else
    recoffset = pfi.xyhdr*4;

  if ( pfi.seqflg ) recoffset += 4;

  //recsize = pfi.gsiz*4;
  recsize = pfi.gsiz*8;
  rec = (char*) malloc(recsize);

  array = (double*) malloc(gridsize*sizeof(double));

  /*
  if (pfi.tmplat)
    for ( i = 0; i <  pfi.dnum[3]; ++i )
      printf("%d %d\n", i, pfi.fnums[i]);
  */

  pfi.infile = NULL;
  tcur = 0;
  e = 1;
  while (1)
    {    /* loop over all times for this ensemble */
      if (pfi.tmplat)
	{
	  /* make sure no file is open */
	  if (pfi.infile!=NULL) {
	    fclose(pfi.infile);
	    pfi.infile=NULL;
	  }
	  /* advance to first valid time step for this ensemble */
	  if (tcur==0) {
	    told = 0;
	    tcur = 1;
	    while (pfi.fnums[tcur-1] == -1) tcur++;  
	  }
	  else {  /* tcur!=0 */
	    told = pfi.fnums[tcur-1];
	    /* increment time step until fnums changes */
	    while (told==pfi.fnums[tcur-1] && tcur<=pfi.dnum[3]) {
	      tcur++;
	      if ( tcur > pfi.dnum[3] ) break;
	    }
	  }

	  /* make sure we haven't advanced past end of time axis */
	  if (tcur>pfi.dnum[3]) break;

	  /* check if we're past all valid time steps for this ensemble */
	  if ((told != -1) && (pfi.fnums[tcur-1] == -1)) break;

	  /* Find the range of t indexes that have the same fnums value.
	     These are the times that are contained in this particular file */
	  tmin = tcur;
	  tmax = tcur-1;
	  fnum = pfi.fnums[tcur-1];
	  if (fnum != -1) {
	    while (fnum == pfi.fnums[tmax])
	      {
		tmax++; 
		if (tmax == pfi.dnum[3]) break;
	      }
	    gr2t(pfi.grvals[3], (gadouble)tcur, &dtim); 
	    gr2t(pfi.grvals[3], (gadouble)1, &dtimi);
	    ch = gafndt(pfi.name, &dtim, &dtimi, pfi.abvals[3], pfi.pchsub1, NULL,tcur,e,&flag);
	    if (ch==NULL) cdoAbort("Couldn't determine data file name for e=%d t=%d!",e,tcur);
	  }
	}
      else { 
	/* Data set is not templated */
	ch = pfi.name;
	tmin = 1;
	tmax = pfi.dnum[3];
      }
       
      /* Open this file and position to start of first record */
      if ( cdoVerbose) cdoPrint("Opening file: %s", ch);
      pfi.infile = fopen(ch,"rb");
      if (pfi.infile==NULL) {
	if (pfi.tmplat) {
	  cdoWarning("Could not open file: %s",ch);
	  break;
	} else {
	  cdoAbort("Could not open file: %s",ch);
	}
      }
      if (pfi.tmplat) gree(ch,"312");

      /* file header */
      if (pfi.fhdr > 0) fseeko(pfi.infile, pfi.fhdr, SEEK_SET);
       
      /* Get file size */
      /*
      fseeko(pfi.infile,0L,2);
      flen = ftello(pfi.infile);

      printf("flen %d tsiz %d\n", flen, pfi.tsiz);
       
      fseeko (pfi.infile,0,0);
      */
      for ( tsID = tmin-1; tsID < tmax; ++tsID )
	{
	  gr2t(pfi.grvals[3], (gadouble)(tsID+1), &dtim); 
	  vdate = cdiEncodeDate(dtim.yr, dtim.mo, dtim.dy);
	  vtime = cdiEncodeTime(dtim.hr, dtim.mn, 0);

	  date2str(vdate, vdatestr, sizeof(vdatestr));
	  time2str(vtime, vtimestr, sizeof(vtimestr));

	  if ( cdoVerbose )
	    cdoPrint(" Reading timestep: %3d %s %s", tsID+1, vdatestr, vtimestr);

	  taxisDefVdate(taxisID, vdate);
	  taxisDefVtime(taxisID, vtime);
	  streamDefTimestep(streamID, tsID);

	  for ( recID = 0; recID < nrecs; ++recID )
	    {
	      /* record size depends on data type */
	      if (var_dfrm[recID] == 1) {
		recsize = pfi.gsiz;
	      }
	      else if ((var_dfrm[recID] == 2) || (var_dfrm[recID] == -2)) {
		recsize = pfi.gsiz*2;
	      }
	      else {
		if ( pfi.flt64 )
		  recsize = pfi.gsiz*8;
		else
		  recsize = pfi.gsiz*4;
	      }

	      rc = fread (rec, 1, recsize, pfi.infile);
	      if ( rc < recsize ) cdoAbort("I/O error reading record=%d of timestep=%d!", recID+1, tsID+1);

	      /* convert */
	      if (var_dfrm[recID] == 1) {
		unsigned char *carray = (void*)(rec + recoffset);
		for (i = 0; i < gridsize; ++i) array[i] = (double) carray[i];
	      }
	      else if (var_dfrm[recID] == 2) {
		unsigned short *sarray = (void*)(rec + recoffset);
	        if (pfi.bswap) gabswp2(sarray, gridsize);
		for (i = 0; i < gridsize; ++i) array[i] = (double) sarray[i];
	      }
	      else if (var_dfrm[recID] == -2) {
		short *sarray = (void*)(rec + recoffset);
	        if (pfi.bswap) gabswp2(sarray, gridsize);
		for (i = 0; i < gridsize; ++i) array[i] = (double) sarray[i];
	      }
	      else if (var_dfrm[recID] == 4) {
		int *iarray = (void*)(rec + recoffset);
	        if (pfi.bswap) gabswp(iarray, gridsize);
		for (i = 0; i < gridsize; ++i) array[i] = (double) iarray[i];
	      }
	      else {
		if ( pfi.flt64 )
		  {
		    double *darray = (double *) (rec + recoffset);
		    if (pfi.bswap) gabswp(darray, gridsize);
		    for ( i = 0; i < gridsize; ++i ) array[i] = darray[i];
		  }
		else
		  {
		    float *farray = (float *) (rec + recoffset);
		    if (pfi.bswap) gabswp(farray, gridsize);
		    for ( i = 0; i < gridsize; ++i ) array[i] = (double) farray[i];
		  }
	      }

	      fmin =  1.e99;
	      fmax = -1.e99;
	      nmiss = 0;
	      n_nan = 0;
	      for ( i = 0; i < gridsize; ++i )
		{
		  if ( array[i] > pfi.ulow && array[i] < pfi.uhi )
		    {
		      array[i] = pfi.undef;
		      nmiss++;
		    }
		  else if ( DBL_IS_NAN(array[i]) )
		    {
		      array[i] = pfi.undef;
		      nmiss++;
		      n_nan++;
		    }
		  else
		    {
		      if ( array[i] < fmin ) fmin = array[i];
		      if ( array[i] > fmax ) fmax = array[i];
		    }
		}
	      /*
	      if ( cdoVerbose )
		printf("%3d %4d %3d %6d %6d %12.5g %12.5g\n", tsID, recID, recoffset, nmiss, n_nan, fmin, fmax);
	      */
	      varID   = recVarID[recID];
	      levelID = recLevelID[recID];
	      streamDefRecord(streamID,  varID,  levelID);
              streamWriteRecord(streamID, array, nmiss);
 	    }
	}

      /* break out if not templating */
      if (!pfi.tmplat) break;
      
    } /* end of while (1) loop */


  processDefVarNum(vlistNvars(vlistID), streamID);

  streamClose(streamID);

  vlistDestroy(vlistID);
  gridDestroy(gridID);
  zaxisDestroy(zaxisID);
  taxisDestroy(taxisID);

  free(array);
  free(rec);

  if ( var_zaxisID ) free(var_zaxisID);
  if ( recVarID    ) free(recVarID);
  if ( recLevelID  ) free(recLevelID);
  if ( var_dfrm    ) free(var_dfrm);

  cdoFinish();

  return (0);
}