示例#1
0
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 = abf.ABFileArchv(myfile, "r")
        n_intloop = 1

    elif filetype == "regional.depth":
        ab = abf.ABFileBathy(myfile, "r", idm=idm, jdm=jdm)
        n_intloop = 1
    elif filetype == "forcing":
        ab = abf.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 = abf.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 main(filemesh,grid2dfiles,first_j=0,mean_file=False,iexpt=10,iversn=22,yrflag=3,makegrid=None,bio_path=None) :

   if mean_file :
      fnametemplate="archm.%Y_%j_%H"
   else :
      fnametemplate="archv.%Y_%j_%H"
   itest=1
   jtest=200
   gdept,gdepw,e3t_ps,e3w_ps,mbathy,hdepw,depth,plon,plat=read_mesh(filemesh)
   if makegrid is not None: 
      logger.info("Making NEMO grid & bathy [ab] files ...")
      make_grid(filemesh)
   mbathy = mbathy -1                       # python indexing starts from 0
   nlev   = gdept.size

   mbathy_u,e3u_ps,depthu=depth_u_points(depth,mbathy,gdepw)
   mbathy_v,e3v_ps,depthv=depth_v_points(depth,mbathy,gdepw)
   #
   mbathy_u=sliced(u_to_hycom_u(mbathy_u))
   e3u_ps  =sliced(u_to_hycom_u(e3u_ps  ))
   depthu  =sliced(u_to_hycom_u(depthu  ))
   #
   mbathy_v=sliced(v_to_hycom_v(mbathy_v))
   e3v_ps  =sliced(v_to_hycom_v(e3v_ps  ))
   depthv  =sliced(v_to_hycom_v(depthv  ))

   dt = gdepw[1:] - gdepw[:-1]

   # Loop over input files. All must be in same directory
   for file2d in grid2dfiles : 

      # See if actually a grid2D file
      dirname=os.path.dirname(file2d)
      m=re.match("(.*_)(grid2D)(_.*\.nc)",os.path.basename(file2d))
      if not m :
         msg="File %s is not a grid2D file, aborting"%file2d
         logger.error(msg)  
         raise ValueError(msg)

      # Construct remaining files
      filet  =os.path.join(dirname,m.group(1) + "gridT" + m.group(3))
      files  =os.path.join(dirname,m.group(1) + "gridS" + m.group(3))
      fileu  =os.path.join(dirname,m.group(1) + "gridU" + m.group(3))
      filev  =os.path.join(dirname,m.group(1) + "gridV" + m.group(3))
      filew  =os.path.join(dirname,m.group(1) + "gridW" + m.group(3))
      fileice=os.path.join(dirname,m.group(1) + "icemod" + m.group(3))
      logger.info("grid2D file: %s"%file2d)

      # P-points
      logger.info("gridS  file: %s"%files)
      logger.info("gridT  file: %s"%filet)
      ncids=netCDF4.Dataset(files,"r")
      ncidt=netCDF4.Dataset(filet,"r")

      # time from gridT file. 
      time = ncidt.variables["time_counter"][0]
      tunit = ncidt.variables["time_counter"].units
      tmp=cfunits.Units(tunit)
      refy, refm, refd=(1958,1,1)
      tmp2=cfunits.Units("hours since %d-%d-%d 00:00:00"%(refy,refm,refd))            # Units from CF convention
      tmp3=cfunits.Units.conform(time,tmp,tmp2)                                       # Transform to new new unit 
      tmp3=int(numpy.round(tmp3))
      mydt = datetime.datetime(refy,refm,refd,0,0,0) + datetime.timedelta(hours=tmp3) # Then calculate dt. Phew!
      if bio_path:
         jdm,idm=numpy.shape(plon)
         points = numpy.transpose(((plat.flatten(),plon.flatten())))
         delta = mydt.strftime( '%Y-%m-%d')
         # filename format MERCATOR-BIO-14-2013-01-05-00
         idx,biofname=search_biofile(bio_path,delta)
         if idx >7: 
            msg="No available BIO file within a week difference with PHY"
            logger.error(msg)
            raise ValueError(msg)
         logger.info("BIO file %s reading & interpolating to 1/12 deg grid cells ..."%biofname)
         ncidb=netCDF4.Dataset(biofname,"r")
         blon=ncidb.variables["longitude"][:];
         blat=ncidb.variables["latitude"][:]
         minblat=blat.min()
         no3=ncidb.variables["NO3"][0,:,:,:];
         no3[numpy.abs(no3)>1e+5]=numpy.nan
         po4=ncidb.variables["PO4"][0,:,:,:]
         si=ncidb.variables["Si"][0,:,:,:]
         po4[numpy.abs(po4)>1e+5]=numpy.nan
         si[numpy.abs(si)>1e+5]=numpy.nan
         # TODO: The following piece will be optimised and replaced soon. 
         nz,ny,nx=no3.shape
         dummy=numpy.zeros((nz,ny,nx+1))
         dummy[:,:,:nx]=no3;dummy[:,:,-1]=no3[:,:,-1]
         no3=dummy
         dummy=numpy.zeros((nz,ny,nx+1))
         dummy[:,:,:nx]=po4;dummy[:,:,-1]=po4[:,:,-1]
         po4=dummy
         dummy=numpy.zeros((nz,ny,nx+1))
         dummy[:,:,:nx]=si;dummy[:,:,-1]=si[:,:,-1]
         si=dummy
         dummy=numpy.zeros((nx+1))
         dummy[:nx]=blon
         blon=dummy
         blon[-1]=-blon[0]
# TODO:  Note that the coordinate files are for global configuration while
#        the data file saved for latitude larger than 30. In the case you change your data file coordinate
#        configuration you need to modify the following lines
         bio_coordfile=bio_path[:-4]+"/GLOBAL_ANALYSIS_FORECAST_BIO_001_014_COORD/GLO-MFC_001_014_mask.nc"
         biocrd=netCDF4.Dataset(bio_coordfile,"r")
         blat2 = biocrd.variables['latitude'][:]
         index=numpy.where(blat2>=minblat)[0]
         depth_lev = biocrd.variables['deptho_lev'][index[0]:,:]
