Logo Search packages:      
Sourcecode: nco version File versions  Download package

nco_dmn_utl.c

/* $Header: /cvsroot/nco/nco/src/nco/nco_dmn_utl.c,v 1.15 2004/08/14 21:00:00 zender Exp $ */

/* Purpose: Dimension utilities */

/* Copyright (C) 1995--2004 Charlie Zender
   This software may be modified and/or re-distributed under the terms of the GNU General Public License (GPL) Version 2
   See http://www.gnu.ai.mit.edu/copyleft/gpl.html for full license text */

#include "nco_dmn_utl.h" /* Dimension utilities */

void
nco_dmn_dfn /* [fnc] Define dimensions in output file */
(const char * const fl_nm, /* I [sng] Name of output file */
 const int nc_id, /* I [id] netCDF output file ID */
 dmn_sct ** const dmn, /* I [sct] Dimension structures to define in output file */
 const int nbr_dmn) /* I [nbr] Number of dimension structures in structure list */
{
  /* Purpose: Define dimensions in output file */

  int idx;
  int rcd=NC_NOERR; /* [rcd] Return code */

  for(idx=0;idx<nbr_dmn;idx++){

    /* Has dimension already been defined? */
    rcd=nco_inq_dimid_flg(nc_id,dmn[idx]->nm,&dmn[idx]->id);

    /* If dimension has not been defined yet, define it */
    if(rcd != NC_NOERR){
      if(dmn[idx]->is_rec_dmn){
      (void)nco_def_dim(nc_id,dmn[idx]->nm,NC_UNLIMITED,&(dmn[idx]->id));
      }else{
      (void)nco_def_dim(nc_id,dmn[idx]->nm,dmn[idx]->cnt,&(dmn[idx]->id));
      } /* end else */
    }else{
      (void)fprintf(stderr,"%s: WARNING dimension \"%s\" is already defined in %s\n",prg_nm_get(),dmn[idx]->nm,fl_nm);
    } /* end if */
  } /* end loop over idx */
  
} /* end nco_dmn_dfn() */

dmn_sct * /* O [sct] Copy of input dimension structure */
nco_dmn_dpl /* [fnc] Duplicate input dimension structure */
(const dmn_sct * const dmn) /* I [sct] Dimension structure to duplicate */
{
  /* Purpose: nco_malloc() and return duplicate of input dmn_sct */
  const void *dmn_vp=dmn;

  dmn_sct *dmn_cpy;

  dmn_cpy=(dmn_sct *)nco_malloc(sizeof(dmn_sct));

  /* Shallow copy structure */
  (void)memcpy((void *)dmn_cpy,dmn_vp,sizeof(dmn_sct));

  /* fxm: Should copy name as well */

  return dmn_cpy;

} /* end nco_dmn_dpl() */

dmn_sct * /* O [sct] Output dimension structure */
nco_dmn_fll /* [fnc] Create and return completed dmn_sct */
(const int nc_id, /* I [id] netCDF input file ID */
 const int dmn_id, /* I [id] Dimension ID */
 const char * const dmn_nm) /* I [sng] Dimension name */
{
  /* Purpose: nco_malloc() and return a completed dmn_sct */

  dmn_sct *dmn;
  
  int rcd=NC_NOERR; /* [rcd] Return code */
  int rec_dmn_id;
  
  dmn=(dmn_sct *)nco_malloc(sizeof(dmn_sct));
  
  dmn->nm=(char *)strdup(dmn_nm);
  dmn->id=dmn_id;
  dmn->nc_id=nc_id;
  dmn->xrf=NULL;
  dmn->val.vp=NULL;

  dmn->is_crd_dmn=False;
  (void)nco_inq_dimlen(dmn->nc_id,dmn_id,&dmn->sz);
  
  /* Get record dimension ID */
  (void)nco_inq(dmn->nc_id,(int *)NULL,(int *)NULL,(int *)NULL,&rec_dmn_id);
  if(dmn->id == rec_dmn_id){
    dmn->is_rec_dmn=True;
  }else{
    dmn->is_rec_dmn=False;
  } /* end if */
   
  rcd=nco_inq_varid_flg(dmn->nc_id,dmn_nm,&dmn->cid);
  if(rcd == NC_NOERR){
    dmn->is_crd_dmn=True;
    /* What type is coordinate? */
    (void)nco_inq_vartype(dmn->nc_id,dmn->cid,&dmn->type);
  } /* end if */
  
  dmn->cnt=dmn->sz;
  dmn->srt=0L;
  dmn->end=dmn->sz-1L;
  dmn->srd=1L;
  
  return dmn;
} /* end nco_dmn_fll() */

