o GgU@sddlTd{ddZd|ddZ d}d d Zd d Z  d~ddZdddZdddZdddZdd d!Z dd"d#Z  dd*d+Z gd,d-d-gd.d/gfd0d1Z d{d2d3Z d4d5Zd6d7Zdd8d9d:Zdd;d<ZGd=d>d>Zdd?d@ZddAdBZdCdDZdEdFZddHdIZddKdLZd|dMdNZdOdPZdQdRZdSdTZdUdVZdWdXZddYdZZdd[d\Z dd^d_Z!ddadbZ"ddcddZ#ddedfZ$dgdhZ%ddkdlZ&ddmdnZ'd|dodpZ(d|dqdrZ)ddsdtZ*ddudvZ+ddxdyZ,e-dzkr dSdS))*NcKsn|durt}t||durt}|durt}t|d|t||d|t|||fi|dS)a add annoation to the current axes at relative location to x-axis and y-axis x: relative location in x-axis, tpycially 0-1, but can be negative or larger than 1 y: relative location in y-axis, typically 0-1, but can be negative or larger than 1 note: annotation string xm: range of x-axis; gca().xlim() is used if not given ym: range of y-axis; gca().ylim() is used if not given ax: axes; gca() is used if not given **args: all other parameters used in matploblib.plot.text are also applicable E.q., rtext(0.1,0.9,"(a)",size=10,weight='bold') -> place label at top left corner note: suggest not to rearrange the x/ylim after using this function, or place this after Nr)gcascaxlimylimtextdiff)xynotexmymaxargsrF/lfs/h1/ops/prod/packages/stofs.v2.1.16/ush/stofs_3d_atl/pysh/mylib.pyrtexts <rcCsX|dkr tj||dd}ntj||d}t|j}|j}|dkr"|S|dkr*||fSdS)a use pd.read_excel to read Excel file fname: name of Excel file sht: name of sheet_name, or number of sheet (default is 0) fmt=0: not treat 1st line as header, return data only; fmt=1: treat 1st line as header, return header and data rN) sheet_nameheader)r)pd read_excelarraycolumnsvalues)fnameshtfmtfdrfdatarrrrs  rsheet_1rowc KsVddl} |ds |d}tj|r%|dks|dkr%tj|dddd} ntj|d dd } t|tks8t |d s>t |gg}t |}|j d kr[|d krS|dddfn|dddf}|j }|d||d |}}|t | jvr|dkrt||d}|j \}}|d kr| j|}t||gd}t|D]}t|D]}||d |d j|||f<qq||krt|td|||gf}|}||krt|td|||gf}|}n td||gd}t|D]\}}t|D]\}}||||||f<qqtdd|D}|j| |ddd|d krP|t | jvrP|dkrP| j|}t|j dD]}t|j d D]}|||f||d |d _q;q2|| | fdks_t| dkr|durntj|d d}| j j!d|| | dkd| }| j|}t|D]\}}t|D]\}}||||d ||d _qq| "dS)a use xlsxwriter to write Excel file data: can be a single data, 1D array or 2D array fname: name of Excel file sht: name of sheet_name indy: starting Row index of cell for data to be written indx: starting Column index of cell for data to be written align='row': write 1D data as a row; align='column': write 1D data as a column old_font=1: for existing sheet,keep old font styles; old_font=0: discard color,fontsize,fontweight: options for specify cell font (see openpyxl.styles.Font) fmt=0: append data to existing file, or create file if not existing fmt=1: replace mode of excel file fmt=2: only replace sheet, but keep other sheets of excel file rNz.xlsxaopenpyxlreplace)modeengineif_sheet_existsw+)r&r'__len__rr!OcSsg|]}t|qSr)list.0irrr ]zwrite_excel..F)rrindexNNNbold)colorsizer5r)#r$endswithospathexistsr ExcelWritertypestrhasattrrndimshaper-sheetsrastypeonesarangecellfontcopyr_tilec_ enumerate DataFrameto_excellenmplcolorsto_hexstylesFontclose)datarrZindyindxralignZold_fontr6fontsize fontweightrr$fiddsnynxdata0Zny0Znx0sidfontskr0dataiZdataiidfcfrrr write_excel+sD"2  2&&($ 8 6 rfcCsnt|d}i}|D])}|d}t|dkrq |d}|d}|dkr*q |d}|||<q |S)z7 read yaml file and return key-value dict r:r"rrr,)open readlinesstripsplitrO)rlinesparamlineslinekeyvaluerrr read_yamlos   rsmpi4pyx5672r01:00:00 screen.outrnflexgg0028c  Cs||} |dkrd||tj| <|dvr d|||||} | S|dvr0d|| ||||} | S|dvrAd|| | ||||} | S|d vrRd || | || ||} | S|d vrvd || ||||||| } |d krtd|| ||||||| } | Std|| S|dkr|dvrd|||} | S|dvrd|| ||} | dkrd||} | S|d vrd|| ||} | dkrd||} | S|dvrd|||} | dkrd| } | S|d vrd|||} |dkrd|||} | Std|| S)a get command for batch jobs on sciclone/ches/viz3 code: job script bdir: current working directory jname: job name qname: partition name (needed on some cluster/project) qnode: hpc node name nnode,ppn,wtime: request node number, core per node, and walltime fmt=0: command for submitting batch jobs; fmt=1: command for run parallel jobs rz{} {})femtoZcyclopsz=sbatch --export=ALL -J {} -N {} --ntasks-per-node {} -t {} {})ZfronterazCsbatch --export=ALL -J {} -p {} -N {} --ntasks-per-node {} -t {} {})ZmistralzPsbatch --export=ALL -J {} -p {} --account={} -N {} --ntasks-per-node {} -t {} {})Z stampede2z& {}z& {}Z run_schismzibrun ./{} >& {}zDmpiexec -envall -genv job_on_node 1 -genv bdir '{}' -n {} ./{} >& {}zhsrun --export=ALL,job_on_node=1,bdir={} -l --propagate=STACK,CORE -l --cpu_bind=verbose,cores ./{} >& {}zmodule unload python3;z3mvp2run -v -e job_on_node=1 -e bdir='{}' ./{} >& {}r|z6mvp2run -v -a -e job_on_node=1 -e bdir='{}' ./{} >& {}zunknow qnode: {},tag=2)formatr9environsysexit)codebdirZjnameqnodennodeppnZwtimeZscroutrZenameqnameZaccountZnprocZscmdrrrget_hpc_commandsV "" r epsg:4326Fc , Cst|} || } || } t|}|| k|| k} t|| }t} || _ddtt|D| _ t|dkr=| St|}t|}g}d}t||} | ||g||kr[n ||}t|||}qOg}d}t||} | ||g||kr}n ||}t|||}qqt |D]\}\}}t |D]\}\}}|||}|||}|||||f}t|} || } || } || k|| k} t|| }t|dkrqt d |d|t|t|t|t}|dt||||}t|tt|jD]c} |j| }!tt|!D]:}"|!|"jdddf}#|!|"jdddf}$|"dkrCt|#tf}%t|$tf}&qt|%|#tf}%t|&|$tf}&qt||| kdd}'| j |'t|%|&fq qqtt|D] }"t| j |"| j |"<qu|durt |D]-\}"}(t})d |)_| j |"|)_ t||)_|(dkrd ||(nd ||( }*t|*|)qd }+|rtt |D]\}"}(| j |"j\}%}&t|%|&|+|"d ddqt g|| S)a compute contour lines Input: x: array for x coordinates (ndx) y: array for y coordinates (ndy) z: matrix of data (ndy,ndx) levels: values of contour lines to be extracted (nx,ny): when ndx(ndy)>nx(ny), subdivide the domain to speed up Output: fname: when fname is not None, write contours in shapefiles prj: projection names of shapefiles show_contour: plot contours cSsg|]}gqSrrr.rrrr1z#compute_contour..rTz'extracting contours in subdomain: {}/{}rFNPOLYLINEz{}_{}z{}_m{}Zkrgbmcy?)r6lw)!isnanminmaxrsortzdatalevelsrErOxyappendrLprintr}figure set_visiblecontourrU collections get_pathsverticesrINaNnonzeroextendrKr= get_prj_fileprjwrite_shapefile_dataTplotlegend),r r zrrrZ show_contourr^r]fpnzminzmaxfpzSndxZndyixsi1i2Ziysmix1ix2niy1iy2ZsxiZsyiZsziZ levels_subZhfPrbpr0xiiyiixiyisindcviccnamecsrrrcompute_contoursr"$$  ,",,  (   $ rc'Csn|}|}|dr$t|ddgd}tt|j}tt|j} n|drt}t|d} t | d} t | d} | \} }t |}| \}}t |}t | d}|}|} t | d}| | dkr|d kr||d }||d }||t| |_||t| | d||_||_ntd ||j|d ks||j|d ks||j| d ks||j| d kr|d kr|d urtt|t}|S|dkrtgtgdgStd|dr0t|}t|ds/d |_n |dr=t|dd|_tt|jd krSt|j|_t|j|_|j}t|}|j}t|} |}|}|}|}|||d k||k}|||<||| d k||k}|||<||k|||d k}||d||<||k||| d k}|| d||<t||k||k||k||kd }||}||}t ||d |d}t ||d | d}t|||d kd }t|d kr)||d||<t|||||d kd } || }t|d kst|||d kd }t|d kr_||d||<t|||||d kd } || }t|d ks<|||||d|j|}!|||||d|j|}"t!|!d k|!dkd krtdt!|"d k|"dkd krtd|jd urt"|jrt"|j}#n|j|jk}#t|j|#<|j||fd|!|j||df|!}$|j|d|fd|!|j|d|df|!}%|$d|"|%|"}&|jd urt"|&}#||#}|&|#}&|d kr'|d ur!tt|t}|&||<|S|dkr0|&|gStdd S)a load bathymetry data onto points(xy) Input: fname: name of DEM file (format can be *.asc or *.npz) Outpt: fmt=0: return dp; depth interpolated for all points fmt=1: return [dpi, sindi]; depth for points only modified, and also flag Znpzlonlat)svarsZascrgr xllcorner yllcornerr"zwrong format of DEMrNint wrong fmtnodataskiprowsgư>zxrat<0 or xrat>1zyrat<0 or yrat>1)#r8loadzabsrrmeanrrrirreadlinerkrlfloatrUlowerrErrrrrzerosrOnanrrCr?loadtxtelevflipudrfloorsumr)'r r rrrZxi0Zyi0rdxdyr[ncolsnrowsxnxllynylldxyrrrlon1lon2lat1lat2rsindprridxZidysindfpsZxratZyratrZdp1Zdp2dprrrload_bathymetry s &   00 4     ,   (((  ""$$     ,4   rcKs|dur tdt|ddgdgdt|d|||gd|gd d |D]"\}}|d vr8d ||}nd ||}t||gd|gd d q)dS)zX function to rewrite the inputs in job-submit scripts (e.g.run_mpi_template.py) Nzplease specify qnoderz#qnodezqnode=)r% startswithzqnode='{}'; nnode={}; ppn={} z #qnode='{}'#)r%rnote_delimiter)Zicmbifsrstacksz{}={}z{}='{}'z{}=)rrrewriter}items)rrrrrrqrrZfstrrrr rewrite_inputs$ rcCstj|rt|d}|}|ndSg} |D]} | } d} |dur/|D]} | | vr.d} q&|durA|D] } | | r@d} q5|durS|D] } | | rRd} qG|}d}|dur| dkr| }||rs|dd}||sh||vr| |}||d}nd}| dkr|durt |dkrqt |dkr|d d|} n| j |} nq| ds| d} | | q|dur|D]} | ds| d} | | qt|d}|| |dS) a function to rewrite file in-situ based on conditions fname: file name replace: string pairs list; e.g. replace=['ON', 'OFF'] include: list of strings included; e.g. include=['USE_ICM'] startswith: list of strings startswith; e.g. startswith=['#USE_ICM'] endswith: list of strings endswith; e.g. endwith=['*.csv'] append: list of lines; e.g. ['add 1st line','add 2nd line'] note_delimiter: keep inline note after delimiter (ignore delimiters in the beginning) rgNrrr,  r))r9r:r;rirjrUrkrr8findrOrstripr%r writelines)rr%includerr8rrr[rmZslinesrorpZiflagr0ndr r`rrrrsP         rcCsZ|dkr|ds |d}t|d}t|d}t|d}|\}}t|}|\}} t| } t|d} t|d} t|dd} || dkr| dkr|| d }| | d } t } || t || _ | | t ||d| | _ | d | _| | _t|| d Sd S) z fname: name of source DEM file sname: name of file to be saved fmt=0: convert DEM file in *.asc format to *.npz format rz.ascrgrrrrrr"float32N)r8rirrrkrlrrrUrrrErrrCrrsavez)rsnamerr[rrrrrrrrrrrrrconvert_dem_formats"  00rr"brbg皙?c  s|durtgtddddd}|durtddd}|dur&tddd}|ttd| fd d |D_td td td d td td ddddd_ fdd |D_ tdtd| fdd |D_ t t tdddft tdddfd| d_tddddddd_tdt| tt} g_|D]c}|d}| |}t|d|dk|dk}t|dkrqt ||||d|d}t|d|}t|t|kdd}td||d||d ||d!d"d#j|qtd$d%d&|ddd'd(_|dury|duryt ddd)d*d+d,d-_g_t|D]*\}||tdd||} t | d.dd+d |d-}j|qNtt|gd/td!d0tjd1 d2tjd3 d2tjd4 d2tjd5 d2d6}tt| |g| |gd7t_!tj"_#fd8d9}|_$| durj!j%d!d0_&t'| d:rfd;d t| DS).g ףp= ?- correlation r5i)rYrZr6rotationc sPg|]$}td|dtd|ddtt|ddddqS)g)\(?rr"{}d)rYr6)rr r}rrr.)r smrrr1 sPr"c s6g|]}|krtt|t|ddqS)rr)rcossinr.)cSTDr rirrrr1$s6r-rggffffff?zstandard deviationZrg333333?gRQ?rr)r6rYrg{Gz?g)\(?RMSD)r6rYrZrzk. rbobs)msr6labelzr.)yticksxticks)rYrightFtopleftbottomgMbP?)rrc[s|jjdi||_dS)Nr)harhl)selfrrrr update_legendJsz*plot_taylor_diagram..update_legendr*cs(g|]\}}j|d|qSr)r* get_textsset_text)r/r0Zlstrrrrr1Q()(rrErlinspaceZhp_RrrpirZht_RZht_R2Zhp_STDrrIZhp_STD2Zht_STDZhp_RMSDr rrrrr}rZht_RMSDZhp_obshprLsetprr#spinesrr)axesrr,rr*r?)RSTDZstd_maxZticks_RZ ticks_STDZ ticks_RMSDr rZcRMSDr Zlw_outernptlabelsrr0rrrr*Zxiiir`r4rdr,r)rr rr rrrrplot_taylor_diagramsT$  @< 40* $(  "r<)rrrrg?c Ks||\}}}}|\}} d||| d|d| } d|||d|d|} |d|| | | g} t| ||fi|S)a return subplot position. Based on and calling get_subplot_position, but using the margin as input. Inut: margin=[left,right,up,down]: distance from left, right, up, and bottom edge for other arguments, see get_subplot_position Sample function call: [ps,pc]=get_subplot_position2(margin=[0.05,0.05,0.1,0.1],dxy=[0.00,0.00],ds=[3,4],dc=[0.01,0.005]) ps=reshape(ps,(12,4)) #to make 3D dimension array to 2 dimension for imon in arange(12)+1: axes(position=ps[imon-1]) rr)get_subplot_position) marginrr\rr'r%updownZrownZcolnZxspanyspanp0rrrget_subplot_position2Ts   rEc s|\|\|\}tfddt|D}|dkry|\}} t|d} d| dd<|dkrId| ttt|t|<t|D]+} tD]$} | | | fdkrw| | | |g| | | f<qSqM|dkrt|dtD]7} t|D]0} t|| | fdt gt g|dkr| | | fdkrt| | | fdt gt gqq|dkr|| gS|S)a return subplot position Input: p0=[x0,y0,xm,ym]: upper left subplot position dxy=[dx,dy]: space between subplots ds=[ny,nx]: subplot structure dc=[xmc,dxc]: add colorbar position with width of xmc, and distance dxc from axes sindc=[:nplot]: indices of subplot colorbars fsize=[fw,fh]: plot out subplot in figure(figsize=fsize) c s.g|]fddtDqS)cs0g|]}|gqSrrr.)rrrbx0r y0r rrr1us0z3get_subplot_position...rEr/rrr^rFr rGr )rbrr1us.z(get_subplot_position..Nr+r)figsize)position) rrErrCravel setdiff1dprodrr7r$r#) rDrr\dcrrKr]psZxmcZdxcpcrbr0rrJrr?gs, &"&  D   "2r?cCs:t|d|dr|}|St||ddf}|S)zu constructe data loop along the first dimension. if xi[0,...]!=xi[-1,...], then,add xi[0,...] in the end )r.).N.) array_equalrMrI)rrrrrclose_data_loops rVc Cstt||kd}g}ggg}}}t|dkr(|d|dg}||nS|d||dg}||tt|dD]*}|||d|||dg}||||||||dg} || q?||dd|dg}||t|}t|}t|dd} |t| | kdd} t|dkrt|dd}|t||kdd}t} ||| | |||f\| _| _ | _ | _ | _ | _ | _| S)a analyze time series to find the locations where differences are larger than dx: (xi[i+1]-xi[i]>dx) return: bind: locations of differences>dx sections: continous sections where all differences are smaller than dx gaps: gap sections where differences are larger than dx slen,glen: lens for each section or gap msection,mgap: maximum section/gap rrSraxis)rrrOrrErrrbindsectionsmsectionslengapsmgapglen) rrrrZr]r_r^sxrZgxr\r[rrrrfind_css( *("(44rarcst|dkr |d}t|trt|}dkrt|}|St|drqt|dtt|ddBr=tfdd|D}|Sg|}|ddkr`|dt|dd|d<td|dd|d<t j |}dkrot j |}|St d|S)z usage: datenum(*args,fmt=[0,1]) datenum(2001,1,1,10,23,0) or datenum([[2001,1,1],[2002,1,5]]) datenum('2001-01-01, 10:23:00') or datenum(['2001-01-1','2002-01-05']) fmt=0: output num; fmt==1: output date rrr*csg|]}t|dqS)rbdatenumr.rbrrr1zdatenum..rzunknown input format)rO isinstancer> datestr2numnum2dater?rrrdatetimerPdatesdate2numrr)rrdnumZdargsrrbrrds$     rdcsd}dkrddkrddkrdd}dkrd d}|d ur<|dkr+td |dkr4d d g}n&gtd d }nt|dkrX|ddkrJd}gt|d|dd}nd}|dkrpd urdd|dkrodd|D}nJ|dkrd urzd|dkrtdd|D}n0|dkrd urd|dkrgttt|ddtt|dddd}n |dkrd urdfdd|D}|dkrdd|D}||gS)u return temporal ticks and labels for plot purpose fmt: format of xtick and xticklabel 0: year; 1: month; 2: day; 3: user-defined xts: time aranges or time arrays e.g. [2000,2010],[datenum(2000,1,1),datenum(2010,1,1)],[*arange(730120,730420)] str: format of label Year: %y=01; %-y=1; %Y=2000 Month: %m=01; %-m=1; %B=January; %b=Jan Day: %d=01; %-d=1 Hour: %H=09; %-H=9; %I=[00,12]; %-I=1 Minute: %M=09; %-M=9; Second: %S=09; %-S=9 AM/PM: %p=[AM,PM] %c='Fri Jan 25 04:05:02 2008' %x='01/25/08' %X='04:05:02' Week: %a=MON; %A=Monday; %w=[0,6] Week of year: %U=[00,53]; %W=[00,53] Day of year: %j=045; %-j=45 1: 2008-02-03 2: 2008-02-03, 04:05:00 3: J,F,M,A,J,J,... (Months) 4: 03/15 (mm/dd) rrz%Y-%m-%dr"z%Y-%m-%d, %H:%M:%Sr=z%br>z%m/%dNzmust provide xts for fmt=3iig@z%YcSsg|]}t|ddqSr-rcr.rrrr1rezget_xtick..cs"g|] fddtdDqS)csg|] }t|ddqSr-rcr/rbr0rrr1z(get_xtick...rrHrIrrnrr1s"z%-dcsg|] }t|qSr)rhstrftimer.r>rrr1!cSsg|]}|dqSrrr.rrrr1"r2) rrrErOrrMrdrr)rZxtsr>Zftitxlsrrqr get_xticks@        6 rvc@seZdZdZddZdS)rzY self-defined data structure by Zhengui Wang. Attributes are used to store data cCsdSNr)r+rrr__init__+szzdata.__init__N)__name__ __module__ __qualname____doc__rxrrrrr's rc CsR|dr d}|dd}|drd}|dd}|dkr"|d}|dkrt|j}d|vr6|dg}|D]-}t|j|drgddl}z ||j||j|<Wq:td || |Yq:q:t ||}d |}|D] }|d ||}qt|d }t |dS|dkrt|dr|` t|d }t||tj|dSdS)z save data as self-defined python format fmt=0: save data as *.npz (small filesize, reads slower) fmt=1: save data as *.pkl (large filesize, reads faster) if fname endswith *.npz or *.pkl, then fmt is reset to match fname .npzrN.pklrVINFO__call__zfunction {} not savedzsavez_compressed("{}" z ,{}=data.{})wb)r8r-__dict__keysremover? cloudpickledumpsrr}rrNexecrripickledumpHIGHEST_PROTOCOLrU) rrVrrZrvarsvarirsave_strr[rrrr.s0   &rcCs|drNt|dd}|dur|n|}t}g}|D]0}||}|jtdkr-|d}dt|vrDddl}z||}WnYqtd |d qn+|d rqddl}t}t |d } || } t | j |_ | ntd |g} |j D]J} |j | } d| }t| trdtt| t| }nt| tjrd| j}ndt| }t| drdt| jnd}| |||qt| |_|S)zh load self-defined data "fname.npz" or "fname.pkl" svars: list of variables to be read r}T) allow_pickleNr+rzcloudpickle.cloudpicklerzvdata.z=datairrbzunknown format: {}z{}: z{}{}z ndarray{}rdtypez ,dtype={}r,)r8loadrrrr>rloadsrridcopyrrHrUrrr}rfr-r=rOnpndarrayrAr?rrr)rrr_Zkeys0Zvdatarkeyircrr[rVfsr0rf0f1f2rrrrUsD          rcCs@|jdt|kr |j}t|j||j|}||}||gS)z perform least square fit usage: CC,fit_data=least_square_fit(X,Y) X: data maxtrix (npt,n) Y: data to be fitted (npt) where CC(n) is coefficient, fit_data is data fitted r)rArOrinv)XYCCfyrrrleast_square_fits rcCs^|j}t|}t|d|dd|}t|d|d}||td|d}|||fS)z Perform FFT for a time series, with a time interval specified usage: period,afx,pfx=mfft(xi,dt) input: xi: time series dt: time interval output: period[period],afx[amplitude],pfx[phase] rr"g@)r7fftranglerE)rdtNfxZafxpfxperiodrrrmffts   rTcCsdddl}|j||j|j|d}|\}}|dkr|d}|dkr'|d}t}||_||_|S)z Capture the command output from the system usage: S=command_outputs('ls') print(S.stderr) print(S.stdout) # normally this is the results rN)stdoutstderrshellzutf-8) subprocessPopenPIPESTDOUT communicatedecoderrr)rrrrrroutrrrcommand_outputss  rrc&Cs|dkrtj||d}|S|dkr8|dddfd|dddf}|dddfd|dddf}t|t|}g}g}g} g} tt|} t| dkrWnLt|| || d} t| }| |} | |} t|t| } | || d| || d| | | | d| | d| | | d} qPg}tt|D]Z}t|||} | |}||}|} | |k}t |dkrn||}q| |d|k}t |d}||}|dddf}|dddf}t||} | j dd}| ||qt gd}t gd}tt| D]}t|| |f}t|||f}qt|}||}|S|dkr|jd}|jd}ttd ||d }td |td}t|} td |||||df} |||df}!|dddf}"|dddf}#| dddf|"dddfd|!dddf|#dddfd} g}t| jdD]}$| dd|$f}%| t |%t|%kddq|dkrt |}n t|tt |f}t||}tt|||}||krnqa|}|S) a return index of pts0 that pts is nearest usage: sind=near_pts(pts,pts0) pts0: c_[x0,y0]; pts: c_[x,y] algorithm: using sp.spatial.cKDTree (default) old methods: method=1 and method=2 usage: sind=near_pts(pts,pts0,method=1[2],N=100) pts[n,2]: xy of points pts0[n,2]: xy of points method=1: quick method by subgroups (N); method=2: slower methods rrNy?Tr"rWrgcAgY@z total pts: {}zprocessing pts: {}-{})spspatialcKDTreequeryrrOrErargsortrrrargminrrCrIrArrr}rsqueeze)&ptsZpts0methodrrrrDZps0rQr\indsinumdistZsNZinds0rZdsipsiZdsmfpind0Zp0iZpsiiZp0iiZindipindZpind0indrn0i0rr r rFrGr0Zdistirrrnear_ptssrN $$>L   $    H"   rc% Cs|jdkr|dddf}|dddf}|jd}|j\}}|dkr|dkr|jdd}|jdd} |jdd} |jdd} g} t|D]} || df}|| df}t||k|| k|| k|| kd}t|}|dkru| dqEt|}t|D]?}t t|||||f|t |d||ff}t t|||||f|t |d||ff}t ||}|dk}d||<q}t|dkd}t|dkr| dqE| ||dqEt | } | S|dkrg} t|D] }t jt |dd|f|dd|ff|}| |qt | jd} n |dkr t||g} |dddfdddf}|dddfdddf}t|D]}||ddfdddf}||ddfdddf}t||g}td|dD]}||||ddfdddf}||||ddfdddf}|||d|ddfdddf}|||d|ddfdddf} |||||||||| ||||||dk}!||||| |||| |||||||dk}"|!|"}#||#d||#<ql|ddk||k||kB}d| |<qA|dkr;t| dd}$d|$| t||$fdk<|$} | S|dkrM|dkrM| dddf} | S)a check whether points are inside polygons usage: sind=inside_polygon(pts,px,py): pts[npt,2]: xy of points px[npt] or px[npt,nploy]: x coordiations of polygons py[npt] or py[npt,nploy]: y coordiations of polygons (npt is number of points, nploy is number of polygons) fmt=0: return flags "index[npt,nploy]" for whether points are inside polygons (1 means Yes, 0 means No) fmt=1: only return the indices "index[npt]" of polygons that pts resides in (if a point is inside multiple polygons, only one indice is returned; -1 mean pt outside of all Polygons) method=0: use mpl.path.Path method=1: use ray method explicitly note: For method=1, the computation time is proportional to npt**2 of the polygons. If the geometry of polygons are too complex, dividing them to subregions will increase efficiency. rNrr=rWrSr")r@rArrrErrOrrDrKmodsignarrPr:Pathcontains_pointsrrargmax)%rpxpyrrr:nvZnpyZpx1Zpx2Zpy1Zpy2rr0ZpxiZpyirZisumrrrarearZsindix1y1x2y2rx3y3Zx4Zy4fp1fp2Zfp12Zsindmrrrinside_polygon(sf  0 0  00   $  2   8 DHPDD   rcCs|jdkr(|d|d|d|d|d|d|d|dd}n'|jdkrO|d|d|d|d|d|d|d|dd}t|}|S)z` compute signed area for triangles along the last dimension (x[...,0:3],y[...,0:3]) rrr").r).r").r)r@rr)r r rrrrrs F D rcCsX|jdkr |dddf}|jdkr|dddf}t||j}||j}t||S)z) perform matrix division B/A rN)r@rrr)ABA2B2rrrmdivides   rc Cs|j}|jddd}||}t|dd}|d}t|}tt|||}d||<d||d<d||d<d ||d ||d <d|||d <d|||d <d|||d<tgt|jd |j}||}t t |dd|} | S) zd low pass filter for 1D (data[time]) or nD (data[time,...]) array along the first dimension rrWrTgzG?gQ?rg~jt?r"gr=r>r) rArrrDrrr@rCrrealifft) rVdelta_tZcutoff_fr\mdatarrfiltrbZlfdatarrrlpfilts$   rcCst|ddkr |d}t|dd}|}|t|j}td|dD]O}||ddf|d| df||ddf<|d| df||ddf|d| df<|d|dfd|d|df<|| dd|| d<q%||}|S)z smooth average (on the 1st dimension): xi[time,...]: time series N: window size (if N is even, then N=N+1) r"rrN.)rrrHrDrArE)rrnzrZSNZnmoveZSXrrrsmooths.0 rc Cstdtddtdtd|d}tdtdt|tdt|t|tdt|}d d tt|}|S) z calculate daytime length based on latitutde and day_of_year lat: latitude, doy: (1-365), sunrise=12-daytimelength/2, sunset=12+daytimelength/2 gd]Fx?g?r"g%T?g"u?g7d?r)arcsinrarctantanrr3arccos)rdoyrrrrrrdaytime_lengths,@rcCsp|durt}t}|dkr|jjjd||fdS|dkr-|jjj||fdS|jjj||dS)zd Move figure (f=gcf()) to upper left corner to pixel (x, y) e.g. move_figure(0,0,gcf()) NTkAggz+%d+%dWXAgg) gcf matplotlib get_backendcanvasmanagerwindowZ wm_geometryZ SetPositionmove)r r fbackendrrr move_figuresrc  Cszddlm} m} m}|dkr| |}|j}|j}|j}|j}nr|dkr4| |}|j}|j}|j}|j }n]|dkrZt |}|j d}|dddf}|dddf}|dddf}n7|dkrt |}|j d}|dddf}|dddf}|dddf}n|dus|durt d|||}|}d}|dkrd} |dkrd} d ||fvrd}d }|dkr|d kr|dkrt d |||dus| durt d ||d t|t| td }|d t|}n|dkr3|d kr3|dkrt d |||durt|}| durt|} |||td t| td }||td }n[| dkr=||}}t|t|B}tt|t}tt|t}t||||||\||<||<| dkrt||}}tt||dktt||dkBrt d|dkr|dkrt d|||_||_|j|d||ddS|dkr|dkr||_||_n|}d|||_||_||_||_||_ ||dS|dks|dkr9t|d>}t|D]0}|dkr |d|||||||dkr$|d|d||||||qWddS1s2wYdS||gS)a tranfrom projection of files: proj(fname0,fmt0,prj0,fname1,fmt1,prj1,x,y,lon0,lat0,order0,order1) fname: file name fmt: 0: SCHISM gr3 file; 1: SCHISM bp file; 2: xyz file; 3: xyz file with line number prj: projection name (e.g. 'epsg:26918', 'epsg:4326','cpp'), or projection string (e.g. prj0=get_prj_file('epsg:4326')) lon0,lat0: center for transformation between lon&lat and x&y; if lon0=None or lat0=None, then x0=mean(lon), and y0=mean(lat) order=0 for projected coordinate; order=1 for lat&lon (if prj='epsg:4326', order=1 is applied automatically') tranform data directly: px,py=proj(prj0='epsg:26918',prj1='epsg:4326',x=px,y=py) function used: lat,lon=Transformer.from_crs('epsg:26918','epsg:4326').transform(x,y) x,y=Transformer.from_crs('epsg:4326','epsg:26918').transform(lat,lon) #x1,y1=transform(Proj(proj0),Proj(proj1),x,y); #not used anymore r)read_schism_hgridread_schism_bpfile schism_bpfilerr"Nr=z%unknown format of input files: {}, {}rZcppgTXAz"projection wrong: prj0={}, prj1={}z(need lon0 and lat0 for cpp=>ll transformrz!nan found in tranformation: x1,y1z{} should have gr3 formatz!coordinate transformed: {}=>{})ZInfozcoordinate transformed: {}=>{}r)z {} {} {} z {} {} {} {} ) schism_filerrrrr r rZnstarrrArrr}rr3rrrrErOr Transformerfrom_crs transformrZ write_hgridr Z write_bpfileriwrite)Zfname0Zfmt0prj0Zfname1Zfmt1prj1r r Zlon0Zlat0Zorder0order1rrrgdrrZicppZrearthrrrr[r0rrrprojsh<<"  662(4      *0$r epsg:26918cCst||||d\}}||gS)z convert projection of points from prj1 to prj2 x,y: coordinate of pts prj1: name of original projection prj2: name of target projection )rrr r )r)r r rZprj2rrrrrproj_ptsBsr %D:\Work\Database\projection\prj_filesc Cstjt}|dkrtd|}|j|S|dkr$td|}|jS|dkrnt|}t}|D]9}t d|}|s=q2t | d} t d||d} | } | |d| <Wd n1sfwYq2|Std d S) a return projection name or entire database (dict) fmt=0: get one projection fmt=1: return dict of projection database fmt=-1: process *.prj files from prj_dir #-------online method----------------- #function to generate .prj file information using spatialreference.org #def getWKT_PRJ (epsg_code): # import urllib # # access projection information # wkt = urllib.urlopen("http://spatialreference.org/ref/epsg/{0}/prettywkt/".format(epsg_code)) # # remove spaces between charachters # remove_spaces = wkt.read().replace(" ","") # # place all the text on one line # output = remove_spaces.replace(" ", "") # return output rz {}/prj.npzrrSzepsg.(\d+).prj{}/{}rgzepsg:{}Nz unknow fmt)r9r:dirname__file__rr}rlistdirdictrematchrgroupsrirrkrr) prjnamerZprj_dirrrfnamesrrr8Zprj_numr[rorrrrLs*     rcCsddlm}|dr|dd|dur|}tj|d}t}|D]-}|dr.q&t||}t |j t j sDt dd|D}|d vrL|d }td |q&t||dS) z convert MATLAB file to zdata examples: 1. convert_matfile('wqdata.mat') 2. convert_matfile('wqdata') 3. convert_matfile('wqdata','sfdata') r)ioz.matNr~__cSs$g|]}t|dkr|dndqS)rr,)rOr.rrrr1s$z#convert_matfile..)ZDoyrinzS.{}=squeeze(valuei))scipyrr8rZloadmatrrrr issubdtyperrnumberrrr}r)Z name_matfileZ name_saverCrrZvalueirrrconvert_matfiles     rc Cs*|}|}t|}t|}t}||}t|} t|} t||d|_t||_tt||_t|d|_ t||_dt |dt t||t||d|_ |dkrdt j ||\} |_| |_| |_ttt||d|jt||||d|j|jg|_|S)z compute statistics between two time series x1, x2 must have the same dimension x1: model; x2: obs fmt=1: compute pvalue using scipy.stats.pearsonr #import matlab.engine #eng=matlab.engine.start_matlab() )rrr"r)rrstdcorrcoefr8ZMErZMAEr rrr!rstatsZpearsonrpvaluestd1std2rZtaylor) Zxi_modelZxi_obsrrrZmx1Zmx2rrr!r"r#rrrget_stats   2 Rr#c sddl}||t}j|_j|_g|_t|jD] }t |j }t |j dd}|j t||tddqtt |j|_t fddtdtjD|_t fd d|jD}t d d}t tt|jd |_tt|jD]}|dd|f|||j|<q||_tjtj|} tj|d d} d | | } tj | rt!| d } | "#|_$Wdn1swYWd|SWd|SWd|S1swY|S)z read shapefile (*.shp) and return its content note: works for pts and polygon only, may not work for other geomerties (need update in these cases) rNr)rrWcsg|] }j|dqSrs)fieldsr.rrrr1rrz'read_shapefile_data..rcsg|] }t|qSr)r=recordr/rr%rrr1ror+. {}/{}.prjrg)% shapefileReaderrZ numRecordsnrecZ shapeTypeNamer=rrErrApointspartsrinsertrrrOr$attnamerecordsrrCattvalueZatttyper9r:r abspathbasenamerlr}r;rirrkr) rshprr0ZxyiZpartistypeZsvaluerrbnamerr[rr%rread_shapefile_datasF $"    " " ""r8rc s.ddl}jdkr!jjtdkrtdtn'jjd}n jdks+jdkr<jjtdkr9tj}nd}ntd t d rS|j krStd t| |}d|_ t d rj jtdkrzfd dttjD}n#j jdkrtj dg}nj jdkrfddttjD}tt|D]\}||tjtjtjtjtjfvr|j|dq||tjtjtjtjfvr|j|d||q||tjtjtjtjfvr|j|ddqtd ||tqn |dd|!t|D]jdkr"j} |j"| nOjdkrEjjtdkr7j} nj} t#| d} |$| n,jdkrqjjtdkrZj} nj} t#| d} dd| dDg} |%| t d rj jtdkrfddtt|D} n#j jdkrj g} nj jdkrfddtt|D} |j!| qt&j'(|)dd} t&j'*t&j'+|} t drt,d | | d}|-j.Wdn1swYWddSWddSWddS1swYdS)a9 write shapefile fname: file name S: data to be outputed example of S: S.type=='POINT' S.xy=c_[slon[:],slat[:]] S.prj=get_prj_file('epsg:4326') S.attname=['station'] S.attvalue=station[:] note: only works for geometry: POINT, POLYLINE, POLYGON rNZPOINTr+zS.xy has a dtype="O" for POINTrZPOLYGONrz unknow typer,znrec inconsistentr0cg|] }tj|dqSrsr=r2r'r0rrr1<z(write_shapefile_data..r"cr:rsr;r'r0rrr1Ar<rFrrzattribute type not included: {}fieldcSsg|]}g|qSrrrmrrrr1er2cg|] }j|qSrr2r'rr0rrr1krrcr?rr@r'rArrr1prrr(rr)r))/r*r=rrrrrrArOr?r,WriterZ autoBalancer2rEr0r@rrint8int16int32int64r>rfloat16rfloat64str0r>str_string_r}r&pointdelete_shapefile_nanropolyr9r:r4rlr r3rirr)rrZ float_lenZ float_decimalr5r,Wr6rZvalivaliiZattir7rr[rrArrs                           ?@$rc Cs|jdkr-d}|jd}t|drd}t|dr|d}|||}tt|d}n2|jdkr_d}|jd}t|drAd}t|drK|d}|||}tt|dddfd}t|dkrr|dkrmt|}|g}|Sg}|d|d}|dkrt|}||tt|dD]!}||d}||d}|||}|dkrt|}||q||ddd}|dkrt|}|||S)z> delete nan (head and tail), and get ind for the rest rrrSr"rr)rSrN)r@rArrrOrVrrE) rZilooprrrrrrrrrrrMzs6  (     rMcsZt||dkr S|dvr&t}j|_g|_ddjD}||_g|_g|_|D]}|jj|j |jj| q,|jd |j|jd |j }||_ |D] }td ||qagj}t||_|D]}|dkrt}j|j} | |_fd d| D|_j|d d |_j| |_ j| D]} j|| } td | q|dkrtt|j|_tt|j|_ttt|j} |j| |_d ||jj} n&|d krtj|d d }|dkr |tt|j}d ||j} |j| td |qx|Stdd S)a read netcdf files, and return its values and attributes fname: file name fmt=0: reorgnaized Dataset with format of zdata fmt=1: return netcdf.Dateset(fname) fmt=2: reorgnaized Dataset (*npz format), ignore attributes order=1: only works for med=2; change dimension order order=0: variable dimension order read not changed for python format order=1: variable dimension order read reversed follwoing in matlab/fortran format r)rr"cSg|]}|qSrrr.rrrr1rzReadNC..z dimname: {}zdim: {}zF.{}=C.getncattr("{}")rcsg|]}j|jqSr) dimensionsr7)r/jr%rrr1reNz fi.{}=ncattriz{}:{}r"zF.{}=fir)Datasetr file_formatrrSdimnamedims dim_unlimitedrr7 isunlimitedr}ncattrsattrsr variablesrvarsval getncattrr-rrEr@ transposerAfliprUrr)rrorderr=ncdimsr0r[ncvarsfiZdimirTZncattrinmvinforr%rReadNCsR   ricCs|dkrt|d|jd}|d|j|}|D] }td||qdd|jD}|D]}|j|dur@||d q.|||j|j q.d d|j D}|d kr|D]7} | | |j | j |j | j} |j | D]} | | |j |  | qq|j | d d |j | d d <qYnR|dkr|D]K} | | |j | j t|j | j} |j | D]} | | |j |  | qttt|j | d d } |j | d d | |j | d d <q|d S|d krt|d|jd}|d|jt|d r|jD] }td||qtt|jD]-}t|d r(|j|} nd} | dur:||j|d q||j||j|q|d kr|jD]8} td| }| | |jj |j} t|d r}|jD]}td|} | || ql|j|j | d d <qPnc|dkr|jD]Z} td| }| | |jj t|j} t|d r|jD]}td|} | || qt|jdkrttt|j} |j| |j | d d <q|j|j | d d <q|d Sd S)aZ write zdata to netcdf file fname: file name data: soure data fmt=0, data has zdata() format fmt=1, data has netcdf.Dataset format order=0: variable dimension order written not changed for python format order=1: variable dimension order written reversed follwoing in matlab/fortran format rw)r}rVzfid.setncattr('{}',data.{})cSrRrrr.rrrr1rzWriteNC..TNcSrRrrr.rrrr1rrr\rYFzdata.{}zvi.{}r")rUrV setncattrr[rr}rSrZcreateDimensionr7r]createVariablerr`rrEr@rarUr?r\rangerOrXrYrWr^evalr_)rrVrrcr[r[r0rdrervidZattrirgZdim_flagrrTrrrWriteNCs""(                rqc Kst|ds%|dkrtgd}n|dkrtgd}n |dkr%tgd}t||fd|i|}t|j|jd}t|D]%\}} ||j|dt|j|d||dd |j |d}q>|S) a; construct time series using harmonics: used to fill data gap, or extrapolation [oti,oyi,dt]: observed (time, value, time interval) mti: time to interpolate/extrapolate tidal_names=0/1/2: tidal names options; tidal_names=['O1','K1','Q1','P1','M2','S2',]: list of tidal consituent names r*r)O1K1Q1P1M2S2K2N2r)rrrsrtrurvrwrxryM3M4M6M7M8M10r")SAZSSAZMMMSFrrrsrtrurvrwrxryrzr{r|r}r~rZN4ZS4ZS6 tidal_namesQ) r?rharmonic_analysisrrA amplituderLrfreqphase) ZotiZoyirZmtirrHZmyirbtnamerrr harmonic_fitEs  Trc Csbddl}|dur d}|durd}|durd}dtjt} |durbddl} | ddg} | d kr>d d | Dd}n| d krPd d | Dd}n t d| |durbt d|durld| }n>t |t std| } tt| j| j} t|d}|dt||D]}|d|| |q||}t|d}t|D]\}}|d|||d|q||||||gt}tdd t|dDj\|_|_|_ t|j!d|_t|j !d|_ t"dtdd t|ddddD!df|_t#|t#|tj$|r/t#||S)a harmonic analyze time series data: time series dt: time step (day) t0: starting time of time series (day); normally use datenum (e.g. datenum(2010,0,0)) tidal_names: 1) path of tidal_const.dat, or 2) names of tidal consituents code: path of executable (tidal_analyze, or tidal_analyze.exe) for HA analysis [tname,fname,sname]: temporary names for tidal_const, time series, and HA results rNz!.temporary_tidal_const_for_HA.datz!.temporary_time_series_for_HA.datz'.temporary_tidal_consituents_for_HA.datz!{}/../pyScripts/Harmonic_AnalysiszD:\Work\Harmonic_Analysisz~/bin/Harmonic_AnalysiswindowscS(g|]}tjd|rd|qS)z{}/tidal_analyze.exer9r:r;r}r.rrrr1vr1z%harmonic_analysis..linuxcSr)z{}/tidal_analyzerr.rrrr1xr1zOperating System unknow: {}z(exectuable "tidal_analyze" was not foundz{}/tidal_const.datz{}/tide_fac_const.npzr)z{} z{} {} z{:12.1f} {:12.7f} rcSsg|]}|qSr)rkrlr.rrrr1rergrcSsg|]}|qSr)rkr.rrrr1r2r")%rr}r9r:r rplatformsystemrrrrrfr>rrzipnamerrirrOupperrUrLcallrrrjrZ tidal_namerrrCrIrr;)rVrt0rrrrrrZsdirrZbdirsrZtdictr[r0rcrrrrr^s<       (  00$6r./HYCOMc8 Csdddddgg}dddd d gg}t|}t|}|jd kr)|d d d f}|d d d f} |d d d f} t| | f} |jd dkrU|d d df} t| | | f} t}|d d d f|_|d d d f|_ |jd dkrz|d d df|_ t}|D]W}||}||}t }g}g}t ||d D]}t |}t |d d}t|tr.d|d |d|d}d|d |d|d}tjd||sqtjd||sqt|d|td||}td||d}td|d td|d t|j|_|jdk}t|j|_|jdk}t|j|<t|j|<nsn   D 7 V ~  I P $ "E  '=   aY  %  T a  , i & C b  8