casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables
plotcomp.py
Go to the documentation of this file.
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