# setjy helper functions from __future__ import absolute_import import os import sys import shutil import numpy from casatasks.private.casa_transition import is_CASA6 if is_CASA6: from casatasks import casalog as default_casalog from casatools import quanta, ms, table, componentlist, measures, calibrater, msmetadata from collections import OrderedDict as odict else: from taskinit import * from casac import casac from odict import odict default_casalog = casalog class ss_setjy_helper: def __init__(self,imtool, vis, casalog=None): self.im = imtool self.vis = vis if not casalog: casalog = default_casalog self._casalog = casalog def setSolarObjectJy(self,field,spw,scalebychan, timerange,observation, scan, intent, useephemdir, usescratch=False): """ Set flux density of a solar system object using Bryan Butler's new python model calculation code. A single time stamp (first time stamp of MS after selections are applied) is currently used per execution. For flux observation done in a long time span may need to run multiple setjy with selections by time range (or scans). """ #retval = True output = {} cleanupcomps = True # leave generated cl files if is_CASA6: qa = quanta() myms = ms( ) mytb = table( ) mycl = componentlist( ) myme = measures( ) mycb = calibrater( ) mymsmd = msmetadata( ) else: #from taskinit import * from taskinit import gentools qa = casac.quanta() (myms, mytb, mycl, myme, mycb, mymsmd) = gentools(['ms','tb','cl','me', 'cb','msmd']) # prepare parameters need to pass to the Bryan's code # make ms selections # get source name # get time ranges # get spwused and get frequency ranges sel={} sel['field']=field sel['spw']=spw sel['timerange']=timerange sel['observation']=str(observation) sel['scan']=scan sel['scanintent']=intent measframes=['REST','LSRK','LSRD','BARY','GEO','TOPO','GALACTO','LGROUP','CMB'] myms.open(self.vis) myms.msselect(sel,False) scansummary=myms.getscansummary() nscan=len(scansummary.keys()) selectedids=myms.msselectedindices() fieldids=selectedids['field'] obsids=selectedids['observationid'] myms.close() mytb.open(os.path.join(self.vis,'OBSERVATION')) if len(obsids)==0: getrow=0 else: getrow=obsids[0] observatory=mytb.getcell('TELESCOPE_NAME',getrow) mytb.close() mytb.open(os.path.join(self.vis,'FIELD')) colnames = mytb.colnames() if len(fieldids)==0: fieldids = range(mytb.nrows()) # frame reference for field position phdir_info=mytb.getcolkeyword("PHASE_DIR","MEASINFO") if 'Ref' in phdir_info: fieldref=phdir_info['Ref'] elif 'TabRefTypes' in phdir_info: colnames=mytb.colnames() for col in colnames: if col=='PhaseDir_Ref': fieldrefind=mytb.getcell(col,fieldids[0]) fieldref=phdir_info['TabRefTypes'][fieldrefind] else: fieldref='' srcnames={} fielddirs={} ftimes={} ephemid={} for fid in fieldids: #srcnames.append(mytb.getcell('NAME',int(fid))) srcnames[fid]=(mytb.getcell('NAME',int(fid))) #fielddirs[fid]=(mytb.getcell('PHASE_DIR',int(fid))) ftimes[fid]=(mytb.getcell('TIME',int(fid))) if colnames.count('EPHEMERIS_ID'): ephemid[fid]=(mytb.getcell('EPHEMERIS_ID',int(fid))) else: ephemid[fid]=-1 mytb.close() # close FIELD table # need to get a list of time # but for now for test just get a time centroid of the all scans # get time range # Also, this needs to be done per source # gather freq info from Spw table mytb.open(os.path.join(self.vis,'SPECTRAL_WINDOW')) nspw = mytb.nrows() freqcol=mytb.getvarcol('CHAN_FREQ') freqwcol=mytb.getvarcol('CHAN_WIDTH') fmeasrefcol=mytb.getcol('MEAS_FREQ_REF') reffreqs=mytb.getcol('REF_FREQUENCY') mytb.close() # store all parameters need to call solar_system_fd for all sources inparams={} validfids = [] # keep track of valid fid that has data (after selection) # if same source name ....need handle this... for fid in fieldids: sel['field']=str(fid) myms.open(self.vis) #reset the selection try: status=myms.msselect(sel) except: #skip this field continue if not status: continue validfids.append(fid) trange=myms.range('time') #if not srcnames[fid] in inparams: # inparams[srcnames[fid]]={} if not fid in inparams: inparams[fid]={} inparams[fid]['fieldname']=srcnames[fid] #tc = (trange['time'][0]+trange['time'][1])/2. #in sec. # use first timestamp to be consistent with the ALMA Control # old setjy (Butler-JPL-Horizons 2010) seems to be using # time in FIELD... but here is first selected time in main table if ephemid[fid]==-1: # keep old behavior tc = trange['time'][0] #in sec. tmsg = "Time used for the model calculation (=first time stamp of the selected data) for field " else: # must have ephem table attached... tc = ftimes[fid]#in sec. tmsg = "Time used for the model calculation for field " #if 'mjd' in inparams[srcnames[fid]]: # inparams[srcnames[fid]]['mjds'][0].append([myme.epoch('utc',qa.quantity(tc,'s'))['m0']['value']]) #else: # inparams[srcnames[fid]]['mjds']=[myme.epoch('utc',qa.quantity(tc,'s'))['m0']['value']] if 'mjd' in inparams[fid]: inparams[fid]['mjds'][0].append([myme.epoch('utc',qa.quantity(tc,'s'))['m0']['value']]) else: inparams[fid]['mjds']=[myme.epoch('utc',qa.quantity(tc,'s'))['m0']['value']] usedtime = qa.time(qa.quantity(tc,'s'),form='ymd')[0] self._casalog.post(tmsg+str(fid)+":"+usedtime) # get a correct direction measure mymsmd.open(self.vis) dirdic = mymsmd.phasecenter(int(fid)) mymsmd.close() # check if frame is J2000 and if not do the transform if dirdic['refer'] != 'J2000': myme.doframe(myme.observatory(observatory)) myme.doframe(myme.epoch('utc', qa.quantity(tc,'s'))) azeldir = myme.measure(dirdic,'AZELGEO') dirdic=myme.measure(azeldir,'J2000') fielddirs[fid]=(numpy.array([[dirdic['m0']['value']],[dirdic['m1']['value']]])) # somehow it gives you duplicated ids .... so need to uniquify selspws= list(set(myms.msselectedindices()['spw'])) # make sure it is int rather than numpy.int32, etc. selspws = [int(ispw) for ispw in selspws] #inparams[srcnames[fid]]['spwids']= selspws if len(selspws)!=0 else range(nspw) inparams[fid]['spwids']= selspws if len(selspws)!=0 else range(nspw) #create a list of freq ranges with selected spws # should worry about freq order??? freqlist=[] freqlistraw=[] framelist=[] #for idx in inparams[srcnames[fid]]['spwids']: for idx in inparams[fid]['spwids']: freqs=freqcol['r'+str(idx+1)] freqws=freqwcol['r'+str(idx+1)] fmeasref=fmeasrefcol[idx] #if scalebychan=T, this has to be min, max determined from # chan_freq(channel center)+/- chan width. if scalebychan: # pack into list of list of list (freqlist[nf][nspw]) perspwfreqlist=[] for nf in range(len(freqs)): fl = freqs[nf][0]-freqws[nf][0]/2. fh = freqs[nf][0]+freqws[nf][0]/2. perspwfreqlist.append([fl,fh]) freqlist.append(perspwfreqlist) else: if (len(freqs)==1): fl = freqs[0][0]-freqws[0][0]/2. fh = freqs[0][0]+freqws[0][0]/2. freqlist.append([float(fl),float(fh)]) else: freqlist.append([float(min(freqs)),float(max(freqs))]) framelist.append(measframes[fmeasref]) freqlistraw.append(freqs.transpose()[0].tolist()) # data chanfreq list #inparams[srcnames[fid]]['freqlist']=freqlist #inparams[srcnames[fid]]['freqlistraw']=freqlistraw #inparams[srcnames[fid]]['framelist']=framelist #inparams[srcnames[fid]]['reffreqs']=reffreqs inparams[fid]['freqlist']=freqlist inparams[fid]['freqlistraw']=freqlistraw inparams[fid]['framelist']=framelist inparams[fid]['reffreqs']=reffreqs myms.close() # call Bryan's code # errcode: list of list - inner list - each values for range of freqs # flluxes: list of list # fluxerrs: # size: [majoraxis, minoraxis, pa] # direction: direction for each time stamp # if is_CASA6: from . import solar_system_setjy as SSsetjy else: import solar_system_setjy as SSsetjy #import solar_system_setjy2 as SSsetjy retdict={} # for returning flux densities? ss_setjy=SSsetjy.solar_system_setjy() #for src in srcnames: self.clnamelist=[] for vfid in validfids: src=srcnames[vfid] #mjds=inparams[src]['mjds'] mjds=inparams[vfid]['mjds'] fluxes=[] # call solar_system_fd() per spw (for scalebychan freqlist has an extra dimention) #nspwused=len(inparams[src]['freqlist']) nspwused=len(inparams[vfid]['freqlist']) # warning for many channels but it is really depends on the source if scalebychan: maxnf=0 for ispw in range(nspwused): #nf = len(inparams[src]['freqlist'][ispw]) nf = len(inparams[vfid]['freqlist'][ispw]) maxnf = max(nf,maxnf) if maxnf >= 3840 and src.upper()!="MARS": # mars shoulde be ok self._casalog.post("Processing %s spw(s) and at least some of them are a few 1000 channels or more. This may take \ many minutes (>3min per spw for 3840 channels) in some cases. Please be patient." % nspwused,"WARN") for i in range(nspwused): # corresponds to n spw if type(freqlist[0][0])==list: #infreqs=inparams[src]['freqlist'][i] infreqs=inparams[vfid]['freqlist'][i] else: #infreqs=[inparams[src]['freqlist'][i]] infreqs=[inparams[vfid]['freqlist'][i]] self._casalog.post("Calling solar_system_fd: %s(%s) for spw%s freqs=%s" % (src, vfid,i,freqlist[i]),'DEBUG1') # casalog.post( "calling solar system fd...") (errcodes, subfluxes, fluxerrs, sizes, dirs)=\ ss_setjy.solar_system_fd(source_name=src, MJDs=mjds, frequencies=infreqs, observatory=observatory, casalog=self._casalog) # for old code #(errcodes, subfluxes, fluxerrs, sizes, dirs)=\ # ss_setjy.solar_system_fd(source_name=src, MJDs=mjds, frequencies=infreqs, casalog=self._casalog) # for nf freq ranges, nt mjds # errcodes[nf][nt], subfluxes[nf][nt], fluxerrs[nf][nt], sizes[nt], dirs[nt] self._casalog.post("+++++ solar_system_fd() returned values +++++", 'DEBUG1') self._casalog.post(" fluxes(fds)=%s" % subfluxes, 'DEBUG1') self._casalog.post(" sizes=%s" % sizes, 'DEBUG1') self._casalog.post(" directions=%s\n" % dirs, 'DEBUG1') # packed fluxes for all spws fluxes.append(subfluxes) #casalog.post( "fluxes=" + fluxes) # fluxes has fluxesi[nspw][nf][nt] # ------------------------------------------------------------------------ # For testing with hardcoded values without calling solar_system_fd()... #errcodes=[[0,0,0,0,0]] #fluxes=[[26.40653147,65.23839313,65.23382757,65.80638802,69.33396562]] #fluxerrs=[[0.0,0.0,0.0,0.0,0.0]] #sizes=[[3.6228991032674371,3.6228991032674371,0.0]] #dirs=[{'m0': {'unit': 'rad', 'value': 0.0}, 'm1': {'unit': 'rad', 'value': 0.0}, 'refer': 'J2000', 'type': 'direction'}] # ------------------------------------------------------------------------ # local params for selected src #framelist=inparams[src]['framelist'] #freqlist=inparams[src]['freqlist'] #freqlistraw=inparams[src]['freqlistraw'] #reffreqs=inparams[src]['reffreqs'] #spwids=inparams[src]['spwids'] framelist=inparams[vfid]['framelist'] freqlist=inparams[vfid]['freqlist'] freqlistraw=inparams[vfid]['freqlistraw'] reffreqs=inparams[vfid]['reffreqs'] spwids=inparams[vfid]['spwids'] clrecs=odict( ) # casalog.post("LOOP over multiple dir...") labels = [] # loop for over for multiple directions (=multiple MJDs) for a given src for i in range(len(dirs)): # this is currently only length of 1 since no multiple timestamps were used # check errcode - error code would be there per flux per time (dir) reterr=testerrs(errcodes[i],src) if reterr == 2: continue #dirstring = [dirs[i]['refer'],qa.tos(dirs[i]['m0']),qa.tos(dirs[i]['m1'])] if useephemdir: dirstring = [dirs[i]['refer'],qa.tos(dirs[i]['m0']),qa.tos(dirs[i]['m1'])] dirmsg = "Using the source position from the ephemeris table in the casa data directory: " else: #dirstring = [fieldref, str(fielddirs[fieldids[0]][0][0])+'rad', str(fielddirs[fieldids[0]][1][0])+'rad'] # extract field direction of first id of the selected field ids #dirstring = [fieldref, "%.18frad" % (fielddirs[fieldids[0]][0][0]), "%.18frad" % (fielddirs[fieldids[0]][1][0])] #dirstring = [fieldref, "%.18frad" % (fielddirs[vfid][0][0]), "%.18frad" % (fielddirs[vfid][1][0])] # by now the direction should be in J2000 dirstring = ['J2000', "%.18frad" % (fielddirs[vfid][0][0]), "%.18frad" % (fielddirs[vfid][1][0])] dirmsg = "Using the source position in the MS (or in the attached ephemeris table, if any): " self._casalog.post(dirmsg+str(dirstring)) # casalog.post("componentlist construction") # setup componentlists # need to set per dir # if scalebychan=F, len(freqs) corresponds to nspw selected # Need to put in for-loop to create cl for each time stamp? or scan? #clpath='/tmp/' clpath='./' # construct cl name (multiple spws in one componentlist table) selreffreqs = [reffreqs[indx] for indx in spwids] minfreq = min(selreffreqs) maxfreq = max(selreffreqs) freqlabel = '%.3f-%.3fGHz' % (minfreq/1.e9, maxfreq/1.e9) #tmlabel = '%.1fd' % (tc/86400.) mjd=inparams[vfid]['mjds'][0] tmlabel = '%.1fd' % (mjd) #clabel = src+'_spw'+str(spwids[j])+'_'+freqlabel+'_'+tmlabel #clabel0 = src+'_'+freqlabel+'_'+tmlabel #pid=str(os.getpid()) #clname = clpath+clabel0+"_"+pid+'.cl' clabel0 = src+'_'+freqlabel+'_'+tmlabel+"_"+os.path.basename(self.vis) clname = clpath+clabel0+'.cl' #debug self._casalog.post("Create componentlist: %s for vfid=%s" % (clname,vfid),'DEBUG1') if (os.path.exists(clname)): shutil.rmtree(clname) # casalog.post("Logging/output dict") iiflux=[] iinfreq=[] # for logging/output dict - pack each freq list for each spw freqsforlog=[] for j in range(len(freqlist)): # loop over nspw freqlabel = '%.3fGHz' % (reffreqs[int(spwids[j])]/1.e9) clabel=src+'_spw'+str(spwids[j])+'_'+freqlabel+'_'+tmlabel # casalog.post("addcomponent...for spw=",spwids[j]," i=",i," flux=",fluxes[j][i]) if scalebychan: index= 2.0 sptype = 'spectral index' else: index= 0.0 sptype = 'constant' # adjust to change in returned flux shape. An extra [] now seems to be gone. 2012-09-27 iflux=fluxes[j][i][0] # casalog.post( "addcomponent with flux=%s at frequency=%s" % # (iflux,str(reffreqs[int(spwids[j])]/1.e9)+'GHz')) # i - time stamps = 0 for now, j = a freq range infreq=freqlist[j][0][0] if type(freqlist[j][0])==list else freqlist[j][0] # for a single CL with multple spws if j ==0: infreq0=infreq # --- version for 'multi-spws in a single comp single CL' # accumulate all frequencies from all spws to a list #if not scalebychan: #freqlist[j] for j spw should contain a list with two freqs (min and max of # of the spw and the same fluxes should be set for the freqs so that cl.setspectrum # with tabular would not interpolate inside each spw ##iinfreq.extend(freqlist[j]) # nch = len(freqlistraw[j]) # iinfreq.extend(freqlistraw[j]) # assigning the same flux to the two freqs ##iiflux.extend([iflux,iflux]) # for ich in range(nch): # iiflux.extend([iflux]) #else: # iiflux.extend(fluxes[j][i]) # if type(freqlist[j][0])==list and len(freqlist[j][0])>1: # for fr in freqlist[j]: # iinfreq.append((fr[1]+fr[0])/2) # else: # if type(freqlist[j])==list: # iinfreq.append((freqlist[j][1]+freqlist[j][0])/2) # else: # iinfreq.append(freqlist[j]) # freqsforlog.append(iinfreq) # ----------------------------------------------------------------------------------- # casalog.post("Logging/output dict addcomp") self._casalog.post("addcomponent with flux=%s at frequency=%s" %\ # (fluxes[j][i][0],str(reffreqs[int(spwids[j])]/1.e9)+'GHz'), 'INFO1') (iflux,str(reffreqs[int(spwids[j])]/1.e9)+'GHz'), 'INFO1') # mycl.addcomponent(iflux,fluxunit='Jy', polarization="Stokes", dir=dirstring, shape='disk', majoraxis=str(sizes[i][0])+'arcsec', minoraxis=str(sizes[i][1])+'arcsec', positionangle=str(sizes[i][2])+'deg', freq=[framelist[0],str(infreq)+'Hz'], spectrumtype=sptype, index=index, label=clabel) if scalebychan: # use tabular form to set flux for each channel # This may be redundant if type(fluxes[j][i]) ==list and len(fluxes[j][i])> 1: if type(freqlist[j][0])==list and len(freqlist[j][0])>1: freqs=[] for fr in freqlist[j]: freqs.append((fr[1]+fr[0])/2) clind = mycl.length() - 1 mycl.setspectrum(which=clind, type='tabular', tabularfreqs=freqs, tabularflux=fluxes[j][0], tabularframe=framelist[j]) ### === per spw process end here # - version that put all spws into a component - # set a single component freq set at the the lower edge of first spw #mycl.addcomponent(iiflux[0],fluxunit='Jy', polarization="Stokes", dir=dirstring, # shape='disk', majoraxis=str(sizes[i][0])+'arcsec', minoraxis=str(sizes[i][1])+'arcsec', # positionangle=str(sizes[i][2])+'deg', freq=[framelist[0],str(infreq0)+'Hz'], # spectrumtype=sptype, index=index, label=clabel) # if it's list of fluxes try to put in tabular form #if type(fluxes[j][i]) ==list and len(fluxes[j][i])> 1: # if len(iiflux)> 1: # casalog.post("framelist[j]=",framelist[j]) #if type(freqlist[j][0])==list and len(freqlist[j][0])>1: # freqs=[] # for fr in freqlist[j]: # freqs.append((fr[1]+fr[0])/2) #else: # freqs=freqlist[j] #clind = mycl.length() - 1 # mycl.setspectrum(which=clind, type='tabular', tabularfreqs=freqs, tabularflux=fluxes[j][0], #tabularframe=framelist[j]) # mycl.setspectrum(which=clind, type='tabular', tabularfreqs=iinfreq, tabularflux=iiflux, # tabularframe=framelist[0]) #mycl.rename(clname) #put in a record for log output #clrecs[clabel] = mycl.torecord() clrecs[clabel0] = mycl.torecord() clrecs[clabel0]['allfluxinfo']=fluxes clrecs[clabel0]['allfreqinfo']=freqsforlog clrecs[clabel0]['spwids']=spwids mycl.rename(clname) # - A CL per field # casalog.post("clrecs=" + clrecs) # casalog.post("clname=" + clname) mycl.close(False) # False for not to send a warning message mycl.done() # if scratch=F check if the virtual model already exist # for the field if it is clear it. # if j==0 and (not usescratch): # mytb.open(self.vis, nomodify=False) # kwds = mytb.getkeywords() # modelkwd='definedmodel_field_'+str(vfid) # if modelkwd in kwds: # clmodname=kwds[modelkwd] # mytb.removekeyword(clmodname) # mytb.removekeyword(modelkwd) # mytb.close() mycb.open(self.vis,addcorr=False,addmodel=False) mycb.delmod(otf=True,field=str(vfid),spw=list(spwids), scr=False) mycb.close() # finally, put the componentlist as model #tqlstr='' #if intent!='': # tqlstr='any(STATE_ID=='+str(stateids.tolist())+')' # Currently still need to do per spw (see the comment below...) # assuming CL contains nrow = nspw components mycl.open(clname) clinrec = mycl.torecord() mycl.close(False) mycl.done() ncomp = clinrec['nelements'] if ncomp != len(spwids): raise Exception("Inconsistency in generated componentlist...Please submit a bug report.") for icomp in range(ncomp): #self.im.selectvis(spw=spwids[icomp],field=field,observation=observation,time=timerange,intent=intent) ok = self.im.selectvis(spw=spwids[icomp],field=vfid,observation=observation,time=timerange,intent=intent) # for MMS, particular subms may not contain the particular spw, so skip for such a case if ok: newclinrec = {} newclinrec['nelements']=1 newclinrec['component0']=clinrec['component'+str(icomp)] mycl.fromrecord(newclinrec) cdir = os.getcwd() if os.access(cdir,os.W_OK): tmpclpath = cdir+"/" elif os.access("/tmp",os.W_OK): tmpclpath = "/tmp/" #tmpclpath=tmpclpath+"_tmp_setjyCLfile_"+pid tmpclpath=tmpclpath+os.path.basename(self.vis)+"_tmp_setjyCLfile" if os.path.exists(tmpclpath): shutil.rmtree(tmpclpath) mycl.rename(tmpclpath) mycl.close(False) self.im.ft(complist=tmpclpath, phasecentertime=tc) # -------------------------------------------------------------------------------------------- # Currently this does not work properly for some case. Need ft can handle multi-component CL # with the way to map which component apply to which spw # Unable when such functionality is implemented in im.ft() #self.im.selectvis(spw=spwids,field=field,observation=observation,time=timerange,intent=intent) #self.im.ft(complist=clname) <= e.g. im.ft(comprec) where comrec = {'spw-mapping':[...],comprecs}.. # -------------------------------------------------------------------------------------------- #debug: set locally saved 2010-version component list instead #cl2010='mod_setjy_spw0_Titan_230.543GHz55674.1d.cl' # casalog.post("Using complist=" + cl2010) #self.im.ft(complist=cl2010) #if cleanupcomps: # shutil.rmtree(clname) #self.clnamelist.append(clname) self.clnamelist.append(clname) msg="Using channel dependent " if scalebychan else "Using spw dependent " if clrecs=={}: raise Exception("No componentlist is generated.") #self._casalog.post(clrecs) self._casalog.post(msg+" flux densities") #self._reportoLog(clrecs,self._casalog) self._reportoLog2(clrecs,self._casalog) #self._updateHistory(clrecs,self.vis) self._updateHistory2(clrecs,self.vis) # dictionary of dictionary for each field retdict[vfid]=clrecs # ==== end of for loop over fields #output=self._makeRetFluxDict(retdict) # casalog.post("makeRetFluxDict2") output=self._makeRetFluxDict2(retdict) #return retval # casalog.post("done setSolarSetJY") return output def getclnamelist(self): return self.clnamelist def _reportoLog(self,clrecs,casalog): """ send model parameters to log """ # casalog.post("clrecs=" + clrecs) for ky in clrecs.keys(): # expect only one component for each nelm = clrecs[ky]['nelements'] for icomp in range(nelm): comp = clrecs[ky]['component'+str(icomp)] complab = comp['label'] #srcn = ky.split('_')[0] #ispw = ky.split('_')[1] srcn = complab.split('_')[0] ispw = complab.split('_')[1] if icomp==0: msg=" direction set in the componentlist: RA=%s rad, Dec%s rad" %\ (float('%.6g' % comp['shape']['direction']['m0']['value']), float('%.6g' % comp['shape']['direction']['m1']['value'])) casalog.post(msg,'INFO2') msg=" %s: %s Flux:[I=%s,Q=%s,U=%s,V=%s] +/- [I=%s,Q=%s,U=%s,V=%s] Jy" %\ (srcn, ispw, float('%.5g' % comp['flux']['value'][0]), float('%.5g' % comp['flux']['value'][1]), float('%.5g' % comp['flux']['value'][2]), float('%.5g' % comp['flux']['value'][3]), float('%.5g' % comp['flux']['error'][0]), float('%.5g' % comp['flux']['error'][1]), float('%.5g' % comp['flux']['error'][2]), float('%.5g' % comp['flux']['error'][3])) casalog.post(msg, 'INFO') def _reportoLog2(self,clrecs,casalog): """ send model parameters to log (This version handles for a single componentlist with possible multiple componet) Assume componentlist has a name src_spw_xxxx or src_spw """ nelm = -1 ncl = len(clrecs.keys()) # casalog.post("clrecs=" + clrecs) if ncl == 1: clname = list(clrecs.keys())[0] comprec = clrecs[clname] if 'nelements' in comprec: nelm = comprec['nelements'] if ncl != 1 or nelm == -1: casalog.post("Cannot process the generated componentlist, possibly a bug.\ Please submit a bug report", "SEVERE") for icomp in range(nelm): comp = comprec['component'+str(icomp)] complab = comp['label'] srcn = complab.split('_')[0] if icomp==0: msg=" direction set in the componentlist: RA=%s rad, Dec%s rad" %\ (float('%.6g' % comp['shape']['direction']['m0']['value']), float('%.6g' % comp['shape']['direction']['m1']['value'])) casalog.post(msg,'INFO2') freq0='' if 'spectrum' in comp: freqv = float('%.5g' % comp['spectrum']['frequency']['m0']['value']) freq0 = str(freqv)+comp['spectrum']['frequency']['m0']['unit'] if nelm==1: for i in range(len(comprec['spwids'])): ispw=comprec['spwids'][i] iflux = comprec['allfluxinfo'][i][0][0] # currently only I flux is reported and no flux error is reported msg=" %s: spw%s Flux:[I=%s,Q=%s,U=%s,V=%s] +/- [I=%s,Q=%s,U=%s,V=%s] Jy @ %s" %\ (srcn, ispw, float('%.5g' % iflux),0.0,0.0,0.0, 0.0,0.0,0.0,0.0, freq0) casalog.post(msg, 'INFO') else: ispw = complab.split('_')[1] #if 'spectrum'in comp: # freqv = float('%.5g' % comp['spectrum']['frequency']['m0']['value']) # freq0 = str(freqv)+comp['spectrum']['frequency']['m0']['unit'] msg=" %s: %s Flux:[I=%s,Q=%s,U=%s,V=%s] +/- [I=%s,Q=%s,U=%s,V=%s] Jy @ %s" %\ (srcn, ispw, float('%.5g' % comp['flux']['value'][0]), float('%.5g' % comp['flux']['value'][1]), float('%.5g' % comp['flux']['value'][2]), float('%.5g' % comp['flux']['value'][3]), float('%.5g' % comp['flux']['error'][0]), float('%.5g' % comp['flux']['error'][1]), float('%.5g' % comp['flux']['error'][2]), float('%.5g' % comp['flux']['error'][3]), freq0) casalog.post(msg, 'INFO') def _updateHistory(self,clrecs,vis): """ Update history table when setSolarObjectJy is run """ # if is_CASA6: mytb = table( ) else: from taskinit import gentools (mytb,) = gentools(['tb']) mytb.open(os.path.join(vis,'HISTORY'),nomodify=False) nrow = mytb.nrows() lasttime=mytb.getcol('TIME')[nrow-1] rown=nrow # for ky in clrecs.keys(): # expect only one component for each comp = clrecs[ky]['component0'] srcn = ky.split('_')[0] ispw = ky.split('_')[1] mytb.addrows(1) appl='setjy' msg = (" %s: spw %s Flux:[I=%s,Q=%s,U=%s,V=%s] +/- [I=%s,Q=%s,U=%s,V=%s] Jy" % (srcn, ispw, comp['flux']['value'][0], comp['flux']['value'][1], comp['flux']['value'][2], comp['flux']['value'][3], comp['flux']['error'][0], comp['flux']['error'][1],comp['flux']['error'][2], comp['flux']['error'][3])) origin='setjy' priority='INFO' time=lasttime emptystrarr=numpy.array(['']) mytb.putcell('APP_PARAMS', rown, ['']) mytb.putcell('CLI_COMMAND',rown, ['']) mytb.putcell('APPLICATION',rown, appl) mytb.putcell('MESSAGE',rown, msg) mytb.putcell('OBSERVATION_ID',rown, -1) mytb.putcell('ORIGIN',rown,origin) mytb.putcell('PRIORITY',rown,priority) mytb.putcell('TIME',rown, time) rown += 1 mytb.close() def _updateHistory2(self,clrecs,vis): """ Update history table when setSolarObjectJy is run (mulitple comopents in one version) """ # if is_CASA6: mytb = table( ) else: from taskinit import gentools (mytb,) = gentools(['tb']) mytb.open(os.path.join(vis,'HISTORY'),nomodify=False) nrow = mytb.nrows() lasttime=mytb.getcol('TIME')[nrow-1] rown=nrow # clname = list(clrecs.keys())[0] #for ky in clrecs.keys(): srcn = clname.split('_')[0] comprec = clrecs[clname] nelm = comprec['nelements'] for icomp in range(nelm): comp = comprec['component'+str(icomp)] complab = comp['label'] origin='setjy' priority='INFO' time=lasttime appl='setjy' emptystrarr=numpy.array(['']) if nelm==1: for i in range(len(comprec['spwids'])): mytb.addrows(1) ispw=comprec['spwids'][i] iflux = comprec['allfluxinfo'][i][0][0] msg = (" %s: spw %s Flux:[I=%s,Q=%s,U=%s,V=%s] +/- [I=%s,Q=%s,U=%s,V=%s] Jy" % (srcn, ispw, iflux, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0)) mytb.putcell('APP_PARAMS', rown, ['']) mytb.putcell('CLI_COMMAND',rown, ['']) mytb.putcell('APPLICATION',rown, appl) mytb.putcell('MESSAGE',rown, msg) mytb.putcell('OBSERVATION_ID',rown, -1) mytb.putcell('ORIGIN',rown,origin) mytb.putcell('PRIORITY',rown,priority) mytb.putcell('TIME',rown, time) rown += 1 else: ispw = complab.split('_')[1] mytb.addrows(1) msg = (" %s: spw %s Flux:[I=%s,Q=%s,U=%s,V=%s] +/- [I=%s,Q=%s,U=%s,V=%s] Jy" % (srcn, ispw, comp['flux']['value'][0], comp['flux']['value'][1], comp['flux']['value'][2], comp['flux']['value'][3], comp['flux']['error'][0], comp['flux']['error'][1],comp['flux']['error'][2], comp['flux']['error'][3])) mytb.putcell('APP_PARAMS', rown, ['']) mytb.putcell('CLI_COMMAND',rown, ['']) mytb.putcell('APPLICATION',rown, appl) mytb.putcell('MESSAGE',rown, msg) mytb.putcell('OBSERVATION_ID',rown, -1) mytb.putcell('ORIGIN',rown,origin) mytb.putcell('PRIORITY',rown,priority) mytb.putcell('TIME',rown, time) rown += 1 mytb.close() def _makeRetFluxDict(self, flxdict): """ re-arrange the calculated flux density info for returned dict. """ # flxdict should contains a ditionary per field retflxdict={} for fid in flxdict.keys(): comp=flxdict[fid] tmpdict={} for ky in comp.keys(): srcn = ky.split('_')[0] ispw = ky.split('_')[1].strip('spw') tmpdict[ispw]={} tmpdict[ispw]['fluxd']=comp[ky]['component0']['flux']['value'] #tmpdict[ispw]['fluxderr']=comp[ky]['component0']['flux']['error'] tmpdict['fieldName']=srcn retflxdict[str(fid)]=tmpdict retflxdict['format']=\ '{field Id: {spw Id: {fluxd:[I,Q,U,V] in %s}, \'fieldName\':field name}}' % \ comp[ky]['component0']['flux']['unit'] return retflxdict def _makeRetFluxDict2(self, flxdict): """ re-arrange the calculated flux density info for returned dict. (for each field id as key, single dict) """ # flxdict should contains a ditionary per field retflxdict={} for fid in flxdict.keys(): clrecs=flxdict[fid] clname=list(clrecs.keys())[0] srcn = clname.split('_')[0] comprec=clrecs[clname] nelm = comprec['nelements'] tmpdict={} for icomp in range(nelm): comp = comprec['component'+str(icomp)] complab = comp['label'] if nelm==1: for i in range(len(comprec['spwids'])): ispw = str(comprec['spwids'][i]) iflux = comprec['allfluxinfo'][i][0][0] tmpdict[ispw]={} tmpdict[ispw]['fluxd']=[iflux,0.0,0.0,0.0] else: ispw = complab.split('_')[1].strip('spw') tmpdict[ispw]={} #tmpdict[ispw]['fluxd']=comp[ky]['component0']['flux']['value'] tmpdict[ispw]['fluxd']=comp['flux']['value'] tmpdict['fieldName']=srcn retflxdict[str(fid)]=tmpdict retflxdict['format']=\ '{field Id: {spw Id: {fluxd:[I,Q,U,V] in %s}, \'fieldName\':field name}}' % \ comprec['component0']['flux']['unit'] return retflxdict def testerrs(errcode,srcname): """ Check error codes from solar_system_fd return = 0 all ok return = 1 partly ok return = 2 all bad - should not proceed to set component """ errcount = 0 if type(errcode)!=list: errcode=[errcode] for ec in errcode: if ec != 0: errcount += 1 if ec == 1: default_casalog.post("The model for %s is not supported" % srcname, 'WARN') elif ec == 2: default_casalog.post("Unsupported frequency range",'WARN') elif ec == 3: default_casalog.post("Tb model not found",'WARN') elif ec == 4: default_casalog.post("The ephemeris table is not found or the time is out of range",'WARN') if errcount == len(errcode): return 2 if errcount != 0: return 1 else: return 0