casa
$Rev:20696$
|
00001 ############################################### 00002 ## To plot stuff in weather tables, saved to MSname+.plotWX.png 00003 ## and estimate zenith opacity per spw, returned as a list named myTau 00004 ## 00005 ## 00006 ## J. Marvil 2.6.12 00007 ## revised 4.27.12 to add support for missing/empty weather table 00008 ## revised 11.05.12 to address CASA 4.0 changes 00009 ############################################### 00010 00011 00012 import casac 00013 from taskinit import * 00014 import pylab as pl 00015 from math import pi,floor 00016 import os.path as osp 00017 00018 00019 ############### 00020 ## hides the extreme Y-axis ticks, helps stack plots close together without labels overlaping 00021 def jm_clip_Yticks(): 00022 xa=pl.gca() 00023 nlabels=0 00024 for label in xa.yaxis.get_ticklabels(): 00025 nlabels+=1 00026 thislabel=0 00027 if nlabels>3: 00028 for label in xa.yaxis.get_ticklabels(): 00029 if thislabel==0: label.set_alpha(0) 00030 if thislabel==nlabels-1: label.set_alpha(0) 00031 thislabel+=1 00032 00033 ############## 00034 ## sets the position of the y-axis label to the right side of the plot, can also move up/down 00035 def jm_set_Ylabel_pos(pos=(0.5,0.5)): 00036 ax=pl.gca(); 00037 ax.yaxis.set_label_position('right') 00038 ax.yaxis.label.set_rotation(270) 00039 ax.yaxis.label.set_position(pos) 00040 00041 00042 ############### 00043 ## fixed y-ticks, from myMin to myMax 00044 def jm_set_Ylim_ticks(myMin=-1,myMax=1): 00045 myYlocs=pl.linspace(round(myMin,1),round(myMax,1),5) 00046 myLocator = pl.FixedLocator(myYlocs) 00047 ax=pl.gca() 00048 ax.yaxis.set_major_locator( myLocator ) 00049 pl.ylim(myMin,myMax) 00050 jm_clip_Yticks() 00051 00052 ############### 00053 ## variable y-ticks, but not more than 1+ this argument 00054 def jm_set_Yvar_ticks(myScale=4): 00055 xa=pl.gca() 00056 xa.yaxis.set_major_locator(pl.MaxNLocator(myScale)) 00057 jm_clip_Yticks() 00058 00059 ############### 00060 ## calculates K-band zenith opacity from temperature and dewpoint 00061 def Tau_K_Calc(D,T,day, weights=(.5,.5)): 00062 P = pl.exp(1.81+(17.27*D)/(D+237.3)) # water vapor partial pressure 00063 h = 324.7*P/(T+273.15) # PWV in mm 00064 tau_w = 3.8 + 0.23*h + 0.065*h**2 # tau from weather, in %, at 22GHz 00065 if day > 199: day = day - 365. 00066 m = day + 165. # modified day of the year 00067 tau_d = 22.1 - 0.178*m + 0.00044*m**2 # tau from seaonal model, in % 00068 tau_k = weights[0]*tau_w + weights[1]*tau_d # the average, with equal weights (as in the AIPS default) 00069 return tau_k, h 00070 00071 ################ 00072 ## calculates elevation of the sun 00073 def jm_sunEL(mytime): 00074 me.doframe(me.observatory('VLA')) 00075 me.doframe(me.epoch('utc',mytime)) 00076 mysun=me.measure(me.direction('SUN'),'AZELGEO') 00077 return mysun['m1']['value'] 00078 00079 ################ 00080 ## gets and plots data from the weather table of the given MS 00081 def plotweather(vis='', seasonal_weight=0.5, doPlot=True, plotName = ''): 00082 myMS=vis 00083 if plotName == '': plotName = myMS+'.plotweather.png' 00084 00085 # check for weather table 00086 00087 if osp.isdir(myMS+'/WEATHER'): 00088 00089 try: 00090 tb.open(myMS+'/WEATHER') 00091 firstTime = tb.getcol('TIME')[0] 00092 tb.close() 00093 WEATHER_table_exists = True 00094 00095 except: 00096 print 'could not open weather table, using seasonal model only and turning off plots' 00097 WEATHER_table_exists = False 00098 doPlot=False 00099 seasonal_weight = 1.0 00100 else: 00101 print 'could not find a weather table, using seasonal model only and turning off plots' 00102 WEATHER_table_exists = False 00103 doPlot=False 00104 seasonal_weight = 1.0 00105 00106 00107 00108 ##retrieve center frequency for each sub-band 00109 tb.open(myMS+'/SPECTRAL_WINDOW') 00110 spwFreqs=tb.getcol('REF_FREQUENCY') * 1e-9 00111 tb.close() 00112 00113 ##retrieve stuff from weather table, if exists 00114 00115 if WEATHER_table_exists: 00116 tb.open(myMS+'/WEATHER') 00117 mytime=tb.getcol('TIME') 00118 mytemp=tb.getcol('TEMPERATURE') - 273.15 00119 mydew=tb.getcol('DEW_POINT') - 273.15 00120 mywinds=tb.getcol('WIND_SPEED') 00121 mywindd=tb.getcol('WIND_DIRECTION')*(180.0/pi) 00122 mypres=tb.getcol('PRESSURE') 00123 myhum=tb.getcol('REL_HUMIDITY') 00124 tb.close() 00125 00126 else: 00127 ms.open(myMS) 00128 mytime_range = ms.range(["time"]) 00129 mytime = [mytime_range['time'][0]] 00130 00131 00132 ##calculate the elevation of the sun 00133 sunEL=[] 00134 for time in mytime: 00135 t1= qa.quantity(time,'s') 00136 myday=qa.convert(t1,'d') 00137 sunEL1=jm_sunEL(myday) 00138 sunEL.append(sunEL1) 00139 00140 ##convert time to a string of date/time 00141 myTimestr = [] 00142 myTimestr2=[] 00143 for time in mytime: 00144 q1=qa.quantity(time,'s') 00145 time1=qa.time(q1,form='ymd')[0] 00146 time2=qa.time(q1,form='local')[0] 00147 myTimestr.append(time1) 00148 myTimestr2.append(time2) 00149 00150 ##convert time to a decimal 00151 numtime=pl.datestr2num(myTimestr) 00152 00153 ##### calculate opacity as in EVLA memo 143 00154 thisday= 30*(float(myTimestr[0][5:7])-1)+float(myTimestr[0][8:10]) 00155 thisday=thisday + 5 * (thisday / 365.) 00156 00157 00158 if WEATHER_table_exists: 00159 # get 22 GHz zenith opacity and pwv estimate from weatherstation (myPWV) 00160 myTauZ, myPWV1 = Tau_K_Calc(mydew,mytemp,thisday) 00161 myTauZ1, myPWV = Tau_K_Calc(mydew,mytemp,thisday, weights=(0,1.0)) 00162 myTauZ2, myPWV = Tau_K_Calc(mydew,mytemp,thisday, weights=(1.0,0)) 00163 00164 # estimate pwv from seasonal model zenith opacity 00165 myPWV2 = -1.71 + 1.3647*myTauZ1 00166 myPWV = (1-seasonal_weight)*myPWV1 + seasonal_weight*myPWV2 00167 00168 else: 00169 day = thisday*1.0 00170 if day > 199: day = day - 365. 00171 m = day + 165. # modified day of the year 00172 myTauZ = 22.1 - 0.178*m + 0.00044*m**2 # tau from seaonal model, in % 00173 myPWV = -1.71 + 1.3647*myTauZ 00174 myPWV1, myPWV2 = myPWV, myPWV 00175 myTauZ1, myTauZ2 = myTauZ, myTauZ 00176 00177 tmp = qa.quantity(270.0,'K') 00178 pre = qa.quantity(790.0,'mbar') 00179 alt = qa.quantity(2125,'m') 00180 h0 = qa.quantity(2.0,'km') 00181 wvl = qa.quantity(-5.6, 'K/km') 00182 mxA = qa.quantity(48,'km') 00183 dpr = qa.quantity(10.0,'mbar') 00184 dpm = 1.2 00185 att = 1 00186 nb = 1 00187 00188 fC=qa.quantity(25.0,'GHz') 00189 fW=qa.quantity(50.,'GHz') 00190 fR=qa.quantity(0.25,'GHz') 00191 00192 at=casac.atmosphere() 00193 hum=20.0 00194 00195 myatm=at.initAtmProfile(alt,tmp,pre,mxA,hum,wvl,dpr,dpm,h0,att) 00196 00197 at.initSpectralWindow(nb,fC,fW,fR) 00198 sg=at.getSpectralWindow() 00199 mysg = sg['value'] 00200 00201 nstep = 20 00202 pwv = [] 00203 opac = pl.zeros((len(mysg),nstep)) 00204 00205 for i in range(nstep): 00206 hum = 20.0*(i+1) 00207 myatm = at.initAtmProfile(alt,tmp,pre,mxA,hum,wvl,dpr,dpm,h0,att) 00208 w=at.getGroundWH2O() 00209 pwv.append(w['value'][0]) 00210 at.initSpectralWindow(nb,fC,fW,fR) 00211 at.setUserWH2O(w) 00212 sg=at.getSpectralWindow() 00213 mysg = sg['value'] 00214 sdry=at.getDryOpacitySpec() 00215 swet=at.getWetOpacitySpec() 00216 sd=sdry[1] 00217 sw=swet[1]['value'] 00218 stot = pl.array(sd)+pl.array(sw) 00219 opac[:,i]=stot 00220 00221 pwv_coef=pl.zeros((len(mysg),2)) 00222 for i in range(len(mysg)): 00223 myfit=pl.polyfit(pwv,opac[i,:],1) 00224 pwv_coef[i,:]=myfit 00225 00226 freqs=pl.array(mysg)/1e9 00227 coef0=pwv_coef[:,1]/1e-3 00228 coef1=pwv_coef[:,0]/1e-3 00229 00230 00231 #interpolate between nearest table entries for each spw center frequency 00232 meanTau=[] 00233 00234 for i in range(len(spwFreqs)): 00235 mysearch=(pl.array(freqs)-spwFreqs[i])**2 00236 hits=pl.find(mysearch == min(mysearch)) 00237 if len(hits) > 1: hits=hits[0] 00238 tau_interp = (pl.array(coef0[hits-2:hits+2])+pl.array(coef1[hits-2:hits+2])*pl.mean(myPWV)) * 1e-1 #percent 00239 tau_F = pl.interp(spwFreqs[i],freqs[hits-2:hits+2],tau_interp) 00240 meanTau.append(pl.mean(tau_F*.01)) #nepers 00241 00242 00243 tau_allF = (pl.array(coef0) + pl.array(coef1)*pl.mean(myPWV)) * 1e-1 #percent 00244 tau_allF1 = (pl.array(coef0) + pl.array(coef1)*pl.mean(myPWV1)) *1e-1 00245 tau_allF2 = (pl.array(coef0) + pl.array(coef1)*pl.mean(myPWV2)) *1e-1 00246 00247 casalog.post('SPW : Frequency (GHz) : Zenith opacity (nepers)') 00248 for i in range(len(meanTau)): 00249 myStr = str(i).rjust(3) + ' : ' 00250 myStr2 = '%.3f'%(spwFreqs[i]) 00251 myStr += myStr2.rjust(7) + ' : ' +str(round(meanTau[i], 3)) 00252 casalog.post(myStr) 00253 00254 00255 00256 ##make the plots 00257 00258 if doPlot==False: 00259 return meanTau 00260 00261 pl.ioff() 00262 myColor2='#A6A6A6' 00263 myColorW='#92B5F2' 00264 myColor1='#4D4DFF' 00265 myOrangeColor='#FF6600' 00266 myYellowColor='#FFCC00' 00267 myWeirdColor='#006666' 00268 myLightBrown='#996633' 00269 myDarkGreay='#333333' 00270 00271 thisfig=pl.figure(1) 00272 thisfig.clf() 00273 thisfig.set_size_inches(8.5,10) 00274 00275 Xrange=numtime[-1]-numtime[0] 00276 Yrange=max(mywinds)-min(mywinds) 00277 Xtextoffset=-Xrange*.01 00278 Ytextoffset=-Yrange*.08 00279 Xplotpad=Xrange*.03 00280 Yplotpad=Yrange*.03 00281 00282 sp1=thisfig.add_axes([.13,.8,.8,.15]) 00283 pl.ylabel('solar el') 00284 nsuns=30 00285 myj=pl.array(pl.linspace(0,len(sunEL)-1,nsuns),dtype='int') 00286 for i in myj: 00287 if sunEL[i]<0: pl.plot([numtime[i],numtime[i]],[(180/pi)*sunEL[i],(180/pi)*sunEL[i]],'kH') 00288 else: pl.plot([numtime[i],numtime[i]],[(180/pi)*sunEL[i],(180/pi)*sunEL[i]],'H',color=myYellowColor) 00289 pl.plot([numtime[0],numtime[-1]],[0,0],'-',color='brown') 00290 xa=pl.gca(); xa.set_xticklabels('') 00291 jm_set_Ylim_ticks(myMin=-90,myMax=90) 00292 jm_set_Ylabel_pos(pos=(0,.5)) 00293 pl.title('Weather Summary for '+myMS) 00294 pl.xlim(numtime[0]-Xplotpad,numtime[-1]+Xplotpad) 00295 xa.set_xticks(pl.linspace(min(numtime),max(numtime),3)) 00296 00297 sp2=thisfig.add_axes([.13,.65,.8,.15]) 00298 pl.ylabel('wind (m/s)') 00299 nwind=60 00300 myj=pl.array(pl.linspace(0,len(mywinds)-1,nwind),dtype='int') 00301 for i in myj: 00302 pl.text(numtime[i]+Xtextoffset,Ytextoffset+mywinds[i],'-->',rotation=mywindd[i], alpha=1,color='purple',fontsize=12) 00303 00304 pl.plot(numtime, .3+mywinds,'.', color='black', ms=2, alpha=0) 00305 jm_set_Ylabel_pos(pos=(0,.5)) 00306 jm_set_Yvar_ticks(5) 00307 xa=pl.gca(); xa.set_xticklabels('') 00308 pl.xlim(numtime[0]-Xplotpad,numtime[-1]+Xplotpad) 00309 pl.ylim(min(mywinds)-Yplotpad,max(mywinds)+Yplotpad) 00310 xa.set_xticks(pl.linspace(min(numtime),max(numtime),3)) 00311 00312 sp4=thisfig.add_axes([.13,.5,.8,.15]) 00313 pl.plot(numtime, mytemp,'-', color=myOrangeColor,lw=2) 00314 pl.plot(numtime, mydew,'-', color=myWeirdColor,lw=2) 00315 pl.ylabel('temp,dew') 00316 jm_set_Ylabel_pos(pos=(0, .5)) 00317 xa=pl.gca(); xa.set_xticklabels('') 00318 jm_set_Yvar_ticks(5) 00319 pl.xlim(numtime[0]-Xplotpad,numtime[-1]+Xplotpad) 00320 xa.set_xticks(pl.linspace(min(numtime),max(numtime),3)) 00321 00322 sp7=thisfig.add_axes([.13,.35,.8,.15]) 00323 pl.ylabel('PWV (mm)') 00324 pl.plot(numtime, myPWV2, color=myColor2, lw=2, label='seasonal model') 00325 pl.plot(numtime, myPWV1, color=myColor1, lw=2, label='weather station') 00326 pl.plot(numtime, myPWV, color=myColorW,lw=2, label='weighted') 00327 00328 thismin=min([min(myPWV),min(myPWV1),min(myPWV2)]) 00329 thismax=max([max(myPWV),max(myPWV1),max(myPWV2)]) 00330 pl.ylim(.8*thismin,1.2*thismax) 00331 jm_set_Ylabel_pos(pos=(0,.5)) 00332 jm_set_Yvar_ticks(5) 00333 xa=pl.gca(); xa.set_xticklabels('') 00334 pl.xlim(numtime[0]-Xplotpad,numtime[-1]+Xplotpad) 00335 00336 middletimei=int(floor(len(myTimestr)/2.)) 00337 middletimes=str(myTimestr[middletimei])[11:] 00338 endtimes=myTimestr[-1][11:] 00339 ax=pl.gca() 00340 axt=ax.get_xticks() 00341 ax.set_xticks(pl.linspace(min(numtime),max(numtime),3)) 00342 ax.set_xticklabels([myTimestr[0],middletimes,endtimes ]) 00343 00344 sp8=thisfig.add_axes([.13,.1,.8,.2]) 00345 pl.plot(freqs,.01*tau_allF2,'-', color=myColor2, lw=2, label='seasonal model') 00346 pl.plot(freqs,.01*tau_allF1,'-', color=myColor1, lw=2, label='weather station') 00347 pl.plot(freqs,.01*tau_allF,'-', color=myColorW, lw=2,label='weighted') 00348 00349 00350 sp8.legend(loc=2, borderaxespad=0) 00351 pl.ylabel('Tau_Z (nepers)') 00352 pl.xlabel('Frequency (GHz)') 00353 pl.ylim(0,.25) 00354 jm_set_Yvar_ticks(6) 00355 jm_set_Ylabel_pos(pos=(0,.5)) 00356 pl.savefig( plotName, dpi=150) 00357 pl.close() 00358 00359 casalog.post('wrote weather figure: '+plotName) 00360 return meanTau 00361 00362