44import cdms2
55import numpy
66import cdat_info
7- def reconstructPressureFromHybrid (ps ,A ,B ,Po ):
7+
8+
9+ def reconstructPressureFromHybrid (ps , A , B , Po ):
810 """
911 Reconstruct the Pressure field on sigma levels, from the surface pressure
10-
12+
1113 Input
1214 Ps : Surface pressure
1315 A,B,Po: Hybrid Convertion Coefficients, such as: p=B.ps+A.Po
1416 Ps: surface pressure
1517 B,A are 1D : sigma levels
1618 Po and Ps must have same units
17-
19+
1820 Output
1921 Pressure field
2022 Such as P=B*Ps+A*Po
@@ -23,200 +25,234 @@ def reconstructPressureFromHybrid(ps,A,B,Po):
2325 P=reconstructPressureFromHybrid(ps,A,B,Po)
2426 """
2527 # Compute the pressure for the sigma levels
26- cdat_info .pingPCMDIdb ("cdat" ,"cdutil.vertical.reconstructPressureFromHybrid" )
27- ps ,B = genutil .grower (ps ,B )
28- ps ,A = genutil .grower (ps ,A )
29- p = ps * B
30- p = p + A * Po
28+ cdat_info .pingPCMDIdb (
29+ "cdat" ,
30+ "cdutil.vertical.reconstructPressureFromHybrid" )
31+ ps , B = genutil .grower (ps , B )
32+ ps , A = genutil .grower (ps , A )
33+ p = ps * B
34+ p = p + A * Po
3135 p .setAxisList (ps .getAxisList ())
32- p .id = 'P'
36+ p .id = 'P'
3337 try :
34- p .units = ps .units
38+ p .units = ps .units
3539 except :
36- pass
37- t = p .getTime ()
40+ pass
41+ t = p .getTime ()
3842 if not t is None :
39- p = p (order = 'tz...' )
43+ p = p (order = 'tz...' )
4044 else :
41- p = p (order = 'z...' )
45+ p = p (order = 'z...' )
4246 return p
43-
44- def linearInterpolation (A ,I ,levels = [100000 , 92500 , 85000 , 70000 , 60000 , 50000 , 40000 , 30000 , 25000 , 20000 , 15000 , 10000 , 7000 , 5000 , 3000 , 2000 , 1000 ], status = None ):
47+
48+
49+ def linearInterpolation (
50+ A , I , levels = [100000 , 92500 , 85000 , 70000 , 60000 , 50000 , 40000 ,
51+ 30000 , 25000 , 20000 , 15000 , 10000 , 7000 , 5000 , 3000 , 2000 , 1000 ], status = None , axis = 'z' ):
4552 """
4653 Linear interpolation
4754 to interpolate a field from some levels to another set of levels
4855 Value below "surface" are masked
49-
56+
5057 Input
5158 A : array to interpolate
5259 I : interpolation field (usually Pressure or depth) from TOP (level 0) to BOTTOM (last level), i.e P value going up with each level
5360 levels : levels to interplate to (same units as I), default levels are:[100000, 92500, 85000, 70000, 60000, 50000, 40000, 30000, 25000, 20000, 15000, 10000, 7000, 5000, 3000, 2000, 1000]
61+ axis: axis over which to do the linear interpolation, default is 'z', accepted: '1' '(myaxis)'
5462
5563 I and levels must have same units
5664
5765 Output
5866 array on new levels (levels)
59-
67+
6068 Examples:
6169 A=interpolate(A,I,levels=[100000, 92500, 85000, 70000, 60000, 50000, 40000, 30000, 25000, 20000, 15000, 10000, 7000, 5000, 3000, 2000, 1000])
6270 """
63-
64- cdat_info .pingPCMDIdb ("cdat" ,"cdutil.vertical.linearInterpolation" )
71+
72+ cdat_info .pingPCMDIdb ("cdat" , "cdutil.vertical.linearInterpolation" )
6573 try :
66- nlev = len (levels ) # Number of pressure levels
74+ nlev = len (levels ) # Number of pressure levels
6775 except :
68- nlev = 1 # if only one level len(levels) would breaks
69- levels = [levels ,]
70- order = A .getOrder ()
71- A = A (order = 'z ...' )
72- I = I (order = 'z ...' )
73- sh = list (I .shape )
74- nsigma = sh [0 ] # number of sigma levels
75- sh [0 ]= nlev
76- t = MV2 .zeros (sh ,typecode = MV2 .float32 )
77- sh2 = I [0 ].shape
78- prev = - 1
79- for ilev in range (nlev ): # loop through pressure levels
76+ nlev = 1 # if only one level len(levels) would breaks
77+ levels = [levels , ]
78+ order = A .getOrder ()
79+ A = A (order = '%s ...' % axis )
80+ I = I (order = '%s ...' % axis )
81+ sh = list (I .shape )
82+ nsigma = sh [0 ] # number of sigma levels
83+ sh [0 ] = nlev
84+ t = MV2 .zeros (sh , typecode = MV2 .float32 )
85+ sh2 = I [0 ].shape
86+ prev = - 1
87+ for ilev in range (nlev ): # loop through pressure levels
8088 if status is not None :
81- prev = genutil .statusbar (ilev ,nlev - 1. ,prev )
82- lev = levels [ilev ] # get value for the level
83- Iabv = MV2 .ones (sh2 ,MV2 .float )
84- Aabv = - 1 * Iabv # Array on sigma level Above
85- Abel = - 1 * Iabv # Array on sigma level Below
86- Ibel = - 1 * Iabv # Pressure on sigma level Below
87- Iabv = - 1 * Iabv # Pressure on sigma level Above
88- Ieq = MV2 .masked_equal (Iabv ,- 1 ) # Area where Pressure == levels
89- for i in range (1 ,nsigma ): # loop from second sigma level to last one
90- a = MV2 .greater_equal (I [i ], lev ) # Where is the pressure greater than lev
91- b = MV2 .less_equal (I [i - 1 ],lev ) # Where is the pressure less than lev
89+ prev = genutil .statusbar (ilev , nlev - 1. , prev )
90+ lev = levels [ilev ] # get value for the level
91+ Iabv = MV2 .ones (sh2 , MV2 .float )
92+ Aabv = - 1 * Iabv # Array on sigma level Above
93+ Abel = - 1 * Iabv # Array on sigma level Below
94+ Ibel = - 1 * Iabv # Pressure on sigma level Below
95+ Iabv = - 1 * Iabv # Pressure on sigma level Above
96+ Ieq = MV2 .masked_equal (Iabv , - 1 ) # Area where Pressure == levels
97+ for i in range (1 , nsigma ): # loop from second sigma level to last one
98+ a = MV2 .greater_equal (
99+ I [i ],
100+ lev ) # Where is the pressure greater than lev
101+ b = MV2 .less_equal (
102+ I [i - 1 ],
103+ lev ) # Where is the pressure less than lev
92104 # Now looks if the pressure level is in between the 2 sigma levels
93105 # If yes, sets Iabv, Ibel and Aabv, Abel
94- a = MV2 .logical_and (a ,b )
95- Iabv = MV2 .where (a ,I [i ],Iabv ) # Pressure on sigma level Above
96- Aabv = MV2 .where (a ,A [i ],Aabv ) # Array on sigma level Above
97- Ibel = MV2 .where (a ,I [i - 1 ],Ibel ) # Pressure on sigma level Below
98- Abel = MV2 .where (a ,A [i - 1 ],Abel ) # Array on sigma level Below
99- Ieq = MV2 .where (MV2 .equal (I [i ],lev ),A [i ],Ieq )
100-
101- val = MV2 .masked_where (MV2 .equal (Ibel ,- 1. ),numpy .ones (Ibel .shape )* lev ) # set to missing value if no data below lev if there is
102-
103- tl = (val - Ibel )/ (Iabv - Ibel )* (Aabv - Abel )+ Abel # Interpolation
106+ a = MV2 .logical_and (a , b )
107+ Iabv = MV2 .where (a , I [i ], Iabv ) # Pressure on sigma level Above
108+ Aabv = MV2 .where (a , A [i ], Aabv ) # Array on sigma level Above
109+ Ibel = MV2 .where (
110+ a ,
111+ I [i - 1 ],
112+ Ibel ) # Pressure on sigma level Below
113+ Abel = MV2 .where (a , A [i - 1 ], Abel ) # Array on sigma level Below
114+ Ieq = MV2 .where (MV2 .equal (I [i ], lev ), A [i ], Ieq )
115+
116+ val = MV2 .masked_where (
117+ MV2 .equal (Ibel , - 1. ), numpy .ones (Ibel .shape ) * lev )
118+ # set to missing value if no data below lev if
119+ # there is
120+
121+ tl = (val - Ibel ) / (Iabv - Ibel ) * \
122+ (Aabv - Abel ) + Abel # Interpolation
104123 if ((Ieq .mask is None ) or (Ieq .mask is MV2 .nomask )):
105- tl = Ieq
124+ tl = Ieq
106125 else :
107- tl = MV2 .where (1 - Ieq .mask ,Ieq ,tl )
108- t [ilev ]= tl .astype (MV2 .float32 )
126+ tl = MV2 .where (1 - Ieq .mask , Ieq , tl )
127+ t [ilev ] = tl .astype (MV2 .float32 )
109128
110- ax = A .getAxisList ()
111- autobnds = cdms2 .getAutoBounds ()
129+ ax = A .getAxisList ()
130+ autobnds = cdms2 .getAutoBounds ()
112131 cdms2 .setAutoBounds ('off' )
113- lvl = cdms2 .createAxis (MV2 .array (levels ).filled ())
132+ lvl = cdms2 .createAxis (MV2 .array (levels ).filled ())
114133 cdms2 .setAutoBounds (autobnds )
115134 try :
116- lvl .units = I .units
135+ lvl .units = I .units
117136 except :
118137 pass
119- lvl .id = 'plev'
120-
138+ lvl .id = 'plev'
139+
121140 try :
122- t .units = I .units
141+ t .units = I .units
123142 except :
124- pass
125-
126- ax [0 ]= lvl
143+ pass
144+
145+ ax [0 ] = lvl
127146 t .setAxisList (ax )
128- t .id = A .id
147+ t .id = A .id
129148 for att in A .listattributes ():
130- setattr (t ,att ,getattr (A ,att ))
149+ setattr (t , att , getattr (A , att ))
131150 return t (order = order )
132151
133- def logLinearInterpolation (A ,P ,levels = [100000 , 92500 , 85000 , 70000 , 60000 , 50000 , 40000 , 30000 , 25000 , 20000 , 15000 , 10000 , 7000 , 5000 , 3000 , 2000 , 1000 ],status = None ):
152+
153+ def logLinearInterpolation (
154+ A , P , levels = [100000 , 92500 , 85000 , 70000 , 60000 , 50000 , 40000 ,
155+ 30000 , 25000 , 20000 , 15000 , 10000 , 7000 , 5000 , 3000 , 2000 , 1000 ], status = None , axis = 'z' ):
134156 """
135157 Log-linear interpolation
136158 to convert a field from sigma levels to pressure levels
137159 Value below surface are masked
138-
160+
139161 Input
140- A : array on sigma levels
141- P : pressure field from TOP (level 0) to BOTTOM (last level)
162+ A : array on sigma levels
163+ P : pressure field from TOP (level 0) to BOTTOM (last level)
142164 levels : pressure levels to interplate to (same units as P), default levels are:[100000, 92500, 85000, 70000, 60000, 50000, 40000, 30000, 25000, 20000, 15000, 10000, 7000, 5000, 3000, 2000, 1000]
165+ axis: axis over which to do the linear interpolation, default is 'z', accepted: '1' '(myaxis)'
143166
144167 P and levels must have same units
145168
146169 Output
147170 array on pressure levels (levels)
148-
171+
149172 Examples:
150173 A=logLinearInterpolation(A,P),levels=[100000, 92500, 85000, 70000, 60000, 50000, 40000, 30000, 25000, 20000, 15000, 10000, 7000, 5000, 3000, 2000, 1000])
151174 """
152-
153- cdat_info .pingPCMDIdb ("cdat" ,"cdutil.vertical.logLinearInterpolation" )
175+
176+ cdat_info .pingPCMDIdb ("cdat" , "cdutil.vertical.logLinearInterpolation" )
154177 try :
155- nlev = len (levels ) # Number of pressure levels
178+ nlev = len (levels ) # Number of pressure levels
156179 except :
157- nlev = 1 # if only one level len(levels) would breaks
158- levels = [levels ,]
159- order = A .getOrder ()
160- A = A (order = 'z ...' )
161- P = P (order = 'z ...' )
162- sh = list (P .shape )
163- nsigma = sh [0 ] # number of sigma levels
164- sh [0 ]= nlev
165- t = MV2 .zeros (sh ,typecode = MV2 .float32 )
166- sh2 = P [0 ].shape
167- prev = - 1
168- for ilev in range (nlev ): # loop through pressure levels
180+ nlev = 1 # if only one level len(levels) would breaks
181+ levels = [levels , ]
182+ order = A .getOrder ()
183+ A = A (order = '%s ...' % axis )
184+ P = P (order = '%s ...' % axis )
185+ sh = list (P .shape )
186+ nsigma = sh [0 ] # number of sigma levels
187+ sh [0 ] = nlev
188+ t = MV2 .zeros (sh , typecode = MV2 .float32 )
189+ sh2 = P [0 ].shape
190+ prev = - 1
191+ for ilev in range (nlev ): # loop through pressure levels
169192 if status is not None :
170- prev = genutil .statusbar (ilev ,nlev - 1. ,prev )
171- lev = levels [ilev ] # get value for the level
172- Pabv = MV2 .ones (sh2 ,MV2 .float )
173- Aabv = - 1 * Pabv # Array on sigma level Above
174- Abel = - 1 * Pabv # Array on sigma level Below
175- Pbel = - 1 * Pabv # Pressure on sigma level Below
176- Pabv = - 1 * Pabv # Pressure on sigma level Above
177- Peq = MV2 .masked_equal (Pabv ,- 1 ) # Area where Pressure == levels
178- for i in range (1 ,nsigma ): # loop from second sigma level to last one
179- a = MV2 .greater_equal (P [i ], lev ) # Where is the pressure greater than lev
180- b = MV2 .less_equal (P [i - 1 ],lev ) # Where is the pressure less than lev
193+ prev = genutil .statusbar (ilev , nlev - 1. , prev )
194+ lev = levels [ilev ] # get value for the level
195+ Pabv = MV2 .ones (sh2 , MV2 .float )
196+ Aabv = - 1 * Pabv # Array on sigma level Above
197+ Abel = - 1 * Pabv # Array on sigma level Below
198+ Pbel = - 1 * Pabv # Pressure on sigma level Below
199+ Pabv = - 1 * Pabv # Pressure on sigma level Above
200+ Peq = MV2 .masked_equal (Pabv , - 1 ) # Area where Pressure == levels
201+ for i in range (1 , nsigma ): # loop from second sigma level to last one
202+ a = MV2 .greater_equal (
203+ P [i ],
204+ lev ) # Where is the pressure greater than lev
205+ b = MV2 .less_equal (
206+ P [i - 1 ],
207+ lev ) # Where is the pressure less than lev
181208 # Now looks if the pressure level is in between the 2 sigma levels
182209 # If yes, sets Pabv, Pbel and Aabv, Abel
183- a = MV2 .logical_and (a ,b )
184- Pabv = MV2 .where (a ,P [i ],Pabv ) # Pressure on sigma level Above
185- Aabv = MV2 .where (a ,A [i ],Aabv ) # Array on sigma level Above
186- Pbel = MV2 .where (a ,P [i - 1 ],Pbel ) # Pressure on sigma level Below
187- Abel = MV2 .where (a ,A [i - 1 ],Abel ) # Array on sigma level Below
188- Peq = MV2 .where (MV2 .equal (P [i ],lev ),A [i ],Peq )
189-
190- val = MV2 .masked_where (MV2 .equal (Pbel ,- 1 ),numpy .ones (Pbel .shape )* lev ) # set to missing value if no data below lev if there is
191-
192- tl = MV2 .log (val / Pbel )/ MV2 .log (Pabv / Pbel )* (Aabv - Abel )+ Abel # Interpolation
210+ a = MV2 .logical_and (a , b )
211+ Pabv = MV2 .where (a , P [i ], Pabv ) # Pressure on sigma level Above
212+ Aabv = MV2 .where (a , A [i ], Aabv ) # Array on sigma level Above
213+ Pbel = MV2 .where (
214+ a ,
215+ P [i - 1 ],
216+ Pbel ) # Pressure on sigma level Below
217+ Abel = MV2 .where (a , A [i - 1 ], Abel ) # Array on sigma level Below
218+ Peq = MV2 .where (MV2 .equal (P [i ], lev ), A [i ], Peq )
219+
220+ val = MV2 .masked_where (
221+ MV2 .equal (Pbel , - 1 ), numpy .ones (Pbel .shape ) * lev )
222+ # set to missing value if no data below lev if
223+ # there is
224+
225+ tl = MV2 .log (
226+ val / Pbel ) / MV2 .log (
227+ Pabv / Pbel ) * (
228+ Aabv - Abel ) + Abel # Interpolation
193229 if ((Peq .mask is None ) or (Peq .mask is MV2 .nomask )):
194- tl = Peq
230+ tl = Peq
195231 else :
196- tl = MV2 .where (1 - Peq .mask ,Peq ,tl )
197- t [ilev ]= tl .astype (MV2 .float32 )
198-
199- ax = A .getAxisList ()
200- autobnds = cdms2 .getAutoBounds ()
232+ tl = MV2 .where (1 - Peq .mask , Peq , tl )
233+ t [ilev ] = tl .astype (MV2 .float32 )
234+
235+ ax = A .getAxisList ()
236+ autobnds = cdms2 .getAutoBounds ()
201237 cdms2 .setAutoBounds ('off' )
202- lvl = cdms2 .createAxis (MV2 .array (levels ).filled ())
238+ lvl = cdms2 .createAxis (MV2 .array (levels ).filled ())
203239 cdms2 .setAutoBounds (autobnds )
204240 try :
205- lvl .units = P .units
241+ lvl .units = P .units
206242 except :
207243 pass
208- lvl .id = 'plev'
209-
244+ lvl .id = 'plev'
245+
210246 try :
211- t .units = P .units
247+ t .units = P .units
212248 except :
213- pass
214-
215- ax [0 ]= lvl
249+ pass
250+
251+ ax [0 ] = lvl
216252 t .setAxisList (ax )
217- t .id = A .id
253+ t .id = A .id
218254 for att in A .listattributes ():
219- setattr (t ,att ,getattr (A ,att ))
255+ setattr (t , att , getattr (A , att ))
220256 return t (order = order )
221-
222- sigma2Pressure = logLinearInterpolation
257+
258+ sigma2Pressure = logLinearInterpolation
0 commit comments