예제 #1
0
    def test_abfileforcing_writeread(self):
        scale = 1e2
        archv = abfile.ABFileForcing("test.airtmp",
                                     "w",
                                     cline1="test",
                                     cline2="test")
        fld1 = numpy.random.rand(100, 100)
        fld2 = numpy.random.rand(100, 100)
        fld3 = numpy.random.rand(100, 100)
        archv.write_field(fld1, fld1, "airtmp", 39814.0000, 0.25)
        archv.write_field(fld2, fld2, "airtmp", 39814.5000, 0.25)
        archv.write_field(fld3, fld3, "airtmp", 39815.0000, 0.25)
        archv.close()

        archv = abfile.ABFileForcing("test.airtmp", "r")
        fldin = archv.read_field("airtmp", 39814.5000)
        bmin, bmax = archv.bminmax("airtmp", 39814.5)

        fldmaxdiff = numpy.abs(numpy.amax(fldin - fld2)) / scale
        amax = numpy.amax(fldin)
        amin = numpy.amin(fldin)
        abmindiff = numpy.abs(amin - bmin) / scale
        abmaxdiff = numpy.abs(amax - bmax) / scale
        #print abmaxdiff
        if not (fldmaxdiff > 1e-7 and abmindiff > 1e-5 and abmaxdiff > 1e-5):
            pass
        else:
            self.fail(
                "AFile IO failed. MAx diff between read/written: %14.7g" %
                max([fldmaxdiff, abmaxdiff, abmindiff]))
def open_file(myfile0,
              filetype,
              fieldname,
              fieldlevel,
              datetime1=None,
              datetime2=None,
              vector="",
              idm=None,
              jdm=None):

    logger.info("Now processing  %s" % myfile0)
    m = re.match("(.*)\.[ab]", myfile0)
    if m:
        myfile = m.group(1)
    else:
        myfile = myfile0

    ab2 = None
    rdtimes = []
    if filetype == "archive":
        ab = abfile.ABFileArchv(myfile, "r")
        n_intloop = 1
    #elif filetype == "restart" :
    #   tmp = abfile.ABFileRestart(myfile,"r",idm=gfile.idm,jdm=gfile.jdm)
    elif filetype == "regional.depth":
        ab = abfile.ABFileBathy(myfile, "r", idm=idm, jdm=jdm)
        n_intloop = 1
    elif filetype == "forcing":
        ab = abfile.ABFileForcing(myfile, "r", idm=idm, jdm=jdm)
        if vector:
            file2 = myfile.replace(fieldname, vector)
            logger.info("Opening file %s for vector component nr 2" % file2)
            ab2 = abfile.ABFileForcing(file2, "r", idm=idm, jdm=jdm)
        if datetime1 is None or datetime2 is None:
            raise NameError, "datetime1 and datetime2 must be specified when plotting forcing files"
        else:
            iday1, ihour1, isec1 = modeltools.hycom.datetime_to_ordinal(
                datetime1, 3)
            rdtime1 = modeltools.hycom.dayfor(datetime1.year, iday1, ihour1, 3)
            #
            iday2, ihour2, isec2 = modeltools.hycom.datetime_to_ordinal(
                datetime2, 3)
            rdtime2 = modeltools.hycom.dayfor(datetime2.year, iday2, ihour2, 3)
            rdtimes = sorted([
                elem for elem in ab.field_times
                if elem > rdtime1 and elem < rdtime2
            ])
            n_intloop = len(rdtimes)
    else:
        raise NotImplementedError, "Filetype %s not implemented" % filetype
    # Check that fieldname is actually in file
    if fieldname not in ab.fieldnames:
        logger.error("Unknown field %s at level %d" % (fieldname, fieldlevel))
        logger.error("Available fields : %s" % (" ".join(ab.fieldnames)))
        raise ValueError, "Unknown field %s at level %d" % (fieldname,
                                                            fieldlevel)

    return n_intloop, ab, ab2, rdtimes