void
nco_dmn_lmt_mrg /* [fnc] Merge limit structure information into dimension structures */
(dmn_sct ** const dmn, /* I [sct] Dimension structures to modify */
 const int nbr_dmn, /* I [nbr] Number of dimension structures in structure list */
 const lmt_sct * const lmt, /* I [sct] Dimension limit information */
 const int lmt_nbr) /* I [nbr] Number of dimensions with user-specified limits */
{
  /* Purpose: Merge limit structure information into dimension structures */

  int idx;
  int lmt_idx;

  for(idx=0;idx<nbr_dmn;idx++){

    /* Decide whether this dimension has any user-specified limits */
    for(lmt_idx=0;lmt_idx<lmt_nbr;lmt_idx++){
      if(lmt[lmt_idx].id == dmn[idx]->id){
      dmn[idx]->cnt=lmt[lmt_idx].cnt;
      dmn[idx]->srt=lmt[lmt_idx].srt;
      dmn[idx]->end=lmt[lmt_idx].end;
      dmn[idx]->srd=lmt[lmt_idx].srd;
      break;
      } /* end if */
    } /* end loop over lmt_idx */
  } /* end loop over dmn */
} /* end nco_dmn_lmt_mrg() */

nm_id_sct * /* O [sct] List of dimensions associated with input variable list */
nco_dmn_lst_ass_var /* [fnc] Create list of all dimensions associated with input variable list */
(const int nc_id, /* I [id] netCDF input-file ID */
 const nm_id_sct * const var, /* I [sct] Variable list */
 const int nbr_var, /* I [nbr] Number of variables in list */
 int * const nbr_dmn) /* O [nbr] Number of dimensions associated with input variable list */
{
  /* Purpose: Create list of all dimensions associated with input variable list */

  bool dmn_has_been_placed_on_list;

  char dmn_nm[NC_MAX_NAME];

  int dmn_id[NC_MAX_DIMS];
  int idx_dmn_in;
  int idx_var;
  int idx_var_dmn;
  int idx_dmn_lst;
  int nbr_dmn_in;
  int nbr_var_dmn;
  
  nm_id_sct *dmn;

  *nbr_dmn=0;

  /* Get number of dimensions */
  (void)nco_inq(nc_id,&nbr_dmn_in,(int *)NULL,(int *)NULL,(int *)NULL);

  /* Number of input dimensions is upper bound on number of output dimensions */
  dmn=(nm_id_sct *)nco_malloc(nbr_dmn_in*sizeof(nm_id_sct));
  
  /* ...For each dimension in file... */
  for(idx_dmn_in=0;idx_dmn_in<nbr_dmn_in;idx_dmn_in++){
    /* ...begin search for dimension in dimension list by... */
    dmn_has_been_placed_on_list=False;
    /* ...looking through the set of output variables... */
    for(idx_var=0;idx_var<nbr_var;idx_var++){
      /* ...and searching each dimension of each output variable... */
      (void)nco_inq_var(nc_id,var[idx_var].id,(char *)NULL,(nc_type *)NULL,&nbr_var_dmn,dmn_id,(int *)NULL);
      for(idx_var_dmn=0;idx_var_dmn<nbr_var_dmn;idx_var_dmn++){
      /* ...until output variable is found which contains input dimension... */
      if(idx_dmn_in == dmn_id[idx_var_dmn]){
        /* ...then search each member of output dimension list... */
        for(idx_dmn_lst=0;idx_dmn_lst<*nbr_dmn;idx_dmn_lst++){
          /* ...until input dimension is found... */
          if(idx_dmn_in == dmn[idx_dmn_lst].id) break; /* ...then search no further... */
        } /* end loop over idx_dmn_lst */
        /* ...and if dimension was not found on output dimension list... */
        if(idx_dmn_lst == *nbr_dmn){
          /* ...then add dimension to output dimension list... */
          (void)nco_inq_dimname(nc_id,idx_dmn_in,dmn_nm);
          dmn[*nbr_dmn].id=idx_dmn_in;
          dmn[*nbr_dmn].nm=(char *)strdup(dmn_nm);
          (*nbr_dmn)++;
        } /* end if dimension was not found in current output dimension list */
        /* ...call off the dogs for this input dimension... */
        dmn_has_been_placed_on_list=True;
      } /* end if input dimension belongs to this output variable */
      if(dmn_has_been_placed_on_list) break; /* break out of idx_var_dmn to idx_var */
      } /* end loop over idx_var_dmn */
      if(dmn_has_been_placed_on_list) break; /* break out of idx_var to idx_dmn_in */
    } /* end loop over idx_var */
  } /* end loop over idx_dmn_in */
  
  /* We now have final list of dimensions to extract. Phew. */
  
  /* Free unused space in output dimension list */
  /* valgrind fxm: 20040814 valgrind reports: Are obsolete names free()'d before realloc()?
     ==31046== 112 bytes in 1 blocks are definitely lost in loss record 2 of 6
     ==31046==    at 0x1B9079FF: realloc (vg_replace_malloc.c:197)
     ==31046==    by 0x8056084: nco_realloc (nco_mmr.c:235)
     ==31046==    by 0x8051490: nco_dmn_lst_ass_var (nco_dmn_utl.c:203)
     ==31046==    by 0x804A057: main (ncpdq.c:327) */
  dmn=(nm_id_sct *)nco_realloc((void *)dmn,*nbr_dmn*sizeof(nm_id_sct));
  
  return dmn;
} /* end nco_dmn_lst_ass_var() */

