U Ue3B@sddlTGdddZGdddZddZd8dd Zd d Zd d Zd9ddZGdddZddZ d:ddZ d;d d!Z dd&d'Zd(d)Zd?d*d+Zd,d-Zd@d.d/Zd0d1ZdAd2d3ZdBd5d6Zed7krdS)C)*c@sZeZdZd^ddZd_dd Zd d Zd`ddZddZddZdaddZ dbddZ dcddZ ddZ ddZ dddd Zded!d"Zd#d$Zd%d&Zd'd(Zd)d*Zdfd+d,Zdgd-d.Zdhd/d0Zdid1d2Zdjd4d5Zdkd8d9Zdld;d<Zdmd@dAZdndCdDZdodGdHZdpdJdKZdqdNdOZdPdQZ dRdSZ!drdTdUZ"dsdVdWZ#dtdXdYZ$dZd[Z%d\d]Z&dS)u schism_gridNcCsj|dkr nV|ds|dr*||n6|ds>|drRt|jj|_ntd|||_dS)z Initialize to empty instance if fname is not provided; otherwise, read from three supported file format NZgr3.llz.pklz.npzz#hgrid file format {} not recognized) endswith read_hgridloadzhgrid__dict__copy Exceptionformat source_fileselffnamerO/lfs/h1/nos/estofs/noscrub/IT-stofs.v2.1.0/ush/stofs_3d_atl/pysh/schism_file.py__init__s zschism_grid.__init__r皙?bothTc!Ks|dkr d}|dkrd}|dkr&t}|dkr|jdk}|jdk}|dk|dkBrr|j|ddf}t||dddff}|j|}|j|}t|tt|dgtf}t ||j }t|tt|dgtf}t ||j }|j|ddf}t||dddff}|j|}|j|}t|tt|dgtf}t ||j }t|tt|dgtf}t ||j }|dkr|dkrd}t t ||ft ||f||d}n|d krNt |j||Bddft|j|df|j|d dfff}|dkr|j }n@t||jkr&|j|d }n"t||jkrHtd |j| dkrt|}t||t||}}||kr|d }n| \}}| dkrd} t| dst||t| } tt|dkr|t||jdd}||t|t|dkr`|dkr2t|j|j||f|||d|}|d krt|j|j||f|||d|}n\|dkrt|j|j||f| |||d|}|d krt|j|j||f| |||d|}tj j!|||d|r$|dkr$t"|}||_#| dk r$t| ds|$t||t| n |$| |dkrNt t ||ft ||f||d}||_%| dk rjt&|| d| dk rt&|| dt'()dkrt*j+j,-}t.dd|D}d|krt/|_0d|kr|1d|kr|2|S|dkrt|j|jf|j} t.ddt3| |jD} |dkrLt|dsD|4|j5}n@t||jkrj|j6|d }n"t||jkrtd |j|dk r| |} ||}| dkrt|t|g} |dkrt'j7j8| f|||dd |}nRt'j7j8| f|||| dd!|}|r3__len__axis绽|=)vminvmaxextend)levelsr&r'r()r&r')xlim)ylimqt5aggZqtaggcSsg|] }|qSrZiconText.0irrr osz)schism_grid.plot_grid..bpquerybndcSs<g|]4\}}|dkr4t|dkr4|ddddfn|qS)rrrNlen)r0si34rrrr2wsdpeF)r edgecolor facecolor antialiased)rr<arrayclimr>);gcar:elnodec_xyonessumnanreshapesizeplotr_dpr8neinterp_elem_to_nodenpsysexitr shapeisnanminmaxhasattrlinspaceintabs tricontourf tricontourcmScalarMappableset_climcolorbarhc set_tickshgsetpmpl get_backendlowergcfcanvastoolbaractionsr? schism_bpfiler3query_pt create_bndzip compute_ctrr;interp_node_to_elem collectionsPolyCollectionadd_collectionautoscale_view)!raxmethodfmtr maskecfcrr)ticksr*r+r@r(cbargsfp3fp4trix3y3quadx4y4rcfpnr&r'raacsatsZxy4rrr plot_grids          $ >       " $ $ $                      zschism_grid.plot_gridcKs |jf|S)z' alias for plot_grid() )rrr~rrrrKszschism_grid.plotr?cKs|dkrt|t|dkr$|d}t|ds6|g}t|jD]}t|d|j|f}qDt| d}|dk}|j |}|j |} t ||<t | |<g} t|j D]H}|j|dkrt| d|j|f} qt| d|j||j|df} qt|  d} | dk}|j | } |j | } t | |<t | |<t|| |dfd|i|} t| | |dfd|i|}| |g|_td krtjj}td d |D}d |krt|_d |kr|d|kr|dS)z plot schims grid boundary gd.plot_bnd(): plot bnd gd.plot_bnd(c='rb'): open bnd in red,land bnd in blue Nrrnobr6rYrrr,cSsg|] }|qSrr.r/rrrr2sz(schism_grid.plot_bnd..r3r4r5)scar8rW compute_bndarangerrLiobnr?astyperDrErHnlbislandilbnrKZhbrerfrgrhrirjrkrlr3rmrn)rcrrvr~sindor1rbx1by1sindlbx2by2Zhb1Zhb2rrrrrplot_bndsL   "     zschism_grid.plot_bndcsT||_t|d}||tdddd\|_|_tdddd|jDdj \|_ |_ |_ t d|j|jkrdSd dd|jd|j|jD}td d|Dd}|dddf|_|ddddfd|_d}|t d |j|jkr,dSd|j|jtd|_dg|_g|_t|jD]b}|jtd|jtfd dt|jd Dd|jd qtt|j|_t|jdd|_t |jdkr|jd|_td|_dg|_g|_g|_t|jD]}dd}|jt|dd}|jtfddt|jd Dd|jd t |dkrt|d}|jd d|jd d krd}|j|qPt|j|_t|j|_t|jdd|_t |jdkrP|jd|_dS)NrrrrrYcSsg|]}|ddqS)rrsplitr/rrrr2sz*schism_grid.read_hgrid..floatcSsg|]}|qSrstriprr/rrrr2scSs$g|]}t|dkr|n|dqS)-1)rr7r/rrrr2srcs0g|](}td|ddqSrrrYrrr0rlinesnrrr2sr6Odtype=cs0g|](}td|ddqSrrrrrrr2s)r open readlinescloser?rrrNrPTrDrErMr8r:rB compute_siderYrrnobnrrappendrnlbnrr)rrr~fidfdatar1slineZibtyperrrrsd &4( * *  zschism_grid.read_hgridcCs2t|}t||jkr.td|jt||S)z9 read schism prop, and return the values zcheck dimension: ne={}, prop={})read_schism_propr8rNrQrRr )rrZevirrr read_propszschism_grid.read_propcCsl|dkr|jn|}|jdk}|}t|j}||j|ddfjdd||<||j|jdd||<|S)zf interpolate node values to element values default is self.dp => self.dpe Nrrr#)rMr:zerosrNrBmean)rr rMrrr;rrrrqs  "zschism_grid.interp_node_to_elemrc Cs~t|ds||dkr,t|ds,||dkr:|jn|}||j}|dkr|jdk}|jdd}tt|dkrd||<|jdd|}n||jdd|}|dkr|d||jdk<|jdd}|d kr|d||jdk<|jdd}|dkrzt |j |jd |j |j|j d |j dddf} d| |}d||jdk<|jdd}||jdd|}|S) a interpolate element values to nodes if value not given, dpe is used fmt=0: simple avarage; fmt=1: inverse distance (power=p) fmt=2: maximum of surrounding nodal values fmt=3: minimum of surrounding nodal values nneNr;rr6rr#rr?)rW compute_nnerpr;inerGrTrUrVrZxctryctrrDrE) rr rxpv0vswtwvdistrrrrO s4       <  zschism_grid.interp_elem_to_nodecCst|dr|dkr|t|dr,|dkr4|t|drF|dkrR|jddt|drd|dkrl|t|dr~|dkr|d S) aw compute all geometry information of hgrid by invoking: functions: compute_ctr(),compute_area(),compute_side(fmt=2),compute_nne(),compute_ic3() attrs: (xctr,yctr,dpe),(area),(ns,isidenode,isdel,xcj,ycj,dps,distj),(nne,mnei,indel,ine),(ic3,elside) fmt=0: skip if already attrs are already available; fmt=1: recompute all attrs r;rareadpsrrxric3N)rWrp compute_arearr compute_ic3)rrxrrr compute_all(s zschism_grid.compute_allcCs t|ds|jdk}|}td|jg\|_|_|_|j|j|ddfj dd|j|<|j|j|ddfj dd|j|<|j |j|ddfj dd|j|<|j |j|ddfj dd|j|<|j |j|ddfj dd|j|<|j |j|ddfj dd|j|<|jS)zE compute element center information: (xctr,yctr,dpe) rrNrr#) rWr:rrNrrr;rDrBrrErM)rrrrrrrp5s  &&&&&&zschism_grid.compute_ctrc Cs:|jdddfdk}|j|jdddf}|j|jdddf}|j|jdddf}|j|jdddf}|j|jdddf}|j|jdddf}|j|jdddf}|j|jdddf} ||||<||| |<||||||||||| |||||d|_|jS)Nr6rrrr)rBrDrEr) rfpx1y1x2y2rrrrrrrrCs Fzschism_grid.compute_areacCst|ds|t|ds$||jdddfdk}|}|j|jdddf}|j|jdddf}|j|jdddf}|j|jdddf}|j|jdddf}|j|jdddf} |j|jdddf} |j|jdddf} |j|jdddf} |j|jdddf} |j|jdddf}|j|jdddf}||| |<||||<||||<||| || |||d}| |||| || |d}||| | | || ||d||_| |||| | ||| d||_t |jd|jd|_ ||| |||| |||||||||| |d||}| || |||||| || || |||||d||}t |d|d}|j||d|j|<|j||d|j|<|j ||d|j |<|j |j|d |_ |j |j|d |_ |j |j |d |_|j |j |jfS) aP Compute gradient of gd.dp on each element first, then transfer to nodes with the following options "see details in interp_elem_to_node()": fmt=0: simple avarage; fmt=1: inverse distance; fmt=2: maximum of surrounding nodal values. The default is (0) simple average rr;Nr6rrrr)r rx)rWrrprBrDrErMZdpedxZdpedysqrtZdpedxyrOZdpdxZdpdyZdpdxy)rrxrrrrv1rrv2rrv3rrv4a1a2Zdpedx2Zdpedy2Zdpedxy2rrrcompute_gradientLsH   $$..TTzschism_grid.compute_gradientc Csb|jdk}|j|df|j|df<g}g}tdD]R}|t|jdd|ddf|jdd|ddff|t|jq2t|j}t| dddg t |dg}t |dddddfdk}||}||}d |j|df<t |ddj}t|dd |dd d d \}}} t ||_|dkr<|jS|d kr^t|} || } || |_|| } t|jd } ttt ||}||| | |<| | } t| | f|_| | k| dk}t|j||j|<|dkrNt|j|j|jf|jjddj\|_|_|_tt |j|jddd t |j|jdddddf|_|j|j|jfSdS)z compute side information of schism's hgrid fmt=0: compute ns (# of sides) only fmt=1: compute (ns,isidenode,isdel) fmt=2: compute (ns,isidenode,isdel), and (xcj,ycj,dps,distj) rrr6rNrrr#rT) return_indexreturn_inverserrY) r:rBrrrCrNr?rravel transposerIr8diffsortuniquensargsort isidenoderFr setdiff1disdelfliplrrDrErMrZxcjZycjrrZZdistj)rrxrZsisZsier1rZusissindsindrZsindasindsZse1Zse2rfpsrrrrwsD  >"$     0>zschism_grid.compute_sidecCs\tdt|drt|ds(|jdd|jdddfdk}|j|}|j|dddf}t|}t|d }t|j |d kd}t|j |d kd}t d D]}|d kr|j ||d f} |j ||df}||df|k||df| k} t ||| ||| <q|j ||f} |j |||dd f||<|j |||df||<|dddf|k|dddf| k} t || || <qt t|dddft |} t|d } d} g}g}t| dkr|t| dkdddf}|| |df}||g}d| | |<d| | |<|| |df}d| | |<||krPq^||q&| d} |t||t|qt|}t|d d }tt|}||||}}t|dst|_g}g}|j}t|D](\}}|||t|t|qt|}t|}||_||_t| d |_| |_||_||_|j||_|j ||_ t | D]}|j|j|}t||!kdd}|j|t|d|j|||d|j|g}t"|j||j |dkrjd|j|<qqjt|dsXd|_#tg|_$tgg|_%t|j}|j|_&|j||_'|j||_(|j||_dS)z. compute boundary information zcomputing grid boundariesrrrrNr6rrYrrrrbndinfor))printrWrrrr8rFrnonzeror:rrBrdictrorGrr?flipudrzdatar enumerater(tileriprnbnbnibnrDrErUsignarrrrrr)rrZisnbenbsi2rrr1i1rrZifbrrrZid0idibnirrrSmpxi0sidrrrrs     (        4    zschism_grid.compute_bndcKs |jf|S)z/ alias for compute_node_ball() )compute_node_ballrrrrrszschism_grid.compute_nnec Cstt|jddgj}|j}|dk}||||}}t|}||||}}t|ddd\}}|_|j |_ t |j |j g d |_t|j D],}|j|k}|||}|||j||f<qtddt|j|jDd d |_|jS) aL compute nodal ball information: nne,mnei,indel,ine where: nne: number of elements in nodal ball mnei: maximum number of elements in nodal ball indel: indices for each nodal ball ine: indices for each nodal ball, but in maxtrix " shape=[np,max(nne)]" rrrT)r return_countsrYcSs g|]\}}t|d|qSN)r?r0r1rrrrr2sz1schism_grid.compute_node_ball..rr)rrrNrrrBrrrrVmneirFrPrrr?roindel) relemnoderZunoderr1Zfpesinderrrr s    "zschism_grid.compute_node_ballcCs2t|ds|jddtt|jddgj}|j}|dk}||||}}t|}||||}}t |dd\}}t |j dg d  |_ |j}t|D]}t|j|kd }|j|} |||} || } |j| j\} } t|D]|}|d| |d| }}|j||f| k|j||f| k|j||f| k|j||f| kB}| ||j |||f<qqd|j |jd kdf<t |j dg d  |_t|j }t|D]b}|j|j d d |f}|d d d f|k}||df|j||f<||d f|j||f<qd|j|j dk<|j|j fS) za compute element-to-side table, where elside: element-to-side table rrrrr6TrrrYrrN)rWrrrrrrrrrrFrNrZelsider:rVrrrBr)rsiderrZuelemrZm34r1rr:rsdn1n2rid1id2Zfpkieesrrrrrs>      H  zschism_grid.compute_ic3cCs@t|}t|dgd }t|dg}|dkrt|d }t|}t|ds\|t||t|j |j f}| |||\} } } t| dkr|| ||| <| ||| <| ||| <||dk} || || }}t|dkrt|ds| t|j D]} |j|| f}| |||\} } } t| dkrl|| ||| <| ||| <| ||| <||dk} || || }}t|dkrqqt|dkrt|ds|t||t|j|jf}|dddf||<d ||df<t|jD]} |j|| f}| |||\} } } t| dkrf|| ||| <| ||| <| ||| <| |jd kr||dk|j|| d fdk} || || }}t|dkrqqt|dkd}||||d k}t|dkr6|j||d d \||<||<||<n|d kr6|jjdd}t||j||j|d d }|dk} |j|| || <t|j d kd}t| d}t|dkrt|dkr|j|jtdd dg}t|||j||j|d d }|dk} ||| ||| <|j|| ||| <|dk}t|dkr|j||j\}}}|j||j\}}}||j\}}tt|||ft|||f}tt|||ft|||f}tt|||ft|||f}t||||d |||f||<t|dkr6t||t|j|jf}|dddf||<d ||df<|||fS) aL compute acor coodinate for points pxy[npt,2] usage: ie,ip,acor=compute_acor(c_[xi,yi]), where xi and yi are array of coordinates outputs: ie[npt],ip[npt,3],acor[npt,3] ie: the element number ip: the nodal indices of the ie acor: the area coordinate fmt=0: (default) faster method by searching the neighbors of elements and nodes fmt=1: slower method using point-wise comparison Note: for interpolation of few pts on a large grid, fmt=1 can be faster than fmt=0 rrYrrr6rrNrrrr)r8rFrrrrWrpnear_ptsrCrr inside_elemrr:rVrrrDrErrr inside_grid compute_acorrBrinside_polygonr?rGr)rpxyrxnptpippacorpiesindprrsipZsacorrr1rZsindnsind4Zsind2Zpie2rrrrrrrrDrEA1A2Arrrr s             " (  &zschism_grid.compute_acorcCs\|dkr|jn|}t||jkr,|j|d}|j||ddd\}}|j||jddS)a interpolate to get value at pxy pxy: c_[x,y] value=None: gd.dp is used; value: array of [np,] or [ne,] fmt=0: (default) faster method by searching the neighbors of elements and nodes fmt=1: slower method using point-wise comparison Note: for interpolation of few pts on a large grid, fmt=1 can be faster than fmt=0 Nrrrr#)rMr8rNrOrrG)rr!r rxvir#r$rrrinterpVs  zschism_grid.interpcKsl|dkr dtj|jd}|ds>|ds>|drN|j|f|nt}||_t ||f|dS)a save hgrid as (*.npz, *.pkl, *.gr3, *.ll or *.ic) examples: 1). gd.save('grid.npz') or gd.save('grid') 2). gd.save('grid.pkl') 3). gd.save('hgrid.gr3') or gd.save('hgrid.ll') or gd.save('temp.ic',value=5) Nz{}.npzrz.gr3rz.ic) r ospathsplitextr r write_hgridrrsavez)rrr~r9rrrsavehszschism_grid.savec Cs|dkr|j}nt|dr |}nt|j|}|dkr:d}t|dD}|d||d|j|jt|jD].} |d| d|j | |j | || qx|dkrHt|jD]} |j | d kr|d j| d|j | f|j | ddfd|j | d kr|d j| d|j | f|j | ddfdq|dkrh|dkrh|j |d |dk r|t|dW5QRXdS)aL write *.gr3 file fname: file name value: depth value to be outputted value=const: uniform value in space value=dp[np]: specify depth value value=None: grid's default depth self.dp is used fmt=0: not output grid boundary info.; fmt=1: output grid boundary info. elnode=1: output grid connectivity; elnode=0: not output grid connectivity bndfile=filepath: if bndfile is not None, append it at the end of file Info: annotation of the gr3 file Nr"rw+z !grd info:{} {} {} z{:.z{} = number of land boundaries z){} = Total number of land boundary nodes rz-{} {} = Number of nodes for land boundary {} z/{} {} = Number of nodes for island boundary {} cSsg|]}d|dqSr;r<rrrrr2s)rWrrr6r rrYrGrrr8rrrrrr)rrrbidr1Znlnrrrr7s$ &( zschism_grid.write_bnd schism.prop{:8.5f}cCs|dkr&t|ds||j}nt|dr6|}nt|j|}d|krV|d}d|d|j}ttd|jd|gd d j }t |d }| |j | |dS) a write schism prop file. fname: file name value: prop value; 1). if value=None, self.dpe is outputed. 2). value=const 3). value=array[gd.ne] fmt: output format of prop value Nr;r"drYz{:d} z rrrr4)rWrpr;r rFrNrr?rangerrr8r rr)rrr rxZpvifstrfvalrrrr write_props      zschism_grid.write_prop hgrid.2dmc Csg}|dt|jD]p}|j|dkrV|dj|df|j|ddfd|j|dkr|dj|df|j|dqt|jD]0}|d|d|j||j||j |qt |d }| || dS) z9 convert grid to *.2dm format and save zMESH2D rzE3T {} {} {} {} 1 rNrzE4Q {} {} {} {} {} 1 zND {} {:.8f} {:.8f} {:.8f} r4) rrrNr:r rBrPrDrErMrr8r)rrrr1rrrrgrd2smss ,&. zschism_grid.grd2sms<xnew.gr3cCst|ds||||j}|j|j|ddf}|j|j|ddf}tdD]}t|ddd}|} t|dd} |dd|f} |dd| f} |dd| f} |dd|f}|dd| f}|dd| f}t| | d||t| | d||}t| | d||t| | d||}t| | d||t| | d||}t|dt dd}t|dt dd}t|dt dd}t |||f}|j dd|j dd}|d kr|}qTt ||f}qTt |ddd f|ddd f|dddf|ddd f}|j}t|j}t|jt|dgd fd |_t|D]}|j|}|j|ddf}||d krt|d dd gd f|j|ddf<d |j|<t|d d d gd f|j||ddf<nVt|dd d gd f|j|ddf<d |j|<t|d d dgd f|j||ddf<qr|||_t|jt|d fd |_|jd |_||dS)z 1). split the quads that have angle (angle_max), add append the connectivity in the end 2). output a new grid "fname" index_bad_quadNrrrhr#rrrrYr)rW check_quadsrJrDrBrErmodanglepirCrVrUsignrNr8rLrFrr r:r1)r angle_min angle_maxrqindrDrEr1rrid3rrrrrrrra3aAir+flagrNZneaindZndsrrr split_quadssX 000 D "  $ *$ , zschism_grid.split_quads bad_quad.bpcCst|jdkd}|j|j|ddf}|j|j|ddf}g}tdD]}t|ddd} |} t|dd} |dd| f} |dd| f} |dd| f}|dd| f}|dd| f}|dd| f}t| | d||t|| d||}||dt qNt |j }t|dd}tdD]f}|dkrr|dd|f|k|dd|f|kB}n,||dd|f|kB|dd|f|kB}q:|t|d|_ t |ds||j|j }|j|j }t}t||_||_||_t|j|_||dS) z 1). check the quality of quads, violation when internal angle < angle_min, or >angle_max 2). the locations of bad quads are saved in file "fname" rrNrrrKrLr)rr:rDrBrErrNrOrrPr?rrJrWrprrrlr8nstarz write_bpfile)rrRrSrrTrDrErWr1rrrUrrrrrrairqxiqyisbprrrrMsB 0   *0    zschism_grid.check_quadsr cGsbt|ds|t|ds$||j|j}|j|j}|t||df|||ddS)NrJr.)rms)rWrMrprrJrrrK)rrrfr~rarbrrrplot_bad_quads9s   zschism_grid.plot_bad_quads epsg:4326c Cs<|dks|dkr|j}|j}t||||||d\}}||gS)a transform the projection of schism grid's coordinates Inputs: prj0: projection name of schism grid prj1: target projection name; default is 'epsg:4326' x,y: values of grid coordiantes; default is (gd.x, gd.y) lon0,lat0: lon&lat of cpp projection center; needed only if 'cpp' in [prj0,prj1] if ("ll"=>"cpp") and (lon0 or lat0 is not provided): lon0=mean(x); lat0=mean(y) N)prj0prj1rDrElon0lat0)rDrEproj) rrirjrDrErkrlrrrrrrmDs zschism_grid.projskew_element.bpc!Cst|ds||jdk}|j|j|ddf}|j|j|ddf}|j|}|j|}|j|} g} t dD]} | } | dd} | dd}|dd| f}|dd| f}|dd|f}|dd| f}|dd| f}|dd|f}t t ||d||t ||d||dt }t ||kd}t|dkrv| |qvt| } t| dkr|| }|| }| | }| }n tg}tg}tg}tg}|jd k}|j|j|ddf}|j|j|ddf}|j|}|j|}|j|} g} t d D]} | } | dd } | dd }|dd| f}|dd| f}|dd|f}|dd| f}|dd| f}|dd|f}t t ||d||t ||d||dt }t ||kd}t|dkr| |qt| } t| dkr2|| }|| }| | }| }n tg}tg}tg}tg}|dk rt||f|_t||f|_t||f}t} t|j| _|j| _|j| _|| _| ||dkrt||d SdS) a 1) check schism grid's skewness with angle<=angle_min 2) the locations of skew elements are (xskew,yskew), and also save in file "fname" Inputs: angle_min: skew element if one of element's internal angles is smaller than angle_min fname=None: not save skew_element.bp; fname!=None: save skew_element.bp fmt=1: return indices of skew elements r;rNrrrrKrrrY)rWrpr:rDrBrErrr;rrZrOrPrr8r(r?r rLZxskewZyskewrlr]r^r_r)!rrRrrxrrDrErrZzctrrr1rrrUrrrrrrr`sindiZXS3ZYS3ZZS3Zsind3ZXS4ZYS4ZZS4r(Zzskewrcrrrcheck_skew_elemsRs     <      <     zschism_grid.check_skew_elemscCs(g}g}g}t|jdD]}|dkrl|j|ddf}|j|j\}} } |j|j\} } } |j\}}|dkr||j|dk}t|d}|j||ddtdddgf}|j|j\}} } |j|j\} } } ||j\}}t t || | ft | | | f}t t || | ft || | f}t t ||| ft | || f}t t || |ft | | |f}|dk|dk|dk}||||}||||}t |t j st|g}|dkr|t|d|dkr|||||||t ||d||fqt|t|t|fS)z check whether pts are inside elements, then compute area coordinates for pts in elements pxy: c_[x,y] ie: array of element indices corresponding to each pt rrNrrr)rr:rVrBrDrrErr?rrC isinstancerPndarrayr()rr!rrr#r$r1rrrrrrrxiyirfprrA0r)r*ZA3Zac1Zac2rrrrs@  $   zschism_grid.inside_elemcCst|}t|}t|ds"|t|jds6|t|jjD]b}|jj|}t|||j||j |dk}|jj |dkr||n||}t|dkrBqqBt | d}d||<|S)z check whether pts are inside grid usage: sind=gd.inside_grid(pxy) sind=0: outside; sind=1: inside rrrrrY) r8rrWrrrrr rDrErrr)rr!r"r&r1Zfpbrrrrrrs   " zschism_grid.inside_gridcCst|_d|j_tgggj}t|jD]B}|j|}t|j ||j |f}t |dt dd}t ||f}q(t|jD]X}|j|}t|j ||j |f}|j|dkrt|}t |dt dd}t ||f}qv||j_t||j_t||jdS)NPOLYLINErr#r)rZshp_bndtyper?rrrrrCrDrEinsertrHrLrrrclose_data_loopxy get_prj_fileprjwrite_shapefile_data)rrr~r|r1rZxyirrrwrite_shapefile_bnds$   zschism_grid.write_shapefile_bndcCs\t|_d|j_t|j|jf|j_dg|j_t|j d|j_ t ||j_ t ||jdS)NPOINTZid_noder)rZshp_noderyrCrDrEr|attnamerrPattvaluer}r~rrrr~rrrwrite_shapefile_nodes  z schism_grid.write_shapefile_nodecCs>t|_d|j_|j}|dddfdk}||df||df<t|}tdD]r}t|j|dd|f|j|dd|ff}|dkr|dddddf}qNt||dddddff}qNt |dddg}t |j  d|j_ t|j D]}|||jj |<qdg|j_t|j d|j_t||j_t||jdS) NPOLYGONr6rrrrrZid_elem)rZshp_elemryrBrrrCrDrErrrNrr|rrr}r~r)rrr~rBrr1rr|rrrwrite_shapefile_elements& 0   z#schism_grid.write_shapefile_elementcsfdd}fddfddfddtjjd krTtjj}t d d |D}d |kr|t |d kd d ntjj d }t dst _jg_g_g_d _g_d _g_d _g_g_|j|tjd S)z: create open and land boundaries for grid cstjd_tds$tdsDfddjD_tjj }t dd|D}|t |dkdd}| s| tjdS) Nbutton_press_eventrhb0c s@g|]8}tjt||dfjt||dfdddqS)rbr)r)rKrDrLrEr/rrrr2szCschism_grid.create_bnd..connect_actions..cSsg|] }|qSrr.r/rrrr2sPanr)rhri mpl_connectcidbndrWrrrrjrkr?r isCheckedtriggerdrawrrac)ronclickrrrconnect_actionss  z/schism_grid.create_bnd..connect_actionsc s4t|j}t|j}|j}|j}|dkr:|dkr:|||dkrT|dkrT|||dkr0|dkr0jddkrtddSjjkrj d}t j |j dkdd}jd_t j ||dj |df}j|tj|j|d}j|j_tjdd _td d jD_ttjttj } jt| _tjfd d | Ddd _td d jD_t tdjtdt| f_tj j!tjj"#} tdd | D} | t | dkdd} | $r$| %tj&dS)Nrrrz!open boundary needs to be definedr6rg-rrcSsg|] }t|qSrr7r/rrrr2sz;schism_grid.create_bnd..onclick..csg|]}j|qSr)rr/rrrr2scSsg|] }t|qSrr7r/rrrr2scSsg|] }|qSrr.r/rrrr2sr)'rYdblclickbuttonxdataydatar"rrrr=rrptrLrrrKrDrEhlbr?rrrrrr8rrrrhrimpl_disconnectrrjrkrrr) spdlkbtnbxbyr=pidrrr rrr)radd_pt remove_ptrrrrsF     $  "  z'schism_grid.create_bnd..onclickc sttj|dj|}t||kdd}j|}j|}tj||kdd}j dkrΈj d}tj|j dkdd}j ddkr||krdSj ddkr||krdS|j krt j||dj|d|fj|<j |j |j d_ tj|j|d} j | j ddkrjd_j|||d} j | tj| j| d} j | j dkr*j ddkr*||kr*jd_j|||d} j | tj| j| d} j | j dkr||krĈjd_t j||dj|df} j | tjt | j|dfjt | j|dfd} j | tjdS) Nrrr6rrrozr-r)squeezerZrDrErrUrrrr"r=rrLrrKhprrhobrrrrhrir) rDrEdistpr rr=rZbid0Zpid0rrrr)rrrrrsL     .     &    $ < z&schism_grid.create_bnd..add_ptcs,jdkrdSjd}tj|jdkdd}jddjjjjd_jddkrjddjj d_ j j j ksj j krjddkrjdkrj ddj j j d_ tjdS)Nrr6rr)r"r=rrrrremovepoprrrrrrrhrir)rDrEr=rrrrr#s(    6 z)schism_grid.create_bnd..remove_ptNcSsg|] }|qSrr.r/rrrr24sz*schism_grid.create_bnd..r5rr)re_pylab_helpersGcf get_activerrhrirjrkr?r addActionrWrrrrrrrrrr"rr= triggeredconnectr)rrrrZabnr)rrrrrrrns0 0  zschism_grid.create_bndcszfdd}fddtjj}tdd|D}d|krZ|t|dkddntjjd}|j|d S) z1 add function for querying depth cstjd_dS)Nr)rhrircidqueryrrrrrrCsz-schism_grid.query_pt..connect_actionscst|j}t|j}|j}|j}|dkr|dkrtjj}t dd|D}|t |dkdd}t |dr|j j dkrdStt|j j|d|j j|}t ||kdd} t|j j| |j j| f\} } } j| | } td| nr|dkr\|dkr\t||f\} } } j| | } td | n$|dkr|d krtjjdS) NrrcSsg|] }|qSrr.r/rrrr2Isz9schism_grid.query_pt..onclick..r3rzquery: bp depth= {}rzquery: depth= {}r)rYrrrrrhrirjrkr?rrWr3r]rrZrDrErUrrCrMrGrr rr)rrrrrrrrrr r%r#r$pzirrrrFs,   $(z%schism_grid.query_pt..onclickcSsg|] }|qSrr.r/rrrr2Usz(schism_grid.query_pt..r4rN) rhrirjrkr?rrrr)rrrrabprrrrm?s  0zschism_grid.query_pt)N)NrrNNNNrNNNNNrT)rrN)N)Nrr)r)r)r)r)Nr)N)NrrNN)r:N)r>Nr?)rE)rGrHrI)rGrHr\)rrd)rhNNNN)rnror)rh)rh)rh)'__name__ __module__ __qualname__rrrKrrrrqrOrrprrrrrr rrr-r3r1r7rDrFr[rMrgrmrqrrrrrrnrmrrrrrs\    (+   + $6 J   '   5 "  3  _rc@sneZdZddZddZdddZdd Zd d Zdd d ZdddZ d ddZ d!ddZ ddZ ddZ dS)"rlcCsBd|_tg|_tg|_tg|_g|_g|_g|_|dS)Nr) r]r?rDrEr^stationrhteditrrrrr[s zschism_bpfile.__init__cCs|j|dddSNrr) read_bpfilerrrrread_reg`szschism_bpfile.read_regrcsddt|dD}ddt|dddD}|dkrt|dd|_|jdkr`dSdd tfd d|dd|jD}|dddft|_|dddft|_|ddd ft|_ n|dkrPt|dd|_|jdkrdSt t|d dgd }|dddf|_|dddf|_t |j|_ n t d t||jkrvt||_ntddt|jD|_dS)NcSsg|]}|qSrrr/rrrr2esz-schism_bpfile.read_bpfile..rcSs&g|]}d|kr|ddqS)!r6rr/rrrr2fsrrrcSs.t|dkr|S|dd|dddfS)Nrrr7)rDrrrjz+schism_bpfile.read_bpfile..csg|] }|qSrr)r0liner{rrr2ksrrz unknow formatcSsg|]}d|qS){}r<r/rrrr2~s)rrrYr]r?rrrDrEr^rrrQrRr8rr)rrrxrstationsdatarrrrcs.  $    zschism_bpfile.read_bpfilecCs,|dr|j|ddn|j|dddS)zo If fname.endswith('reg'), save points as ACE/gredit *.reg file. Otherwise, save as *.bp file z.regrrrN)rr_rrrrr3s zschism_bpfile.savecCs|j|dddSr)r_rrrr write_regszschism_bpfile.write_regc Cs t|d}t|dr&|d|j|dkr@|d|j|dkrZ|d|jdd t|jD}t|d rt|j|jkr|j}t|jD]d}|dkr|d |d|j ||j ||j ||||dkr|d |j ||j |q| d S)z^ fmt=0: write ACE/gredit *.bp file fmt=1: write ACE/gredit *.reg file r4notezACE/gredit: {}rzbpfile in ACE/gredit format {} rz#Region in ACE/gredit format 1 {} 1 cSsg|] }|dqSrrr/rrrr2sz.schism_bpfile.write_bpfile..rz"{:.connect_actions..rz>double click: left=add pt, right=remove pt; middle=finish editzsingle click: middle=move pt)rhrircidmovecidpressr]r8rrrjrkr?rrrrrr)ronmoverrrrs z+schism_bpfile.edit..connect_actionscsH|jdk rDt|j}t|j}|j}|j}|dkrD|dkrD||dS)Nrr)rrYrrr)rrrrr)move_ptrrrs  z"schism_bpfile.edit..onmovecst|j}t|j}|j}|j}|dkr:|dkr:|||dkrT|dkrT|||dkr|dkrtjjtjj tjj }t dd|D}|t |dkdd}|r|tjdS)NrrrcSsg|] }|qSrr.r/rrrr2sz7schism_bpfile.edit..onclick..rr)rYrrrrrhrirrrrjrkr?rrrr)rrrrrrrr)rrrrrrs"   z#schism_bpfile.edit..onclickc s$jd_jdjf_tj|f_tj|f_tjdf_tjdkrjdd}j d}| }| }| }| }|}|} | } nd}d}d}d }d }d } d} t||||||d } j| t||jd| || d } j | tjdS)Nrrgrr6rre@r normalr markersizerrrfontsize fontweight)r]rr rLrDrEr^r8rr get_color get_markerget_markersize get_linestyle get_fontsizeget_fontweightrKrrrhrir) rDrErrrmkrfrfsfwr{rrrrrrs6     z"schism_bpfile.edit..add_ptc sjdkrdSttj|dj|}t||kdd}d}d}d}d}d}d} d} t|jD]} | jd krjd d j d  jd =j d =qnj| d } j| d } | j| <| j| <d | d j | <j| d j |  t | | ||||d }|j| <t| | j | | || d }|j | <qnjdd _jdd _jdd _j dd _ jd _tjdS)Nrrrrerrrrrr6rrr)r]rrZrDrErrUrrrrr rrKrr^rhrir)rDrErr rrrfrrrr{r1rtrurrrrrrsD       z%schism_bpfile.edit..remove_ptc sttj|dj|}t||kdd}d}d}d}d}d}d} d} |j|<|j|<j|dj|t ||||||d } | j|<t ||j || || d } | j|<t j dS) Nrrrrerrrrrr)rrZrDrErrUrrrrKrrrhrir) rtrurr rrrfrrrr{rrrrrrs$    z#schism_bpfile.edit..move_ptcSsg|] }|qSrr.r/rrrr2sz&schism_bpfile.edit..r3rr6)rerrrrhrirjrkr?rrrWr3r8rrrrr disconnectrr)rrrrrZnhpr1r)rrrrrrrrs*    0      zschism_bpfile.edit)r)r)r)rh)NrreNTr)rrrrrrr3rr_rrrrrrrrrrlZs    rlcCst}|||Sr )rr)rrrrrread_schism_hgrid-s rcCst}|j||d|S)zM read schism *bp (fmt=0) or *.reg (fmt=1) file created by ACE/gredit r)rlr)rrxr3rrrread_schism_bpfile2srcCsBt|}|jdkr"|dddfn|dddfdddf}|S)zH read schism *.prop file (element based), and return the values rNr)loadtxtndim)rZpdatapvaluerrrr:s6rcCs t|ddS)z6 read schism *.reg file created by ACE/gredit rr)r)rrrrread_schism_regBsrgridrec Csd|}d|}d|}t}tj|r|t|}tj|r^t|}|j|j|_|_ |dkrv| | ||_ tj|rt ||_t|dst|dstd||t|||S)z read and save path/{hgrid.gr3,hgrid.ll,vgrid.in} fname: save name path: directory whether grids exist fmt=0: not save grid's full geometry; fmt=1: save z {}/hgrid.gr3z {}/hgrid.llz {}/vgrid.inrrvgridznot found: {}, {})r rr.r/existsrrDrElonlatrrrread_schism_vgridrrWrQrRr2) rr/rxgnameZgname_llZvnamerrZgdlrrrsave_schism_gridHs&      rc@s0eZdZddZddZd ddZd d d ZdS) schism_vgridcCsdSr rrrrrr\szschism_vgrid.__init__c Cst|d}|}|t|dd|_t|dd|_|jdkr^|dd}t|d d}| dkrtdd|D|_ t |j |_ t|j |jg |_t|D]:\}}t|dd d|j||j |df<qnV| d}|d|_ t ||_ td d|ddDj d|_|jd k}d |j|<n,|jdkr|ddd \|_|_t|j|_t|j|_g|_d}t|jD]*}|d}|j||dqt|j d|_g|_|d}|j|jd|_t||dd  d\|_|_|_t|jD]*}|d}|j||dqLt|j d|_|jS) NrrrrrcSs g|]}t|ddqSr)rYrr/rrrr2hsz+schism_vgrid.read_vgrid..rYcSsg|]}|ddqS)rNrr/rrrr2nsr6r)rrrrYrrivcornvrtr?rrUkbpr8rPrFsigmarrkzh_srztotrrZnsigh_ctheta_btheta_f) rrrrrr1rZfpmZirecrrr read_vgrid_sN    6 $    . zschism_vgrid.read_vgridrNc Cs|jdkrD|dkr(t|j||||jdS|dkrt|||||dSnD|jdkrt|j|||d|d|d\}}|dkrx|S|dkr||gSdS)a compute schism zcor (ivcor=1) dp: depth at nodes (dim=[np] or [1]) eta: surface elevation (dim=[np] or [1]) fmt: output format of zcor fmt=0: bottom depths byeond kbp are extended fmt=1: bottom depths byeond kbp are nan method=1 and ivcor=1: used for computing zcor for subset of nodes (need sigma,kbp) method=1 and ivcor=2: return zcor and kbp ifix=1 and ivcor=2: using traditional sigma in shallow if error raise rr)etarxrr)rrxrvdrwifixN)r compute_zcorrr) rrMrrxrwrrrzcorrrrrs  zschism_vgrid.compute_zcorvgrid.inc s|jdkrB|j|j|j|jf\}}}}t|ddt ||||dkrt |D]}d||d||f<qddd|d |d}j|d d |d |j }fd d t |Dnb|dkr8t t ||D]H\}\}}dd||d j|d|df||dqn|jdkrt|ddd|j|j|jt |jD] \}} d|d| qd|j|j|jt |jD] \}} d|d| q̈ntd|jdS)z write schism vertical grid fmt=0: write vgrid.in in latest format of ivcor=1 (one line per lelvel) fmt=1: write vgrid.in in old format of ivcor=1 (one line per node) rr4z"1 !average # of layers={} {} riNz z {:10d} z{:8d}z {:10.6f}cs*g|]"\}}j|df|qSr)r6r r rrBrrr2sz,schism_vgrid.write_vgrid..z {:9d} {:3d}z {:11.6f}rz 2 !ivcor z"{} {} {} !nvrt, kz, h_s Z levels r5z)S levels {} {} {} !h_c, theta_b, theta_f z {} {:9.6f} zunknow ivcor={})rrrPrr rrr6r rrrrrorrr r r r r rQrR) rrrxrrPrrr1rZzlevelZslevelrrr write_vgrids: $   *    zschism_vgrid.write_vgrid)rrrNNr)rr)rrrrrrrrrrrr[s% rcCst}|||S)z' read schism vgrid information )rr)rrrrrrs rNrc Cs|dkr|jd} t|ds(t| |}t|ds>t| |}|dkrXtdd|D}||} | dddf||dddf} | dk} || dddf | | <|dkrt| D]} t| | d|| f<q| S|dkrt|dsd} t|g}nt|} t|dst| |}t|j| gt} d|jt |j |j t |j |jt |j |j dt |j ddt |j d}| }||jk}|j||<||jk}|j dddf||dddf||dddf||dddf| |jdd|f<||j ||j|j t |j k}t|dkr|dkr^td |j|dkrJ||dddf||dddf||dddf|j dddf| |jdd|f<nx||dddfd|j dddf|j|j dddf|dddf|||j| |jdd|f<t| d  }|jd|||jk<||jk} t| d}|D]} td|jdD]B}||  |j|k||  |j|dkr||| <qq|| d krtd n:|| dks|| |jdkr4td || |j||  | || | f<t|| d|jdD]}|j|| || f<qbq| j} ||_|dkrt| D]&} | | || f| | d|| f<q|dkr| S|dkr| |gSdS)a# compute schism zcor (ivcor=1) sigma: sigma cooridinate (dim=[np,nvrt]) dp: depth at nodes (dim=[np] or [1]) eta: surface elevation (dim=[np] or [1]) fmt: output format of zcor fmt=0: bottom depths byeond kbp are extended fmt=1: bottom depths byeond kbp are nan kbp: index of bottom layer (not necessary, just to speed up if provided for ivcor=1) method=1 and ivcor=2: return zcor and kbp ifix=1 and ivcor=2: using traditional sigma in shallow if error raise rrr"NcSs(g|] }tt|ddkddqS)rr%rr6)rrZr/rrrr2sz compute_zcor..rrzPls choose a larger h_c: {}rYr6z$can not find a bottom level for nodezimpossible kbp,kz: {}, {})rSrWrFr?rrHr8rr sinhr rtanhr r r rrGrQrRr rrr rr)rrMrrxrrrrwrrPhwrfpzr1csZhmodrrZfpcrrrrrrs   $     "8  `&  jx .  "  $  rrrr.r?cCst}|||_|_|dkrt|drHt|||d |_|_|_nd|g| |_|_|_||||_|_ |_ t dd|d|j|_ | |n tddS)a+ create schism vertical grid: fname: name of the grid nvrt: number of vertical layers ivcor=2: SZ grid zlevels: 1). Z levels or 2). single number for h_s h_c, theta_b, theta_f: strench constants for sigma grid ivcor=1: LCS^2 grid rr"r6rrz ivcor=1 option not available yetN)rrrrWr8rr r r r r rXrrrQrR)rrrZzlevelsr r r rrrrcreate_schism_vgrids  " rc3 Cs2t|dr4t|dr4||j }t|j|jf}n>t|tjrht|tjrh|j dkrr|dddf}n t dt |}|j d} t|dst d|j} ||j } |j||d\} } }| | |djdd } t| ddd f| dgj}||k}||||<t| ddd f| dgj}||k}||||<d}t|tjrVd d|ggn dt ||g\}}}d d |D}dd |D}|dkrtt|}|dkrtt|}t|d}t|d}g}d}g}tt|||D]v\}\}}}t||jkd }t||jkd }t|| kd }||d krt |dkrV|d ||<t |d kr~t |dkr~|d ||<t |d krt |d krd ||<t |dkrt |dkrt d|d||j|j||d kr@t |dkr|d ||<t |d krd ||<t |dkr@t d|d|| ||d kr||d kr||||ftt|||||g}n@||d kr||d kr||ftt|||g}nd}|||dk r||||<|||||<||d kr||d |jkrt|ds0| |dkrP|j!d k}|jdd } |"}!| "}"t|dD]}#t#|!dd }!t#|"dd }"ql|!|||j!jdd |"||<||"}$||d kr||$d <||d kr| |$d<t$|$}%||d krV|"}&t|dD]}#t#|&dd }&q||| |&jdd ||<||d krV||}%||%qt|jD]d\}'}(t| D]N}#| ddt%| d|#df| dd|#f})}*|#| dkr|(|)k}t$t|}+n0|(|)k|(|*k}|(||)||*||)|}+t|d krqtt|||||D]\}\}}}},}-|,d ks0|-d krZq0||t%| d|#df|||#f}.}/|+"}0t|dD]}1t#|0dd }0q|.d|0|/|0||||'f<q0qqntt||D]6\}\}%}|dkrqt&|}2|||2||<q|d kr.|d }|S)aH 3D interpolation for multiple variables; interplation only for the variables with a dimension of ne or np (gd, vd): (hgrid,vgrid) from save_schism_grid (pxy, pz): (c_[x,y], z[:,:]) or (hgrid,vgrid) from save_schism_grid values: list of np.array, or np.array pind: indice of ne/np dimension for each variable; use -1 to skip interpolation of the variables zind: indice of nvrt dimension for each variable; use -1 to skip the vertical dimension fmt=0: higher efficency for many pts; fmt=1: higher efficency for fewer pts rMrrNzM(pxy,pz) should be either (schism_grid, schism_vgrid) or (np.array, np.array)z$vgrid should a "schism_vgrid" objectr).Nr#r6rcSsg|]}t|jqSr)r?rSr/rrrr2Gsz$interp_schism_3d..cSsg|] }t|qSrr7r/rrrr2GsrYz=need "pind" for np/ne in {}th variable: dims={}, np={}, ne={}z8need "zind" for nvrt in {}th variable: dims={}, nvrt={} rr)'rWrrMrCrDrErrrPrsrrQrRr8rSrrrGrrrHrFr?rrrorrNr rrrrrrr expand_dimsrrUr)3rrr!ZpzvaluespindZzindrxr"nzrrr%r#r$ZzmrZilstnvardimsndimsZtindZw0Zpvaluesr1r dsrr&rZsindkrZtw0rrrZdsnrrrrz1z2Zratzrizrrratrrrrrinterp_schism_3d's       .      ,   "   " 0 &(,  r,cCstd|dd\}}d||}t}tt|dd|_ |dkr|j dd\|_ |_ |_ |_ |_|_|j dd|_n td |S) z get global information about schism run (ne,ns,np,nvrt,nproc,ntracers,ntrs) dirpath: run directory or outputs directory fmt=0: default is 0; fmt(!=0) are for eariler schism versions rr)dirpathrxz{}/local_to_global_{}rrYNrz fmt unknown)srankr rr?rreadlinerrrinforrNrPrnprocZntracersZntrsrQrR)r-rxZrstrbdirrrrrrgetglobs "& r3cCsd}d}tjd|r0tj|}d|}tjd|r^tjd|}d|}tjd|rtj|}d|}tjd |rtjd|}d|}|d kr|S|d kr||gSdS) z return string of schism rank number ('0032', or '000032') dirpath: run directory, or RUN*/outputs fmt=0: return rank string; fmt=1: return rank string and the location dir. Nz{}/local_to_global_0000z{:04}z{}/outputs/local_to_global_0000z {}/outputs/z{}/local_to_global_000000z{:06}z!{}/outputs/local_to_global_000000rr)r.r/rr abspath)rankr-rxr2Zstr_rankrrrr.s$    r.c Cst|ddd}t}t|d}t||d}t|||d}tdd|d|dDdddfdd|_td d||d||dDdddfdd|_td d|||d |||d Ddddfdd|_ t |||d t |D]V}|| }t |dkrRq,t|d|kr,t|d|kr,|}qq,td d|||d|||dDd} | dddfd} | ddddfdd} |||| | f\|_ |_|_|_|_|S) z+ read schism partition information rrNrrcSsg|]}|qSrrr/rrrr2sz/read_schism_local_to_global..rYcSsg|]}|qSrrr/rrrr2scSsg|]}|qSrrr/rrrr2srcSs8g|]0}t|dkr$|n|dqS)rnr)r)r8rrr/rrrr2s)rrrrYrr?rZielgZiplgZislgrr8rrNrPrr:rB) rrrrNrPrr1rndslinesr:rBrrrread_schism_local_to_globals(6>F$ 4"r9cCst|d}dd|D}|dd|D}i}|D]|}d|krX|d|d}|d\}}|}|}|dkr|d d d drd |krt |nt |}|||<q:|S) z read schism parameters from param.nml/param.in/cosine.in fmt=0: return all field as string; fmt=1: return field as float if possible rcSsg|] }|qSr)rr/rrrr2sz%read_schism_param..cSs8g|]0}d|kr|dkr|ddkr|ddkr|qS)rr4rr&rr/rrrr2s  rNrr-rer4) rrrfindrrlstripreplaceisdigitrrY)rrxrrparamrkeyivalirrrread_schism_params   rCc CsVt|}t|d6}tt|D]"}|d|||||q$W5QRXdS)Nr4z {:10}= {:} )sortedkeysrrAr8r6r )rr@Zpkeysrr1rrrwrite_schism_params  rFc CsLt|d}|}|tdd|Dd}tdd|Dd}t||f}t|dddf}||}tdd|Dd }t|dddf}||}t} |jd| _ |jd| _ |ddd dfd | _ |ddd dfj \| _ | _| _d t| j d| _|ddd fd k} d | j| <|dk rH| || S)z 1). read SMS *2dm grid, and return grid object 2). if grd!=None, save grid as *gr3 format e.g. gd=sms2gr3('hgrid.2dm','hgrid.gr3') rcSs.g|]&}|dr|dddqS)ZE3Trr6r)r startswithrrr/rrrr2s zsms2grd..rYcSs*g|]"}|dr|ddqS)ZE4Qrr6rGr/rrrr2s NrcSs*g|]"}|dr|ddqS)NDrNrGr/rrrr2s rrrr6r)rrrr?rrLrrrSrNrPrBrrDrErMrFr:r1) smsgrdrrZE3ZE4ZE34rrIrrrrrsms2grds,   "  rLcCsBt|trt|}n t|tr$|}ntd|||dS)z convert schism hgrid to SMS *.2dm format usage: 1). grd2sms('hgrid.gr3','hgrid.2dm') 2). grd2sms(gd,'hgrid.2dm'), or gd.grd2sms('hgrid.2dm') note gd=read_schism_hgrid('hgrid.gr3') zunknow format of grd: {}N)rrstrrrrQrRr rF)rKrJrrrrrF s   rFc Cs|jdd\}}t|} |jddkr8|dddfnt| } tj||} t} | t| j| _ | _ ||| | _ | _ | _ t| jdt| j dgfd| _dt| j d| _t| ||||||d} | S)a create schism grid from scatter pts xyz: c_[x,y] or c_[x,y,z] angle_min: remove element with internal_angle < angle_min area_max: remove element with element_area > area_max side_min: remove element with side_length < side_min side_max: remove element with side_length > side_max reg_in: ACE/xgredit region file. remove elements in region if reg_in is provided reg_out: ACE/xgredit region file. remove elements outside of region if reg_out is provided NrrrrrY)rRarea_maxside_minside_maxreg_inreg_out)rr8rSrrer Triangulationr trianglesrPrNrDrErMrCrFrrBr:delete_schism_grid_element) xyzrRrNrOrPrQrRrDrErPr^trrrrrscatter_to_schism_grid!s &$rXrnc)CsJgg}} |jdk} |jdk} td|jgd\} } }t|j}tdD]@}|d| | <|dd| | <|dd|| <|d| | <|dd| | <|dd|| <|j|j|| f}|j|j|| f}|j|j||f}|j|j|| f}|j|j|| f}|j|j||f}tt ||d||t ||d||dt }| |t|d||d|}| |qJt |j }t | } |jdd}| jd d}| jd d}|||d k rt||kd nt g}|d k rt|j|kd nt g}|d k r4t||kd nt g}|d k rVt||kd nt g}t||||fd} |d k rt| d krt|dd }!tt|j| |j| f|!j|!jdk}"| |"} |d k rt|dd }!ttt|j|jf|!j|!jd kd }#t| |#f} tt|j| }$tt|jt|j|$}%t|%d kr|g}&|%D]x}'|j |'}(|d kr||(}|& |(t|t|kd d |dkr^||(}|& |(t|t|kd d q^t!t|$t |&f}$t|$|j|$|j|$|_|_|_|j|$|j|$|j|$|j"|$f\|_|_|_|_"|S) ag delete schism grid's elements grd: schism_grid object angle_min: remove element with internal_angle < angle_min area_max: remove element with element_area > area_max side_min: remove element with side_length < side_min side_max: remove element with side_length > side_max reg_in: ACE/xgredit region file. remove elements in region if reg_in is provided reg_out: ACE/xgredit region file. remove elements outside of region if reg_out is provided method=0: use side_max for dangling pts; method=1: use angle_min for dangling pts rrrYrrrrKr#rNr)#r:rFrNrrrDrBrErZrOrPrr?rrUrVrrprrrLr8rr rCrrrrPrrrrrr;))rrRrNrOrPrQrRrwanglessidesrrrrrUr r1rrrrrrr`siZmangleZsideminZsidemaxZfangleZfareaZ fside_maxZ fside_minr&r3rvrrZipsrrZiesrrrrU:sv    <    "$"" (  (   " &&4rU__main__)r)rrer)rrNrNrr)rrrrrrr)NNr)rer)rrer)r)N)NNNNNN)rnNNNNNr)pylibrrlrrrrrrrrrr,r3r.r9rCrFrLrFrXrUrrrrrs@^T  Y V  o      =