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
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()
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=[]
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)