Skip to content

Commit c8f627a

Browse files
committed
Update to README on how to setup PYTHONPATH and what scripts use deprecated units package. Small fixes to other python scripts so they run.
1 parent 862bb28 commit c8f627a

File tree

11 files changed

+148
-142
lines changed

11 files changed

+148
-142
lines changed

helpers/README.md

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,28 @@
11
# Install Python Dependencies
22
The following instructions and dependecy files work for the core ICAR scripts.
3-
Tools in `make_domain.py` and ccsm, cesm, cmip, erai, and wrf directories will require Bunch and mygis packages as well.
3+
Tools in `make_domain.py` and ccsm, cesm, cmip, erai, and wrf directories will require the mygis packages as well.
44
The Python script `ideal_linear.py` will require Nio to be installed with `pip install nio`.
55

6-
## Install With Conda
6+
## Setup Environment
7+
### Install With Conda
78
```bash
89
$ conda env create -f environment.yml --prefix /path/to/install/icar_env
910
$ conda activate icar_env
11+
$ conda env config vars set PYTHONPATH=$(pwd)/lib:$PYTHONPATH
12+
13+
reactivate environment, this will be saved for future use
14+
$ conda activate icar_env
1015
```
1116

12-
## Install With Pip
17+
### Install With Pip
1318
```bash
1419
$ pip install -r requirements.txt
1520
```
21+
Make sure the `lib` directory is in the `PYTHONPATH`, add to `.bashrc` or other startup files for repeat use.
22+
```bash
23+
$ export PYTHONPATH=$(pwd)/lib:$PYTHONPATH
24+
```
25+
26+
27+
## Deprecated Scripts
28+
The units package used in the `cmip/convert.py, cesm/bias_correct.py` and `gen_sounding.py` scripts has been deprecated.

helpers/ccsm/config.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,28 +15,28 @@ def set_bounds(info):
1515
ccsm_file=atm_file.replace("_Y_","2006").replace("_M_","01").replace("_D_","01").replace("_VAR_","hus")
1616
ccsm_file=glob.glob(ccsm_file)[0]
1717
varlist=["lat","lon"]
18-
18+
1919
lat=io.read_nc(ccsm_file,varlist[0]).data
2020
lon=io.read_nc(ccsm_file,varlist[1]).data-360
21-
21+
2222
info.xmin=np.where(lon>=info.lon[0])[0][0]
2323
info.xmax=np.where(lon<=info.lon[1])[0][-1]+1
2424
info.ymin=np.where(lat>=info.lat[0])[0][0]
2525
info.ymax=np.where(lat<=info.lat[1])[0][-1]+1
26-
26+
2727
lon,lat=np.meshgrid(lon[info.xmin:info.xmax],lat[info.ymin:info.ymax])
2828
info.lat_data=lat
2929
info.lon_data=lon
30-
30+
3131
def make_timelist(info,hrs=6.0):
3232
dt=datetime.timedelta(hrs/24)
33-
info.ntimes=np.int(np.round((info.end_date-info.start_date).total_seconds()/60./60./hrs))
33+
info.ntimes=np.int64(np.round((info.end_date-info.start_date).total_seconds()/60./60./hrs))
3434
info.times=[info.start_date+dt*i for i in range(info.ntimes)]
3535

3636
def update_info(info):
3737
make_timelist(info)
3838
set_bounds(info)
39-
39+
4040

4141
def parse():
4242
parser= argparse.ArgumentParser(description='Convert CCSM files to ICAR input forcing files')
@@ -51,24 +51,24 @@ def parse():
5151
parser.add_argument('sfcdir', nargs="?",action='store',help="CCSM surface data file location", default="ccsm_sfc/")
5252
parser.add_argument('atmfile', nargs="?",action='store',help="CCSM atmospheric files", default="_VAR__6hrLev_CCSM4_rcp85_r6i1p1__Y__M__D_00-*.nc")
5353
parser.add_argument('sfcfile', nargs="?",action='store',help="CCSM surface files", default="_VAR__3hr_CCSM4_rcp85_r6i1p1__Y__M__D_0000-*.nc")
54-
54+
5555
parser.add_argument('-v', '--version',action='version',
5656
version='CCSM2ICAR v'+version)
5757
parser.add_argument ('--verbose', action='store_true',
5858
default=False, help='verbose output', dest='verbose')
5959
args = parser.parse_args()
60-
60+
6161
date0=args.start_date.split("-")
6262
start_date=datetime.datetime(int(date0[0]),int(date0[1]),int(date0[2]))
6363

