def make_model(coor, yr, month, day, period=46, dt=900 ,opt='SUNTANS', images_dir=os.getcwd()+"/images"):
    '''
    Run multiple GNOME;
    yr,month,day---oil spill start time;
    period---oil spill simulation duration;
    dt--oil spill time step in second
    '''    
    
    print "initializing the model"

    base_dir=os.getcwd()
    #start_time = datetime(2014,8,21,0)
    start_time = datetime(yr,month,day,0)
    model = Model(start_time = start_time,
                              duration = timedelta(hours=period),
                              time_step =dt,
                              uncertain = False,
                              )
    
    mapfile = os.path.join(base_dir, './coast.bna')
    print "adding the map"
    gnome_map = MapFromBNA(mapfile, refloat_halflife=6)  # hours
    
    print "adding renderer" 
    model.outputters += Renderer(mapfile, images_dir, size=(1800, 1600))

    
    print "adding a wind mover from a time-series"
    ## this is wind
    wind_file=get_datafile(os.path.join(base_dir, 'wind.WND'))
    wind = Wind(filename=wind_file)
    w_mover = WindMover(wind)
    model.movers += w_mover
    
    print "adding a current mover:"
    ## this is currents
    curr_file = get_datafile(os.path.join(base_dir, 'current_'+opt+'.txt'))
    model.movers += GridCurrentMover(curr_file)

    #model.movers += RandomMover(1000)
    ##
    ## Add some spills (sources of elements)
    ##
    print "adding 13 points in a cluster that has some small initial separation as the source of spill"
    
    for i in range(len(coor)):
        
        xcoor,ycoor=nctools.utmToLatLng(15,coor[i][0],coor[i][1],northernHemisphere=True)
        model.spills += point_line_release_spill(num_elements=1,
                                                start_position = (ycoor,xcoor, 0.0),
                                                release_time = start_time,
                                                )

    print "adding netcdf output"
    netcdf_output_file = os.path.join(base_dir,'GNOME_'+opt+'.nc')
    scripting.remove_netcdf(netcdf_output_file)
    model.outputters += NetCDFOutput(netcdf_output_file, which_data='all')
    
    return model
def duplicate(starttime,endtime,dt):
    """
    
    Traverse the SUNTANS boundary grid to locate the points that ROMS result enters
    and run GNOME
    
    """
    print "Trying to duplicate the oil spill particles at the SUNTANS boundary!!\n"
    base_dir = os.path.dirname(__file__)
    
    try:
        ncfile=Dataset(base_dir+'/CoarseTri/rundata/'+'GalvCoarse_0000.nc','r')
    except IOError:
        print 'No SUNTANS output available'
        
    mark=ncfile.variables['mark'][:]
    xe=ncfile.variables['xe'][:]
    ye=ncfile.variables['ye'][:]

    tide=[] #tide boundary mark
    river=[] #river boundary mark
    for ii in mark:
        if ii==3:
            tide.append(ii)
        if ii==2:
            river.append(ii)

    tide_index=[]
    for ind,mk in enumerate(mark):
        if mk==3:
            tide_index.append(ind)
    ###########Output the cooridinate of SUNTANS open boundary points#########
    open_boundary=[]
    for kk in tide_index:
        open_boundary.append([xe[kk],ye[kk]])
    boundary=[]
    for i in range(len(open_boundary)):
        boundary.append(nctools.utmToLatLng(15,open_boundary[i][0],open_boundary[i][1]))
        
    ###########ROMS output############
    roms_spill=spill_locations('GNOME_ROMS.nc')
    ##################################
    cbp=[]            ###cbp is cross SUNTANS boundary point 
    SUN13=[]
    for nn in range(len(roms_spill)):
        particle=roms_spill[nn]
        for i in range(len(particle)):
            find=False
            for j in range(len(boundary)):                                
                if abs(boundary[j][0]-particle[i][0])<0.0035 \
                and abs(boundary[j][1]-particle[i][1])<0.0035:
                    SUN13.append([boundary[j][0],boundary[j][1]])
                    find=True
                    break
            if find==True:
                cbp.append(i) ###cbp is cross SUNTANS boundary point 
                break     
         
    if SUN13==[]:
        print '#########\n ROMS output particles will not cross SUNTANS boundary!! \n#########'
        print '#########\n check the Google map for details!! \n#########'
        raise RuntimeError('adjust initial locations and time period for GNOME run \
                            or you can change to mode 1 and rerun')
    else:
        print '#########\n %s particles generating at SUNTANS boundary!! \n#########'%str(len(SUN13))
        
    timeformat='%Y-%m-%d'
    SUN_starttime=datetime.strptime(starttime,timeformat)+timedelta(math.floor(min(cbp)/(24*3600./dt))+1)
    SUN_starttime=SUN_starttime.strftime(timeformat) ##SUNTANS starttime before particle cross ROMS boundary
    diff=datetime.strptime(endtime,timeformat)-datetime.strptime(SUN_starttime,timeformat) 
    period=diff.days*24 

    ####running SUNTANS from the SUN_starttime to endtime 
    hydro_wrapper.runSUNTANS(SUN_starttime, endtime) 
    ####generating input of GNOME from SUNTANS output
    infile=base_dir+'/CoarseTri/rundata/'+'GalvCoarse_0000.nc'
    outfile=base_dir+'/GNOME/'+'txsuntans.nc'
    Tx_SUNTANS(infile,outfile)
    
    coor=[]
    for i in range(len(SUN13)):
        coor.append(utm.from_latlon(SUN13[i][0],SUN13[i][1])[0:2])
    
    
    yr=int(SUN_starttime[0:4]);
    #month=int(SUN_starttime[5:7].lstrip("0").replace("0", " "))
    month=int(SUN_starttime[5:7].lstrip('0'))
    #day=int(SUN_starttime[8:].lstrip("0").replace("0", " "))
    day=int(SUN_starttime[8:].lstrip('0'))
    
        
    row1='NetCDF Files'
    row2='[File]    ./txsuntans.nc'
    f=open(os.getcwd()+'/GNOME/'+'current_SUNTANS.txt','w')
    f.write(row1+'\n')
    f.write(row2+'\n')
    f.close()
    
    work_dir=os.getcwd()
    os.chdir(work_dir+'/GNOME/')
    scripting.make_images_dir()         
    pdb.set_trace()
    model = make_model(coor,yr,month,day,period,dt,images_dir=os.getcwd()+"/images")
    wdd=[0.01,0.04]
    model.full_run(wdd,logger=True)
    os.chdir(work_dir) 