#
#
#
         dummy=numpy.zeros((ny,nx+1))
         dummy[:,:nx]=depth_lev;dummy[:,-1]=depth_lev[:,-1]
         depth_lev=dummy
         depth_lev[depth_lev>50]=0
         depth_lev=depth_lev.astype('i')
         dummy_no3=no3
         dummy_po4=po4
         dummy_si=si

         for j in range(ny):
            for i in range(nx):
               dummy_no3[depth_lev[j,i]:nz-2,j,i]=no3[depth_lev[j,i]-1,j,i]
               dummy_po4[depth_lev[j,i]:nz-2,j,i]=po4[depth_lev[j,i]-1,j,i]
               dummy_si[depth_lev[j,i]:nz-2,j,i]=si[depth_lev[j,i]-1,j,i]
         no3=dummy_no3
         po4=dummy_po4
         si=dummy_si
         po4 = po4 * 106.0 * 12.01
         si = si   * 6.625 * 12.01
         no3 = no3 * 6.625 * 12.01
      #   field_interpolator=FieldInterpolatorBilinear(blon,blat,plon.flatten(),plat.flatten())
      # Read and calculculate U in hycom U-points. 
      logger.info("gridU, gridV, gridT & gridS  file")
      ncidu=netCDF4.Dataset(fileu,"r")
      u=numpy.zeros((nlev,mbathy.shape[0],mbathy.shape[1]))
      ncidv=netCDF4.Dataset(filev,"r")
      v=numpy.zeros((nlev,mbathy.shape[0],mbathy.shape[1]))
      udummy=ncidu.variables["vozocrtx"][:,:,:,:] 
      vdummy=ncidv.variables["vomecrty"][:,:,:,:]
      tdummy=ncidt.variables["votemper"][:,:,:,:]
      tdummy_fill=ncidt.variables["votemper"]._FillValue
      sdummy=ncids.variables["vosaline"][:,:,:,:]
      sdummy_fill=ncids.variables["vosaline"]._FillValue

      for k in range(nlev) : 
         u[k,:,:] = sliced(u_to_hycom_u(udummy[0,k,:,:] ))   # Costly, make more efficient if needed
         v[k,:,:] = sliced(v_to_hycom_v(vdummy[0,k,:,:] ))   # Costly, make more efficient if needed

      u = numpy.where(numpy.abs(u)<1e10,u,0.)
      v = numpy.where(numpy.abs(v)<1e10,v,0.)
      logger.info("Calculate barotropic velocities ...")

      #Calculate barotropic and baroclinic u
      usum=numpy.zeros(u.shape[-2:])
      dsumu=numpy.zeros(u.shape[-2:])
      vsum=numpy.zeros(v.shape[-2:])
      dsumv=numpy.zeros(v.shape[-2:])

      for k in range(u.shape[0]-1) : # Dont include lowest layer
         J,I = numpy.where(mbathy_u>k) 
         usum[J,I] = usum[J,I] + u[k,J,I]*dt[k]
         dsumu[J,I] = dsumu[J,I] + dt[k]
         J,I = numpy.where(mbathy_v>k)
         vsum[J,I] = vsum[J,I] + v[k,J,I]*dt[k]
         dsumv[J,I] = dsumv[J,I] + dt[k]
      J,I = numpy.where(mbathy>=0)
      usum[J,I] = usum[J,I] + u[mbathy_u[J,I],J,I]*e3u_ps[J,I]
      dsumu[J,I] = dsumu[J,I] + e3u_ps[J,I]
      dsumu=numpy.where(abs(dsumu)<1e-2,0.05,dsumu)
      ubaro=numpy.where(dsumu>0.1,usum/dsumu,0.)
      J,I = numpy.where(mbathy_v>=0)
      vsum[J,I] = vsum[J,I] + v[mbathy_v[J,I],J,I]*e3v_ps[J,I]
      dsumv[J,I] = dsumv[J,I] + e3v_ps[J,I]
      dsumv=numpy.where(abs(dsumv)<1e-2,0.05,dsumv)
      vbaro=numpy.where(dsumv>.1,vsum/dsumv,0.)
      fnametemplate="archv.%Y_%j"
      deltat=datetime.datetime(refy,refm,refd,0,0,0)+datetime.timedelta(hours=tmp3)
      oname=deltat.strftime(fnametemplate)+"_00"

      # model day
      refy, refm, refd=(1900,12,31)
      model_day= deltat-datetime.datetime(refy,refm,refd,0,0,0)
      model_day=model_day.days
      logger.info("Model day in HYCOM is %s"%str(model_day))

      # Masks (land:True)
      if mask_method == 1 :
         ip = mbathy   == -1
         iu = mbathy_u == -1
         iv = mbathy_v == -1
      else :
         ip = depth   == 0
         iu = depthu  == 0
         iv = depthv  == 0

      # 2D data
      ncid2d=netCDF4.Dataset(file2d,"r")
      ssh          = sliced(ncid2d.variables["sossheig"][0,:,:])
      ssh = numpy.where(ssh==ncid2d.variables["sossheig"]._FillValue,0.,ssh)
      ssh = numpy.where(ssh>1e10,0.,ssh*9.81) # NB: HYCOM srfhgt is in geopotential ...
      montg1=numpy.zeros(ssh.shape)

      # Write to abfile
      outfile = abf.ABFileArchv("./data/"+oname,"w",iexpt=iexpt,iversn=iversn,yrflag=yrflag,)

      logger.info("Writing 2D variables")
      outfile.write_field(montg1,                ip,"montg1"  ,0,model_day,1,0)
      outfile.write_field(ssh,                   ip,"srfhgt"  ,0,model_day,0,0)
      outfile.write_field(numpy.zeros(ssh.shape),ip,"surflx"  ,0,model_day,0,0) # Not used
      outfile.write_field(numpy.zeros(ssh.shape),ip,"salflx"  ,0,model_day,0,0) # Not used
      outfile.write_field(numpy.zeros(ssh.shape),ip,"bl_dpth" ,0,model_day,0,0) # Not used
      outfile.write_field(numpy.zeros(ssh.shape),ip,"mix_dpth",0,model_day,0,0) # Not used
      outfile.write_field(ubaro                 ,iu,"u_btrop" ,0,model_day,0,0) # u: nemo in cell i is hycom in cell i+1
      outfile.write_field(vbaro                 ,iv,"v_btrop" ,0,model_day,0,0) # v: nemo in cell j is hycom in cell j+1
      ny=mbathy.shape[0];nx=mbathy.shape[1]
      error=numpy.zeros((ny,nx))
      for k in numpy.arange(u.shape[0]) :
         if bio_path:
            no3k=interpolate2d(blat, blon, no3[k,:,:], points).reshape((jdm,idm))
            no3k = maplev(no3k)
            po4k=interpolate2d(blat, blon, po4[k,:,:], points).reshape((jdm,idm))
            po4k = maplev(po4k)
            si_k=interpolate2d(blat, blon, si[k,:,:], points).reshape((jdm,idm))
            si_k = maplev(si_k)
            if k%10==0 : logger.info("Writing 3D variables including BIO, level %d of %d"%(k+1,u.shape[0]))
         else:
            if k%10==0 : logger.info("Writing 3D variables, level %d of %d"%(k+1,u.shape[0]))
         #
         ul = numpy.squeeze(u[k,:,:]) - ubaro # Baroclinic velocity
         vl = numpy.squeeze(v[k,:,:]) - vbaro # Baroclinic velocity

         # Layer thickness
         dtl=numpy.zeros(ul.shape)
         if k < u.shape[0]-1 :
            J,I = numpy.where(mbathy>k)
            dtl[J,I] = dt[k]
            J,I = numpy.where(mbathy==k)
            dtl[J,I] = e3t_ps[J,I]
         else:
            J,I = numpy.where(mbathy==k)
            dtl[J,I] = e3t_ps[J,I]

         tmpfill=sdummy_fill#ncids.variables["vosaline"]._FillValue
         sl = sliced(sdummy[0,k,:,:])
         tmpfill=tdummy_fill#ncidt.variables["votemper"]._FillValue
         tl = sliced(tdummy[0,k,:,:])
         sl = numpy.where(numpy.abs(sl)<1e2,sl,numpy.nan)
         sl = numpy.minimum(numpy.maximum(maplev(sl),25),80.)
         tl = numpy.where(numpy.abs(tl)<=5e2,tl,numpy.nan)
         tl = numpy.minimum(numpy.maximum(maplev(tl),-5.),50.)

         # Fill empty layers with values from above
         if k > 0 :
            K= numpy.where(dtl < 1e-4)

            tl[K] = tl_above[K]


         onem=9806.
         outfile.write_field(ul      ,iu,"u-vel.",0,model_day,k+1,0) # u: nemo in cell i is hycom in cell i+1
         outfile.write_field(vl      ,iv,"v-vel.",0,model_day,k+1,0) # v: nemo in cell j is hycom in cell j+1
         outfile.write_field(dtl*onem,ip,"thknss",0,model_day,k+1,0)
         outfile.write_field(tl      ,ip,"temp"  ,0,model_day,k+1,0)
         outfile.write_field(sl      ,ip,"salin" ,0,model_day,k+1,0)
         if bio_path :
            outfile.write_field(no3k      ,ip,"ECO_no3"  ,0,model_day,k+1,0)
            outfile.write_field(po4k      ,ip,"ECO_pho" ,0,model_day,k+1,0)
            outfile.write_field(si_k      ,ip,"ECO_sil" ,0,model_day,k+1,0)

         tl_above=numpy.copy(tl)
         sl_above=numpy.copy(sl)
         

      # TODO: Process ice data
      ncid2d.close()
      outfile.close()
      ncidt.close()
      ncids.close()
      ncidu.close()
      ncidv.close()
      if bio_path:ncidb.close()
   nemo_mesh = []