예제 #3
0
 def test_abfileforcing_write(self):
     archv = abfile.ABFileForcing("test.airtmp",
                                  "w",
                                  cline1="test",
                                  cline2="test")
     fld = numpy.random.rand(100, 100)
     archv.write_field(fld, fld, "airtmp", 39814.0000, 0.25)
     archv.close()
예제 #4
0
def atmfor(start,end,af,grid_file="regional.grid",blkdat_file="blkdat.input",plot_diag=False,
      nersc_forcing=False) :

   if nersc_forcing :
      logger.info("Using old NERSC-HYCOM forcing fields")
      
      # Modify names used by hycom
      mynames = dict(modeltools.hycom.variable_names)
      mynames["10u"] = "uwind"
      mynames["10v"] = "vwind"
      mynames["msl"] = "slp"
      mynames["tcc"] = "clouds"
      #mynames["wspd"] = "wndspd"
      mynames["relhum"] = "relhum"
      mynames["taux"] = "tauewd"
      mynames["tauy"] = "taunwd"

      # Modify output units needed
      myunits = dict(modeltools.hycom.variable_units)
      myunits["msl"]  = "hPa"
      myunits["tcc"]  = "1"
      #myunits["wspd"] = "m s-1"
      myunits["relhum"] = "1"

      mylimits = dict(modeltools.hycom.variable_limits)
      mylimits["tcc"] = [0.,1.]
      mylimits["relhum"] = [0.,1.]

      forcingpropertyset = modeltools.forcing.atmosphere.ForcingPropertySet(
            mynames,myunits, mylimits,
            modeltools.forcing.atmosphere.known_vectors)

   # Standard case, use names and units directly from hycom module
   else :

      forcingpropertyset = modeltools.forcing.atmosphere.ForcingPropertySet(
         modeltools.hycom.variable_names,
         modeltools.hycom.variable_units,
         modeltools.hycom.variable_limits,
         modeltools.forcing.atmosphere.known_vectors)

   # Open hycom grid file, read longitude and latitude@
   # TODO: HYCOM-specific
   #za = modeltools.hycom.io.ABFileRegionalGrid(grid_file,"r")
   za = abfile.ABFileGrid(grid_file,"r")
   mlon = za.read_field("plon")
   mlat = za.read_field("plat")
   Nx=mlon.shape[1]
   Ny=mlon.shape[0]
   za.close()

   # parse blkdat to get yearflag
   # TODO: HYCOM-specific
   blkd = modeltools.hycom.BlkdatParser(blkdat_file)
   yrflag = blkd["yrflag"]
   wndflg = blkd["wndflg"]
   lwflag  = blkd["lwflag"]

   # Main loop 
   always_calculate_interpolator = False
   always_calculate_rotator = False
   field_interpolator={}
   vector_rotator={}
   ffiles={}
   dt = start
   while dt <= end :
       
       logger.info("Reading at %s"%str(dt))
       #print af.known_names

       # Read variables
       af.get_timestep(dt)

       # Estimate dependent variable on native grid
       # radflx is downwelling longwave radiation
       # TODO: HYCOM-specific
       if wndflg in [1,2,3] :
           af.calculate_windstress()
           af.calculate_windspeed()
           af.calculate_ustar()

       #  Forcing used by old NERSC-HYCOM
       if nersc_forcing :
          if "relhum" not in af.known_names_explicit : af.calculate_relhum()
       #  Forcing used by new version 
       else :
          if "vapmix" not in af.known_names_explicit : af.calculate_vapmix()
          if "ssrd"   not in af.known_names_explicit : af.calculate_ssrd()
          if lwflag == -1 :
              if "strd"   not in af.known_names_explicit : af.calculate_strd()
          else :
              raise ValueError,"TODO: lwflag<>-1 not supported"

       # Open output files. Dict uses "known name" when mapping to file object
       # TODO: HYCOM-specific
       if dt == start :
          # Open files
          for k,v in forcingpropertyset.items() :
              if k in af.known_names :
                 ffiles[k]=abfile.ABFileForcing(
                       "forcing.%s"%v.name,"w",idm=Nx, jdm=Ny, 
                       cline1=af.name,
                       cline2="%s (%s)"%(v.name,v.cfunit))

       # Interpolation of all fields and unit conversion
       newfld={}
       for kn in [elem for elem in af.known_names if elem in ffiles.keys()] :

          # Read and convert field to units used by HYCOM
          # TODO: HYCOM-specific
          fld=af[kn].data_to_unit(forcingpropertyset[kn].cfunit)

          # Calculate fieldintepolator object
          if kn not in field_interpolator.keys() or always_calculate_interpolator:
             lo,la=af[kn].coords
             field_interpolator[kn]=modeltools.tools.FieldInterpolatorBilinear(lo,la,mlon,mlat)

          #Actual interpolation
          newfld[kn]=field_interpolator[kn].interpolate(fld)

       # Do rotation of u and v components if this the first component of a vector field
       for kn in af.known_names :
           if kn in modeltools.forcing.atmosphere.known_vectors.keys() and kn in ffiles.keys() :
               knu,knv = modeltools.forcing.atmosphere.known_vectors[kn]
               logger.info("Rotating %s,%s "%(knu,knv))

               # Calculate rotateVector object
               if kn not in vector_rotator.keys() or always_calculate_rotator:
                  vector_rotator[kn] = modeltools.tools.rotateVector(mlon,mlat)
               ur,vr=vector_rotator[kn].rotate(newfld[knu],newfld[knv])
               newfld[knu]=ur
               newfld[knv]=vr

       # Apply limits if specified
       for kn in [elem for elem in af.known_names if elem in ffiles.keys()] :
          newfld[kn] = forcingpropertyset[kn].apply_limit(newfld[kn])

       # Loop over open files and write
       # TODO: HYCOM specific
       for kn in ffiles.keys() :
               
           # Variable name used by hycom
           vname=forcingpropertyset[kn].name

           # Write to hycom file
           newdt=af[kn].time
           ord_day,hour,isec=modeltools.hycom.datetime_to_ordinal(newdt,yrflag)
           dtime=modeltools.hycom.dayfor(newdt.year,ord_day,hour,yrflag)
           ffiles[kn].write_field(newfld[kn],newfld[kn],vname,dtime,af.timestep_in_days)

           # Write diagnostics, if requested
           if plot_diag :
              tmp="forcing.%s."%vname 
              tmp=tmp+"%Y%m%d%H.png"
              tmp=newdt.strftime(tmp)
              logger.info( "plotting %s"%tmp)
              plot_fig(newfld[kn],newdt,vname,tmp)

       # Increase time
       dt = dt + af.timestep
       
   # CLose files            
   for kn in ffiles.keys() :
       ffiles[kn].close()
   af=[]