def Tx_SUNTANS(infile,outfile):
    """
    step 1: 
    interpolate the data from SUNTANS output to GNOME input
    Input:
        infile='GalvCoarse_0000.nc'
        outfile='txsuntans_example.nc'
    """
    '''
    Sample script to retrieve data from unstructured grid netcdf "file" (can be
    OPeNDAP url), generate necessary grid topology (boundary info), and write 
    GNOME compatible output.
    The boundary file is saved to the data files directory so it only needs 
    to be generated once (unless you are subsetting the grid).
    To process multiple files (urls) either
    a) pass the filenames/urls in as a list -- this creates a netcdf4 MFDataset and is
    a good option for not too many files (all output is written to one nc file for GNOME 
    in this case)
    b) add a file list loop -- in this case put it after the grid topo vars are loaded (as
    this only has to be done once). See NGOFS_multifile_example.py
    '''
    
    data_files_dir=os.path.dirname(__file__)
       
    # specify local file or opendap url 
    data_file = os.path.join(data_files_dir,infile)
    
    # the utools class requires a mapping of specific model variable names (values)
    # to common names (keys) so that the class methods can work with FVCOM, SELFE,
    # and ADCIRC which have different variable names
    # (This seemed easier than finding them by CF long_names etc)
    #!!!!!!!!txsuntans output on server does not include eles_surrounding_ele info
    #I have it saved as a netcdf file included in libgoods data_files directory
    var_map = { 
                'time':'time',\
                'u_velocity':'uc', \
                'v_velocity':'vc', \
                'nodes_surrounding_ele':'cells',\
                'eles_surrounding_ele':'nbe',\
                'edge_node_connectivity':'edges',\
                }  

    # class instantiation creates a netCDF Dataset object as an attribute
    txsuntans = nctools.ugrid(data_file)

    # get longitude, latitude, and time variables
    print 'Downloading data dimensions'
    txsuntans.get_dimensions(var_map)
    
    # UTM coordinates -- calculate lat/lon
    x = txsuntans.Dataset.variables['xp'][:]
    y = txsuntans.Dataset.variables['yp'][:]
    lon = np.ones_like(x); lat = np.ones_like(x)
    for ii in range(len(x)):
        lat[ii], lon[ii] = nctools.utmToLatLng(15,x[ii],y[ii])
    txsuntans.data['lon'] = lon
    txsuntans.data['lat'] = lat
    txsuntans.atts['lon'] = {'long_name': 'longitude'}
    txsuntans.atts['lat'] = {'long_name': 'latitude'}
    
    # get grid topo variables (nbe, nv)
    print 'Downloading grid topo variables'
    txsuntans.get_grid_topo(var_map)

    edge_types = txsuntans.Dataset.variables['mark'][:].tolist()
    #"0 - computational; 1 - closed; 2 flux BC; 3 - stage BC; 4 - other BC; 5 - interproc; 6 - ghost
    #Based on personal communication we use 1,2, and 3
    bound_id, bound_type = zip(*[(i,x) for i,x in enumerate(edge_types) if x>0 and x<4])
    bound_segs = txsuntans.data['edges'][bound_id,:] + 1 #Node numbering starts at 0, GNOME expects it to start at 1 -- adjust nv and bnd
    bound_type_gnome = (np.array(bound_type)<=2).choose(1,0)
    
    txsuntans.order_boundary(bound_segs.tolist(),list(bound_type_gnome))
    txsuntans.atts['bnd'] = {'long_name':'Boundary segment information required for GNOME model'} 
    
    #Node numbering starts at 0, GNOME expects it to start at 1 -- adjust nv and bnd
    txsuntans.data['nv'] = txsuntans.data['nv'] + 1
    
    ## GNOME needs to know whether the elements are ordered clockwise (FVCOM) or counter-clockwise (SELFE)
    txsuntans.atts['nbe']['order'] = 'ccw'

    '''
    !!!!!!!!!!!!!All the stuff above here only has to be done once -- if you want to 
    process multiple files, I'd put a loop here and just keep overwriting 
    txsuntans.data['u'] and ['v'] and incrementing the output file name
    Also need to change txsuntans.data['time'] appropriately
    '''
    # get the data
    print 'Loading u/v'
    txsuntans.get_data(var_map,zindex=0) 
    
    
    print 'Writing to GNOME file'
    txsuntans.write_unstruc_grid(os.path.join(data_files_dir, outfile))
    
    txsuntans.Dataset.close()