nm_id_sct * /* O [sct] Dimension list */
nco_dmn_lst_mk /* [fnc] Attach dimension IDs to dimension list */
(const int nc_id, /* I [id] netCDF file ID */
 CST_X_PTR_CST_PTR_CST_Y(char,dmn_lst_in), /* I [sng] User-specified list of dimension names */
 const int nbr_dmn) /* I [nbr] Total number of dimensions in list */
{
  /* Purpose: Create list of dimension name-id structures from list of dimension name strings */
  int idx;

  nm_id_sct *dmn_lst;
  
  dmn_lst=(nm_id_sct *)nco_malloc(nbr_dmn*sizeof(nm_id_sct));
  for(idx=0;idx<nbr_dmn;idx++){
    /* See if requested dimension is in input file */
    dmn_lst[idx].nm=(char *)strdup(dmn_lst_in[idx]);
    (void)nco_inq_dimid(nc_id,dmn_lst[idx].nm,&dmn_lst[idx].id);
  } /* end loop over idx */
  
  return dmn_lst;
} /* end nco_dmn_lst_mk() */

void
nco_dmn_xrf  /* [fnc] Crossreference xrf elements of dimension structures */
(dmn_sct * const dmn_1, /* I/O [sct] Dimension structure */
 dmn_sct * const dmn_2) /* I/O [sct] Dimension structure */
{
  /* Purpose: Make xrf elements of dimension structures point to eachother */
  dmn_1->xrf=dmn_2;
  dmn_2->xrf=dmn_1;
} /* end nco_dmn_xrf() */


Generated by  Doxygen 1.6.0   Back to index