def main(lon1,
         lat1,
         lon2,
         lat2,
         variable,
         files,
         filetype="archive",
         clim=None,
         sectionid="",
         ijspace=False,
         xaxis="distance",
         section_map=False,
         dens=False,
         dpi=180):

    logger.info("Filetype is %s" % filetype)
    gfile = abf.ABFileGrid("regional.grid", "r")
    plon = gfile.read_field("plon")
    plat = gfile.read_field("plat")

    # Set up section info
    if ijspace:
        sec = gridxsec.SectionIJSpace([lon1, lon2], [lat1, lat2], plon, plat)
    else:
        sec = gridxsec.Section([lon1, lon2], [lat1, lat2], plon, plat)
    I, J = sec.grid_indexes
    dist = sec.distance
    print('dit.shae=', dist.shape)
    slon = sec.longitude
    slat = sec.latitude

    logger.info("Min max I-index (starts from 0):%d %d" % (I.min(), I.max()))
    logger.info("Min max J-index (starts from 0):%d %d" % (J.min(), J.max()))
    #
    #
    if section_map:
        ll_lon = slon.min() - 10.
        ur_lon = slon.max() + 10.
        ll_lat = np.maximum(-90., slat.min() - 10.)
        ur_lat = np.minimum(90., slat.max() + 10.)

        proj = ccrs.Stereographic(central_latitude=90.0,
                                  central_longitude=-40.0)
        pxy = proj.transform_points(ccrs.PlateCarree(), plon, plat)
        px = pxy[:, :, 0]
        py = pxy[:, :, 1]
        x, y = np.meshgrid(np.arange(slon.shape[0]), np.arange(slat.shape[0]))

        figure = plt.figure(figsize=(10, 8))
        ax = figure.add_subplot(111)

        ax = plt.axes(projection=ccrs.PlateCarree())
        ax.set_extent([-179, 179, 53, 85], ccrs.PlateCarree())
        ax.add_feature(cfeature.GSHHSFeature('auto', edgecolor='grey'))
        ax.add_feature(cfeature.GSHHSFeature('auto', facecolor='grey'))
        ax.gridlines()
        ax.plot(slon, slat, "r-", lw=1)

        pos = ax.get_position()
        asp = pos.height / pos.width
        w = figure.get_figwidth()
        h = asp * w
        figure.set_figheight(h)
        if sectionid:
            figure.canvas.print_figure("map_%s.png" % sectionid, dpi=dpi)
        else:
            figure.canvas.print_figure("map.png", dpi=dpi)

    # Get layer thickness variable used in hycom
    dpname = modeltools.hycom.layer_thickness_variable[filetype]
    logger.info("Filetype %s: layer thickness variable is %s" %
                (filetype, dpname))

    if xaxis == "distance":
        x = dist / 1000.
        xlab = "Distance along section[km]"
    elif xaxis == "i":
        x = I
        xlab = "i-index"
    elif xaxis == "j":
        x = J
        xlab = "j-index"
    elif xaxis == "lon":
        x = slon
        xlab = "longitude"
    elif xaxis == "lat":
        x = slat
        xlab = "latitude"
    else:
        logger.warning("xaxis must be i,j,lo,lat or distance")
        x = dist / 1000.
        xlab = "Distance along section[km]"

    # Loop over archive files
    figure = plt.figure()
    ax = figure.add_subplot(111)
    pos = ax.get_position()
    for fcnt, myfile0 in enumerate(files):

        # Remove [ab] ending if present
        m = re.match("(.*)\.[ab]", myfile0)
        if m:
            myfile = m.group(1)
        else:
            myfile = myfile0

        # Add more filetypes if needed. By def we assume archive
        if filetype == "archive":
            i_abfile = abf.ABFileArchv(myfile, "r")
        elif filetype == "restart":
            i_abfile = abf.ABFileRestart(myfile,
                                         "r",
                                         idm=gfile.idm,
                                         jdm=gfile.jdm)
        else:
            raise NotImplementedError("Filetype %s not implemented" % filetype)

        # kdm assumed to be max level in ab file
        kdm = max(i_abfile.fieldlevels)

        # Set up interface and daat arrays
        xx = np.zeros((kdm + 1, I.size))
        intfsec = np.zeros((kdm + 1, I.size))
        datasec = np.zeros((kdm + 1, I.size))
        if dens:
            datasec_sal = np.zeros((kdm + 1, I.size))
            sigma_sec = np.zeros((kdm + 1, I.size))

        # Loop over layers in file.
        logger.info("File %s" % (myfile))
        for k in range(kdm):
            logger.debug("File %s, layer %03d/%03d" % (myfile, k, kdm))

            # Get 2D fields
            dp2d = i_abfile.read_field(dpname, k + 1)
            data2d = i_abfile.read_field(variable, k + 1)
            dp2d = np.ma.filled(dp2d, 0.) / modeltools.hycom.onem
            data2d = np.ma.filled(data2d, 1e30)

            # Place data into section arrays
            intfsec[k + 1, :] = intfsec[k, :] + dp2d[J, I]
            if k == 0: datasec[k, :] = data2d[J, I]
            datasec[k + 1, :] = data2d[J, I]

            if dens:
                data2d_sal = i_abfile.read_field('salin', k + 1)
                data2d_sal = np.ma.filled(data2d_sal, 1e30)
                datasec_sal[k + 1, :] = data2d_sal[J, I]

        i_maxd = np.argmax(np.abs(intfsec[kdm, :]))
        for k in range(kdm + 1):
            xx[k, :] = x[:]

        datasec = np.ma.masked_where(datasec > 0.5 * 1e30, datasec)
        print("datasec min, max=", datasec.min(), datasec.max())
        if dens:
            datasec_sal = np.ma.masked_where(datasec_sal > 0.5 * 1e30,
                                             datasec_sal)
            print("datasec_sal min, max=", datasec_sal.min(),
                  datasec_sal.max())
            sigma_sec = mod_hyc2plot.sig(datasec, datasec_sal)
            sigma_sec = np.ma.masked_where(sigma_sec < 0.0, sigma_sec)
            datasec = sigma_sec
        # Set up section plot
        datasec = np.ma.masked_where(datasec > 0.5 * 1e30, datasec)
        print("min, max=", datasec.min(), datasec.max())
        if clim is None:
            clim = [datasec.min(), datasec.max()]
            #clim=[0.0,13]
        print("clim=", clim[0], clim[1])
        if clim is not None:
            lvls = MaxNLocator(nbins=70).tick_values(clim[0], clim[1])
        mf = 'sawtooth_fc100.txt'
        LinDic = mod_hyc2plot.cmap_dict(mf)
        my_cmap = matplotlib.colors.LinearSegmentedColormap(
            'my_colormap', LinDic)
        cmap = my_cmap
        norm = BoundaryNorm(lvls, ncolors=cmap.N, clip=True)
        P = ax.contourf(xx, -intfsec, datasec, cmap=cmap, levels=lvls)

        # Plot layer interfaces
        for k in range(1, kdm + 1):
            if k % 100 == 0:
                PL = ax.plot(x, -intfsec[k, :], "-", color="k")
                textx = x[i_maxd]
                texty = -0.5 * (intfsec[k - 1, i_maxd] + intfsec[k, i_maxd])
                ax.text(textx,
                        texty,
                        str(k),
                        verticalalignment="center",
                        horizontalalignment="center",
                        fontsize=6)
            elif k % 5 == 0:
                PL = ax.plot(x, -intfsec[k, :], "--", color="k", linewidth=0.5)
                textx = x[i_maxd]
                texty = -0.5 * (intfsec[k - 1, i_maxd] + intfsec[k, i_maxd])
                ax.text(textx,
                        texty,
                        str(k),
                        verticalalignment="center",
                        horizontalalignment="center",
                        fontsize=6)
            else:
                if k > 2 and k % 2 == 0:
                    PL = ax.plot(x,
                                 -intfsec[k, :],
                                 "-",
                                 color=".5",
                                 linewidth=0.5)
                    textx = x[i_maxd]
                    texty = -0.5 * (intfsec[k - 1, i_maxd] +
                                    intfsec[k, i_maxd])
                    ax.text(textx,
                            texty,
                            str(k),
                            verticalalignment="center",
                            horizontalalignment="center",
                            fontsize=6)
                else:
                    continue
        # Print figure
        ax.set_facecolor('xkcd:gray')
        aspect = 90
        pad_fraction = 0.25
        divider = make_axes_locatable(ax)
        width = axes_size.AxesY(ax, aspect=1. / aspect)
        pad = axes_size.Fraction(pad_fraction, width)
        cax = divider.append_axes("right", size=width, pad=pad)
        cb = ax.figure.colorbar(P, cax=cax)
        if clim is not None: P.set_clim(clim)
        if dens:
            ax.set_title('[P. density ]: ' + myfile)
        else:
            ax.set_title('[' + variable + ']: ' + myfile)

        ax.set_ylabel('Depth [m]')
        ax.set_xlabel(xlab)

        # Print in different y-lims
        suff = os.path.basename(myfile)
        if sectionid: suff = suff + "_" + sectionid
        if dens: variable = "dens"
        figure.canvas.print_figure("sec_%s_full_%s.png" % (variable, suff),
                                   dpi=dpi)
        ax.set_ylim(-1000, 0)
        figure.canvas.print_figure("sec_%s_1000m_%s.png" % (variable, suff),
                                   dpi=dpi)

        # Close input file
        i_abfile.close()

        #
        ax.clear()
        cb.remove()