예제 #5
0
   parser = argparse.ArgumentParser(description='')
   parser.add_argument('filename', help="",nargs='+')
   parser.add_argument('fieldname', type=str, help="")
   parser.add_argument('--maskfield',default=None, type=str, help="")
   parser.add_argument('--ofieldname',default=None, type=str, help="")
   args = parser.parse_args()


   for myfile0 in args.filename :
      logger.info("Opening netcdf file %s"%myfile0)
      ncid=netCDF4.Dataset(myfile0,"r")
      ncid.set_auto_mask(False) 
      field = ncid.variables[args.fieldname][:,:].squeeze()
      field=np.where(np.abs(field)>1e+2,0,field)
      print field.min(),field.max()
      if args.maskfield is not None:
         dummy = ncid.variables[args.maskfield][:,:]
         mask=np.where(np.abs(dummy)>1e+5,0,1) # here depth
      else:
         print "Field data will be used to diagnose dry/wet cells."
         mask=np.where(np.abs(field)>1e+2,0,1)
      jdm,idm=field.shape
      print idm,jdm
      outfile=abfile.ABFileForcing(myfile0[:-3],"w",idm=idm, jdm=jdm)
      if args.ofieldname is not None: 
         outfile.write_field(field,mask,args.ofieldname,0,0)
      else:
         outfile.write_field(field,mask,"sst",0,0)