6464
date0=args.end_date.split("-")
6565
end_date=datetime.datetime(int(date0[0]),int(date0[1]),int(date0[2]))
66-
66+
6767
info=Bunch(lat=[float(args.lat_s),float(args.lat_n)],
6868
lon=[float(args.lon_w),float(args.lon_e)],
6969
start_date=start_date, end_date=end_date,
7070
atmdir=args.dir+args.atmdir, sfcdir=args.dir+args.sfcdir,
7171
atmfile=args.atmfile, sfcfile=args.sfcfile,
7272
version=version)
73-
73+
7474
return info

helpers/cmip/io_routines.py

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@ def read_nc(filename,var="data",proj=None,returnNCvar=False):
1717
data:raw data as an array
1818
proj:string representation of the projection information
1919
atts:data attribute dictionary (if any)
20-
if (returnNCvar==True) then the netCDF4 file is note closed and the netCDF4
21-
representation of the variable is returned instead of being read into
22-
memory immediately.
20+
if (returnNCvar==True) then the netCDF4 file is note closed and the netCDF4
21+
representation of the variable is returned instead of being read into
22+
memory immediately.
2323
'''
2424
d=netCDF4.Dataset(filename, mode='r',format="nc")
2525
outputdata=None
@@ -39,8 +39,8 @@ def read_nc(filename,var="data",proj=None,returnNCvar=False):
3939
if proj!=None:
4040
projection=d.variables[proj]
4141
outputproj=str(projection)
42-
43-
42+
43+
4444
if returnNCvar:
4545
return Bunch(data=outputdata,proj=outputproj,ncfile=d,atts=attributes)
4646
d.close()
@@ -53,7 +53,7 @@ def find_atm_file(time,varname,info):
5353
file_base= file_base.replace("_Y_",str(time.year))
5454
file_base= file_base.replace("_EXP_",info.experiment)
5555
atm_file = file_base.replace("_ENS_",info.ensemble)
56-
56+
5757
print(atm_file)
5858
filelist = glob.glob(atm_file)
5959
filelist.sort()
@@ -67,7 +67,7 @@ def find_sst_file(time,info):
6767
file_base= file_base.replace("_Y_",str(time.year))
6868
file_base= file_base.replace("_EXP_",info.experiment)
6969
sst_file = file_base.replace("_ENS_",info.ensemble)
70-
70+
7171
print(sst_file)
7272
filelist=glob.glob(sst_file)
7373
filelist.sort()
@@ -76,7 +76,7 @@ def find_sst_file(time,info):
7676

7777
def load_atm(time,info):
7878
"""Load atmospheric variable from a netcdf file"""
79-
79+
8080
outputdata=Bunch()
8181

8282
for s,v in zip(icar_atm_var,atmvarlist):
@@ -98,24 +98,24 @@ def load_atm(time,info):
9898
outputdata[varname]=np.concatenate([outputdata[varname],newdata])
9999
else:
100100
outputdata[varname]=newdata
101-
101+
102102
varname="p"
103103
newdata=info.read_pressure(atmfile)[:,:,info.ymin:info.ymax,info.xmin:info.xmax]
104104
if varname in outputdata:
105105
outputdata[varname]=np.concatenate([outputdata[varname],newdata])
106106
else:
107107
outputdata[varname]=newdata
108-
108+
109109
outputdata.ntimes = outputdata.p.shape[0]
110-
110+
111111
# outputdata.times=info.read_time(atmfile)
112112
try:
113113
calendar = mygis.read_attr(atmfile_list[0], "calendar", varname="time")
114-
except KeyError,IndexError:
114+
except (KeyError,IndexError):
115115
calendar = None
116-
116+
117117
outputdata.calendar = calendar
118-
118+
119119
return outputdata
120120

121121
def load_sfc(time,info):
@@ -137,5 +137,3 @@ def load_data(time,info):
137137
atm=load_atm(time,info)
138138
sfc=load_sfc(time,info)
139139
return Bunch(sfc=sfc,atm=atm)
140-
141-

helpers/erai/config.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,8 @@
33

44
import numpy as np
55

6-
from bunch import Bunch
76
import sys
8-
sys.path.append('../lib') # required to find mygis.py. Update as required.
7+
from bunch import Bunch
98
import mygis
109

1110
import io_routines as io
@@ -53,7 +52,7 @@ def set_bounds(info):
5352
def make_timelist(info):
5453
hrs=6.0
5554
dt=datetime.timedelta(hrs/24)
56-
info.ntimes=np.int(np.round((info.end_date-info.start_date).total_seconds()/60./60./hrs))
55+
info.ntimes=np.int64(np.round((info.end_date-info.start_date).total_seconds()/60./60./hrs))
5756
info.times=[info.start_date+dt*i for i in range(info.ntimes)]
5857

5958
def update_info(info):

helpers/gen_bc.py

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ def update_base(base,filename,nz):
2626
def main():
2727
filename="bc"
2828
nx,ny,nz,nt=(20.,20,10,24)
29-
dims=[nt,nz,ny,nx]
30-
29+
dims=[nt,nz,ny,int(nx)]
30+
3131
lonmin=-110.0; lonmax=-100.0; dlon=(lonmax-lonmin)/nx
3232
latmin=35.0; latmax=45.0; dlat=(latmax-latmin)/ny
3333

@@ -41,32 +41,32 @@ def main():
4141
update_base(base,"sounding.txt",nz)
4242
nz=base.th.size
4343
dims=[nt,nz,ny,nx]
44-
44+
4545
u=np.zeros(dims,dtype="f")+base.u
4646
w=np.zeros(dims,dtype="f")+base.w
4747
v=np.zeros(dims,dtype="f")+base.v
4848
qv=np.zeros(dims,dtype="f")+base.qv
4949
qc=np.zeros(dims,dtype="f")+base.qc
5050
coscurve=np.cos(np.arange(dims[2])/dims[2]*2*np.pi+np.pi)+1
51-
hgt=(coscurve*1000).reshape((1,nx)).repeat(ny,axis=0)
52-
51+
hgt=(coscurve*1000).reshape((1,int(nx))).repeat(ny,axis=0)
52+
5353
lon=np.arange(lonmin,lonmax,dlon)
5454
lat=np.arange(latmin,latmax,dlat)
5555
lon,lat=np.meshgrid(lon,lat)
56-
56+
5757
dz=np.zeros(dims)+base.dz
58-
z=np.zeros(dims,dtype="f")+base.z.reshape((1,nz,1,1))+hgt.reshape((1,1,ny,nx))
59-
58+
z=np.zeros(dims,dtype="f")+base.z.reshape((1,nz,1,1))+hgt.reshape((1,1,ny,int(nx)))
59+
6060
layer1=(dz[0,0,:,:]/2)
6161
z[0,0,:,:]+=layer1
6262
for i in range(1,int(nz)):
6363
z[:,i,:,:]=z[:,i-1,:,:]+(dz[:,i-1,:,:]+dz[:,i,:,:])/2.0
64-
64+
6565
p=np.zeros(dims,dtype="f")+base.p
6666
adjust_p(p,0.0,z)
6767
th=np.zeros(dims,dtype="f")+base.th
68-
69-
68+
69+
7070
d4dname=("t","z","y","x")
7171
d3dname=("z","y","x")
7272
d2dname=("y","x")
@@ -86,7 +86,7 @@ def main():
8686
if fileexists:
8787
print("Removing : "+fileexists[0])
8888
os.remove(fileexists[0])
89-
89+
9090
io.write(filename, u,varname="U", dims=d4dname,dtype="f",attributes=dict(units="m/s",description="Horizontal (x) wind speed"),
9191
extravars=othervars)
9292

helpers/gen_ideal.py

Lines changed: 22 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ def adjust_p(p,h,dz):
3030

3131
def update_base(base,filename,nz):
3232
"""update the base information using data from a sounding file
33-
33+
3434
filename should be a space delimited text file with 3 columns
3535
height [m], potential temperature [K], and specific humidity [g/kg]"""
3636
print("Using Sounding from : "+filename)
@@ -43,7 +43,7 @@ def update_base(base,filename,nz):
4343

4444
def build_topography(experiment,dims):
4545
"""create the topography to be used for a given case study"""
46-
46+
4747
# experiment D1 D2 D3
4848
# h height of the hill 1800 1400 1040 [meters]
4949
# sigma half-width 60 40 3.1 [grid cells]
@@ -60,8 +60,8 @@ def build_topography(experiment,dims):
6060
x = np.linspace(0,Lx,Nx) # % distance array (m)
6161
zo = [1700.0,2000.0,2200.0][experiment] # mountain base height (m) NOT REALLY USED CORRECTLY YET, NEED to truncate the sounding...
6262
zo = 0.0
63-
64-
63+
64+
6565
zs=hm/(1.0+((x/dx-xm)/am)**2.)
6666
# zs-=zs[0]
6767
zs=zs.reshape((1,dims[3])).repeat(dims[2],axis=0)
@@ -71,8 +71,8 @@ def main():
7171
filename="ideal_{}_{}".format(case_study,int(wind_speed))
7272
print(filename)
7373
nx,nz,ny=master_dims[case_study]
74-
dims=[1,nz,ny,nx]
75-
74+
dims=[1,int(nz),int(ny),int(nx)]
75+
7676
# this is just arbitrary for now
7777
dlon=dx/111.1
7878
dlat=dx/111.1
@@ -89,7 +89,7 @@ def main():
8989
update_base(base,"sounding.txt",nz)
9090
nz=base.th.size
9191
dims=[1,nz,ny,nx]
92-
92+
9393
udims=copy(dims)
9494
udims[-1]+=1
9595
vdims=copy(dims)
@@ -99,40 +99,40 @@ def main():
9999
v=np.zeros(vdims,dtype="f")+base.v
100100
qv=np.zeros(dims,dtype="f")+base.qv
101101
qc=np.zeros(dims,dtype="f")+base.qc
102-
102+
103103
# simple topography = a cosine
104104
# coscurve=np.cos(np.arange(dims[3])/dims[3]*2*np.pi+np.pi)+1
105105
# hgt=(coscurve*1000).reshape((1,nx)).repeat(ny,axis=0)
106106
hgt=build_topography(case_study,dims)
107-
108-
lon=np.arange(lonmin,lonmax,dlon)[:nx]
107+
108+
lon=np.arange(lonmin,lonmax,dlon)[:int(nx)]
109109
lat=np.arange(latmin,latmax,dlat)[:ny]
110110
lon,lat=np.meshgrid(lon,lat)
111111

112-
ulon=np.arange(lonmin-dlon/2,lonmax+dlon/2,dlon)[:nx+1]
112+
ulon=np.arange(lonmin-dlon/2,lonmax+dlon/2,dlon)[:int(nx)+1]
113113
ulat=np.arange(latmin,latmax,dlat)[:ny]
114114
ulon,ulat=np.meshgrid(ulon,ulat)
115115

116-
vlon=np.arange(lonmin,lonmax,dlon)[:nx]
116+
vlon=np.arange(lonmin,lonmax,dlon)[:int(nx)]
117117
vlat=np.arange(latmin-dlat/2,latmax+dlat/2,dlat)[:ny+1]
118118
vlon,vlat=np.meshgrid(vlon,vlat)
119-
119+
120120
dz=np.zeros(dims)+base.dz
121-
z=np.zeros(dims,dtype="f")+base.z.reshape((1,nz,1,1))+hgt.reshape((1,1,ny,nx))
122-
121+
z=np.zeros(dims,dtype="f")+base.z.reshape((1,nz,1,1))+hgt.reshape((1,1,ny,int(nx)))
122+
123123
layer1=(dz[0,:,:]/2)
124124
z[0,:,:]+=layer1
125125
for i in range(1,int(nz)):
126126
z[:,i,:,:]=z[:,i-1,:,:]+(dz[:,i-1,:,:]+dz[:,i,:,:])/2.0
127-
127+
128128
p=np.zeros(dims,dtype="f")+base.p
129129
adjust_p(p,0.0,z)
130130
th=np.zeros(dims,dtype="f")+base.th
131-
132-
lat=lat.reshape((1,ny,nx))
133-
lon=lon.reshape((1,ny,nx))
134-
hgt=hgt.reshape((1,ny,nx))
135-
131+
132+
lat=lat.reshape((1,ny,int(nx)))
133+
lon=lon.reshape((1,ny,int(nx)))
134+
hgt=hgt.reshape((1,ny,int(nx)))
135+
136136
d3dname=("t","z","y","x")
137137
ud3dname=("t","z","y","xu")
138138
ud2dname=("t","y","xu")
@@ -164,13 +164,12 @@ def main():
164164
if fileexists:
165165
print("Removing : "+fileexists[0])
166166
os.remove(fileexists[0])
167-
167+
168168
io.write(filename, u,varname="U", dims=ud3dname,dtype="f",attributes=dict(units="m/s",description="Horizontal (x) wind speed"),
169169
extravars=othervars)
170170

171171

172172
if __name__ == '__main__':
173-
global wind_speed, case_study
174173
for case in range(3):
175174
for ws in [5,10,15,25]:
176175
wind_speed=float(ws)

0 commit comments

Comments
 (0)