def main(lon1,lat1,lon2,lat2,variable,files,filetype="archive",clim=None,sectionid="",
      ijspace=False,xaxis="distance",section_map=False,ncfiles="",dpi=180) :
   #TP4Grd='/cluster/work/users/aal069/TP4a0.12/mfile/'
   logger.info("Filetype is %s"% filetype)
   gfile = abf.ABFileGrid("regional.grid","r")
   plon=gfile.read_field("plon")
   plat=gfile.read_field("plat")


   # Set up section info
   if ijspace :
      sec = gridxsec.SectionIJSpace([lon1,lon2],[lat1,lat2],plon,plat)
   else  :
      sec = gridxsec.Section([lon1,lon2],[lat1,lat2],plon,plat)
   I,J=sec.grid_indexes
   dist=sec.distance
   print('dit.shae=',dist.shape)
   slon=sec.longitude
   slat=sec.latitude
   # In testing
   #J,I,slon,slat,case,dist=sec.find_intersection(qlon,qlat)
   #print I,J
   #raise NameError,"test"

   logger.info("Min max I-index (starts from 0):%d %d"%(I.min(),I.max()))
   logger.info("Min max J-index (starts from 0):%d %d"%(J.min(),J.max()))
   #
   #
   if section_map :
      ll_lon=slon.min()-10.
      ur_lon=slon.max()+10.
      ll_lat=np.maximum(-90.,slat.min()-10.)
      ur_lat=np.minimum(90. ,slat.max()+10.)

      proj=ccrs.Stereographic(central_latitude=90.0,central_longitude=-40.0)
      #pxy = proj.transform_points(ccrs.PlateCarree(), plon, plat)
      #px=pxy[:,:,0]
      #py=pxy[:,:,1]
      #x,y=np.meshgrid(np.arange(slon.shape[0]),np.arange(slat.shape[0]))
        
      figure =plt.figure(figsize=(8,8))
      ax=figure.add_subplot(111,projection=proj)
      #ax = plt.axes(projection=ccrs.PlateCarree())
      ax.set_extent([-179, 179, 53, 85],ccrs.PlateCarree())
      #ax = plt.axes(projection=ccrs.Stereographic())
      ax.add_feature(cfeature.GSHHSFeature('auto', edgecolor='grey'))
      ax.add_feature(cfeature.GSHHSFeature('auto', facecolor='grey'))
      ax.gridlines()
      #ax.coastlines(resolution='110m')
      ax.plot(slon,slat,"r-",lw=1,transform=ccrs.PlateCarree())
       
      pos = ax.get_position()
      asp=pos.height/pos.width
      w=figure.get_figwidth()
      h=asp*w
      figure.set_figheight(h)
      if sectionid :
         figure.canvas.print_figure("map_%s.png"%sectionid,dpi=dpi,bbox_inches='tight')
      else :
         figure.canvas.print_figure("map.png",dpi=dpi,bbox_inches='tight')

   # Get layer thickness variable used in hycom
   dpname = modeltools.hycom.layer_thickness_variable[filetype]
   logger.info("Filetype %s: layer thickness variable is %s"%(filetype,dpname))


   if xaxis == "distance" :
      x=dist/1000.
      xlab="Distance along section[km]"
   elif xaxis == "i" :
      x=I
      xlab="i-index"
   elif xaxis == "j" :
      x=J
      xlab="j-index"
   elif xaxis == "lon" :
      x=slon
      xlab="longitude"
   elif xaxis == "lat" :
      x=slat
      xlab="latitude"
   else :
      logger.warning("xaxis must be i,j,lo,lat or distance")
      x=dist/1000.
      xlab="Distance along section[km]"

   # get kdm from the first file:
   # Remove [ab] ending if present
   print('firstfilw', files[0])
   m=re.match("(.*)\.[ab]",files[0])
   print('m=',m.group(1))
   myf=m.group(1)
   fi_abfile = abf.ABFileArchv(myf,"r")
   kdm=max(fi_abfile.fieldlevels)

   # Loop over archive files
   figure = plt.figure()
   ax=figure.add_subplot(111)
   pos = ax.get_position()
   count_sum=0
   intfsec_sum=np.zeros((kdm+1,I.size))
   datasec_sum=np.zeros((kdm+1,I.size))
   for fcnt,myfile0 in enumerate(files) :
      count_sum=count_sum+1
      print('count_sum==', count_sum)
      print('fcnt=', fcnt)
      print('mfile0=', myfile0)
      # Remove [ab] ending if present
      m=re.match("(.*)\.[ab]",myfile0)
      if m :
         myfile=m.group(1)
      else :
         myfile=myfile0

      # Add more filetypes if needed. By def we assume archive
      if filetype == "archive" :
         i_abfile = abf.ABFileArchv(myfile,"r")
      elif filetype == "restart" :
         i_abfile = abf.ABFileRestart(myfile,"r",idm=gfile.idm,jdm=gfile.jdm)
      else :
         raise NotImplementedError("Filetype %s not implemented"%filetype)
      # kdm assumed to be max level in ab file
      kdm=max(i_abfile.fieldlevels)

      # Set up interface and daat arrays
      
      xx=np.zeros((kdm+1,I.size))
      intfsec=np.zeros((kdm+1,I.size))
      datasec=np.zeros((kdm+1,I.size))
      # Loop over layers in file. 
      logger.info("File %s"%(myfile))
      for k in range(kdm) :
         logger.debug("File %s, layer %03d/%03d"%(myfile,k,kdm))

         # Get 2D fields
         dp2d=i_abfile.read_field(dpname,k+1)
         data2d=i_abfile.read_field(variable,k+1)
         #print('---mn,mx  data=',  data2d.min(),data2d.max())
         if (k%kdm==49):
            print("---Reach bottom layer" )
         dp2d=np.ma.filled(dp2d,0.)/modeltools.hycom.onem
         data2d=np.ma.filled(data2d,1e30)
         # Place data into section arrays
         intfsec[k+1,:] = intfsec[k,:] + dp2d[J,I]
         if k==0 : datasec[k,:] = data2d[J,I]
         datasec[k+1,:] = data2d[J,I]
      

      intfsec_sum=intfsec_sum + intfsec
      datasec_sum=datasec_sum + datasec
      #print 'prs_intafce=', np.transpose(intfsec[:,15]) 
      i_abfile.close()

      # end loop over files
      
   intfsec_avg=intfsec_sum/count_sum
   datasec_avg=datasec_sum/count_sum

   if ncfiles :
      MLDGS_sum=np.zeros((1,I.size))
      count_sum=0
      for fcnt,ncfile in enumerate(ncfiles) :
         count_sum=count_sum+1
         print('ncfile count_sum==', count_sum)
         print('ncfile fcnt=', fcnt)
         print('ncfilefile=', ncfile)
         MLDGS=np.zeros((1,I.size))
         ncfile0 = netCDF4.Dataset(ncfile,'r')
         MLD_2D  = ncfile0.variables['GS_MLD'][:]
         #MLD_2D  = ncfile0.variables['mlp'][:]
         MLDGS[0,:]=MLD_2D[0,J,I]
         MLDGS_sum= MLDGS_sum + MLDGS
         ncfile0.close()
      # end loop over files
      MLDGS_avg=MLDGS_sum/count_sum
   #
   #-----------------------------------------------------------------
   # read from clim mld TP5netcdf
   if ncfiles :
      if 'TP2' in files[0]:
         fh=netCDF4.Dataset('mld_dr003_l3_modif_Interp_TP2grd.nc')
      else:
         fh=netCDF4.Dataset('mld_dr003_l3_modif_Interp_TP5grd.nc')
      fhmldintrp = fh.variables['TP5mld'][:]
      fh.close()
      #fhMLDintrp_sum=np.zeros((760,800))
      MLDclim_sum=np.zeros((1,I.size))
      cunt_sum=0
      for ii in range(12) :
          cunt_sum=cunt_sum +1
          MLDclim=np.zeros((1,I.size))
          MLDclim[0,:]=fhmldintrp[ii,J,I]

          MLDclim_sum= MLDclim_sum + MLDclim
          print('clim count_sum==', cunt_sum)
      MLDclim_avg=MLDclim_sum/cunt_sum
   #-----------------------------------------------------------------   
   i_maxd=np.argmax(np.abs(intfsec_avg[kdm,:]))
   #print i_maxd
   for k in range(kdm+1) :
      xx[k,:] = x[:]
   # Set up section plot
   #datasec = np.ma.masked_where(datasec==1e30,datasec)
   datasec_avg = np.ma.masked_where(datasec_avg>0.5*1e30,datasec_avg)
   #print datasec.min(),datasec.max()
   #P=ax.pcolormesh(dist/1000.,-intfsec,datasec)
   #print i_maxd
   for k in range(kdm+1) :
      xx[k,:] = x[:]
   
   if clim is not None : lvls = MaxNLocator(nbins=30).tick_values(clim[0], clim[1])
   #print 'levels=', lvls
   mf='sawtooth_0-1.txt'
   LinDic=mod_hyc2plot.cmap_dict(mf)
   my_cmap = matplotlib.colors.LinearSegmentedColormap('my_colormap',LinDic)
   cmap=my_cmap
   #cmap = matplotlib.pyplot.get_cmap('gist_rainbow_r')
   norm = BoundaryNorm(lvls, ncolors=cmap.N, clip=True)
   print('x.shape=' ,      x.shape)
   print('x.min,xmax=' ,  x.min(),x.max())
   print('xx.shape=' ,      xx.shape)
   print('xx.min,xxmax=' ,  xx.min(),xx.max())
   print('intfsec_avg.shape=', intfsec_avg.shape)
   print('datasec_avg.shape=', datasec_avg.shape)
   #P=ax.pcolormesh(x,-intfsec,datasec,cmap=cmap)
   P=ax.contourf(xx,-intfsec_avg,datasec_avg,extend='both',cmap=cmap,levels=lvls)
   if 'sal' in variable:
      P1=ax.contour(xx,-intfsec_avg,datasec_avg,levels=[32.0,33.0,34.0,35.0,35.5],
          colors=('k',),linestyles=('-',),linewidths=(1.5,))
   else:
      P1=ax.contour(xx,-intfsec_avg,datasec_avg,levels=[-1,0.0,2.0],
          colors=('k',),linestyles=('-',),linewidths=(1.5,))
   matplotlib.pyplot.clabel(P1, fmt = '%2.1d', colors = 'k', fontsize=10) #contour line labels
   # Plot layer interfaces
   for k in range(1,kdm+1) :
      if k%100 == 0 : 
         PL=ax.plot(x,-intfsec_avg[k,:],"-",color="k")
      elif k%5 == 0 and k <= 10: 
         PL=ax.plot(x,-intfsec_avg[k,:],"--",color="k", linewidth=0.5)
         textx = x[i_maxd]
         texty = -0.5*(intfsec_avg[k-1,i_maxd] + intfsec_avg[k,i_maxd])
         ax.text(textx,texty,str(k),verticalalignment="center",horizontalalignment="center",fontsize=6)
      elif k%2 and k > 10 : 
         PL=ax.plot(x,-intfsec_avg[k,:],"--",color="k", linewidth=0.5)
         textx = x[i_maxd]
         texty = -0.5*(intfsec_avg[k-1,i_maxd] + intfsec_avg[k,i_maxd])
         ax.text(textx,texty,str(k),verticalalignment="center",horizontalalignment="center",fontsize=6)
   if ncfiles :
      PL=ax.plot(x,-MLDGS_avg[0,:],"-",color="w", linewidth=1.50)
      PL=ax.plot(x,-MLDclim_avg[0,:],"--",color="r", linewidth=1.50)
###    else :
###       PL=ax.plot(x,-intfsec_avg[k,:],"-",color=".5")
  # Print figure and remove wite space.
   aspect = 50
   pad_fraction = 0.25
   divider = make_axes_locatable(ax)
   width = axes_size.AxesY(ax, aspect=1./aspect)
   pad = axes_size.Fraction(pad_fraction, width)
   cax = divider.append_axes("right", size=width, pad=pad)
   cb=ax.figure.colorbar(P,cax=cax,extend='both')
   #cb=ax.figure.colorbar(P,extend='both')
   if clim is not None : P.set_clim(clim)
   #cb=ax.figure.colorbar(P,extend='both')
   ax.set_title(variable+':'+myfile+'AVG-')
   ax.set_ylabel('Depth [m]')
   ax.set_xlabel(xlab)
   #ax.set_position(pos)
   #matplotlib.pyplot.tight_layout()

   # Print in different y-lims 
   suff=os.path.basename(myfile)
   if sectionid : suff=suff+"_"+sectionid
   figure.canvas.print_figure("sec_AVG_%s_full_%s.png"%(variable,suff),dpi=dpi)
   #ax.set_ylim(-1000,0)
   if 'Fram' in sectionid or 'Svin' in sectionid:
      print('sectionid=', sectionid)
      ax.set_ylim(-600,0)
      figure.canvas.print_figure("sec_AVG_%s_600m_%s.png"%(variable,suff),dpi=dpi)
   else:
      #ax.set_ylim(-2500,0)
      #figure.canvas.print_figure("sec_AVG_%s_2500m_%s.png"%(variable,suff),dpi=dpi)
      ax.set_ylim(-3000,0)
      figure.canvas.print_figure("sec_AVG_%s_3000m_%s.png"%(variable,suff),dpi=dpi)

   # Close input file
   #i_abfile.close()
   #
   ax.clear()
   cb.remove()
