casa
$Rev:20696$
|
00001 from taskinit import casalog, metool, qa, smtool, tbtool 00002 from simutil import simutil 00003 import pylab as pl 00004 import os 00005 import shutil 00006 import tempfile 00007 import matplotlib 00008 00009 def plotcomp(compdict, showplot=True, wantdict=False, symb=',', 00010 include0amp=False, include0bl=False, blunit='', bl0flux=0.0): 00011 00012 """ 00013 Given a dict including 00014 00015 {'clist': component list, 00016 'objname': objname, 00017 'epoch': epoch, 00018 'shape': component shape dict, including direction. 00019 'freqs (GHz)': pl.array of frequencies, 00020 'antennalist': An array configuration file as used by simdata, 00021 'savedfig': False or, if specified, the filename to save the plot to, 00022 'standard': setjy fluxstandard type}, 00023 00024 and symb: One of matplotlib's codes for plot symbols: .:,o^v<>s+xDd234hH|_ 00025 default: ',': The smallest points I could find, 00026 00027 make a plot of visibility amplitude vs. baseline length for clist at epoch. 00028 00029 If antennalist is not found as is, it will look for antennalist in 00030 os.getenv('CASAPATH').split(' ')[0] + '/data/alma/simmos/'. 00031 00032 showplot: Whether or not to show the plot on screen. 00033 00034 If wantdict is True, it returns a dictionary with the amplitudes and 00035 baselines on success. Otherwise, it returns True or False as its estimated 00036 success value. 00037 00038 include0amp: Force the lower limit of the amplitude axis to 0. 00039 include0bl: Force the lower limit of the baseline length axis to 0. 00040 blunit: unit of the baseline length (='' used the unit in the data or klambda) 00041 bl0flux: Zero baseline flux 00042 """ 00043 def failval(): 00044 """ 00045 Returns an appropriate failure value. 00046 Note that mydict.update(plotcomp(wantdict=True, ...)) would give a 00047 confusing error message if plotcomp returned False. 00048 """ 00049 retval = False 00050 if wantdict: 00051 retval = {} 00052 return retval 00053 retval = failval() # Default 00054 try: 00055 clist = compdict['clist'] 00056 objname = compdict['objname'] 00057 epoch = compdict['epoch'] 00058 epstr = mepoch_to_str(epoch) 00059 antennalist = compdict['antennalist'] 00060 00061 # Read the configuration info. 00062 if not antennalist: 00063 print "compdict['antennalist'] must be set!" 00064 print "Try something in", os.getenv("CASAPATH").split(' ')[0] + "/data/alma/simmos/" 00065 return failval() 00066 # Try repodir if raw antennalist doesn't work. 00067 if not os.path.exists(antennalist): 00068 repodir = os.getenv("CASAPATH").split(' ')[0] + "/data/alma/simmos/" 00069 antennalist = repodir + antennalist 00070 00071 su = simutil("") 00072 stnx, stny, stnz, diam, padnames, nant, telescopename = su.readantenna(antennalist) 00073 #print "telescopename:", telescopename 00074 00075 # Check that the source is up. 00076 myme = metool() 00077 posobs = myme.observatory(telescopename) 00078 #print "posobs:", posobs 00079 myme.doframe(epoch) 00080 myme.doframe(posobs) 00081 azel = myme.measure(compdict['shape']['direction'], 'azel') 00082 azeldegs = tuple([qa.convert(azel[m], 'deg')['value'] for m in ('m0', 'm1')]) 00083 casalog.post("(az, el): (%.2f, %.2f) degrees" % azeldegs) 00084 # riseset blabs to the logger, so introduce it now. 00085 casalog.post('Rise and set times of ' + objname + " from " + telescopename + ':') 00086 approx = '' 00087 if 'JPL' in compdict.get('standard', 'JPL'): 00088 # The object is in the Solar System or not known to be extragalactic. 00089 approx = "APPROXIMATE. The times do not account for the apparent motion of "\ 00090 + objname + "." 00091 casalog.post(" (" + approx + ")") 00092 riset = myme.riseset(compdict['shape']['direction']) 00093 msg = '' 00094 if riset['rise'] == 'above': 00095 msg = objname + " is circumpolar" 00096 elif riset['rise'] == 'below': 00097 msg = objname + ' is not visible from ' + telescopename 00098 if msg: 00099 if approx: 00100 msg += ' around ' + mepoch_to_str(epoch) 00101 casalog.post(msg) 00102 else: 00103 for t in riset: 00104 riset[t]['str'] = mepoch_to_str(riset[t]['utc']) 00105 casalog.post(objname + " rises at %s and sets at %s." % (riset['rise']['str'], 00106 riset['set']['str'])) 00107 tmeridian=(riset['rise']['utc']['m0']['value']+riset['set']['utc']['m0']['value'])/2. 00108 casalog.post(objname + ': meridian passage at ' + qa.time(str(tmeridian)+'d')[0]) 00109 00110 if approx: 00111 riset['NOTE'] = approx 00112 if not azel['m1']['value'] > 0.0: 00113 casalog.post(objname + " is not visible from " + telescopename + " at " + epstr, 00114 'SEVERE') 00115 if wantdict: 00116 return riset 00117 else: 00118 return False 00119 00120 # Start a temp MS. 00121 workingdir = os.path.abspath(os.path.dirname(clist.rstrip('/'))) 00122 tempms = tempfile.mkdtemp(prefix=objname, dir=workingdir) 00123 00124 mysm = smtool() 00125 mysm.open(tempms) 00126 00127 su.setcfg(mysm, telescopename, stnx, stny, stnz, diam, 00128 padnames, posobs) 00129 00130 #print "cfg set" 00131 00132 # Only 1 polarization is wanted for now. 00133 stokes, feeds = su.polsettings(telescopename, 'RR') 00134 00135 casalog.post("stokes, feeds: %s, %s" % (stokes, feeds)) 00136 fband = su.bandname(compdict['freqs (GHz)'][0]) 00137 chaninc = 1.0 00138 nchan = len(compdict['freqs (GHz)']) 00139 if nchan > 1: 00140 chaninc = (compdict['freqs (GHz)'][-1] - compdict['freqs (GHz)'][0]) / (nchan - 1) 00141 mysm.setspwindow(spwname=fband, 00142 freq=str(compdict['freqs (GHz)'][0]) + 'GHz', 00143 deltafreq=str(chaninc) + 'GHz', 00144 freqresolution='1Hz', 00145 nchannels=nchan, refcode="LSRK", 00146 stokes=stokes) 00147 mysm.setfeed(mode=feeds, pol=['']) 00148 mysm.setlimits(shadowlimit=0.01, elevationlimit='10deg') 00149 mysm.setauto(0.0) 00150 mysm.setfield(sourcename=objname, 00151 sourcedirection=compdict['shape']['direction'], 00152 calcode="OBJ", distance='0m') 00153 mysm.settimes(integrationtime="1s", usehourangle=False, 00154 referencetime=epoch) 00155 00156 # this only creates blank uv entries 00157 mysm.observe(sourcename=objname, spwname=fband, 00158 starttime="-0.5s", stoptime="0.5s", project=objname) 00159 00160 mysm.setdata(fieldid=[0]) 00161 mysm.setvp() 00162 casalog.post("done setting up simulation parameters") 00163 00164 mysm.predict(complist=clist) # do actual calculation of visibilities: 00165 00166 mysm.close() 00167 casalog.post("Simulation finished.") 00168 00169 mytb = tbtool() 00170 mytb.open(tempms) 00171 data = mytb.getcol('DATA')[0] # Again, only 1 polarization for now. 00172 data = abs(data) 00173 baselines = mytb.getcol('UVW')[:2,:] # Drop w. 00174 datablunit = mytb.getcolkeywords('UVW')['QuantumUnits'] 00175 mytb.close() 00176 #print "Got the data and baselines" 00177 shutil.rmtree(tempms) 00178 00179 if datablunit[1] != datablunit[0]: 00180 casalog.post('The baseline units are mismatched!: %s' % datablunit, 00181 'SEVERE') 00182 return failval() 00183 datablunit = datablunit[0] 00184 # uv dist unit in klambda or m 00185 if datablunit == 'm' and blunit=='klambda': 00186 kl = qa.constants('C')['value']/(compdict['freqs (GHz)'][0]*1e6) 00187 blunit = 'k$\lambda$' 00188 else: 00189 blunit = datablunit 00190 kl = 1.0 00191 #baselines = pl.hypot(baselines[0]/kl, baselines[1]/kl) 00192 baselines = pl.hypot(baselines[0], baselines[1]) 00193 00194 if not showplot: 00195 casalog.post('Sorry, not showing the plot is not yet implemented', 00196 'WARN') 00197 00198 pl.ion() 00199 pl.clf() 00200 pl.ioff() 00201 nfreqs = len(compdict['freqs (GHz)']) 00202 for freqnum in xrange(nfreqs): 00203 freq = compdict['freqs (GHz)'][freqnum] 00204 casalog.post("Plotting " + str(freq) + " GHz.") 00205 pl.plot(baselines/kl, data[freqnum], symb, label="%.3g GHz" % freq) 00206 #pl.plot(baselines, data[freqnum], symb, label="%.3g GHz" % freq) 00207 pl.xlabel("Baseline length (" + blunit + ")") 00208 pl.ylabel("Visibility amplitude (Jy)") 00209 if include0amp: 00210 pl.ylim(ymin=0.0) 00211 if include0bl: 00212 pl.xlim(xmin=0.0) 00213 pl.suptitle(objname + " (predicted by %s)" % compdict['standard'], fontsize=14) 00214 #pl.suptitle(objname + " (predicted)", fontsize=14) 00215 00216 # Unlike compdict['antennalist'], antennalist might have had repodir 00217 # prefixed to it. 00218 pl.title('at ' + epstr + ' for ' + compdict['antennalist'], fontsize=10) 00219 titletxt='($%.0f^\circ$ az, $%.0f^\circ$ el)' % azeldegs 00220 # for comparison of old and new models - omit azeldegs as all in az~0 00221 if bl0flux > 0.0: 00222 if len(compdict['freqs (GHz)']) == 1: 00223 titletxt+='\n bl0 flux:%.3f Jy' % bl0flux 00224 else: 00225 titletxt+='\n bl0 flux:%.3f Jy @ %s GHz' % (bl0flux, compdict['freqs (GHz)'][0]) 00226 pl.legend(loc='best', title=titletxt) 00227 #pl.legend(loc='best', title='($%.0f^\circ$ az, $%.0f^\circ$ el)' % azeldegs) 00228 y_formatter=matplotlib.ticker.ScalarFormatter(useOffset=False) 00229 pl.axes().yaxis.set_major_formatter(y_formatter) 00230 pl.ion() 00231 pl.draw() 00232 if compdict.get('savedfig'): 00233 pl.savefig(compdict.get('savedfig')) 00234 casalog.post("Saved plot to " + str(compdict.get('savedfig'))) 00235 00236 if wantdict: 00237 retval = {'amps': data, 00238 'antennalist': antennalist, # Absolute path, now. 00239 'azel': azel, 00240 'baselines': baselines, 00241 'blunit': blunit, 00242 'riseset': riset, 00243 'savedfig': compdict.get('savedfig')} 00244 else: 00245 retval = True 00246 except Exception, instance: 00247 casalog.post(str(instance), 'SEVERE') 00248 if os.path.isdir(tempms): 00249 shutil.rmtree(tempms) 00250 return retval 00251 00252 def mepoch_to_str(mepoch, showdate=True, showtime=True, showmjd=True): 00253 """ 00254 Given an epoch as a measure, return it as a nicely formatted string. 00255 """ 00256 tdic = qa.splitdate(mepoch['m0']) 00257 fmt = "" 00258 if showdate: 00259 fmt += '%(year)d-%(month)02d-%(monthday)02d' 00260 if showtime: 00261 if fmt: 00262 fmt += '/' 00263 fmt += '%(hour)02d:%(min)02d:%(sec)02d %(tz)s' 00264 tdic['tz'] = mepoch['refer'] 00265 if showmjd: 00266 islast = False 00267 if fmt: 00268 fmt += ' (' 00269 islast = True 00270 fmt += 'MJD %(mjd).2f' 00271 if islast: 00272 fmt += ')' 00273 return fmt % tdic