示例#4
0
def mul_GNOME_inputs(number,yr,month,day,hr,period):
    
    '''
    Transform multiple SELFE combined binary outputs into GNOME's inputs in NetCDF format;
    number is SELFE number;
    Oil spill starting time: yr,month,day,hr; month is based on 30 days
    Oil spill simulation time period: period (hours)
    
    '''
        
    data_file = os.path.join(base_dir,'169_hvel.nc')
    
    var_map = { 'longitude':'lon', \
                'latitude':'lat', \
                'time':'', \
                'u_velocity':'u', \
                'v_velocity':'v', \
                'nodes_surrounding_ele':'ele',\
                'eles_surrounding_ele':'',\
              }  


    txselfe = utools.ugrid(data_file)

    print 'Downloading data dimensions'

    x = txselfe.Dataset.variables['x'][:]
    y = txselfe.Dataset.variables['y'][:]
    lon = np.ones_like(x); lat = np.ones_like(x)
    for ii in range(len(x)):
        lat[ii], lon[ii] = nctools.utmToLatLng(14,x[ii],y[ii])
    txselfe.data['lon'] = lon
    txselfe.data['lat'] = lat
    txselfe.atts['lon'] = {'long_name': 'longitude'}
    txselfe.atts['lat'] = {'long_name': 'latitude'}
    
    
    # get grid topo variables (nbe, nv)
    print 'Downloading grid topo variables'
    try:
        txselfe.get_grid_topo(var_map)
    except KeyError: #model output on server doesn't have nbe
        txselfe.build_face_face_connectivity()
        
    # GNOME requires boundary info -- this file can be read form data_files directory
    # if saved or generated
    print 'Loading/generating boundary segments'
    bndry_file = os.path.join(base_dir, 'txselfe.bry')
    try:
        txselfe.read_bndry_file(bndry_file)
    except IOError:
        txselfe.write_bndry_file('txselfe',bndry_file)
        txselfe.read_bndry_file(bndry_file)
    txselfe.data['nbe'] = txselfe.data['nbe']
    txselfe.data['nv'] = txselfe.data['nv']
    # GNOME needs to know whether the elements are ordered clockwise (FVCOM) or counter-clockwise (SELFE)
    txselfe.atts['nbe']['order'] = 'ccw'
    
    
    # get the SELFE data
    print 'Loading u/v'

    # specify SELFE output path
    for n in range(number):

        shutil.copy(base_dir+'/txselfe.bry',base_dir+'/'+str(n+1)+'/GNOME')
    
        selfe = pyselfe_v1.Dataset(base_dir+'/'+str(n+1)+'/outputs/169_hvel.64')

        for j in range(period):
    
            model_time = dt.datetime(yr,month+j/720,day+(j/24)%30,hr+j%24,0,0) 
            t_units = 'hours since 2012-01-01 00:00:00'
            txselfe.data['time'] = [date2num(model_time,t_units),]
            txselfe.atts['time'] = {'units':t_units}
        
            num_nodes = len(txselfe.data['lon'])
            txselfe.data['u'] = np.ones([1,num_nodes],)
            txselfe.data['v'] = np.ones([1,num_nodes],)
            txselfe.atts['u'] = {'long_name':'eastward_velocity','units':'m/s'}
            txselfe.atts['v'] = {'long_name':'northward_velocity','units':'m/s'}
    
            [t, t_iter, eta, dp, mdata] = selfe.read_time_series('hvel.64', nfiles=1, sfile=169+j, datadir=base_dir+'/'+str(n+1)+'/outputs/')    
    
            for i in range(num_nodes):
                txselfe.data['u'][0][i]=mdata[0,i,5,0]
                txselfe.data['v'][0][i]=mdata[0,i,5,1]
 
            print 'Writing to GNOME file'
            txselfe.write_unstruc_grid(os.path.join(base_dir, str(n+1)+'/GNOME/'+str(169+j)+'_hvel.nc'))