示例#5
0
def main(meshfile,file,iexpt=10,iversn=22,yrflag=3,bio_path=None) :
    
    #
    # Trim input netcdf file name being appropriate for reading
    #
    meshfile=str(meshfile)[2:-2]
    logger.info("Reading mesh information from %s."%(meshfile))
    #
    # Read mesh file containing grid and coordinate information.
    # Note that for now, we are using T-grid in vertical which may need
    # to be improved by utilizing W-point along the vertical axis.
    #
    hdept,gdept,mbathy,mbathy_u,mbathy_v,mask,e3t,plon,plat=read_grid(meshfile)
    logger.warning("Reading grid information from regional.grid.[ab] (not completed)")
    #
    # Convert from P-point (i.e. NEMO grid) to U and V HYCOM grids
    #
    mask_u=p2u_2d(mask)
    mask_v=p2v_2d(mask)
    #
    # Read regional.grid.[ab]
    # Grid angle is not used for this product because all quantities are
    # on regular rectangular grid points.
    #
    angle=numpy.zeros(plon.shape)
    #
    # Number vertical layers in T-point.
    #
    nlev=gdept.size
    #
    # layer thickness in the absence of layer partial steps.
    #
    dt = gdept[1:] - gdept[:-1]
    #
    # Prepare/read input data file (in netcdf format). Reference time is 1950-01-01
    #
    logger.info("Reading data files.")
    file=str(file).strip()[2:-2]
    dirname=os.path.dirname(file)
    logger.debug("file name is {}".format(file))
    logger.debug("dirname is {}".format(dirname))
    logger.debug("basename is {}".format(os.path.basename(file)))
    m=re.match("(MERCATOR-PHY-24-)(.*\.nc)",os.path.basename(file))
    logger.debug("file prefix is {}".format(file_pre))
###    m=re.match(file_pre,os.path.basename(file))
    if not m:
        msg="File %s is not a grid2D file, aborting"%file
        logger.error(msg)
        raise ValueError(msg)
    
    #fileinput0=os.path.join(dirname+"/"+"MERCATOR-PHY-24-"+m.group(2))
    file_date=file[-16:-6]
    fileinput0=file
    print((file_date,file))
    next_day=datetime.datetime.strptime(file_date, '%Y-%m-%d')+datetime.timedelta(days=1)
    fileinput1=datetime.datetime.strftime(next_day,'%Y%m%d')
    fileinput1=os.path.join(dirname+"/"+file_pre+fileinput1+'.nc')
    
    logger.info("Reading from %s"%(fileinput0))
    ncid0=netCDF4.Dataset(fileinput0,"r")
    if timeavg_method==1 and os.path.isfile(fileinput1) :
        
        logger.info("timeavg_method=1, Reading from %s"%(fileinput1))
        ncid1=netCDF4.Dataset(fileinput1,"r")
        #
        # Calculate temporal averaged temperature, salinity, and velocity
        #
        uo =   0.5*(ncid0.variables["uo"][0,:,:,:]+    ncid1.variables["uo"][0,:,:,:])
        vo =   0.5*(ncid0.variables["vo"][0,:,:,:]+    ncid1.variables["vo"][0,:,:,:])
        salt = 0.5*(ncid0.variables["so"][0,:,:,:]+    ncid1.variables["so"][0,:,:,:])
        temp = 0.5*(ncid0.variables["thetao"][0,:,:,:]+ncid1.variables["thetao"][0,:,:,:])
        ssh = numpy.squeeze(0.5*(ncid0.variables["zos"][0,:,:]+ncid1.variables["zos"][0,:,:]))
    
    else:
        #
	# Set variables based on current file when timeavg_method ~=1 or the next netcdf file is not available
        logger.debug("time average method set to {}".format(timeavg_method))
        uo =   ncid0.variables["uo"][0,:,:,:]
        vo =   ncid0.variables["vo"][0,:,:,:]
        salt = ncid0.variables["so"][0,:,:,:]
        temp = ncid0.variables["thetao"][0,:,:,:]
        ssh = numpy.squeeze(ncid0.variables["zos"][0,:,:])
    #
    # I will account these values afterward. Because in the current version, I am accounting for missing values using a gap-filling methodology.
    #	
    logger.debug("getting _FillValue")
    uofill=ncid0.variables["uo"]._FillValue
    vofill=ncid0.variables["vo"]._FillValue
    slfill=ncid0.variables["so"]._FillValue
    tlfill=ncid0.variables["thetao"]._FillValue
    shfill=ncid0.variables["zos"]._FillValue

    # Set time
    logger.info("Set time.")
    time=ncid0.variables["time"][0]
    unit=ncid0.variables["time"].units
    tmp=cfunits.Units(unit)
    refy,refm,refd=(1950,1,1)
    tmp2=cfunits.Units("hours since %d-%d-%d 00:00:00"%(refy,refm,refd))
    tmp3=int(numpy.round(cfunits.Units.conform(time,tmp,tmp2)))
    mydt = datetime.datetime(refy,refm,refd,0,0,0) + datetime.timedelta(hours=tmp3) # Then calculate dt. Phew!

    if timeavg_method==1 and os.path.isfile(fileinput1)  :
        fnametemplate="archv.%Y_%j_%H"
        deltat=datetime.datetime(refy,refm,refd,0,0,0) + \
              datetime.timedelta(hours=tmp3) + \
              datetime.timedelta(hours=12)
        oname=deltat.strftime(fnametemplate)
    else:
        #
        # I am assuming that daily mean can be set at 00 instead of 12
        # for cases that there is no information of next day.
        #
        fnametemplate="archv.%Y_%j"
        deltat=datetime.datetime(refy,refm,refd,0,0,0) + \
              datetime.timedelta(hours=tmp3)
        oname=deltat.strftime(fnametemplate) + '_00'

    # model day
    refy, refm, refd=(1900,12,31)
    model_day= deltat-datetime.datetime(refy,refm,refd,0,0,0)
    model_day=model_day.days
    logger.info("Model day in HYCOM is %s"%str(model_day))
    if bio_path:
       jdm,idm=numpy.shape(plon)
       points = numpy.transpose(((plat.flatten(),plon.flatten())))
       delta = mydt.strftime( '%Y-%m-%d')
       # filename format MERCATOR-BIO-14-2013-01-05-00
       print((bio_path,delta))
       idx,biofname=search_biofile(bio_path,delta)
       if idx >7: 
          msg="No available BIO file within a week difference with PHY"
          logger.error(msg)
          raise ValueError(msg)
       logger.info("BIO file %s reading & interpolating to 1/12 deg grid cells ..."%biofname)
       ncidb=netCDF4.Dataset(biofname,"r")
       blon=ncidb.variables["longitude"][:];
       blat=ncidb.variables["latitude"][:]
       minblat=blat.min()
       no3=ncidb.variables["NO3"][0,:,:,:];
       no3[numpy.abs(no3)>1e+10]=numpy.nan
       po4=ncidb.variables["PO4"][0,:,:,:]
       si=ncidb.variables["Si"][0,:,:,:]
       po4[numpy.abs(po4)>1e+10]=numpy.nan
       si[numpy.abs(si)>1e+10]=numpy.nan
       # TODO: Ineed to improve this part
       nz,ny,nx=no3.shape
       dummy=numpy.zeros((nz,ny,nx+1))
       dummy[:,:,:nx]=no3;dummy[:,:,-1]=no3[:,:,-1]
       no3=dummy
       dummy=numpy.zeros((nz,ny,nx+1))
       dummy[:,:,:nx]=po4;dummy[:,:,-1]=po4[:,:,-1]
       po4=dummy
       dummy=numpy.zeros((nz,ny,nx+1))
       dummy[:,:,:nx]=si;dummy[:,:,-1]=si[:,:,-1]
       si=dummy
       dummy=numpy.zeros((nx+1))
       dummy[:nx]=blon
       blon=dummy
       blon[-1]=-blon[0]
# TODO:  Note that the coordinate files are for global configuration while
#        the data file saved for latitude larger than 30. In the case you change your data file coordinate
#        configuration you need to modify the following lines
       bio_coordfile=bio_path[:-4]+"/GLOBAL_ANALYSIS_FORECAST_BIO_001_014_COORD/GLO-MFC_001_014_mask.nc"
       biocrd=netCDF4.Dataset(bio_coordfile,"r")
       blat2 = biocrd.variables['latitude'][:]
       index=numpy.where(blat2>=minblat)[0]
       depth_lev = biocrd.variables['deptho_lev'][index[0]:,:]
#
#
#
       dummy=numpy.zeros((ny,nx+1))
       dummy[:,:nx]=depth_lev;dummy[:,-1]=depth_lev[:,-1]
       depth_lev=dummy
       depth_lev[depth_lev>50]=0
       depth_lev=depth_lev.astype('i')
       dummy_no3=no3
       dummy_po4=po4
       dummy_si=si
       for j in range(ny):
          for i in range(nx):
             dummy_no3[depth_lev[j,i]:nz-2,j,i]=no3[depth_lev[j,i]-1,j,i]
             dummy_po4[depth_lev[j,i]:nz-2,j,i]=po4[depth_lev[j,i]-1,j,i]
             dummy_si[depth_lev[j,i]:nz-2,j,i]=si[depth_lev[j,i]-1,j,i]
       no3=dummy_no3
       po4=dummy_po4
       si=dummy_si

#
       po4 = po4 * 106.0 * 12.01
       si = si   * 6.625 * 12.01
       no3 = no3 * 6.625 * 12.01


    logger.info("Read, trim, rotate NEMO velocities.")
    u=numpy.zeros((nlev,mbathy.shape[0],mbathy.shape[1]))
    v=numpy.zeros((nlev,mbathy.shape[0],mbathy.shape[1]))
    utmp=numpy.zeros((mbathy.shape))
    vtmp=numpy.zeros((mbathy.shape))
    #
    # Metrices to detect carrefully bottom at p-, u-, and v-grid points.While I have used 3D, mask data,following methods are good enough for now.
    #
    if mbathy_method  ==  1 :
        ip = mbathy   == -1
        iu = mbathy_u == -1
        iv = mbathy_v == -1
    else:
        ip = mask   == 0
        iu = mask_u == 0
        iv = mask_v == 0
    #
    # Read 3D velocity field to calculate barotropic velocity
    #
    # Estimate barotropic velocities using partial steps along the vertical axis. Note that for the early version of this code, 
    # I used dt = gdept[1:] - gdept[:-1] on NEMO t-grid. Furthermore, you may re-calculate this part on vertical grid cells for future. 
    #
    logger.info("Calculate barotropic velocities.")
    ubaro,vbaro=calc_uvbaro(uo,vo,e3t,iu,iv)
    #
    # Save 2D fields (here only ubaro & vbaro)
    #
    zeros=numpy.zeros(mbathy.shape)
    #flnm = open(oname+'.txt', 'w')
    #flnm.write(oname)
    #flnm.close()
    ssh = numpy.where(numpy.abs(ssh)>1000,0.,ssh*9.81) # NB: HYCOM srfhgt is in geopotential ...
    #
    outfile = abf.ABFileArchv("./data/"+oname,"w",iexpt=iexpt,iversn=iversn,yrflag=yrflag,)
    outfile.write_field(zeros,                   ip,"montg1"  ,0,model_day,1,0)
    outfile.write_field(ssh,                     ip,"srfhgt"  ,0,model_day,0,0)
    outfile.write_field(zeros,                   ip,"surflx"  ,0,model_day,0,0) # Not used
    outfile.write_field(zeros,                   ip,"salflx"  ,0,model_day,0,0) # Not used
    outfile.write_field(zeros,                   ip,"bl_dpth" ,0,model_day,0,0) # Not used
    outfile.write_field(zeros,                   ip,"mix_dpth",0,model_day,0,0) # Not used
    outfile.write_field(ubaro,                   iu,"u_btrop" ,0,model_day,0,0)
    outfile.write_field(vbaro,                   iv,"v_btrop" ,0,model_day,0,0)
    #
    if bio_path:
       logger.info("Calculate baroclinic velocities, temperature, and salinity data as well as BIO field.")
    else:
       logger.info("Calculate baroclinic velocities, temperature, and salinity data.")
    for k in numpy.arange(u.shape[0]) :
        if bio_path:
           no3k=interpolate2d(blat, blon, no3[k,:,:], points).reshape((jdm,idm))
           no3k = maplev(no3k)
           po4k=interpolate2d(blat, blon, po4[k,:,:], points).reshape((jdm,idm))
           po4k = maplev(po4k)
           si_k=interpolate2d(blat, blon, si[k,:,:], points).reshape((jdm,idm))
           si_k = maplev(si_k)
           if k%10==0 : logger.info("Writing 3D variables including BIO, level %d of %d"%(k+1,u.shape[0]))
        else:
           if k%10==0 : logger.info("Writing 3D variables, level %d of %d"%(k+1,u.shape[0]))
        #

        #
        uo[k,:,:]=numpy.where(numpy.abs(uo[k,:,:])<10,uo[k,:,:],0)
        vo[k,:,:]=numpy.where(numpy.abs(vo[k,:,:])<10,vo[k,:,:],0)

        # Baroclinic velocity (in HYCOM U- and V-grid)
        ul = p2u_2d(numpy.squeeze(uo[k,:,:])) - ubaro
        vl = p2v_2d(numpy.squeeze(vo[k,:,:])) - vbaro
        ul[iu]=spval
        vl[iv]=spval
        
        # Layer thickness
        
        dtl=numpy.zeros(mbathy.shape)
        # Use dt for the water column except the nearest cell to bottom 
        if thickness_method==1:
            if k < u.shape[0]-1 :
                J,I = numpy.where(mbathy>k)
                e3=(e3t[k,:,:])
                dtl[J,I]=dt[k]
                J,I = numpy.where(mbathy==k)
                dtl[J,I]=e3[J,I]
            else:
                e3=(e3t[k,:,:])
                J,I = numpy.where(mbathy==k)
                dtl[J,I]=e3[J,I]
	# Use partial cells for the whole water column.
        else :
            J,I = numpy.where(mbathy>=k)
            dtl[J,I]=e3t[k,J,I]

        # Salinity
        sl = salt[k,:,:]

        # Temperature
        tl = temp[k,:,:]
        # Need to be carefully treated in order to minimize artifacts to the resulting [ab] files.
        if fillgap_method==1:
            J,I= numpy.where(mbathy<k)
            sl = maplev(numpy.where(numpy.abs(sl)<1e2,sl,numpy.nan))
            sl[J,I]=spval
            J,I= numpy.where(mbathy<k)
            tl = maplev(numpy.where(numpy.abs(tl)<1e2,tl,numpy.nan))
            tl[J,I]=spval
        else:
            sl = numpy.where(numpy.abs(sl)<1e2,sl,numpy.nan)
            sl = numpy.minimum(numpy.maximum(maplev(sl),25),80.)
            tl = numpy.where(numpy.abs(tl)<=5e2,tl,numpy.nan)
            tl = numpy.minimum(numpy.maximum(maplev(tl),-5.),50.)

        # Thickness
        dtl = maplev(dtl)
        if k > 0 :
            with numpy.errstate(invalid='ignore'):
                K= numpy.where(dtl < 1e-4)
            sl[K] = sl_above[K]
            tl[K] = tl_above[K]
        #
        sl[ip]=spval
        tl[ip]=spval

        # Save 3D fields
        outfile.write_field(ul      ,iu,"u-vel.",0,model_day,k+1,0)
        outfile.write_field(vl      ,iv,"v-vel.",0,model_day,k+1,0)
        outfile.write_field(dtl*onem,ip,"thknss",0,model_day,k+1,0)
        outfile.write_field(tl      ,ip,"temp" , 0,model_day,k+1,0)
        outfile.write_field(sl      ,ip,"salin" ,0,model_day,k+1,0)
        if bio_path :
           outfile.write_field(no3k      ,ip,"ECO_no3" ,0,model_day,k+1,0)
           outfile.write_field(po4k      ,ip,"ECO_pho" ,0,model_day,k+1,0)
           outfile.write_field(si_k      ,ip,"ECO_sil" ,0,model_day,k+1,0)
                
        tl_above=numpy.copy(tl)
        sl_above=numpy.copy(sl)
    
    outfile.close()
    ncid0.close()
    if timeavg_method==1 and os.path.isfile(fileinput1)  :
        ncid1.close()
    if bio_path :
       ncidb.close()
示例#6
0
def main(psikk_file, archv_files, psikk_file_type="restart", month=1):

    logger.info("psikk file type is %s" % psikk_file_type)
    from_relax_archv = psikk_file_type == "relax_archv"
    from_relax = psikk_file_type == "relax"
    from_restart = psikk_file_type == "restart"
    if not from_relax_archv and not from_relax and not from_restart:
        msg = "psikk_file_type must be either restart relax or relax_archv"
        logger.error(msg)
        raise ValueError(msg)

    # Open blkdat files. Get some properties
    bp = modeltools.hycom.BlkdatParser("blkdat.input")
    idm = bp["idm"]
    jdm = bp["jdm"]
    kdm = bp["kdm"]
    thflag = bp["thflag"]
    thbase = bp["thbase"]
    kapref = bp["kapref"]
    iversn = bp["iversn"]
    iexpt = bp["iexpt"]
    yrflag = bp["yrflag"]
    thref = modeltools.hycom.thref
    if kapref == -1:
        kapnum = 2
        msg = "Only kapref>=0 is implemented for now"
        logger.error(msg)
        raise ValueError(msg)
    else:
        kapnum = 1

    if kapnum > 1:
        msg = "Only kapnum=1 is implemented for now"
        logger.error(msg)
        raise ValueError(msg)

    path0 = os.path.join(".", "montg1")
    if os.path.exists(path0) and os.path.isdir(path0):
        pass
    else:
        os.mkdir(path0)

    # hycom sigma and kappa, written in python. NB: sigver is not used here.
    # Modify to use other equations of state. For now we assume sigver is:
    #    1 (7-term eqs referenced to    0 bar)
    #    2 (7-term eqs referenced to 2000 bar)
    if thflag == 0:
        sigver = 1
    else:
        sigver = 2
    sig = modeltools.hycom.Sigma(thflag)
    if kapref > 0: kappa = modeltools.hycom.Kappa(kapref, thflag * 1000.0e4)  #

    # Option 1: Get psikk and thkk directly from a restart file
    if from_restart:

        # Read input variables from lowest layer of a restart file
        m = re.match("^(.*)(\.[ab])", psikk_file)
        if m: psikk_file = m.group(1)
        rfile = abf.ABFileRestart(psikk_file, "r", idm=idm, jdm=jdm)
        psikk = rfile.read_field("psikk", 0)
        thkk = rfile.read_field("thkk", 0)
        rfile.close()

    # Option 2: Get temp, salinity and dp from relaxaiton fields. Estimate thkk and psikk
    elif from_relax:
        pattern = "^(.*)_(tem|int|sal)"
        psikk_file = abf.ABFile.strip_ab_ending(psikk_file)
        m = re.match(pattern, psikk_file)
        if m:
            relaxtem = abf.ABFileRelax(m.group(1) + "_tem", "r")
            relaxsal = abf.ABFileRelax(m.group(1) + "_sal", "r")
            relaxint = abf.ABFileRelax(m.group(1) + "_int", "r")
        else:
            msg = """Input hycom relaxation file %s does not match pattern
         %s""" % (psikk_file, pattern)
            logger.error(msg)
            raise ValueError(msg)

    # Option 3: Get temp, salinity and dp from relaxation fields (archive files generated during relaxation setup). Estimate thkk and psikk
    elif from_relax_archv:
        arcfile0 = abf.ABFileArchv(psikk_file, "r")

    else:
        msg = "No way of estimating psikk and thkk. Aborting ..."
        logger(msg)
        raise ValueError(msg)

    # Estimate psikk, thkk from climatology. (Option 1 or option 2)
    if from_relax or from_relax_archv:
        logger.info("Estimating psikk and thkk from climatology")
        p = numpy.ma.zeros((jdm, idm))
        pup = numpy.ma.zeros((jdm, idm))
        montg = numpy.ma.zeros((jdm, idm))
        for k in range(kdm):
            logger.debug("Reading layer %d from climatology" % k)
            if k > 0: thstarup = numpy.ma.copy(thstar)

            if from_relax:
                saln = relaxsal.read_field("sal", k + 1, month)
                temp = relaxtem.read_field("tem", k + 1, month)
                plo = relaxint.read_field("int", k + 1,
                                          month)  # lowest interface of layer
                dp = plo - pup
                pup = numpy.copy(plo)  # Next loop, pup = plo of this loop
            elif from_relax_archv:
                saln = arcfile0.read_field("salin", k + 1)
                temp = arcfile0.read_field("temp", k + 1)
                dp = arcfile0.read_field("thknss", k + 1)
            else:
                msg = "No way of estimating sal, tem and dp. Aborting ..."
                logger(msg)
                raise ValueError(msg)

            th3d = sig.sig(temp, saln) - thbase
            thstar = numpy.ma.copy(th3d)
            if kapref > 0:
                thstar = thstar + kappa.kappaf(temp[:, :], saln[:, :],
                                               th3d[:, :] + thbase, p[:, :])
            elif kapref < 0:
                msg = "Only kapref>=0 is implemented for now"
                logger.error(msg)
                raise ValueError(msg)
            # From hycom inicon.f
            #        montg(i,j,1,kkap)=0.0
            #        do k=1,kk-1
            #          montg(i,j,k+1,kkap)=montg(i,j,k,kkap)-
            #     &    p(i,j,k+1)*(thstar(i,j,k+1,kkap)-thstar(i,j,k,kkap))*thref**2
            #        enddo
            #c
            #        thkk( i,j,kkap)=thstar(i,j,kk,kkap)
            #        psikk(i,j,kkap)=montg( i,j,kk,kkap)
            if k > 0:
                #print (thstar - thstarup).min(), (thstar - thstarup).min()
                montg = montg - p * (thstar - thstarup) * thref**2
            p = p + dp
        thkk = thstar
        psikk = montg
        if from_relax:
            relaxtem.close()
            relaxsal.close()
            relaxint.close()
        elif from_relax_archv:
            arcfile0.close()
    else:
        pass
    logger.info("Min max of thkk: %12.6g %12.6g" % (thkk.min(), thkk.max()))
    logger.info("Min max of psikk: %12.6g %12.6g" % (psikk.min(), psikk.max()))

    # Loop through archive files
    for archv_file in archv_files:

        logger.debug("Processing %s" % (archv_file))
        arcfile = abf.ABFileArchv(archv_file, "r")

        # Read all layers .. (TODO: If there is memory problems, read and estimate sequentially)
        temp = numpy.ma.zeros(
            (jdm, idm))  # Only needed when calculating density
        saln = numpy.ma.zeros(
            (jdm, idm))  # Only needed when calculating density
        th3d = numpy.ma.zeros((kdm, jdm, idm))
        thstar = numpy.ma.zeros((kdm, jdm, idm))
        dp = numpy.ma.zeros((jdm, idm))
        p = numpy.ma.zeros((kdm + 1, jdm, idm))
        for k in range(kdm):
            logger.info("Reading layer %d from %s" % (k, archv_file))
            temp = arcfile.read_field("temp", k + 1)
            saln = arcfile.read_field("salin", k + 1)
            #dp    [k  ,:,:]=arcfile.read_field("thknss",k+1)
            dp[:, :] = arcfile.read_field("thknss", k + 1)
            th3d[k, :, :] = sig.sig(temp, saln) - thbase
            p[k + 1, :, :] = p[k, :, :] + dp[:, :]
            thstar[k, :, :] = numpy.ma.copy(th3d[k, :, :])
            if kapref > 0:
                thstar[k, :, :] = thstar[k, :, :] + kappa.kappaf(
                    temp[:, :], saln[:, :], th3d[k, :, :] + thbase, p[k, :, :])
            elif kapref < 0:
                msg = "Only kapref>=0 is implemented for now"
                logger.error(msg)
                raise ValueError(msg)

        # This part of montg1 does nto depend on pbavg
        montg1c = modeltools.hycom.montg1_pb(thstar, p)

        # This part depends linearly on pbavg
        montg1pb = modeltools.hycom.montg1_no_pb(psikk, thkk, thstar, p)
        print montg1c.min(), montg1c.max()
        print montg1pb.min(), montg1pb.max()

        # ... we have ...
        #     montg1 = montgc + montgpb * pbavg
        #     srfhgt = montg1 + thref*pbavg = montgc + montgpb * pbavg + thref*pbavg
        #  ... which gives new montg1n for srfhgtn
        #     pbavgn  = (srfhgtn-montgc) / (montgpb+thref)
        #     montg1n = montgc + montgpb*pbavgn
        # Systematic differences due to choice of sigma and or eq of state is not taken into account ...

        # Barotropic pressure. NB: srfhgt is in geopotential height :
        srfhgt = arcfile.read_field("srfhgt", 0)
        pbavg = (srfhgt - montg1c) / (montg1pb + thref)
        print pbavg.min(), pbavg.max()
        montg1 = montg1pb * pbavg + montg1c
        logger.info("Estimated montg1 ")
        print montg1.min(), montg1.max()

        # Open new archive file, and write montg1 to it.
        fnameout = os.path.join(path0, os.path.basename(arcfile.basename))
        arcfile_out = abf.ABFileArchv(fnameout,
                                      "w",
                                      iversn=iversn,
                                      yrflag=yrflag,
                                      iexpt=iexpt,
                                      mask=False)

        for key in sorted(arcfile.fields.keys()):
            fieldname = arcfile.fields[key]["field"]
            time_step = arcfile.fields[key]["step"]
            model_day = arcfile.fields[key]["day"]
            k = arcfile.fields[key]["k"]
            dens = arcfile.fields[key]["dens"]
            fld = arcfile.read_field(fieldname, k)

            if fieldname == "montg1":
                logger.info(
                    "Writing field %10s at level %3d to %s (modified)" %
                    (fieldname, k, fnameout))
                arcfile_out.write_field(montg1, None, fieldname, time_step,
                                        model_day, sigver, thbase)
            else:
                arcfile_out.write_field(fld, None, fieldname, time_step,
                                        model_day, k, dens)
                #logger.info("Writing field %10s at level %3d to %s (copy from original)"%(fieldname,k,fnameout))

        logger.info("Finished writing to %s" % fnameout)
        arcfile_out.close()
        arcfile.close()

    logger.warning("Sigver assumed to be those of 7 term eqs")
    logger.warning("    1 for sigma-0/thflag=0, 2 for sigma-2/thflag=2")
    logger.warning(
        "For other eqs, you need to modify the code so that sigver is set correctly in the archv file"
        "")
    logger.warning(
        "psikk and thkk from relaxation fields is beta. Preferred method is restart"
    )

    logger.info("Finito")
def main(archv_files,opath,header_line1=cline1,header_line2=cline2,header_line3=cline3 ) :


   # Open blkdat files. Get some properties
   bp=modeltools.hycom.BlkdatParser("blkdat.input")
   idm    = bp["idm"]
   jdm    = bp["jdm"]
   kdm    = bp["kdm"]
   thflag = bp["thflag"]
   thbase = numpy.float(bp["thbase"])
   kapref = bp["kapref"]
   iversn = bp["iversn"]
   iexpt  = bp["iexpt"]
   yrflag = bp["yrflag"]
   #thref=modeltools.hycom.thref
   thref=1e-3
   if kapref == -1 : 
      kapnum = 2
      msg="Only kapref>=0 is implemented for now"
      logger.error(msg)
      raise ValueError(msg)
   else :
      kapnum = 1 

   if kapnum > 1 :
      msg="Only kapnum=1 is implemented for now"
      logger.error(msg)
      raise ValueError(msg)


   # hycom sigma and kappa, written in python. NB: sigver is not used here.
   # Modify to use other equations of state. For now we assume sigver is:
   #    1 (7-term eqs referenced to    0 bar)
   #    2 (7-term eqs referenced to 2000 bar)
   if thflag == 0 :
      sigver=1
   else :
      sigver=2
   sig  = modeltools.hycom.Sigma(thflag)
   if kapref > 0  : kappa = modeltools.hycom.Kappa(kapref,thflag*1000.0e4) # 



   # Loop through archive files
   for archv_file in archv_files :
      archv_file=archv_file[:-2]
      logger.debug("Processing %s"%(archv_file))
      arcfile=abf.ABFileArchv(archv_file,"r")
      
      temp    = numpy.ma.zeros((jdm,idm))    # Only needed when calculating density
      saln    = numpy.ma.zeros((jdm,idm))    # Only needed when calculating density
      th3d  =numpy.ma.zeros((kdm,jdm,idm))
      thstar=numpy.ma.zeros((kdm,jdm,idm))
      dp    =numpy.ma.zeros((jdm,idm))
      p     =numpy.ma.zeros((kdm+1,jdm,idm))
      pup  =numpy.ma.zeros((jdm,idm))
      montg=numpy.ma.zeros((jdm,idm))
      for k in range(kdm) :
         logger.info("Reading layer %d from %s"%(k,archv_file))
         temp  =arcfile.read_field("temp",k+1)
         saln  =arcfile.read_field("salin",k+1)
         dp    [:,:]=arcfile.read_field("thknss",k+1)
         th3d  [k  ,:,:]=sig.sig(temp,saln) - thbase
         p     [k+1,:,:]= p[k,:,:] + dp[:,:]
         if k>0 : thstarup   =numpy.ma.copy(thstar[k  ,:,:])
         thstar[k  ,:,:]=numpy.ma.copy(th3d  [k  ,:,:])
         if kapref > 0 :
            thstar[k  ,:,:]=thstar  [k  ,:,:] + kappa.kappaf(temp[:,:],
                                                           saln[:,:], 
                                                           th3d[k,:,:]+thbase,
                                                           p[k,:,:])
         elif kapref < 0 :
            msg="Only kapref>=0 is implemented for now"
            logger.error(msg)
            raise ValueError(msg)
         if k > 0 : 
            montg = montg - p[k,:,:] * (thstar[k  ,:,:] - thstarup) * thref**2

      thkk = thstar[k  ,:,:]
      psikk = montg

      # This part of montg1 does nto depend on pbavg
      montg1c  = montg1_pb(thstar,p)
      # This part depends linearly on pbavg
      montg1pb = montg1_no_pb(psikk,thkk,thstar,p) 
      # Barotropic pressure. NB: srfhgt is in geopotential height : 
      srfhgt=arcfile.read_field("srfhgt",0)
      pbavg  = (srfhgt - montg1c) / (montg1pb+thref)
      montg1 = montg1pb*pbavg + montg1c
      logger.info("Estimated montg1 ")
 
      # Apply mask
      #montg1=numpy.ma.masked_where(srfhgt.mask,montg1) 
      #montg1[~msk]=2**100
      #montg1 = numpy.ma.masked_where(srfhgt<2.0**99,montg1)
      msk=numpy.where(srfhgt>2.0**99,1,0)


      # Open new archive file, and write montg1 to it.
      fnameout = opath+str(archv_file[-17:])
      arcfile_out=abf.ABFileArchv(fnameout,"w",iversn=iversn,yrflag=yrflag,iexpt=iexpt,mask=False,cline1=header_line1,cline2=header_line2,cline3=header_line3)

      fields=arcfile.get_fields()
      for key in sorted(fields.keys()) :
         fieldname = fields[key]["field"]
         time_step = fields[key]["step"]
         model_day = fields[key]["day"]
         k         = fields[key]["k"]
         dens      = fields[key]["dens"]
         fld       =arcfile.read_field(fieldname,k)

         if fieldname == "montg1" :
            logger.info("Writing field %10s at level %3d to %s (modified)"%(fieldname,k,fnameout))
            arcfile_out.write_field(montg1,None,fieldname,time_step,model_day,k,dens) 
         else :
            arcfile_out.write_field(fld   ,None,fieldname,time_step,model_day,k,dens) 

      logger.info("Finished writing to %s"%fnameout)
      arcfile_out.close()
      arcfile.close()
def main(lon1,
         lat1,
         lon2,
         lat2,
         variable,
         files,
         filetype="archive",
         clim=None,
         sectionid="",
         ijspace=False,
         xaxis="distance",
         section_map=False,
         dpi=180):

    logger.info("Filetype is %s" % filetype)
    gfile = abf.ABFileGrid("regional.grid", "r")
    plon = gfile.read_field("plon")
    plat = gfile.read_field("plat")

    # Set up section info
    if ijspace:
        sec = gridxsec.SectionIJSpace([lon1, lon2], [lat1, lat2], plon, plat)
    else:
        sec = gridxsec.Section([lon1, lon2], [lat1, lat2], plon, plat)
    I, J = sec.grid_indexes
    dist = sec.distance
    slon = sec.longitude
    slat = sec.latitude
    print(slon.shape)
    print(slat.shape)

    logger.info("Min max I-index (starts from 0):%d %d" % (I.min(), I.max()))
    logger.info("Min max J-index (starts from 0):%d %d" % (J.min(), J.max()))

    if section_map:
        ll_lon = slon.min() - 10.
        ur_lon = slon.max() + 10.
        ll_lat = np.maximum(-90., slat.min() - 10.)
        ur_lat = np.minimum(90., slat.max() + 10.)

        proj = ccrs.Stereographic(central_latitude=90.0,
                                  central_longitude=-40.0)
        pxy = proj.transform_points(ccrs.PlateCarree(), plon, plat)
        px = pxy[:, :, 0]
        py = pxy[:, :, 1]
        x, y = np.meshgrid(np.arange(slon.shape[0]), np.arange(slat.shape[0]))

        figure = plt.figure(figsize=(10, 8))
        ax = figure.add_subplot(111)

        ax = plt.axes(projection=ccrs.PlateCarree())
        ax.set_extent([-179, 179, 53, 85], ccrs.PlateCarree())
        ax.add_feature(cfeature.GSHHSFeature('auto', edgecolor='grey'))
        ax.add_feature(cfeature.GSHHSFeature('auto', facecolor='grey'))
        ax.gridlines()
        ax.plot(slon, slat, "r-", lw=1)

        pos = ax.get_position()
        asp = pos.height / pos.width
        w = figure.get_figwidth()
        h = asp * w
        figure.set_figheight(h)
        if sectionid:
            figure.canvas.print_figure("map_%s.png" % sectionid, dpi=dpi)
        else:
            figure.canvas.print_figure("map.png", dpi=dpi)

    # Get layer thickness variable used in hycom
    dpname = modeltools.hycom.layer_thickness_variable[filetype]
    logger.info("Filetype %s: layer thickness variable is %s" %
                (filetype, dpname))

    if xaxis == "distance":
        x = dist / 1000.
        xlab = "Distance along section[km]"
    elif xaxis == "i":
        x = I
        xlab = "i-index"
    elif xaxis == "j":
        x = J
        xlab = "j-index"
    elif xaxis == "lon":
        x = slon
        xlab = "longitude"
    elif xaxis == "lat":
        x = slat
        xlab = "latitude"
    else:
        logger.warning("xaxis must be i,j,lo,lat or distance")
        x = dist / 1000.
        xlab = "Distance along section[km]"

    # Loop over archive files
    figure = plt.figure()
    ax = figure.add_subplot(111)
    pos = ax.get_position()
    for fcnt, myfile0 in enumerate(files):

        # Remove [ab] ending if present
        m = re.match("(.*)\.[ab]", myfile0)
        if m:
            myfile = m.group(1)
        else:
            myfile = myfile0

        # Add more filetypes if needed. By def we assume archive
        if filetype == "archive":
            i_abfile = abf.ABFileArchv(myfile, "r")
        elif filetype == "restart":
            i_abfile = abf.ABFileRestart(myfile,
                                         "r",
                                         idm=gfile.idm,
                                         jdm=gfile.jdm)
        else:
            raise NotImplementedError("Filetype %s not implemented" % filetype)

        # kdm assumed to be max level in ab file
        kdm = max(i_abfile.fieldlevels)

        # Set up interface and daat arrays
        intfsec = np.zeros((kdm + 1, I.size))
        datasec = np.zeros((kdm + 1, I.size))

        # Loop over layers in file.
        logger.info("File %s" % (myfile))
        for k in range(kdm):
            logger.debug("File %s, layer %03d/%03d" % (myfile, k, kdm))

            # Get 2D fields
            dp2d = i_abfile.read_field(dpname, k + 1)
            data2d = i_abfile.read_field(variable, k + 1)
            dp2d = np.ma.filled(dp2d, 0.) / modeltools.hycom.onem
            data2d = np.ma.filled(data2d, 1e30)

            # Place data into section arrays
            intfsec[k + 1, :] = intfsec[k, :] + dp2d[J, I]
            if k == 0: datasec[k, :] = data2d[J, I]
            datasec[k + 1, :] = data2d[J, I]

        i_maxd = np.argmax(np.abs(intfsec[kdm, :]))

        # Set up section plot
        datasec = np.ma.masked_where(datasec > 0.5 * 1e30, datasec)
        P = plt.pcolormesh(x, -intfsec, datasec, cmap="jet", shading='auto')
        if clim is not None: P.set_clim(clim)

        # Plot layer interfaces
        for k in range(1, kdm + 1):
            if k % 10 == 0:
                PL = ax.plot(x, -intfsec[k, :], "--", color="k", lw=.5)
            elif k % 5 == 0:
                PL = ax.plot(x, -intfsec[k, :], "--", color="k", lw=.5)
            else:
                PL = ax.plot(x, -intfsec[k, :], "--", color=".5", lw=.5)

            textx = x[i_maxd]
            texty = -0.5 * (intfsec[k - 1, i_maxd] + intfsec[k, i_maxd])
            ax.text(textx,
                    texty,
                    str(k),
                    verticalalignment="center",
                    horizontalalignment="center",
                    fontsize=6)
        cb = ax.figure.colorbar(P)
        ax.set_title(myfile)
        ax.set_ylabel(variable)
        ax.set_xlabel(xlab)

        # Print in different y-lims
        suff = os.path.basename(myfile)
        if sectionid: suff = suff + "_" + sectionid
        figure.canvas.print_figure("sec_%s_full_%s.png" % (variable, suff),
                                   dpi=dpi)
        ax.set_ylim(-1000, 0)
        figure.canvas.print_figure("sec_%s_1000m_%s.png" % (variable, suff),
                                   dpi=dpi)
        ax.set_ylim(-300, 0)
        figure.canvas.print_figure("sec_%s_300m_%s.png" % (variable, suff),
                                   dpi=dpi)

        # Close input file
        i_abfile.close()

        #
        ax.clear()
        cb.remove()