Exemple #1
0
    def test_readAndParseTbuff(self):
        '''flaghelper: compare the read and parse and apply tbuff'''
        print ''
        
        # MJD in seconds of timeranges are these
        # <startTime>4891227930515540000 <endTime>4891227932453838000
        # <startTime>4891228473545856000 <endTime>4891228473731891000
        # <startTime>4891226924455911000 <endTime>4891226927502314000
        # <startTime>4891228838164987000 <endTime>4891228838418996000
        # <startTime>4891228609440808000 <endTime>4891228612489617000

        online = ["antenna='DV03&&*' timerange='2013/11/15/10:25:30.516~2013/11/15/10:25:32.454'",
                  "antenna='DA44&&*' timerange='2013/11/15/10:34:33.546~2013/11/15/10:34:33.732'",
                  "antenna='DA46&&*' timerange='2013/11/15/10:08:44.456~2013/11/15/10:08:47.502'",
                  "antenna='DV09&&*' timerange='2013/11/15/10:18:11.798~2013/11/15/10:18:13.837'",
                  "antenna='DV05&&*' timerange='2013/11/15/10:40:38.165~2013/11/15/10:40:38.419'"]

        myinput = "antenna='DV03&&*' timerange='2013/11/15/10:25:30.516~2013/11/15/10:25:32.454'\n"\
                  "antenna='DA44&&*' timerange='2013/11/15/10:34:33.546~2013/11/15/10:34:33.732'\n"\
                  "antenna='DA46&&*' timerange='2013/11/15/10:08:44.456~2013/11/15/10:08:47.502'\n"\
                  "antenna='DV09&&*' timerange='2013/11/15/10:18:11.798~2013/11/15/10:18:13.837'\n"\
                  "antenna='DV05&&*' timerange='2013/11/15/10:40:38.165~2013/11/15/10:40:38.419'"
        
        filename1 = 'flaghelperonline2.txt'
        create_input(myinput, filename1)
        
        # First timerange from online before padding
        origt = timerange='2013/11/15/10:25:30.516~2013/11/15/10:25:32.454'
        
        # Apply tbuff to timeranges
        timebuffer = 1.1
        dlist1 = fh.readAndParse([filename1], tbuff=timebuffer)
        self.assertEqual(len(dlist1), 5)
        
        # Get the first padded timerange from output
        padt = dlist1[0]['timerange']
        
        # Revert the tbuff application manually
        t0,t1 = padt.split('~',1)
        startTime = qa.totime(t0)['value']
        startTimeSec = float((startTime * 24 * 3600) + timebuffer)
        startTimeSec = qa.quantity(startTimeSec, 's')
        paddedT0 = qa.time(startTimeSec,form='ymd',prec=9)[0]
        # end time
        endTime = qa.totime(t1)['value']
        endTimeSec = float((endTime * 24 * 3600) - timebuffer)
        endTimeSec = qa.quantity(endTimeSec, 's')
        paddedT1 = qa.time(endTimeSec,form='ymd',prec=9)[0]
        
        newtimerange =  paddedT0+'~'+paddedT1
        
        # Compare with the original
        self.assertEqual(origt, newtimerange)
        
        # Compare with original values from Flag.xml
        xmlt0 = float(4891227930515540000) * 1.0E-9
        xmlt1 = float(4891227932453838000) * 1.0E-9
        
        self.assertAlmostEqual(xmlt0, startTimeSec['value'], places=3)
        self.assertAlmostEqual(xmlt1, endTimeSec['value'], places=3)
Exemple #2
0
def time2filename(msfile, timerange='', spw=''):
    from astropy.time import Time
    tb.open(msfile)
    starttim = Time(tb.getcell('TIME', 0) / 24. / 3600., format='mjd')
    endtim = Time(tb.getcell('TIME', tb.nrows() - 1) / 24. / 3600., format='mjd')
    tb.close()
    datstr = starttim.iso[:10]
    ms.open(msfile)
    metadata = ms.metadata()
    observatory = metadata.observatorynames()[0]
    ms.close()
    if timerange is None or timerange == '':
        starttim1 = starttim
        endtim1 = endtim
    else:
        (tstart, tend) = timerange.split('~')
        if tstart[2] == ':':
            starttim1 = Time(datstr + 'T' + tstart)
            endtim1 = Time(datstr + 'T' + tend)
        else:
            starttim1 = Time(qa.quantity(tstart, 'd')['value'], format='mjd')
            endtim1 = Time(qa.quantity(tend, 'd')['value'], format='mjd')
    midtime = Time((starttim1.mjd + endtim1.mjd) / 2., format='mjd')

    tstr = midtime.to_datetime().strftime('{}_%Y%m%dT%H%M%S'.format(observatory))

    if spw:
        spstr = 'spw{}'.format(spw.replace('~', '-'))
        filename = '.'.join([tstr, spstr])
    else:
        filename = tstr

    return filename
Exemple #3
0
def randomCoords(imagenames, ncoords=10):
    import random
    from taskinit import ia, qa

    xmin, xmax = [], []
    ymin, ymax = [], []
    for image in imagenames:
        ia.open(image)
        print image, ia.boundingbox()
        trc = ia.boundingbox()['trcf'].split(', ')
        blc = ia.boundingbox()['blcf'].split(', ')
        xmin.append(qa.convert(qa.quantity(trc[0]), 'rad')['value'])
        xmax.append(qa.convert(qa.quantity(blc[0]), 'rad')['value'])
        ymin.append(qa.convert(qa.quantity(blc[1]), 'rad')['value'])
        ymax.append(qa.convert(qa.quantity(trc[1]), 'rad')['value'])
        ia.done()

    randomcoords = CoordList(imagenames)
    for i in range(ncoords):
        imageid = random.randint(0, len(imagenames) - 1)
        x = random.uniform(xmin[imageid], xmax[imageid])
        y = random.uniform(ymin[imageid], ymax[imageid])
        c = Coord(x, y, 1.0)
        randomcoords.append(c)

    return randomcoords
Exemple #4
0
 def __axis(self, idx, unit):
     refpix = self.coordsys.referencepixel()['numeric'][idx]
     refval = self.coordsys.referencevalue()['numeric'][idx]
     increment = self.coordsys.increment()['numeric'][idx]
     _unit = self.units[idx]
     if _unit != unit:
         refval = qa.convert(qa.quantity(refval,_unit),unit)['value']
         increment = qa.convert(qa.quantity(increment,_unit),unit)['value']
     #return numpy.array([refval+increment*(i-refpix) for i in xrange(self.nchan)])
     return (refpix, refval, increment)
 def __axis(self, idx, unit):
     refpix = self.coordsys.referencepixel()['numeric'][idx]
     refval = self.coordsys.referencevalue()['numeric'][idx]
     increment = self.coordsys.increment()['numeric'][idx]
     _unit = self.units[idx]
     if _unit != unit:
         refval = qa.convert(qa.quantity(refval,_unit),unit)['value']
         increment = qa.convert(qa.quantity(increment,_unit),unit)['value']
     #return numpy.array([refval+increment*(i-refpix) for i in xrange(self.nchan)])
     return (refpix, refval, increment)
Exemple #6
0
    def select(self, rowid=None, rasterid=None):
        if not ((rowid is None) ^ (rasterid is None)):
            raise RuntimeError('one of rowid or rasterid must be specified')

        if (rowid is not None) and (rowid >= self.nrow):
            raise IndexError('row index %s is out of range (number of rows detected: %s)'%(rowid,self.nrow))
        if (rasterid is not None) and (rasterid >= self.nraster):
            raise IndexError('row index %s is out of range (number of rasters detected: %s)'%(rasterid,self.nraster))

        with selection_manager(self.scantab, self.original_selection, types=0, ifs=self.spw, pols=self.pol) as s:
            alltimes = numpy.array(map(lambda x: qa.quantity(x)['value'], s.get_time(prec=16)))
            mean_interval = numpy.array(s.get_inttime()).mean()
            self.margin = 0.1 * mean_interval
            mjd_margin = self.margin / 86400.0

        if rowid is not None:
            times = alltimes[self.gaplist[rowid]:self.gaplist[rowid+1]]
        else:
            times = alltimes[self.gaplist_raster[rasterid]:self.gaplist_raster[rasterid+1]]

        tmp_mjd_range = (times.min() - mjd_margin, times.max() + mjd_margin,)
        tmp_mjd_range_nomargin = (times.min(), times.max(),)
        casalog.post('time range: %s ~ %s'%(tmp_mjd_range_nomargin), priority='DEBUG')

        if rowid is not None:
            self.mjd_range = tmp_mjd_range
            self.mjd_range_nomargin = tmp_mjd_range_nomargin
        else:
            self.mjd_range_raster = tmp_mjd_range
            self.mjd_range_nomargin_raster = tmp_mjd_range_nomargin
Exemple #7
0
    def select(self, rowid=None, rasterid=None):
        if not ((rowid is None) ^ (rasterid is None)):
            raise RuntimeError('one of rowid or rasterid must be specified')

        if (rowid is not None) and (rowid >= self.nrow):
            raise IndexError('row index %s is out of range (number of rows detected: %s)'%(rowid,self.nrow))
        if (rasterid is not None) and (rasterid >= self.nraster):
            raise IndexError('row index %s is out of range (number of rasters detected: %s)'%(rasterid,self.nraster))

        with selection_manager(self.scantab, self.original_selection, types=0, ifs=self.spw, pols=self.pol) as s:
            alltimes = numpy.array(map(lambda x: qa.quantity(x)['value'], s.get_time(prec=16)))
            mean_interval = numpy.array(s.get_inttime()).mean()
            self.margin = 0.1 * mean_interval
            mjd_margin = self.margin / 86400.0

        if rowid is not None:
            times = alltimes[self.gaplist[rowid]:self.gaplist[rowid+1]]
        else:
            times = alltimes[self.gaplist_raster[rasterid]:self.gaplist_raster[rasterid+1]]

        tmp_mjd_range = (times.min() - mjd_margin, times.max() + mjd_margin,)
        tmp_mjd_range_nomargin = (times.min(), times.max(),)
        casalog.post('time range: %s ~ %s'%(tmp_mjd_range_nomargin), priority='DEBUG')

        if rowid is not None:
            self.mjd_range = tmp_mjd_range
            self.mjd_range_nomargin = tmp_mjd_range_nomargin
        else:
            self.mjd_range_raster = tmp_mjd_range
            self.mjd_range_nomargin_raster = tmp_mjd_range_nomargin
Exemple #8
0
def detect_gap(scantab, spw, pol):
    with selection_manager(scantab, scantab.get_selection(), types=0, ifs=spw, pols=pol) as s:
        alldir = numpy.array([s.get_directionval(i) for i in xrange(s.nrow())]).transpose()
        timestamp = numpy.array(map(lambda x: qa.quantity(x)['value'], s.get_time(prec=16)))

    row_gap = _detect_gap(timestamp)
    ras_gap = _detect_gap_raster(timestamp, alldir, row_gap=row_gap)
    return row_gap, ras_gap
Exemple #9
0
def detect_gap(scantab, spw, pol):
    with selection_manager(scantab, scantab.get_selection(), types=0, ifs=spw, pols=pol) as s:
        alldir = numpy.array([s.get_directionval(i) for i in xrange(s.nrow())]).transpose()
        timestamp = numpy.array(map(lambda x: qa.quantity(x)['value'], s.get_time(prec=16)))

    row_gap = _detect_gap(timestamp)
    ras_gap = _detect_gap_raster(timestamp, alldir, row_gap=row_gap)
    return row_gap, ras_gap
Exemple #10
0
def asdatestring(mjd, digit, timeonly=False):
    datedict = qa.splitdate(qa.quantity(mjd, 'd'))
    if digit > 10 : digit = 10
    sstr_tmp = str(numpy.round(datedict['s'], digit)).split('.')
    sstr = sstr_tmp[0] + '.' + sstr_tmp[1][0:digit]
    if timeonly:
        return '%s:%s:%s'%(datedict['hour'],datedict['min'],sstr)
    else:
        return '%s/%s/%s/%s:%s:%s'%(datedict['year'],datedict['month'],datedict['monthday'],datedict['hour'],datedict['min'],sstr)
Exemple #11
0
def asdatestring(mjd, digit, timeonly=False):
    datedict = qa.splitdate(qa.quantity(mjd, 'd'))
    if digit > 10 : digit = 10
    sstr_tmp = str(numpy.round(datedict['s'], digit)).split('.')
    sstr = sstr_tmp[0] + '.' + sstr_tmp[1][0:digit]
    if timeonly:
        return '%s:%s:%s'%(datedict['hour'],datedict['min'],sstr)
    else:
        return '%s/%s/%s/%s:%s:%s'%(datedict['year'],datedict['month'],datedict['monthday'],datedict['hour'],datedict['min'],sstr)
 def to_velocity(self, frequency, freq_unit='GHz', restfreq=None):
     rest_frequency = self.coordsys.restfrequency()
     # user-defined rest frequency takes priority
     if restfreq is not None:
         vrf = qa.convert(qa.quantity(restfreq), freq_unit)['value']
     elif rest_frequency['unit'] != freq_unit:
         vrf = qa.convert(rest_frequency, freq_unit)['value']
     else:
         vrf = rest_frequency['value']
     return (1.0 - (frequency / vrf)) * LightSpeed
 def to_velocity(self, frequency, freq_unit='GHz', restfreq=None):
     rest_frequency = self.coordsys.restfrequency()
     # user-defined rest frequency takes priority 
     if restfreq is not None:
         vrf = qa.convert(qa.quantity(restfreq), freq_unit)['value']
     elif rest_frequency['unit'] != freq_unit:
         vrf = qa.convert(rest_frequency, freq_unit)['value']
     else:
         vrf = rest_frequency['value']
     return (1.0 - (frequency / vrf)) * LightSpeed
Exemple #14
0
 def format_coord(x, y):
     col = np.argmin(np.absolute(tim - x))
     row = np.argmin(np.absolute(freqghz - y))
     if col >= 0 and col < ntim and row >= 0 and row < nfreq:
         timv = tim[col]
         timstr = qa.time(qa.quantity(timv, 's'),
                          form='clean',
                          prec=9)[0]
         flux = spec_plt[row, col]
         return 'time {0} = {1}, freq = {2:.3f} GHz, flux = {3:.2f} Jy'.format(
             col, timstr, y, flux)
     else:
         return 'x = {0}, y = {1:.3f}'.format(x, y)
Exemple #15
0
def coordsTocl(name, flux, coords):
    from taskinit import cl, qa

    flux = qa.quantity(flux)
    cl.done()
    cl.rename(name)
    for coord in coords:
        clpars = {}
        clpars['flux'] = -flux['value']
        clpars['fluxunit'] = flux['unit']
        clpars['dir'] = ['J2000', str(coord.x) + 'rad', str(coord.y) + 'rad']
        clpars['shape'] = 'point'
        cl.addcomponent(**clpars)
    cl.done()
Exemple #16
0
def read_msinfo(vis=None, msinfofile=None):
    # read MS information #
    msinfo = dict.fromkeys(['vis', 'scans', 'fieldids', 'btimes', 'btimestr', \
                            'inttimes', 'ras', 'decs'])
    ms.open(vis)
    scans = ms.getscansummary()
    scanids = sorted(scans.keys(), key=lambda x: int(x))
    nscanid = len(scanids)
    btimes = []
    btimestr = []
    etimes = []
    fieldids = []
    inttimes = []
    dirs = []
    ras = []
    decs = []
    for i in range(nscanid):
        btimes.append(scans[scanids[i]]['0']['BeginTime'])
        etimes.append(scans[scanids[i]]['0']['EndTime'])
        fieldid = scans[scanids[i]]['0']['FieldId']
        fieldids.append(fieldid)
        dir = ms.getfielddirmeas('PHASE_DIR', fieldid)
        dirs.append(dir)
        ras.append(dir['m0'])
        decs.append(dir['m1'])
        inttimes.append(scans[scanids[i]]['0']['IntegrationTime'])
    ms.close()
    btimestr = [qa.time(qa.quantity(btimes[i], 'd'), form='fits', prec=10)[0] \
                for i in range(nscanid)]
    msinfo['vis'] = vis
    msinfo['scans'] = scans
    msinfo['fieldids'] = fieldids
    msinfo['btimes'] = btimes
    msinfo['btimestr'] = btimestr
    msinfo['inttimes'] = inttimes
    msinfo['ras'] = ras
    msinfo['decs'] = decs
    if msinfofile:
        np.savez(msinfofile, vis=vis, scans=scans, fieldids=fieldids, \
                 btimes=btimes, btimestr=btimestr, inttimes=inttimes, \
                 ras=ras, decs=decs)
    return msinfo
def parse_figsize(figsize):
    """
    return figsize in inches
    """
    casalog.post('parse_figsize input: {input}'.format(input=figsize),
                 priority='DEBUG')
    parsed = None
    if figsize is not None and isinstance(figsize, str) and len(figsize) > 0:
        size_list = figsize.split(',')
        size_inch_list = [
            x / 25.4 for s in size_list
            for x in qa.getvalue(qa.convert(qa.quantity(s), outunit='mm'))
        ]
        if len(size_inch_list) == 1:
            s = size_inch_list[0]
            parsed = (s, s)
        else:
            parsed = tuple(size_inch_list[:2])
    casalog.post('parse_figsize output: {output}'.format(output=parsed),
                 priority='DEBUG')
    return parsed
def parse_figsize(figsize):
    """
    return figsize in inches
    """
    casalog.post('parse_figsize input: {input}'.format(input=figsize), priority='DEBUG')
    parsed = None
    if figsize is not None and isinstance(figsize, str) and len(figsize) > 0:
        size_list = figsize.split(',')
        size_inch_list = [x / 25.4 for s in size_list for x in qa.getvalue(qa.convert(qa.quantity(s),outunit='mm'))]
        if len(size_inch_list) == 1:
            s = size_inch_list[0]
            parsed = (s, s)
        else:
            parsed = tuple(size_inch_list[:2])
    casalog.post('parse_figsize output: {output}'.format(output=parsed), priority='DEBUG')
    return parsed
Exemple #19
0
def imreg(vis=None,
          ephem=None,
          msinfo=None,
          imagefile=None,
          timerange=None,
          reftime=None,
          fitsfile=None,
          beamfile=None,
          offsetfile=None,
          toTb=None,
          scl100=None,
          verbose=False,
          p_ang=False,
          overwrite=True,
          usephacenter=True,
          deletehistory=False):
    ''' 
    main routine to register CASA images
           Required Inputs:
               vis: STRING. CASA measurement set from which the image is derived
               imagefile: STRING or LIST. name of the input CASA image
               timerange: STRING or LIST. timerange used to generate the CASA image, must have the same length as the input images. 
                          Each element should be in CASA standard time format, e.g., '2012/03/03/12:00:00~2012/03/03/13:00:00'
           Optional Inputs:
               msinfo: DICTIONARY. CASA MS information, output from read_msinfo. If not provided, generate one from the supplied vis
               ephem: DICTIONARY. solar ephem, output from read_horizons. 
                      If not provided, query JPL Horizons based on time info of the vis (internet connection required)
               fitsfile: STRING or LIST. name of the output registered fits files
               reftime: STRING or LIST. Each element should be in CASA standard time format, e.g., '2012/03/03/12:00:00'
               offsetfile: optionally provide an offset with a series of solar x and y offsets with timestamps 
               toTb: Bool. Convert the default Jy/beam to brightness temperature?
               scl100: Bool. If True, scale the image values up by 100 (to compensate VLA 20 dB attenuator)
               verbose: Bool. Show more diagnostic info if True.
               usephacenter: Bool -- if True, correct for the RA and DEC in the ms file based on solar empheris.
                                     Otherwise assume the phasecenter is correctly pointed to the solar disk center
                                     (EOVSA case)
    '''
    ia = iatool()

    if deletehistory:
        msclearhistory(vis)
    if verbose:
        import time
        t0 = time.time()
        prtidx = 1
        print('point {}: {}'.format(prtidx, time.time() - t0))
        prtidx += 1

    if not imagefile:
        raise ValueError, 'Please specify input image'
    if not timerange:
        raise ValueError, 'Please specify timerange of the input image'
    if type(imagefile) == str:
        imagefile = [imagefile]
    if type(timerange) == str:
        timerange = [timerange]
    if not fitsfile:
        fitsfile = [img + '.fits' for img in imagefile]
    if type(fitsfile) == str:
        fitsfile = [fitsfile]
    nimg = len(imagefile)
    if len(timerange) != nimg:
        raise ValueError, 'Number of input images does not equal to number of timeranges!'
    if len(fitsfile) != nimg:
        raise ValueError, 'Number of input images does not equal to number of output fits files!'
    nimg = len(imagefile)
    if verbose:
        print str(nimg) + ' images to process...'

    if verbose:
        print('point {}: {}'.format(prtidx, time.time() - t0))
        prtidx += 1

    if reftime:  # use as reference time to find solar disk RA and DEC to register the image, but not the actual timerange associated with the image
        if type(reftime) == str:
            reftime = [reftime] * nimg
        if len(reftime) != nimg:
            raise ValueError, 'Number of reference times does not match that of input images!'
        helio = ephem_to_helio(vis,
                               ephem=ephem,
                               msinfo=msinfo,
                               reftime=reftime,
                               usephacenter=usephacenter)
    else:
        # use the supplied timerange to register the image
        helio = ephem_to_helio(vis,
                               ephem=ephem,
                               msinfo=msinfo,
                               reftime=timerange,
                               usephacenter=usephacenter)

    if verbose:
        print('point {}: {}'.format(prtidx, time.time() - t0))
        prtidx += 1

    for n, img in enumerate(imagefile):
        if verbose:
            print 'processing image #' + str(n)
        fitsf = fitsfile[n]
        timeran = timerange[n]
        # obtain duration of the image as FITS header exptime
        try:
            [tbg0, tend0] = timeran.split('~')
            tbg_d = qa.getvalue(qa.convert(qa.totime(tbg0), 'd'))[0]
            tend_d = qa.getvalue(qa.convert(qa.totime(tend0), 'd'))[0]
            tdur_s = (tend_d - tbg_d) * 3600. * 24.
            dateobs = qa.time(qa.quantity(tbg_d, 'd'), form='fits', prec=10)[0]
        except:
            print 'Error in converting the input timerange: ' + str(
                timeran) + '. Proceeding to the next image...'
            continue

        if verbose:
            print('point {}: {}'.format(prtidx, time.time() - t0))
            prtidx += 1

        hel = helio[n]
        if not os.path.exists(img):
            raise ValueError, 'Please specify input image'
        if os.path.exists(fitsf) and not overwrite:
            raise ValueError, 'Specified fits file already exists and overwrite is set to False. Aborting...'
        else:
            p0 = hel['p0']
            ia.open(img)
            imr = ia.rotate(pa=str(-p0) + 'deg')
            imr.tofits(fitsf, history=False, overwrite=overwrite)
            imr.close()
            imsum = ia.summary()
            ia.close()

        if verbose:
            print('point {}: {}'.format(prtidx, time.time() - t0))
            prtidx += 1

        # construct the standard fits header
        # RA and DEC of the reference pixel crpix1 and crpix2
        (imra, imdec) = (imsum['refval'][0], imsum['refval'][1])
        # find out the difference of the image center to the CASA phase center
        # RA and DEC difference in arcseconds
        ddec = degrees((imdec - hel['dec_fld'])) * 3600.
        dra = degrees((imra - hel['ra_fld']) * cos(hel['dec_fld'])) * 3600.
        # Convert into image heliocentric offsets
        prad = -radians(hel['p0'])
        dx = (-dra) * cos(prad) - ddec * sin(prad)
        dy = (-dra) * sin(prad) + ddec * cos(prad)
        if offsetfile:
            try:
                offset = np.load(offsetfile)
            except:
                raise ValueError, 'The specified offsetfile does not exist!'
            reftimes_d = offset['reftimes_d']
            xoffs = offset['xoffs']
            yoffs = offset['yoffs']
            timg_d = hel['reftime']
            ind = bisect.bisect_left(reftimes_d, timg_d)
            xoff = xoffs[ind - 1]
            yoff = yoffs[ind - 1]
        else:
            xoff = hel['refx']
            yoff = hel['refy']
        if verbose:
            print 'offset of image phase center to visibility phase center (arcsec): ', dx, dy
            print 'offset of visibility phase center to solar disk center (arcsec): ', xoff, yoff
        (crval1, crval2) = (xoff + dx, yoff + dy)
        # update the fits header to heliocentric coordinates

        if verbose:
            print('point {}: {}'.format(prtidx, time.time() - t0))
            prtidx += 1

        hdu = pyfits.open(fitsf, mode='update')

        if verbose:
            print('point {}: {}'.format(prtidx, time.time() - t0))
            prtidx += 1

        header = hdu[0].header
        (cdelt1,
         cdelt2) = (-header['cdelt1'] * 3600., header['cdelt2'] * 3600.
                    )  # Original CDELT1, 2 are for RA and DEC in degrees
        header['cdelt1'] = cdelt1
        header['cdelt2'] = cdelt2
        header['cunit1'] = 'arcsec'
        header['cunit2'] = 'arcsec'
        header['crval1'] = crval1
        header['crval2'] = crval2
        header['ctype1'] = 'HPLN-TAN'
        header['ctype2'] = 'HPLT-TAN'
        header['date-obs'] = dateobs  # begin time of the image
        if not p_ang:
            hel['p0'] = 0
        try:
            # this works for pyfits version of CASA 4.7.0 but not CASA 4.6.0
            if tdur_s:
                header.set('exptime', tdur_s)
            else:
                header.set('exptime', 1.)
            header.set('p_angle', hel['p0'])
            header.set('dsun_obs',
                       sun.sunearth_distance(Time(dateobs)).to(u.meter).value)
            header.set(
                'rsun_obs',
                sun.solar_semidiameter_angular_size(Time(dateobs)).value)
            header.set('rsun_ref', sun.constants.radius.value)
            header.set('hgln_obs', 0.)
            header.set('hglt_obs',
                       sun.heliographic_solar_center(Time(dateobs))[1].value)
        except:
            # this works for astropy.io.fits
            if tdur_s:
                header.append(('exptime', tdur_s))
            else:
                header.append(('exptime', 1.))
            header.append(('p_angle', hel['p0']))
            header.append(
                ('dsun_obs',
                 sun.sunearth_distance(Time(dateobs)).to(u.meter).value))
            header.append(
                ('rsun_obs',
                 sun.solar_semidiameter_angular_size(Time(dateobs)).value))
            header.append(('rsun_ref', sun.constants.radius.value))
            header.append(('hgln_obs', 0.))
            header.append(
                ('hglt_obs',
                 sun.heliographic_solar_center(Time(dateobs))[1].value))

        if verbose:
            print('point {}: {}'.format(prtidx, time.time() - t0))
            prtidx += 1

        # update intensity units, i.e. to brightness temperature?
        if toTb:
            # get restoring beam info
            (bmajs, bmins, bpas, beamunits,
             bpaunits) = getbeam(imagefile=imagefile, beamfile=beamfile)
            bmaj = bmajs[n]
            bmin = bmins[n]
            beamunit = beamunits[n]
            data = hdu[
                0].data  # remember the data order is reversed due to the FITS convension
            dim = data.ndim
            sz = data.shape
            keys = header.keys()
            values = header.values()
            # which axis is frequency?
            faxis = keys[values.index('FREQ')][-1]
            faxis_ind = dim - int(faxis)
            if header['BUNIT'].lower() == 'jy/beam':
                header['BUNIT'] = 'K'
                header['BTYPE'] = 'Brightness Temperature'
                for i in range(sz[faxis_ind]):
                    nu = header['CRVAL' + faxis] + header['CDELT' + faxis] * (
                        i + 1 - header['CRPIX' + faxis])
                    if header['CUNIT' + faxis] == 'KHz':
                        nu *= 1e3
                    if header['CUNIT' + faxis] == 'MHz':
                        nu *= 1e6
                    if header['CUNIT' + faxis] == 'GHz':
                        nu *= 1e9
                    if len(bmaj) > 1:  # multiple (per-plane) beams
                        bmajtmp = bmaj[i]
                        bmintmp = bmin[i]
                    else:  # one single beam
                        bmajtmp = bmaj[0]
                        bmintmp = bmin[0]
                    if beamunit == 'arcsec':
                        bmaj0 = np.radians(bmajtmp / 3600.)
                        bmin0 = np.radians(bmajtmp / 3600.)
                    if beamunit == 'arcmin':
                        bmaj0 = np.radians(bmajtmp / 60.)
                        bmin0 = np.radians(bmintmp / 60.)
                    if beamunit == 'deg':
                        bmaj0 = np.radians(bmajtmp)
                        bmin0 = np.radians(bmintmp)
                    if beamunit == 'rad':
                        bmaj0 = bmajtmp
                        bmin0 = bmintmp
                    beam_area = bmaj0 * bmin0 * np.pi / (4. * log(2.))
                    k_b = qa.constants('k')['value']
                    c_l = qa.constants('c')['value']
                    factor = 2. * k_b * nu**2 / c_l**2  # SI unit
                    jy_to_si = 1e-26
                    # print nu/1e9, beam_area, factor
                    factor2 = 1.
                    if scl100:
                        factor2 = 100.
                    if faxis == '3':
                        data[:,
                             i, :, :] *= jy_to_si / beam_area / factor * factor2
                    if faxis == '4':
                        data[
                            i, :, :, :] *= jy_to_si / beam_area / factor * factor2

        if verbose:
            print('point {}: {}'.format(prtidx, time.time() - t0))
            prtidx += 1

        hdu.flush()
        hdu.close()

        if verbose:
            print('point {}: {}'.format(prtidx, time.time() - t0))
            prtidx += 1
Exemple #20
0
def subvs(vis=None,
          outputvis=None,
          timerange=None,
          spw=None,
          subtime1=None,
          subtime2=None,
          splitsel=True,
          reverse=False,
          overwrite=False):
    """Perform vector subtraction for visibilities
    Keyword arguments:
    vis -- Name of input visibility file (MS)
            default: none; example: vis='ngc5921.ms'
    outputvis -- Name of output uv-subtracted visibility file (MS)
                  default: none; example: outputvis='ngc5921_src.ms'
    timerange -- Time range of performing the UV subtraction:
                 default='' means all times.  examples:
                 timerange = 'YYYY/MM/DD/hh:mm:ss~YYYY/MM/DD/hh:mm:ss'
                 timerange = 'hh:mm:ss~hh:mm:ss'
    spw -- Select spectral window/channel.
           default = '' all the spectral channels. Example: spw='0:1~20'
    subtime1 -- Time range 1 of the background to be subtracted from the data 
                 default='' means all times.  format:
                 timerange = 'YYYY/MM/DD/hh:mm:ss~YYYY/MM/DD/hh:mm:ss'
                 timerange = 'hh:mm:ss~hh:mm:ss'
    subtime2 -- Time range 2 of the backgroud to be subtracted from the data
                 default='' means all times.  examples:
                 timerange = 'YYYY/MM/DD/hh:mm:ss~YYYY/MM/DD/hh:mm:ss'
                 timerange = 'hh:mm:ss~hh:mm:ss'
    splitsel -- True or False. default = False. If splitsel = False, then the entire input
            measurement set is copied as the output measurement set (outputvis), with 
            background subtracted at selected timerange and spectral channels. 
            If splitsel = True,then only the selected timerange and spectral channels 
            are copied into the output measurement set (outputvis).
    reverse -- True or False. default = False. If reverse = False, then the times indicated
            by subtime1 and/or subtime2 are treated as background and subtracted; If reverse
            = True, then reverse the sign of the background-subtracted data. The option can 
            be used for mapping absorptive structure.
    overwrite -- True or False. default = False. If overwrite = True and
                outputvis already exists, the selected subtime and spw in the 
                output measurment set will be replaced with background subtracted 
                visibilities

    """
    #check the visbility ms
    if not outputvis or outputvis.isspace():
        raise ValueError, 'Please specify outputvis'

    if os.path.exists(outputvis):
        if overwrite:
            print "The already existing output measurement set will be updated."
        else:
            raise ValueError, "Output MS %s already exists - will not overwrite." % outputvis
    else:
        if not splitsel:
            shutil.copytree(vis, outputvis)
        else:
            ms.open(vis, nomodify=True)
            ms.split(outputvis, spw=spw, time=timerange, whichcol='DATA')
            ms.close()

    #define and check the time ranges
    if subtime1 and (type(subtime1) == str):
        [bsubtime1, esubtime1] = subtime1.split('~')
        bsubtime1sec = qa.getvalue(qa.convert(qa.totime(bsubtime1), 's'))
        esubtime1sec = qa.getvalue(qa.convert(qa.totime(esubtime1), 's'))
        timebin1sec = esubtime1sec - bsubtime1sec
        if timebin1sec < 0:
            raise Exception, 'Negative timebin! Please check the "subtime1" parameter.'
        casalog.post('Selected timerange 1: ' + subtime1 +
                     ' as background for uv subtraction.')
    else:
        raise Exception, 'Please enter at least one timerange as the background'

    if subtime2 and (type(subtime2) == str):
        [bsubtime2, esubtime2] = subtime2.split('~')
        bsubtime2sec = qa.getvalue(qa.convert(qa.totime(bsubtime2), 's'))
        esubtime2sec = qa.getvalue(qa.convert(qa.totime(esubtime2), 's'))
        timebin2sec = esubtime2sec - bsubtime2sec
        if timebin2sec < 0:
            raise Exception, 'Negative timebin! Please check the "subtime2" parameter.'
        timebin2 = str(timebin2sec) + 's'
        casalog.post('Selected timerange 2: ' + subtime2 +
                     ' as background for uv subtraction.')
        #plus 1s is to ensure averaging over the entire timerange
    else:
        casalog.post(
            'Timerange 2 not selected, using only timerange 1 as background')

    if timerange and (type(timerange) == str):
        [btimeo, etimeo] = timerange.split('~')
        btimeosec = qa.getvalue(qa.convert(qa.totime(btimeo), 's'))
        etimeosec = qa.getvalue(qa.convert(qa.totime(etimeo), 's'))
        timebinosec = etimeosec - btimeosec
        if timebinosec < 0:
            raise Exception, 'Negative timebin! Please check the "timerange" parameter.'
        casalog.post('Selected timerange: ' + timerange +
                     ' as the time for UV subtraction.')
    else:
        casalog.post(
            'Output timerange not specified, using the entire timerange')

    if spw and (type(spw) == str):
        [spwid, chanran] = spw.split(':')
        [bchan, echan] = chanran.split('~')
    else:
        casalog.post('spw not specified, use all frequency channels')

    #Select the background indicated by subtime1
    ms.open(vis, nomodify=True)
    #Select the spw id
    ms.msselect({'time': subtime1})
    if spw and (type(spw) == str):
        ms.selectinit(datadescid=int(spwid))
        nchan = int(echan) - int(bchan) + 1
        ms.selectchannel(nchan, int(bchan), 1, 1)
    rec1 = ms.getdata(['data', 'time', 'axis_info'], ifraxis=True)
    #print 'shape of the frequency matrix ',rec1['axis_info']['freq_axis']['chan_freq'].shape
    sz1 = rec1['data'].shape
    print 'dimension of selected background 1', rec1['data'].shape
    #the data shape is (n_pol,n_channel,n_baseline,n_time), no need to reshape
    #rec1['data']=rec1['data'].reshape(sz1[0],sz1[1],sz1[2],nspw,sz1[3]/nspw,order='F')
    #print 'reshaped rec1 ', rec1['data'].shape
    rec1avg = np.average(rec1['data'], axis=3)
    casalog.post('Averaging the visibilities in subtime1: ' + subtime1)
    ms.close()
    if subtime2 and (type(subtime2) == str):
        ms.open(vis, nomodify=True)
        #Select the spw id
        ms.msselect({'time': subtime2})
        if spw and (type(spw) == str):
            ms.selectinit(datadescid=0)
            nchan = int(echan) - int(bchan) + 1
            ms.selectchannel(nchan, int(bchan), 1, 1)
        rec2 = ms.getdata(['data', 'time', 'axis_info'], ifraxis=True)
        sz2 = rec2['data'].shape
        print 'dimension of selected background 2', rec2['data'].shape
        #rec2['data']=rec2['data'].reshape(sz2[0],sz2[1],sz2[2],nspw,sz2[3]/nspw,order='F')
        #print 'reshaped rec1 ', rec2['data'].shape
        rec2avg = np.average(rec2['data'], axis=3)
        ms.close()
        casalog.post('Averaged the visibilities in subtime2: ' + subtime2)

    #do UV subtraction, according to timerange and spw
    ms.open(outputvis, nomodify=False)
    if not splitsel:
        #outputvis is identical to input visibility, do the selection
        if timerange and (type(timerange == str)):
            ms.msselect({'time': timerange})
        if spw and (type(spw) == str):
            ms.selectinit(datadescid=int(spwid))
            nchan = int(echan) - int(bchan) + 1
            ms.selectchannel(nchan, int(bchan), 1, 1)
    else:
        #outputvis is splitted, selections have already applied, select all the data
        ms.selectinit(datadescid=0)
    orec = ms.getdata(['data', 'time', 'axis_info'], ifraxis=True)
    b_rows = orec['data'].shape[2]
    nchan = orec['data'].shape[1]
    #szo=orec['data'].shape
    print 'dimension of output data', orec['data'].shape
    #orec['data']=orec['data'].reshape(szo[0],szo[1],szo[2],nspw,szo[3]/nspw,order='F')
    #print 'reshaped rec1 ', orec['data'].shape
    t_rows = orec['data'].shape[3]
    casalog.post('Number of baselines: ' + str(b_rows))
    casalog.post('Number of spectral channels: ' + str(nchan))
    casalog.post('Number of time pixels: ' + str(t_rows))

    if subtime1 and (not subtime2):
        casalog.post(
            'Only "subtime1" is defined, subtracting background defined in subtime1: '
            + subtime1)
        t1 = (np.amax(rec1['time']) + np.amin(rec1['time'])) / 2.
        print 't1: ', qa.time(qa.quantity(t1, 's'), form='ymd', prec=10)
        for i in range(t_rows):
            orec['data'][:, :, :, i] -= rec1avg
            if reverse:
                orec['data'][:, :, :, i] = -orec['data'][:, :, :, i]
    if subtime1 and subtime2 and (type(subtime2) == str):
        casalog.post(
            'Both subtime1 and subtime2 are specified, doing linear interpolation between "subtime1" and "subtime2"'
        )
        t1 = (np.amax(rec1['time']) + np.amin(rec1['time'])) / 2.
        t2 = (np.amax(rec2['time']) + np.amin(rec2['time'])) / 2.
        touts = orec['time']
        print 't1: ', qa.time(qa.quantity(t1, 's'), form='ymd', prec=10)
        print 't2: ', qa.time(qa.quantity(t2, 's'), form='ymd', prec=10)
        for i in range(t_rows):
            tout = touts[i]
            if tout > np.amax([t1, t2]):
                tout = np.amax([t1, t2])
            elif tout < np.amin([t1, t2]):
                tout = np.amin([t1, t2])
            orec['data'][:, :, :,
                         i] -= (rec2avg - rec1avg) * (tout -
                                                      t1) / (t2 - t1) + rec1avg
            if reverse:
                orec['data'][:, :, :, i] = -orec['data'][:, :, :, i]

    #orec['data']=orec['data'].reshape(szo[0],szo[1],szo[2],szo[3],order='F')
    #put the modified data back into the output visibility set
    del orec['time']
    del orec['axis_info']
    ms.putdata(orec)
    ms.close()
Exemple #21
0
def ephem_to_helio(vis=None,
                   ephem=None,
                   msinfo=None,
                   reftime=None,
                   polyfit=None,
                   usephacenter=False):
    '''1. Take a solar ms database, read the scan and field information, find out the pointings (in RA and DEC)
       2. Compare with the ephemeris of the solar disk center (in RA and DEC)
       3. Generate VLA pointings in heliocentric coordinates
       inputs:
           msinfo: CASA MS information, output from read_msinfo
           ephem: solar ephem, output from read_horizons
           reftime: list of reference times (e.g., used for imaging)
                    CASA standard time format, either a single time (e.g., '2012/03/03/12:00:00'
                    or a time range (e.g., '2012/03/03/12:00:00~2012/03/03/13:00:00'. If the latter,
                    take the midpoint of the timerange for reference. If no date specified, take
                    the date of the first scan
           polyfit: ONLY works for MS database with only one source with continously tracking; 
                    not recommanded unless scan length is too long and want to have very high accuracy
           usephacenter: Bool -- if True, correct for the RA and DEC in the ms file based on solar empheris. 
                                 Otherwise assume the phasecenter is correctly pointed to the solar disk center
                                 (EOVSA case)
     
       return value:
           helio: a list of VLA pointing information
                   reftimestr: reference time, in FITS format string
                   reftime: reference time, in mjd format
                   ra: actual RA of phasecenter in the ms file at the reference time (interpolated)
                   dec: actual DEC of phasecenter in the ms file at the reference time (interpolated)
                   # CASA uses only RA and DEC of the closest field (e.g. in clean) #
                   ra_fld: right ascention of the CASA reference pointing direction
                   dec_fld: declination of the CASA reference pointing direction
                   raoff: RA offset of the phasecenter in the ms file to solar center
                   decoff: DEC offset of the phasecenter in the ms file to solar center
                   refx: heliocentric X offset of the phasecenter in the ms file to solar center
                   refy: heliocentric Y offset of the phasecenter in the ms file to solar center
    ######## Example #########
         msfile='sun_C_20140910T221952-222952.10s.cal.ms'
         ephemfile='horizons_sun_20140910.radecp'
         ephem=vla_prep.read_horizons(ephemfile=ephemfile)
         msinfo=vla_prep.read_msinfo(msfile=msfile)
         polyfit=0
         reftime = '22:25:20~22:25:40'
    '''
    if not vis or not os.path.exists(vis):
        raise ValueError, 'Please provide information of the MS database!'
    if not ephem:
        ephem = read_horizons(vis)
    if not msinfo:
        msinfo0 = read_msinfo(vis)
    else:
        if isinstance(msinfo, str):
            try:
                msinfo0 = np.load(msinfo)
            except:
                raise ValueError, 'The specified input msinfo file does not exist!'
        elif isinstance(msinfo, dict):
            msinfo0 = msinfo
        else:
            raise ValueError, 'msinfo should be either a numpy npz or a dictionary'
    print 'msinfo is derived from: ', msinfo0['vis']
    scans = msinfo0['scans']
    fieldids = msinfo0['fieldids']
    btimes = msinfo0['btimes']
    inttimes = msinfo0['inttimes']
    ras = msinfo0['ras']
    decs = msinfo0['decs']
    ra_rads = [ra['value'] for ra in ras]
    dec_rads = [dec['value'] for dec in decs]
    # fit 2nd order polynomial fits to the RAs and DECs #
    if polyfit:
        cra = np.polyfit(btimes, ra_rads, 2)
        cdec = np.polyfit(btimes, dec_rads, 2)

    # find out phase center infomation in ms according to the input time or timerange #
    if not reftime:
        raise ValueError, 'Please specify a reference time of the image'
    if type(reftime) == str:
        reftime = [reftime]
    if (not isinstance(reftime, list)):
        print 'input "reftime" is not a valid list. Abort...'

    nreftime = len(reftime)
    helio = []
    for reftime0 in reftime:
        helio0 = dict.fromkeys(['reftimestr', 'reftime', \
                                'ra', 'dec', 'ra_fld', 'dec_fld', \
                                'raoff', 'decoff', 'refx', 'refy', 'p0'])
        helio0['reftimestr'] = reftime0
        if '~' in reftime0:
            # if reftime0 is specified as a timerange
            [tbg0, tend0] = reftime0.split('~')
            tbg_d = qa.getvalue(qa.convert(qa.totime(tbg0), 'd'))[0]
            tend_d = qa.getvalue(qa.convert(qa.totime(tend0), 'd'))[0]
            tdur_s = (tend_d - tbg_d) * 3600. * 24.
            # if no date is specified, add up the date of the first scan
            if tend_d < 1.:
                if tend_d >= tbg_d:
                    tend_d += int(btimes[0])
                else:
                    tend_d += int(btimes[0]) + 1
            if tbg_d < 1.:
                tbg_d += int(btimes[0])
            tref_d = (tbg_d + tend_d) / 2.
        else:
            # if reftime0 is specified as a single value
            tref_d = qa.getvalue(qa.convert(qa.totime(reftime0), 'd'))
            # if no date is specified, add up the date of the first scan
            if tref_d < 1.:
                tref_d += int(btimes[0])
            tbg_d = tref_d
            # use the intergration time
            ind = bisect.bisect_left(btimes, tref_d)
            tdur_s = inttims[ind - 1]
        helio0['reftime'] = tref_d
        helio0['date-obs'] = qa.time(qa.quantity(tbg_d, 'd'),
                                     form='fits',
                                     prec=10)[0]
        helio0['exptime'] = tdur_s

        # find out phase center RA and DEC in the measurement set according to the reference time
        # if polyfit, then use the 2nd order polynomial coeffs
        ind = bisect.bisect_left(btimes, tref_d)
        if ind > 1:
            dt = tref_d - btimes[ind - 1]
            if ind < len(btimes):
                scanlen = btimes[ind] - btimes[ind - 1]
                (ra_b, ra_e) = (ras[ind - 1]['value'], ras[ind]['value'])
                (dec_b, dec_e) = (decs[ind - 1]['value'], decs[ind]['value'])
            if ind >= len(btimes):
                scanlen = btimes[ind - 1] - btimes[ind - 2]
                (ra_b, ra_e) = (ras[ind - 2]['value'], ras[ind - 1]['value'])
                (dec_b, dec_e) = (decs[ind - 2]['value'],
                                  decs[ind - 1]['value'])
        if ind == 1:  # only one scan exists (e.g., imported from AIPS)
            ra_b = ras[ind - 1]['value']
            ra_e = ra_b
            dec_b = decs[ind - 1]['value']
            dec_e = dec_b
            scanlen = 10.  # radom value
            dt = 0.
        if ind < 1:
            raise ValueError, 'Reference time does not fall into the scan list!'
        if polyfit:
            ra = cra[0] * tref_d**2. + cra[1] * tref_d + cra[2]
            dec = cdec[0] * tref_d**2. + cdec[1] * tref_d + cdec[2]
        # if not, use linearly interpolated RA and DEC at the beginning of this scan and next scan
        else:
            ra = ra_b + (ra_e - ra_b) / scanlen * dt
            dec = dec_b + (dec_e - dec_b) / scanlen * dt
        if ra < 0:
            ra += 2. * np.pi
        if ra_b < 0:
            ra_b += 2. * np.pi

        # compare with ephemeris from JPL Horizons
        time0 = ephem['time']
        ra0 = ephem['ra']
        dec0 = ephem['dec']
        p0 = ephem['p0']
        delta0 = ephem['delta']
        ind = bisect.bisect_left(time0, tref_d)
        dt0 = time0[ind] - time0[ind - 1]
        dt_ref = tref_d - time0[ind - 1]
        dra0 = ra0[ind] - ra0[ind - 1]
        ddec0 = dec0[ind] - dec0[ind - 1]
        dp0 = p0[ind] - p0[ind - 1]
        ddelta0 = delta0[ind] - delta0[ind - 1]
        ra0 = ra0[ind - 1] + dra0 / dt0 * dt_ref
        dec0 = dec0[ind - 1] + ddec0 / dt0 * dt_ref
        p0 = p0[ind - 1] + dp0 / dt0 * dt_ref
        delta0 = delta0[ind - 1] + ddelta0 / dt0 * dt_ref
        if ra0 < 0:
            ra0 += 2. * np.pi

        # RA and DEC offset in arcseconds
        decoff = degrees((dec - dec0)) * 3600.
        raoff = degrees((ra - ra0) * cos(dec)) * 3600.
        # Convert into heliocentric offsets
        prad = -radians(p0)
        refx = (-raoff) * cos(prad) - decoff * sin(prad)
        refy = (-raoff) * sin(prad) + decoff * cos(prad)
        helio0['ra'] = ra  # ra of the actual pointing
        helio0['dec'] = dec  # dec of the actual pointing
        helio0[
            'ra_fld'] = ra_b  # ra of the field, used as the reference in e.g., clean
        helio0[
            'dec_fld'] = dec_b  # dec of the field, used as the refenrence in e.g., clean
        helio0['raoff'] = raoff
        helio0['decoff'] = decoff
        if usephacenter:
            helio0['refx'] = refx
            helio0['refy'] = refy
        else:
            helio0['refx'] = 0.
            helio0['refy'] = 0.
        helio0['p0'] = p0
        # helio['r_sun']=np.degrees(R_sun.value/(au.value*delta0))*3600. #in arcsecs
        helio.append(helio0)
    return helio
Exemple #22
0
    def test_readAndParseIrregularTbuff(self):
        '''flaghelper: compare the read and parse and apply of irregular tbuff'''
        print ''
        
        # MJD in seconds of timeranges are these
        # <startTime>4891227930515540000 <endTime>4891227932453838000
        # <startTime>4891228473545856000 <endTime>4891228473731891000
        # <startTime>4891226924455911000 <endTime>4891226927502314000
        # <startTime>4891228838164987000 <endTime>4891228838418996000
        # <startTime>4891228609440808000 <endTime>4891228612489617000

        online = ["antenna='DV03&&*' timerange='2013/11/15/10:25:30.516~2013/11/15/10:25:32.454'",
                  "antenna='DA44&&*' timerange='2013/11/15/10:34:33.546~2013/11/15/10:34:33.732'",
                  "antenna='DA46&&*' timerange='2013/11/15/10:08:44.456~2013/11/15/10:08:47.502'",
                  "antenna='DV09&&*' timerange='2013/11/15/10:18:11.798~2013/11/15/10:18:13.837'",
                  "antenna='DV05&&*' timerange='2013/11/15/10:40:38.165~2013/11/15/10:40:38.419'"]

        myinput = "antenna='DV03&&*' timerange='2013/11/15/10:25:30.516~2013/11/15/10:25:32.454'\n"\
                  "antenna='DA44&&*' timerange='2013/11/15/10:34:33.546~2013/11/15/10:34:33.732'\n"\
                  "antenna='DA46&&*' timerange='2013/11/15/10:08:44.456~2013/11/15/10:08:47.502'\n"\
                  "antenna='DV09&&*' timerange='2013/11/15/10:18:11.798~2013/11/15/10:18:13.837'\n"\
                  "antenna='DV05&&*' timerange='2013/11/15/10:40:38.165~2013/11/15/10:40:38.419'"
        
        filename1 = 'flaghelperonline2.txt'
        create_input(myinput, filename1)
        
        # timeranges from online before padding, for comparison later
        timeranges=[]
        for cmd in online:
            a,b = cmd.split(' ')
            b = b.lstrip('timerange=')
            timeranges.append(b.strip("'"))
                    
        # Apply 2 values of tbuff to timeranges
        timebuffer = [0.4, 0.7]
        dlist1 = fh.readAndParse([filename1], tbuff=timebuffer)
        self.assertEqual(len(dlist1), 5)
        
        # check the padded time ranges before and after the application
        n = 0
        for cmd in dlist1:
            padt = cmd['timerange']
            
#        padt = dlist1[0]['timerange']
        
            # Revert the tbuff application manually
            t0,t1 = padt.split('~',1)
            startTime = qa.totime(t0)['value']
            startTimeSec = float((startTime * 24 * 3600) + timebuffer[0])
            startTimeSec = qa.quantity(startTimeSec, 's')
            paddedT0 = qa.time(startTimeSec,form='ymd',prec=9)[0]
            # end time
            endTime = qa.totime(t1)['value']
            endTimeSec = float((endTime * 24 * 3600) - timebuffer[1])
            endTimeSec = qa.quantity(endTimeSec, 's')
            paddedT1 = qa.time(endTimeSec,form='ymd',prec=9)[0]
            
            newtimerange =  paddedT0+'~'+paddedT1
            
            # Compare with the original
            self.assertEqual(timeranges[n], newtimerange)
            n += 1
Exemple #23
0
def plt_dspec(specdata,
              pol='I',
              dmin=None,
              dmax=None,
              timerange=None,
              freqrange=None,
              timestr=True,
              movie=False,
              framedur=60.,
              dtframe=10.,
              goessav=None,
              goes_trange=None,
              savepng=True,
              savepdf=False):
    """
    timerange: format: ['2012/03/10/18:00:00','2012/03/10/19:00:00']
    freqrange: format: [1000.,1500.] in MHz
    movie: do a movie of dynamic spectrum?
    framedur: time range of each frame
    dtframe: time difference of consecutive frames
    goessav: provide an IDL save file from the sswidl GOES widget output
    goes_trange: plot only the specified time range for goes
    timestr: display time as strings on X-axis -- currently the times do not update themselves when zooming in
    """
    # Set up variables
    import matplotlib.pyplot as plt
    import numpy
    from numpy import log10
    from astropy.time import Time
    if pol != 'RR' and pol != 'LL' and pol != 'RRLL' and pol != 'I' and pol != 'V' and pol != 'IV':
        print "Please enter 'RR', 'LL', 'RRLL', 'I', 'V', 'IV' for pol"
        return 0

    if type(specdata) is str:
        specdata = np.load(specdata)
        bl = specdata['bl'].item()
    try:
        (npol, nbl, nfreq, ntim) = specdata['spec'].shape
        spec = specdata['spec']
        tim = specdata['tim']
        tim_ = Time(tim / 3600. / 24., format='mjd')
        tim_plt = tim_.plot_date
        freq = specdata['freq']
        if not 'bl' in vars():
            bl = specdata['bl']
    except:
        print('format of specdata not recognized. Check your input')
        return -1

    if timerange:
        if type(timerange[0]) is str:
            timerange = [
                qa.convert(qa.quantity(t), 's')['value'] for t in timerange
            ]
        tidx = np.where((tim >= timerange[0]) & (tim <= timerange[1]))[0]
    else:
        tidx = range(ntim)
    if freqrange:
        fidx = np.where((freq >= freqrange[0] * 1e6)
                        & (freq <= freqrange[1] * 1e6))[0]
    else:
        fidx = range(nfreq)

    # setup plot parameters
    print 'ploting dynamic spectrum...'
    spec_med = np.median(np.absolute(spec))
    # if not dmin:
    #    dmin = spec_med / 20.
    # if not dmax:
    #    dmax = spec_med * 5.
    # do the plot
    for b in range(nbl):
        if pol != 'RRLL' and pol != 'IV':
            if pol == 'RR':
                spec_plt = spec[0, b, :, :]
            elif pol == 'LL':
                spec_plt = spec[1, b, :, :]
            elif pol == 'I':
                spec_plt = (spec[0, b, :, :] + spec[1, b, :, :]) / 2.
            elif pol == 'V':
                spec_plt = (spec[0, b, :, :] - spec[1, b, :, :]) / 2.
            if movie:
                f = plt.figure(figsize=(16, 8), dpi=100)
                if goessav:
                    gs = gridspec.GridSpec(2, 1, height_ratios=[2, 1])
                    gs.update(left=0.06, right=0.97, top=0.95, bottom=0.06)
                    ax1 = f.add_subplot(gs[0])
                    ax2 = f.add_subplot(gs[1])
                    if os.path.exists(goessav):
                        goes = readsav(goessav)
                        # IDL anytim 0 sec correspond to 1979 Jan 01, convert to mjd time
                        anytimbase = qa.convert(
                            qa.quantity('1979/01/01/00:00:00'), 's')['value']
                        mjdbase = goes['utbase'] + anytimbase
                        ts = goes['tarray'] + mjdbase
                        lc0 = goes['yclean'][0, :]
                        lc1 = goes['yclean'][1, :]
                else:
                    ax1 = f.add_subplot(211)
                tstart = tim[tidx[0]]
                tend = tim[tidx[-1]]
                tstartstr = qa.time(qa.quantity(tstart, 's'))[0]
                tendstr = qa.time(qa.quantity(tend, 's'))[0]
                nfrm = int((tend - tstart) / dtframe) + 1
                print 'Movie mode set. ' + str(
                    nfrm
                ) + ' frames to plot from ' + tstartstr + ' to ' + tendstr
                for i in range(nfrm):
                    if (i != 0) and (i % 10 == 0):
                        print str(i) + ' frames done'
                    timeran = [
                        tstart + i * dtframe, tstart + i * dtframe + framedur
                    ]
                    tidx1 = np.where((tim >= timeran[0])
                                     & (tim <= timeran[1]))[0]
                    tim1 = tim_[tidx1]
                    freq1 = freq[fidx] / 1e9
                    spec_plt1 = spec_plt[fidx, :][:, tidx1]
                    ax1.pcolormesh(tim1.plot_date,
                                   freq1,
                                   spec_plt1,
                                   cmap='jet',
                                   vmin=dmin,
                                   vmax=dmax)
                    ax1.set_xlim(tim1[0].plot_date, tim1[-1].plot_date)
                    ax1.set_ylim(freq1[0], freq1[-1])
                    ax1.set_ylabel('Frequency (GHz)')
                    ax1.set_title('Dynamic spectrum @ bl ' + bl.split(';')[b] +
                                  ', pol ' + pol)
                    if timestr:
                        # date_format = mdates.DateFormatter('%H:%M:%S.%f')
                        # ax1.xaxis_date()
                        # ax1.xaxis.set_major_formatter(date_format)
                        locator = AutoDateLocator()
                        ax1.xaxis.set_major_locator(locator)
                        ax1.xaxis.set_major_formatter(
                            AutoDateFormatter(locator))
                    ax1.set_autoscale_on(False)
                    if goessav:
                        if goes_trange:
                            if type(goes_trange[0]) is str:
                                goes_trange = [
                                    qa.convert(qa.quantity(t), 's')['value']
                                    for t in goes_trange
                                ]
                                idx = np.where((ts >= goes_trange[0])
                                               & (ts <= goes_trange[1]))[0]
                        else:
                            idx = range(len(ts))
                        ts_plt = ts[idx]
                        lc0_plt = lc0[idx]
                        utbase = qa.convert(qa.quantity('0001/01/01/00:00:00'),
                                            'd')['value'] + 1
                        ts_plt_d = ts_plt / 3600. / 24. - utbase
                        ax2.plot_date(ts_plt_d, lc0_plt, 'b-')
                        ax2.axvspan(tim1[0].mjd - utbase,
                                    tim1[-1].mjd - utbase,
                                    color='red',
                                    alpha=0.5)
                        ax2.set_yscale('log')
                        ax2.set_title('GOES 1-8 A')

                    tstartstr_ = tim1[0].datetime.strftime(
                        '%Y-%m-%dT%H%M%S.%f')[:-3]
                    tendstr_ = tim1[1].datetime.strftime('%H%M%S.%f')[:-3]
                    timstr = tstartstr_ + '-' + tendstr_
                    figfile = 'dspec_t' + timstr + '.png'
                    if not os.path.isdir('dspec'):
                        os.makedirs('dspec')
                    f.savefig('dspec/' + figfile)
                    plt.cla()
            else:
                f = plt.figure(figsize=(8, 4), dpi=100)
                ax = f.add_subplot(111)
                freqghz = freq / 1e9
                ax.pcolormesh(tim_plt,
                              freqghz,
                              spec_plt,
                              cmap='jet',
                              vmin=dmin,
                              vmax=dmax)
                ax.set_xlim(tim_plt[tidx[0]], tim_plt[tidx[-1]])
                ax.set_ylim(freqghz[fidx[0]], freqghz[fidx[-1]])
                try:
                    from sunpy import lightcurve
                    from sunpy.time import TimeRange, parse_time
                    t1 = tim_[tidx[0]]
                    t2 = tim_[tidx[-1]]
                    tr = TimeRange(t1.iso, t2.iso)
                    goes = lightcurve.GOESLightCurve.create(tr)
                    goes.data['xrsb'] = 2 * (np.log10(goes.data['xrsb'])) + 26
                    xx = [str(ll) for ll in np.array(goes.data.index)]
                    yy = np.array(goes.data['xrsb'])
                    ax.plot(Time(xx).mjd * 24 * 3600, yy, c='yellow')
                    rightaxis_label_time = Time(xx[-1]).mjd * 24 * 3600
                    ax.text(rightaxis_label_time, 9.6, 'A', fontsize='15')
                    ax.text(rightaxis_label_time, 11.6, 'B', fontsize='15')
                    ax.text(rightaxis_label_time, 13.6, 'C', fontsize='15')
                    ax.text(rightaxis_label_time, 15.6, 'M', fontsize='15')
                    ax.text(rightaxis_label_time, 17.6, 'X', fontsize='15')
                except:
                    pass

                def format_coord(x, y):
                    col = np.argmin(np.absolute(tim_plt - x))
                    row = np.argmin(np.absolute(freqghz - y))
                    if col >= 0 and col < ntim and row >= 0 and row < nfreq:
                        timstr = tim_[col].isot
                        flux = spec_plt[row, col]
                        return 'time {0} = {1}, freq = {2:.3f} GHz, flux = {3:.2f} Jy'.format(
                            col, timstr, y, flux)
                    else:
                        return 'x = {0}, y = {1:.3f}'.format(x, y)

                ax.format_coord = format_coord
                ax.set_ylabel('Frequency (GHz)')
                if bl:
                    ax.set_title('Dynamic spectrum @ bl ' + bl.split(';')[b] +
                                 ', pol ' + pol)
                else:
                    ax.set_title('Medium dynamic spectrum')
                if timestr:
                    # date_format = mdates.DateFormatter('%H:%M:%S.%f')
                    # ax.xaxis_date()
                    # ax.xaxis.set_major_formatter(date_format)
                    locator = AutoDateLocator()
                    ax.xaxis.set_major_locator(locator)
                    ax.xaxis.set_major_formatter(AutoDateFormatter(locator))
                ax.set_autoscale_on(False)

        else:
            f = plt.figure(figsize=(8, 6), dpi=100)
            R_plot = np.absolute(spec[0, b, :, :])
            L_plot = np.absolute(spec[1, b, :, :])
            I_plot = (R_plot + L_plot) / 2.
            V_plot = (R_plot - L_plot) / 2.
            if pol == 'RRLL':
                spec_plt_1 = R_plot
                spec_plt_2 = L_plot
                polstr = ['RR', 'LL']
            if pol == 'IV':
                spec_plt_1 = I_plot
                spec_plt_2 = V_plot
                polstr = ['I', 'V']

            ax1 = f.add_subplot(211)
            freqghz = freq / 1e9
            ax1.pcolormesh(tim_plt,
                           freqghz,
                           spec_plt_1,
                           cmap='jet',
                           vmin=dmin,
                           vmax=dmax)
            ax1.set_xlim(tim_plt[tidx[0]], tim_plt[tidx[-1]])
            ax1.set_ylim(freqghz[fidx[0]], freqghz[fidx[-1]])

            def format_coord(x, y):
                col = np.argmin(np.absolute(tim_plt - x))
                row = np.argmin(np.absolute(freqghz - y))
                if col >= 0 and col < ntim and row >= 0 and row < nfreq:
                    timstr = tim_[col].isot
                    flux = spec_plt[row, col]
                    return 'time {0} = {1}, freq = {2:.3f} GHz, flux = {3:.2f} Jy'.format(
                        col, timstr, y, flux)
                else:
                    return 'x = {0}, y = {1:.3f}'.format(x, y)

            ax1.format_coord = format_coord
            ax1.set_ylabel('Frequency (GHz)')
            if timestr:
                # date_format = mdates.DateFormatter('%H:%M:%S.%f')
                # ax1.xaxis_date()
                # ax1.xaxis.set_major_formatter(date_format)
                locator = AutoDateLocator()
                ax1.xaxis.set_major_locator(locator)
                ax1.xaxis.set_major_formatter(AutoDateFormatter(locator))
            ax1.set_title('Dynamic spectrum @ bl ' + bl.split(';')[b] +
                          ', pol ' + polstr[0])
            ax1.set_autoscale_on(False)
            ax2 = f.add_subplot(212)
            ax2.pcolormesh(tim_plt,
                           freqghz,
                           spec_plt_2,
                           cmap='jet',
                           vmin=dmin,
                           vmax=dmax)
            ax2.set_xlim(tim_plt[tidx[0]], tim_plt[tidx[-1]])
            ax2.set_ylim(freqghz[fidx[0]], freqghz[fidx[-1]])
            if timestr:
                # date_format = mdates.DateFormatter('%H:%M:%S.%f')
                # ax2.xaxis_date()
                # ax2.xaxis.set_major_formatter(date_format)
                locator = AutoDateLocator()
                ax2.xaxis.set_major_locator(locator)
                ax2.xaxis.set_major_formatter(AutoDateFormatter(locator))

            def format_coord(x, y):
                col = np.argmin(np.absolute(tim_plt - x))
                row = np.argmin(np.absolute(freqghz - y))
                if col >= 0 and col < ntim and row >= 0 and row < nfreq:
                    timstr = tim_[col].isot
                    flux = spec_plt[row, col]
                    return 'time {0} = {1}, freq = {2:.3f} GHz, flux = {3:.2f} Jy'.format(
                        col, timstr, y, flux)
                else:
                    return 'x = {0}, y = {1:.3f}'.format(x, y)

            ax2.format_coord = format_coord
            ax2.set_ylabel('Frequency (GHz)')
            ax2.set_title('Dynamic spectrum @ bl ' + bl.split(';')[b] +
                          ', pol ' + polstr[1])
            ax2.set_autoscale_on(False)
Exemple #24
0
    def test_readAndParseIrregularTbuff(self):
        '''flaghelper: compare the read and parse and apply of irregular tbuff'''
        print ''

        # MJD in seconds of timeranges are these
        # <startTime>4891227930515540000 <endTime>4891227932453838000
        # <startTime>4891228473545856000 <endTime>4891228473731891000
        # <startTime>4891226924455911000 <endTime>4891226927502314000
        # <startTime>4891228838164987000 <endTime>4891228838418996000
        # <startTime>4891228609440808000 <endTime>4891228612489617000

        online = [
            "antenna='DV03&&*' timerange='2013/11/15/10:25:30.516~2013/11/15/10:25:32.454'",
            "antenna='DA44&&*' timerange='2013/11/15/10:34:33.546~2013/11/15/10:34:33.732'",
            "antenna='DA46&&*' timerange='2013/11/15/10:08:44.456~2013/11/15/10:08:47.502'",
            "antenna='DV09&&*' timerange='2013/11/15/10:18:11.798~2013/11/15/10:18:13.837'",
            "antenna='DV05&&*' timerange='2013/11/15/10:40:38.165~2013/11/15/10:40:38.419'"
        ]

        myinput = "antenna='DV03&&*' timerange='2013/11/15/10:25:30.516~2013/11/15/10:25:32.454'\n"\
                  "antenna='DA44&&*' timerange='2013/11/15/10:34:33.546~2013/11/15/10:34:33.732'\n"\
                  "antenna='DA46&&*' timerange='2013/11/15/10:08:44.456~2013/11/15/10:08:47.502'\n"\
                  "antenna='DV09&&*' timerange='2013/11/15/10:18:11.798~2013/11/15/10:18:13.837'\n"\
                  "antenna='DV05&&*' timerange='2013/11/15/10:40:38.165~2013/11/15/10:40:38.419'"

        filename1 = 'flaghelperonline2.txt'
        create_input(myinput, filename1)

        # timeranges from online before padding, for comparison later
        timeranges = []
        for cmd in online:
            a, b = cmd.split(' ')
            b = b.lstrip('timerange=')
            timeranges.append(b.strip("'"))

        # Apply 2 values of tbuff to timeranges
        timebuffer = [0.4, 0.7]
        dlist1 = fh.readAndParse([filename1], tbuff=timebuffer)
        self.assertEqual(len(dlist1), 5)

        # check the padded time ranges before and after the application
        n = 0
        for cmd in dlist1:
            padt = cmd['timerange']

            #        padt = dlist1[0]['timerange']

            # Revert the tbuff application manually
            t0, t1 = padt.split('~', 1)
            startTime = qa.totime(t0)['value']
            startTimeSec = float((startTime * 24 * 3600) + timebuffer[0])
            startTimeSec = qa.quantity(startTimeSec, 's')
            paddedT0 = qa.time(startTimeSec, form='ymd', prec=9)[0]
            # end time
            endTime = qa.totime(t1)['value']
            endTimeSec = float((endTime * 24 * 3600) - timebuffer[1])
            endTimeSec = qa.quantity(endTimeSec, 's')
            paddedT1 = qa.time(endTimeSec, form='ymd', prec=9)[0]

            newtimerange = paddedT0 + '~' + paddedT1

            # Compare with the original
            self.assertEqual(timeranges[n], newtimerange)
            n += 1
Exemple #25
0
    def test_readAndParseTbuff(self):
        '''flaghelper: compare the read and parse and apply tbuff'''
        print ''

        # MJD in seconds of timeranges are these
        # <startTime>4891227930515540000 <endTime>4891227932453838000
        # <startTime>4891228473545856000 <endTime>4891228473731891000
        # <startTime>4891226924455911000 <endTime>4891226927502314000
        # <startTime>4891228838164987000 <endTime>4891228838418996000
        # <startTime>4891228609440808000 <endTime>4891228612489617000

        online = [
            "antenna='DV03&&*' timerange='2013/11/15/10:25:30.516~2013/11/15/10:25:32.454'",
            "antenna='DA44&&*' timerange='2013/11/15/10:34:33.546~2013/11/15/10:34:33.732'",
            "antenna='DA46&&*' timerange='2013/11/15/10:08:44.456~2013/11/15/10:08:47.502'",
            "antenna='DV09&&*' timerange='2013/11/15/10:18:11.798~2013/11/15/10:18:13.837'",
            "antenna='DV05&&*' timerange='2013/11/15/10:40:38.165~2013/11/15/10:40:38.419'"
        ]

        myinput = "antenna='DV03&&*' timerange='2013/11/15/10:25:30.516~2013/11/15/10:25:32.454'\n"\
                  "antenna='DA44&&*' timerange='2013/11/15/10:34:33.546~2013/11/15/10:34:33.732'\n"\
                  "antenna='DA46&&*' timerange='2013/11/15/10:08:44.456~2013/11/15/10:08:47.502'\n"\
                  "antenna='DV09&&*' timerange='2013/11/15/10:18:11.798~2013/11/15/10:18:13.837'\n"\
                  "antenna='DV05&&*' timerange='2013/11/15/10:40:38.165~2013/11/15/10:40:38.419'"

        filename1 = 'flaghelperonline2.txt'
        create_input(myinput, filename1)

        # First timerange from online before padding
        origt = timerange = '2013/11/15/10:25:30.516~2013/11/15/10:25:32.454'

        # Apply tbuff to timeranges
        timebuffer = 1.1
        dlist1 = fh.readAndParse([filename1], tbuff=timebuffer)
        self.assertEqual(len(dlist1), 5)

        # Get the first padded timerange from output
        padt = dlist1[0]['timerange']

        # Revert the tbuff application manually
        t0, t1 = padt.split('~', 1)
        startTime = qa.totime(t0)['value']
        startTimeSec = float((startTime * 24 * 3600) + timebuffer)
        startTimeSec = qa.quantity(startTimeSec, 's')
        paddedT0 = qa.time(startTimeSec, form='ymd', prec=9)[0]
        # end time
        endTime = qa.totime(t1)['value']
        endTimeSec = float((endTime * 24 * 3600) - timebuffer)
        endTimeSec = qa.quantity(endTimeSec, 's')
        paddedT1 = qa.time(endTimeSec, form='ymd', prec=9)[0]

        newtimerange = paddedT0 + '~' + paddedT1

        # Compare with the original
        self.assertEqual(origt, newtimerange)

        # Compare with original values from Flag.xml
        xmlt0 = float(4891227930515540000) * 1.0E-9
        xmlt1 = float(4891227932453838000) * 1.0E-9

        self.assertAlmostEqual(xmlt0, startTimeSec['value'], places=3)
        self.assertAlmostEqual(xmlt1, endTimeSec['value'], places=3)
Exemple #26
0
def mk_diskmodel(outname='disk', bdwidth='325MHz', direction='J2000 10h00m00.0s 20d00m00.0s',
                 reffreq='2.8GHz', flux=660000.0, eqradius='16.166arcmin', polradius='16.166arcmin',
                 pangle='21.1deg', index=None, cell='2.0arcsec', overwrite=True):
    ''' Create a blank solar disk model image (or optionally a data cube)
        outname       String to use for part of the image and fits file names (default 'disk')
        direction     String specifying the position of the Sun in RA and Dec.  Default
                        means use the standard string "J2000 10h00m00.0s 20d00m00.0s"
        reffreq       The reference frequency to use for the disk model (the frequency at which
                        the flux level applies). Default is '2.8GHz'.
        flux          The flux density, in Jy, for the entire disk. Default is 66 sfu.
        eqradius      The equatorial radius of the disk.  Default is
                        16 arcmin + 10" (for typical extension of the radio limb)
        polradius     The polar radius of the disk.  Default is
                        16 arcmin + 10" (for typical extension of the radio limb)
        pangle        The solar P-angle (geographic position of the N-pole of the Sun) in
                        degrees E of N.  This only matters if eqradius != polradius
        index         The spectral index to use at other frequencies.  Default None means
                        use a constant flux density for all frequencies.
        cell          The cell size (assumed square) to use for the image.  The image size
                        is determined from a standard radius of 960" for the Sun, divided by
                        cell size, increased to nearest power of 512 pixels. The default is '2.0arcsec',
                        which results in an image size of 1024 x 1024.
        Note that the frequency increment used is '325MHz', which is the width of EOVSA bands
          (not the width of individual science channels)
    '''

    diskim = outname + reffreq + '.im'
    if os.path.exists(diskim):
        if overwrite:
            os.system('rm -rf {}'.format(diskim))
        else:
            return diskim

    ia = iatool()
    cl = cltool()
    cl.done()
    ia.done()

    try:
        aspect = 1.01  # Enlarge the equatorial disk by 1%
        eqradius = qa.quantity(eqradius)
        diamajor = qa.quantity(2 * aspect * eqradius['value'], eqradius['unit'])
        polradius = qa.quantity(polradius)
        diaminor = qa.quantity(2 * polradius['value'], polradius['unit'])
        solrad = qa.convert(polradius, 'arcsec')
    except:
        print('Radius', eqradius, polradius,
              'does not have the expected format, number + unit where unit is arcmin or arcsec')
        return
    try:
        cell = qa.convert(qa.quantity(cell), 'arcsec')
        cellsize = float(cell['value'])
        diskpix = solrad['value'] * 2 / cellsize
        cell_rad = qa.convert(cell, 'rad')
    except:
        print('Cell size', cell, 'does not have the expected format, number + unit where unit is arcmin or arcsec')
        return

    # Add 90 degrees to pangle, due to angle definition in addcomponent() -- it puts the majoraxis vertical
    pangle = qa.add(qa.quantity(pangle), qa.quantity('90deg'))
    mapsize = ((int(diskpix) / 512) + 1) * 512
    # Flux density is doubled because it is split between XX and YY
    cl.addcomponent(dir=direction, flux=flux * 2, fluxunit='Jy', freq=reffreq, shape='disk',
                    majoraxis=diamajor, minoraxis=diaminor, positionangle=pangle)
    cl.setrefdirframe(0, 'J2000')

    ia.fromshape(diskim, [mapsize, mapsize, 1, 1], overwrite=True)
    cs = ia.coordsys()
    cs.setunits(['rad', 'rad', '', 'Hz'])
    cell_rad_val = cell_rad['value']
    cs.setincrement([-cell_rad_val, cell_rad_val], 'direction')
    epoch, ra, dec = direction.split()
    cs.setreferencevalue([qa.convert(ra, 'rad')['value'], qa.convert(dec, 'rad')['value']], type="direction")
    cs.setreferencevalue(reffreq, 'spectral')
    cs.setincrement(bdwidth, 'spectral')
    ia.setcoordsys(cs.torecord())
    ia.setbrightnessunit("Jy/pixel")
    ia.modify(cl.torecord(), subtract=False)
    ia.close()
    ia.done()
    # cl.close()
    cl.done()
    return diskim
Exemple #27
0
def split_core(vis, outputvis, datacolumn, field, spw, width, antenna,
               timebin, timerange, scan, intent, array, uvrange,
               correlation, observation, combine, keepflags):

    retval = True

    if not outputvis or outputvis.isspace():
        raise ValueError, 'Please specify outputvis'

    myms = mstool()
    mytb = None
    if ((type(vis)==str) & (os.path.exists(vis))):
        myms.open(vis, nomodify=True)
    else:
        raise ValueError, 'Visibility data set not found - please verify the name'

    if os.path.exists(outputvis):
        myms.close()
        raise ValueError, "Output MS %s already exists - will not overwrite." % outputvis

    if (os.path.exists(outputvis+".flagversions")):
        myms.close()
        raise ValueError, "The flagversions \"%s.flagversions\" for the output MS already exist. Please delete." % outputvis

    # No longer needed.  When did it get put in?  Note that the default
    # spw='*' in myms.split ends up as '' since the default type for a variant
    # is BOOLVEC.  (Of course!)  Therefore both split and myms.split must
    # work properly when spw=''.
    #if(spw == ''):
    #    spw = '*'
    
    if(type(antenna) == list):
        antenna = ', '.join([str(ant) for ant in antenna])

    ## Accept digits without units ...assume seconds
    timebin = qa.convert(qa.quantity(timebin), 's')['value']
    timebin = str(timebin) + 's'
    
    if timebin == '0s':
        timebin = '-1s'

    # MSStateGram is picky ('CALIBRATE_WVR.REFERENCE, OBSERVE_TARGET_ON_SOURCE'
    # doesn't work, but 'CALIBRATE_WVR.REFERENCE,OBSERVE_TARGET_ON_SOURCE'
    # does), and I don't want to mess with bison now.  A .upper() might be a
    # good idea too, but the MS def'n v.2 does not say whether OBS_MODE should
    # be case-insensitive.
    intent = intent.replace(', ', ',')

    if '^' in spw:
        casalog.post("The interpretation of ^n in split's spw strings has changed from 'average n' to 'skip n' channels!", 'WARN')
        casalog.post("Watch for Slicer errors", 'WARN')
        
    if type(width) == str:
        try:
            if(width.isdigit()):
                width=[string.atoi(width)]
            elif(width.count('[') == 1 and width.count(']') == 1):
                width = width.replace('[', '')
                width = width.replace(']', '')
                splitwidth = width.split(',')
                width = []
                for ws in splitwidth:
                    if(ws.isdigit()):
                        width.append(string.atoi(ws)) 
            else:
                width = [1]
        except:
            raise TypeError, 'parameter width is invalid...using 1'

    if type(correlation) == list:
        correlation = ', '.join(correlation)
    correlation = correlation.upper()

    if hasattr(combine, '__iter__'):
        combine = ', '.join(combine)

    if type(spw) == list:
        spw = ','.join([str(s) for s in spw])
    elif type(spw) == int:
        spw = str(spw)
    do_chan_mod = spw.find('^') > -1     # '0:2~11^1' would be pointless.
    if not do_chan_mod:                  # ...look in width.
        if type(width) == int and width > 1:
            do_chan_mod = True
        elif hasattr(width, '__iter__'):
            for w in width:
                if w > 1:
                    do_chan_mod = True
                    break

    do_both_chan_and_time_mod = (do_chan_mod and
                                 string.atof(timebin[:-1]) > 0.0)
    if do_both_chan_and_time_mod:
        # Do channel averaging first because it might be included in the spw
        # string.
        import tempfile
        # We want the directory outputvis is in, not /tmp, because /tmp
        # might not have enough space.
        # outputvis is itself a directory, so strip off a trailing slash if
        # it is present.
        # I don't know if giving tempfile an absolute directory is necessary -
        # dir='' is effectively '.' in Ubuntu.
        workingdir = os.path.abspath(os.path.dirname(outputvis.rstrip('/')))
        cavms = tempfile.mkdtemp(suffix=outputvis, dir=workingdir)

        casalog.post('Channel averaging to ' + cavms)
        if not myms.split(outputms=cavms,     field=field,
                          spw=spw,            step=width,
                          baseline=antenna,   subarray=array,
                          timebin='',         time=timerange,
                          whichcol=datacolumn,
                          scan=scan,          uvrange=uvrange,
                          combine=combine,
                          correlation=correlation, intent=intent,
                          obs=str(observation)):
            myms.close()
            if os.path.isdir(cavms):
                import shutil
                shutil.rmtree(cavms)
            return False
        
        # The selection was already made, so blank them before time averaging.
        field = ''
        spw = ''
        width = [1]
        antenna = ''
        array = ''
        timerange = ''
        datacolumn = 'all'
        scan = ''
        intent = ''
        uvrange = ''
        observation = ''

        myms.close()
        myms.open(cavms)
        casalog.post('Starting time averaging')

    if keepflags:
        taqlstr = ''
    else:
        taqlstr = 'NOT (FLAG_ROW OR ALL(FLAG))'

    if not myms.split(outputms=outputvis,  field=field,
                      spw=spw,             step=width,
                      baseline=antenna,    subarray=array,
                      timebin=timebin,     time=timerange,
                      whichcol=datacolumn,
                      scan=scan,           uvrange=uvrange,
                      combine=combine,
                      correlation=correlation,
                      taql=taqlstr, intent=intent,
                      obs=str(observation)):
        myms.close()
        return False
    myms.close()

    if do_both_chan_and_time_mod:
        import shutil
        shutil.rmtree(cavms)

    # Write history to output MS, not the input ms.
    try:
        param_names = split_core.func_code.co_varnames[:split_core.func_code.co_argcount]
        param_vals = [eval(p) for p in param_names]   
        retval &= write_history(myms, outputvis, 'oldsplit', param_names, param_vals,
                                casalog)
    except Exception, instance:
        casalog.post("*** Error \'%s\' updating HISTORY" % (instance),
                     'WARN')
Exemple #28
0
def clean_iter(
        tim, vis, imageprefix, imagesuffix, twidth, doreg, usephacenter,
        reftime, ephem, msinfo, toTb, overwrite, selectdata, field, spw,
        uvrange, antenna, scan, observation, intent, datacolumn, imsize, cell,
        phasecenter, stokes, projection, startmodel, specmode, reffreq, nchan,
        start, width, outframe, veltype, restfreq, interpolation, gridder,
        facets, chanchunks, wprojplanes, vptable, usepointing, mosweight,
        aterm, psterm, wbawp, conjbeams, cfcache, computepastep, rotatepastep,
        pblimit, normtype, deconvolver, scales, nterms, smallscalebias,
        restoration, restoringbeam, pbcor, outlierfile, weighting, robust,
        npixels, uvtaper, niter, gain, threshold, nsigma, cycleniter,
        cyclefactor, minpsffraction, maxpsffraction, interactive, usemask,
        mask, pbmask, sidelobethreshold, noisethreshold, lownoisethreshold,
        negativethreshold, smoothfactor, minbeamfrac, cutthreshold,
        growiterations, dogrowprune, minpercentchange, verbose, restart,
        savemodel, calcres, calcpsf, parallel, subregion, tmpdir, btidx):
    from tclean_cli import tclean_cli as tclean
    from split_cli import split_cli as split
    bt = btidx  # 0
    if bt + twidth < len(tim) - 1:
        et = btidx + twidth - 1
    else:
        et = len(tim) - 1

    if bt == 0:
        bt_d = tim[bt] - ((tim[bt + 1] - tim[bt]) / 2)
    else:
        bt_d = tim[bt] - ((tim[bt] - tim[bt - 1]) / 2)
    if et == (len(tim) - 1) or et == -1:
        et_d = tim[et] + ((tim[et] - tim[et - 1]) / 2)
    else:
        et_d = tim[et] + ((tim[et + 1] - tim[et]) / 2)

    timerange = qa.time(qa.quantity(bt_d, 's'), prec=9, form='ymd')[0] + '~' + \
                qa.time(qa.quantity(et_d, 's'), prec=9, form='ymd')[0]
    btstr = qa.time(qa.quantity(bt_d, 's'), prec=9, form='fits')[0]
    etstr = qa.time(qa.quantity(et_d, 's'), prec=9, form='fits')[0]
    print('cleaning timerange: ' + timerange)

    image0 = btstr.replace(':', '').replace('-', '')
    imname = imageprefix + image0 + imagesuffix

    # ms_tmp = tmpdir + image0 + '.ms'
    # print('checkpoint 1')
    # # split(vis=vis, outputvis=ms_tmp, field=field, scan=scan, antenna=antenna, timerange=timerange,
    # #       datacolumn=datacolumn)
    # ms.open(vis)
    # print('checkpoint 1-1')
    # ms.split(ms_tmp,field=field, scan=scan, baseline=antenna, time=timerange,whichcol=datacolumn)
    # print('checkpoint 1-2')
    # ms.close()
    # print('checkpoint 2')

    if overwrite or (len(glob.glob(imname + '*')) == 0):
        os.system('rm -rf {}*'.format(imname))
        try:
            tclean(vis=vis,
                   selectdata=selectdata,
                   field=field,
                   spw=spw,
                   timerange=timerange,
                   uvrange=uvrange,
                   antenna=antenna,
                   scan=scan,
                   observation=observation,
                   intent=intent,
                   datacolumn=datacolumn,
                   imagename=imname,
                   imsize=imsize,
                   cell=cell,
                   phasecenter=phasecenter,
                   stokes=stokes,
                   projection=projection,
                   startmodel=startmodel,
                   specmode=specmode,
                   reffreq=reffreq,
                   nchan=nchan,
                   start=start,
                   width=width,
                   outframe=outframe,
                   veltype=veltype,
                   restfreq=restfreq,
                   interpolation=interpolation,
                   gridder=gridder,
                   facets=facets,
                   chanchunks=chanchunks,
                   wprojplanes=wprojplanes,
                   vptable=vptable,
                   usepointing=usepointing,
                   mosweight=mosweight,
                   aterm=aterm,
                   psterm=psterm,
                   wbawp=wbawp,
                   conjbeams=conjbeams,
                   cfcache=cfcache,
                   computepastep=computepastep,
                   rotatepastep=rotatepastep,
                   pblimit=pblimit,
                   normtype=normtype,
                   deconvolver=deconvolver,
                   scales=scales,
                   nterms=nterms,
                   smallscalebias=smallscalebias,
                   restoration=restoration,
                   restoringbeam=restoringbeam,
                   pbcor=pbcor,
                   outlierfile=outlierfile,
                   weighting=weighting,
                   robust=robust,
                   npixels=npixels,
                   uvtaper=uvtaper,
                   niter=niter,
                   gain=gain,
                   threshold=threshold,
                   nsigma=nsigma,
                   cycleniter=cycleniter,
                   cyclefactor=cyclefactor,
                   minpsffraction=minpsffraction,
                   maxpsffraction=maxpsffraction,
                   interactive=interactive,
                   usemask=usemask,
                   mask=mask,
                   pbmask=pbmask,
                   sidelobethreshold=sidelobethreshold,
                   noisethreshold=noisethreshold,
                   lownoisethreshold=lownoisethreshold,
                   negativethreshold=negativethreshold,
                   smoothfactor=smoothfactor,
                   minbeamfrac=minbeamfrac,
                   cutthreshold=cutthreshold,
                   growiterations=growiterations,
                   dogrowprune=dogrowprune,
                   minpercentchange=minpercentchange,
                   verbose=verbose,
                   restart=restart,
                   savemodel=savemodel,
                   calcres=calcres,
                   calcpsf=calcpsf,
                   parallel=parallel)
            # print('checkpoint 3')
            if pbcor:
                clnjunks = [
                    '.flux', '.mask', '.model', '.psf', '.residual', '.pb',
                    '.sumwt', '.image'
                ]
            else:
                clnjunks = [
                    '.flux', '.mask', '.model', '.psf', '.residual', '.pb',
                    '.sumwt', '.image.pbcor'
                ]
            for clnjunk in clnjunks:
                if os.path.exists(imname + clnjunk):
                    shutil.rmtree(imname + clnjunk)
            if pbcor:
                os.system('mv {} {}'.format(imname + '.image.pbcor',
                                            imname + '.image'))
        except:
            print('error in cleaning image: ' + btstr)
            return [False, btstr, etstr, '']
    else:
        print(imname + ' exists. Clean task aborted.')

    if doreg and not os.path.isfile(imname + '.fits'):
        # ephem.keys()
        # msinfo.keys()
        try:
            # check if ephemfile and msinfofile exist
            if not ephem:
                print(
                    "ephemeris info does not exist, querying from JPL Horizons on the fly"
                )
                ephem = hf.read_horizons(vis=vis)
            if not msinfo:
                print("ms info not provided, generating one on the fly")
                msinfo = hf.read_msinfo(vis)
            hf.imreg(vis=vis,
                     ephem=ephem,
                     msinfo=msinfo,
                     timerange=timerange,
                     reftime=reftime,
                     imagefile=imname + '.image',
                     fitsfile=imname + '.fits',
                     toTb=toTb,
                     scl100=False,
                     usephacenter=usephacenter,
                     subregion=subregion)
            if os.path.exists(imname + '.fits'):
                shutil.rmtree(imname + '.image')
                return [True, btstr, etstr, imname + '.fits']
            else:
                return [False, btstr, etstr, '']
        except:
            print('error in registering image: ' + btstr)
            return [False, btstr, etstr, imname + '.image']
    else:
        if os.path.exists(imname + '.image'):
            return [True, btstr, etstr, imname + '.image']
        else:
            return [False, btstr, etstr, '']
Exemple #29
0
def predictcomp(objname=None,
                standard=None,
                epoch=None,
                minfreq=None,
                maxfreq=None,
                nfreqs=None,
                prefix=None,
                antennalist=None,
                showplot=None,
                savefig=None,
                symb=None,
                include0amp=None,
                include0bl=None,
                blunit=None,
                bl0flux=None):
    """
    Writes a component list named clist to disk and returns a dict of
    {'clist': clist,
     'objname': objname,
     'angdiam': angular diameter in radians (if used in clist),
     'standard': standard,
     'epoch': epoch,
     'freqs': pl.array of frequencies, in GHz,
     'uvrange': pl.array of baseline lengths, in m,
     'amps':  pl.array of predicted visibility amplitudes, in Jy,
     'savedfig': False or, if made, the filename of a plot.}
    or False on error.

    objname: An object supported by standard.
    standard: A standard for calculating flux densities, as in setjy.
              Default: 'Butler-JPL-Horizons 2010'
    epoch: The epoch to use for the calculations.   Irrelevant for
           extrasolar standards.
    minfreq: The minimum frequency to use.
             Example: '342.0GHz'
    maxfreq: The maximum frequency to use.
             Default: minfreq
             Example: '346.0GHz'
             Example: '', anything <= 0, or None: use minfreq.
    nfreqs:  The number of frequencies to use.
             Default: 1 if minfreq == maxfreq,
                      2 otherwise.
    prefix: The component list will be saved to
              prefix + '<objname>_spw0_<minfreq><epoch>.cl'
            Default: ''
    antennalist: An array configuration file as used by simdata.
                 If given, a plot of S vs. |u| will be made.
                 Default: '' (None, just make clist.)
    showplot: Whether or not to show the plot on screen.
              Subparameter of antennalist.
              Default: Necessarily False if antennalist is not specified.
                       True otherwise.
    savefig: Filename for saving a plot of S vs. |u|.
             Subparameter of antennalist.
             Default: False (necessarily if antennalist is not specified)
             Examples: True (save to prefix + '.png')
                       'myplot.png' (save to myplot.png) 
    symb: One of matplotlib's codes for plot symbols: .:,o^v<>s+xDd234hH|_
          default: '.'
    include0amp: Force the lower limit of the amplitude axis to 0.
                 Default: False
    include0bl: Force the lower limit of the baseline length axis to 0.
    blunit: Unit of the baseline length 
    bl0flux: show zero baseline flux
    """
    retval = False
    try:
        casalog.origin('predictcomp')
        # some parameter minimally required
        if objname == '':
            raise Exception, "Error, objname is undefined"
        if minfreq == '':
            raise Exception, "Error, minfreq is undefined"
        minfreqq = qa.quantity(minfreq)
        minfreqHz = qa.convert(minfreqq, 'Hz')['value']
        try:
            maxfreqq = qa.quantity(maxfreq)
        except Exception, instance:
            maxfreqq = minfreqq
        frequnit = maxfreqq['unit']
        maxfreqHz = qa.convert(maxfreqq, 'Hz')['value']
        if maxfreqHz <= 0.0:
            maxfreqq = minfreqq
            maxfreqHz = minfreqHz
        if minfreqHz != maxfreqHz:
            if nfreqs < 2:
                nfreqs = 2
        else:
            nfreqs = 1
        freqs = pl.linspace(minfreqHz, maxfreqHz, nfreqs)

        myme = metool()
        mepoch = myme.epoch('UTC', epoch)
        #if not prefix:
        ## meanfreq = {'value': 0.5 * (minfreqHz + maxfreqHz),
        ##             'unit': frequnit}
        ## prefix = "%s%s_%.7g" % (objname, epoch.replace('/', '-'),
        ##                         minfreqq['value'])
        ## if minfreqHz != maxfreqHz:
        ##     prefix += "to" + maxfreq
        ## else:
        ##     prefix += minfreqq['unit']
        ## prefix += "_"
        #    prefix = ''

        #
        if not prefix:
            if not os.access("./", os.W_OK):
                casalog.post(
                    "No write access in the current directory, trying to write cl to /tmp...",
                    "WARN")
                prefix = "/tmp/"
                if not os.access(prefix, os.W_OK):
                    casalog.post("No write access to /tmp to write cl file",
                                 "SEVERE")
                    return False
        else:
            prefixdir = os.path.dirname(prefix)
            if prefixdir == '/' and len(prefix) > 1:
                prefix = prefix + '/'
                prefixdir = os.path.dirname(prefix)
            if not os.path.exists(prefixdir):
                prefixdirs = prefixdir.split('/')
                if prefixdirs[0] == "" and len(prefixdirs) > 1:
                    rootdir = "/" + prefixdirs[1]
                else:
                    rootdir = "./"
                if os.access(rootdir, os.W_OK):
                    if prefixdir != '':
                        os.makedirs(prefixdir)
                else:
                    casalog.post(
                        "No write access to " + rootdir + " to write cl file",
                        "SEVERE")
                    return False

        # Get clist
        myim = imtool()
        if hasattr(myim, 'predictcomp'):
            casalog.post('local im instance created', 'DEBUG1')
        else:
            casalog.post('Error creating a local im instance.', 'SEVERE')
            return False
        #print "FREQS=",freqs
        # output CL file name is fixed : prefix+"spw0_"+minfreq+mepoch.cl
        minfreqGHz = qa.convert(qa.quantity(minfreq), 'GHz')['value']
        decimalfreq = minfreqGHz - int(minfreqGHz)
        decimalepoch = mepoch['m0']['value'] - int(mepoch['m0']['value'])
        if decimalfreq == 0.0:
            minfreqGHzStr = str(int(minfreqGHz)) + 'GHz'
        else:
            minfreqGHzStr = str(minfreqGHz) + 'GHz'

        if decimalepoch == 0.0:
            epochStr = str(int(mepoch['m0']['value'])) + 'd'
        else:
            epochStr = str(mepoch['m0']['value']) + 'd'
        outfilename = "spw0_" + objname + "_" + minfreqGHzStr + epochStr + '.cl'
        outfilename = prefix + outfilename
        if (os.path.exists(outfilename) and os.path.isdir(outfilename)):

            shutil.rmtree(outfilename)
            casalog.post("Removing the existing componentlist, " + outfilename)

        if standard == 'Butler-JPL-Horizons 2012':
            clist = predictSolarObjectCompList(objname, mepoch, freqs.tolist(),
                                               prefix)
        else:
            clist = myim.predictcomp(objname, standard, mepoch, freqs.tolist(),
                                     prefix)
        #print "created componentlist =",clist
        if os.path.isdir(clist):
            # The spw0 is useless here, but it is added by FluxStandard for the sake of setjy.
            casalog.post('The component list was saved to ' + clist)

            retval = {
                'clist': clist,
                'objname': objname,
                'standard': standard,
                'epoch': mepoch,
                'freqs (GHz)': 1.0e-9 * freqs,
                'antennalist': antennalist
            }
            mycl = cltool()
            mycl.open(clist)
            comp = mycl.getcomponent(0)
            zeroblf = comp['flux']['value']
            if standard == 'Butler-JPL-Horizons 2012':
                f0 = comp['spectrum']['frequency']['m0']['value']
            else:
                f0 = retval['freqs (GHz)'][0]
            casalog.post("Zero baseline flux %s @ %sGHz " % (zeroblf, f0),
                         'INFO')
            mycl.close(False)  # False prevents the stupid warning.
            for k in ('shape', 'spectrum'):
                retval[k] = comp[k]
            if antennalist:
                retval['spectrum']['bl0flux'] = {}
                retval['spectrum']['bl0flux']['value'] = zeroblf[0]
                retval['spectrum']['bl0flux']['unit'] = 'Jy'
                retval['savedfig'] = savefig
                if not bl0flux:
                    zeroblf = [0.0]
                retval.update(
                    plotcomp(retval,
                             showplot,
                             wantdict=True,
                             symb=symb,
                             include0amp=include0amp,
                             include0bl=include0bl,
                             blunit=blunit,
                             bl0flux=zeroblf[0]))
            else:
                retval['savedfig'] = None
        else:
            casalog.post("There was an error in making the component list.",
                         'SEVERE')
Exemple #30
0
def ptclean(vis, imageprefix, ncpu, twidth, doreg, overwrite, ephemfile,
            msinfofile, outlierfile, field, spw, selectdata, timerange,
            uvrange, antenna, scan, observation, intent, mode, resmooth,
            gridmode, wprojplanes, facets, cfcache, rotpainc, painc, aterm,
            psterm, mterm, wbawp, conjbeams, epjtable, interpolation, niter,
            gain, threshold, psfmode, imagermode, ftmachine, mosweight,
            scaletype, multiscale, negcomponent, smallscalebias, interactive,
            mask, nchan, start, width, outframe, veltype, imsize, cell,
            phasecenter, restfreq, stokes, weighting, robust, uvtaper,
            outertaper, innertaper, modelimage, restoringbeam, pbcor, minpb,
            usescratch, noise, npixels, npercycle, cyclefactor, cyclespeedup,
            nterms, reffreq, chaniter, flatnoise, allowchunk):
    if not (type(ncpu) is int):
        casalog.post('ncpu should be an integer')
        ncpu = 8

    if doreg:
        # check if ephemfile and msinfofile exist
        try:
            ephem = vla_prep.read_horizons(ephemfile=ephemfile)
        except ValueError:
            print("error in reading ephemeris file")
        if not os.path.isfile(msinfofile):
            print("msinfofile does not exist!")
    else:
        ephem = None

    # get number of time pixels
    ms.open(vis)
    ms.selectinit()
    timfreq = ms.getdata(['time', 'axis_info'], ifraxis=True)
    tim = timfreq['time']
    # dt = tim[1]-tim[0] #need to change to median of all time intervals
    dt = np.median(np.diff(tim))
    freq = timfreq['axis_info']['freq_axis']['chan_freq'].flatten()
    ms.close()

    if twidth < 1 or twidth > len(tim):
        casalog.post(
            'twidth not between 1 and # of time pixels in the dataset. Change to 1'
        )
        twidth = 1

    # find out the start and end time index according to the parameter timerange
    # if not defined (empty string), use start and end from the entire time of the ms
    if not timerange:
        btidx = 0
        etidx = len(tim) - 1
    else:
        try:
            (tstart, tend) = timerange.split('~')
            bt_s = qa.convert(qa.quantity(tstart, 's'), 's')['value']
            et_s = qa.convert(qa.quantity(tend, 's'), 's')['value']
            # only time is given but not date, add the date (at 0 UT) from the first record
            if bt_s < 86400. or et_s < 86400.:
                bt_s += np.fix(
                    qa.convert(qa.quantity(tim[0], 's'),
                               'd')['value']) * 86400.
                et_s += np.fix(
                    qa.convert(qa.quantity(tim[0], 's'),
                               'd')['value']) * 86400.
            btidx = np.argmin(np.abs(tim - bt_s))
            etidx = np.argmin(np.abs(tim - et_s))
            # make the indice back to those bracket by the timerange
            if tim[btidx] < bt_s:
                btidx += 1
            if tim[etidx] > et_s:
                etidx -= 1
            if etidx <= btidx:
                print "ending time must be greater than starting time"
                print "reinitiating to the entire time range"
                btidx = 0
                etidx = len(tim) - 1
        except ValueError:
            print "keyword 'timerange' has a wrong format"

    btstr = qa.time(qa.quantity(tim[btidx], 's'), prec=9, form='fits')[0]
    etstr = qa.time(qa.quantity(tim[etidx], 's'), prec=9, form='fits')[0]

    iterable = range(btidx, etidx + 1, twidth)
    print 'First time pixel: ' + btstr
    print 'Last time pixel: ' + etstr
    print str(len(iterable)) + ' images to clean...'

    res = []
    # partition
    clnpart = partial(
        clean_iter, tim, freq, vis, imageprefix, ncpu, twidth, doreg,
        overwrite, ephemfile, ephem, msinfofile, outlierfile, field, spw,
        selectdata, uvrange, antenna, scan, observation, intent, mode,
        resmooth, gridmode, wprojplanes, facets, cfcache, rotpainc, painc,
        aterm, psterm, mterm, wbawp, conjbeams, epjtable, interpolation, niter,
        gain, threshold, psfmode, imagermode, ftmachine, mosweight, scaletype,
        multiscale, negcomponent, smallscalebias, interactive, mask, nchan,
        start, width, outframe, veltype, imsize, cell, phasecenter, restfreq,
        stokes, weighting, robust, uvtaper, outertaper, innertaper, modelimage,
        restoringbeam, pbcor, minpb, usescratch, noise, npixels, npercycle,
        cyclefactor, cyclespeedup, nterms, reffreq, chaniter, flatnoise,
        allowchunk)
    timelapse = 0
    t0 = time()
    # parallelization
    para = 1
    if para:
        casalog.post('Perform clean in parallel ...')
        pool = mp.Pool(ncpu)
        # res = pool.map_async(clnpart, iterable)
        res = pool.map(clnpart, iterable)
        pool.close()
        pool.join()
    else:
        for i in iterable:
            res.append(clnpart(i))

    t1 = time()
    timelapse = t1 - t0
    print 'It took %f secs to complete' % timelapse
    # repackage this into a single dictionary
    results = {'succeeded': [], 'timestamps': [], 'imagenames': []}
    for r in res:
        results['succeeded'].append(r[0])
        results['timestamps'].append(r[1])
        results['imagenames'].append(r[2])

    return results
Exemple #31
0
def clean_iter(tim, freq, vis, imageprefix, ncpu, twidth, doreg, overwrite,
               ephemfile, ephem, msinfofile, outlierfile, field, spw,
               selectdata, uvrange, antenna, scan, observation, intent, mode,
               resmooth, gridmode, wprojplanes, facets, cfcache, rotpainc,
               painc, aterm, psterm, mterm, wbawp, conjbeams, epjtable,
               interpolation, niter, gain, threshold, psfmode, imagermode,
               ftmachine, mosweight, scaletype, multiscale, negcomponent,
               smallscalebias, interactive, mask, nchan, start, width,
               outframe, veltype, imsize, cell, phasecenter, restfreq, stokes,
               weighting, robust, uvtaper, outertaper, innertaper, modelimage,
               restoringbeam, pbcor, minpb, usescratch, noise, npixels,
               npercycle, cyclefactor, cyclespeedup, nterms, reffreq, chaniter,
               flatnoise, allowchunk, btidx):
    from taskinit import ms
    from taskinit import qa
    # from  __casac__.quanta import quanta as qa
    from __main__ import default, inp
    from clean import clean
    bt = btidx  # 0
    if bt + twidth < len(tim) - 1:
        et = btidx + twidth - 1
    else:
        et = len(tim) - 1

    # tim_d = tim/3600./24.-np.fix(tim/3600./24.)

    if bt == 0:
        bt_d = tim[bt] - ((tim[bt + 1] - tim[bt]) / 2)
    else:
        bt_d = tim[bt] - ((tim[bt] - tim[bt - 1]) / 2)
    if et == (len(tim) - 1) or et == -1:
        et_d = tim[et] + ((tim[et] - tim[et - 1]) / 2)
    else:
        et_d = tim[et] + ((tim[et + 1] - tim[et]) / 2)

    #
    # bt_d=tim[bt]
    # et_d=tim[et]+0.005

    timerange = qa.time(qa.quantity(bt_d, 's'), prec=9)[0] + '~' + \
                qa.time(qa.quantity(et_d, 's'), prec=9)[0]
    tmid = (bt_d + et_d) / 2.
    btstr = qa.time(qa.quantity(bt_d, 's'), prec=9, form='fits')[0]
    print 'cleaning timerange: ' + timerange

    try:
        image0 = btstr.replace(':', '').replace('-', '')
        imname = imageprefix + image0
        if overwrite or (len(glob.glob(imname + '*')) == 0):
            # inp(taskname = 'clean')
            os.system('rm -rf {}*'.format(imname))
            clean(vis=vis,
                  imagename=imname,
                  outlierfile=outlierfile,
                  field=field,
                  spw=spw,
                  selectdata=selectdata,
                  timerange=timerange,
                  uvrange=uvrange,
                  antenna=antenna,
                  scan=scan,
                  observation=str(observation),
                  intent=intent,
                  mode=mode,
                  resmooth=resmooth,
                  gridmode=gridmode,
                  wprojplanes=wprojplanes,
                  facets=facets,
                  cfcache=cfcache,
                  rotpainc=rotpainc,
                  painc=painc,
                  psterm=psterm,
                  aterm=aterm,
                  mterm=mterm,
                  wbawp=wbawp,
                  conjbeams=conjbeams,
                  epjtable=epjtable,
                  interpolation=interpolation,
                  niter=niter,
                  gain=gain,
                  threshold=threshold,
                  psfmode=psfmode,
                  imagermode=imagermode,
                  ftmachine=ftmachine,
                  mosweight=mosweight,
                  scaletype=scaletype,
                  multiscale=multiscale,
                  negcomponent=negcomponent,
                  smallscalebias=smallscalebias,
                  interactive=interactive,
                  mask=mask,
                  nchan=nchan,
                  start=start,
                  width=width,
                  outframe=outframe,
                  veltype=veltype,
                  imsize=imsize,
                  cell=cell,
                  phasecenter=phasecenter,
                  restfreq=restfreq,
                  stokes=stokes,
                  weighting=weighting,
                  robust=robust,
                  uvtaper=uvtaper,
                  outertaper=outertaper,
                  innertaper=innertaper,
                  modelimage=modelimage,
                  restoringbeam=restoringbeam,
                  pbcor=pbcor,
                  minpb=minpb,
                  usescratch=usescratch,
                  noise=noise,
                  npixels=npixels,
                  npercycle=npercycle,
                  cyclefactor=cyclefactor,
                  cyclespeedup=cyclespeedup,
                  nterms=nterms,
                  reffreq=reffreq,
                  chaniter=chaniter,
                  flatnoise=flatnoise,
                  allowchunk=False)
            clnjunks = ['.flux', '.mask', '.model', '.psf', '.residual']
            for clnjunk in clnjunks:
                if os.path.exists(imname + clnjunk):
                    shutil.rmtree(imname + clnjunk)
        else:
            print imname + ' existed. Clean task aborted.'

        if doreg and not os.path.isfile(imname + '.fits'):
            # check if ephemfile and msinfofile exist
            if not ephem:
                print("ephemeris info does not exist!")
                return
            reftime = [timerange]
            helio = vla_prep.ephem_to_helio(msinfo=msinfofile,
                                            ephem=ephem,
                                            reftime=reftime)
            imagefile = [imname + '.image']
            fitsfile = [imname + '.fits']
            vla_prep.imreg(imagefile=imagefile,
                           fitsfile=fitsfile,
                           helio=helio,
                           toTb=False,
                           scl100=True)
            if os.path.exists(imname + '.fits'):
                return [True, btstr, imname + '.fits']
            else:
                return [False, btstr, '']
        else:
            if os.path.exists(imname + '.image'):
                return [True, btstr, imname + '.image']
            else:
                return [False, btstr, '']

    except:
        print('error in processing image: ' + btstr)
        return [False, btstr, '']
Exemple #32
0
def subvs2(vis=None,
           outputvis=None,
           timerange='',
           spw='',
           mode=None,
           subtime1=None,
           subtime2=None,
           smoothaxis=None,
           smoothtype=None,
           smoothwidth=None,
           splitsel=None,
           reverse=None,
           overwrite=None):
    """Perform vector subtraction for visibilities
    Keyword arguments:
    vis -- Name of input visibility file (MS)
            default: none; example: vis='ngc5921.ms'
    outputvis -- Name of output uv-subtracted visibility file (MS)
                  default: none; example: outputvis='ngc5921_src.ms'
    timerange -- Time range of performing the UV subtraction:
                 default='' means all times.  examples:
                 timerange = 'YYYY/MM/DD/hh:mm:ss~YYYY/MM/DD/hh:mm:ss'
                 timerange = 'hh:mm:ss~hh:mm:ss'
    spw -- Select spectral window/channel.
           default = '' all the spectral channels. Example: spw='0:1~20'
    mode -- operation mode
            default 'linear' 
                mode = 'linear': use a linear fit for the background to be subtracted
                mode = 'lowpass': act as a lowpass filter---smooth the data using different
                        smooth types and window sizes. Can be performed along either time
                        or frequency axis
                mode = 'highpass': act as a highpass filter---smooth the data first, and 
                        subtract the smoothed data from the original. Can be performed along
                        either time or frequency axis
            mode = 'linear' expandable parameters:
                subtime1 -- Time range 1 of the background to be subtracted from the data 
                             default='' means all times.  format:
                             timerange = 'YYYY/MM/DD/hh:mm:ss~YYYY/MM/DD/hh:mm:ss'
                             timerange = 'hh:mm:ss~hh:mm:ss'
                subtime2 -- Time range 2 of the backgroud to be subtracted from the data
                             default='' means all times.  examples:
                             timerange = 'YYYY/MM/DD/hh:mm:ss~YYYY/MM/DD/hh:mm:ss'
                             timerange = 'hh:mm:ss~hh:mm:ss'
            mode = 'lowpass' or 'highpass' expandable parameters:
                smoothaxis -- axis of smooth
                    Default: 'time'
                    smoothaxis = 'time': smooth is along the time axis
                    smoothaxis = 'freq': smooth is along the frequency axis
                smoothtype -- type of the smooth depending on the convolving kernel
                    Default: 'flat'
                    smoothtype = 'flat': convolving kernel is a flat rectangle,
                            equivalent to a boxcar moving smooth
                    smoothtype = 'hanning': Hanning smooth kernel. See numpy.hanning
                    smoothtype = 'hamming': Hamming smooth kernel. See numpy.hamming
                    smoothtype = 'bartlett': Bartlett smooth kernel. See numpy.bartlett
                    smoothtype = 'blackman': Blackman smooth kernel. See numpy.blackman
                smoothwidth -- width of the smooth kernel
                    Default: 5
                    Examples: smoothwidth=5, meaning the width is 5 pixels
    splitsel -- True or False. default = False. If splitsel = False, then the entire input
            measurement set is copied as the output measurement set (outputvis), with 
            background subtracted at selected timerange and spectral channels. 
            If splitsel = True,then only the selected timerange and spectral channels 
            are copied into the output measurement set (outputvis).
    reverse -- True or False. default = False. If reverse = False, then the times indicated
            by subtime1 and/or subtime2 are treated as background and subtracted; If reverse
            = True, then reverse the sign of the background-subtracted data. The option can 
            be used for mapping absorptive structure.
    overwrite -- True or False. default = False. If overwrite = True and
                outputvis already exists, the selected subtime and spw in the 
                output measurment set will be replaced with background subtracted 
                visibilities

    """
    # check the visbility ms
    casalog.post('input parameters:')
    casalog.post('vis: ' + vis)
    casalog.post('outputvis: ' + outputvis)
    casalog.post('smoothaxis: ' + smoothaxis)
    casalog.post('smoothtype: ' + smoothtype)
    casalog.post('smoothwidth: ' + str(smoothwidth))
    if not outputvis or outputvis.isspace():
        raise (ValueError, 'Please specify outputvis')

    if os.path.exists(outputvis):
        if overwrite:
            print(
                "The already existing output measurement set will be updated.")
        else:
            raise (ValueError,
                   "Output MS %s already exists - will not overwrite." %
                   outputvis)
    else:
        if not splitsel:
            shutil.copytree(vis, outputvis)
        else:
            ms.open(vis, nomodify=True)
            ms.split(outputvis, spw=spw, time=timerange, whichcol='DATA')
            ms.close()

    if timerange and (type(timerange) == str):
        [btimeo, etimeo] = timerange.split('~')
        btimeosec = qa.getvalue(qa.convert(qa.totime(btimeo), 's'))
        etimeosec = qa.getvalue(qa.convert(qa.totime(etimeo), 's'))
        timebinosec = etimeosec - btimeosec
        if timebinosec < 0:
            raise Exception(
                'Negative timebin! Please check the "timerange" parameter.')
        casalog.post('Selected timerange: ' + timerange +
                     ' as the time for UV subtraction.')
    else:
        casalog.post(
            'Output timerange not specified, using the entire timerange')

    if spw and (type(spw) == str):
        spwlist = spw.split(';')
    else:
        casalog.post('spw not specified, use all frequency channels')

    # read the output data
    datams = mstool()
    datams.open(outputvis, nomodify=False)
    datamsmd = msmdtool()
    datamsmd.open(outputvis)
    spwinfod = datams.getspectralwindowinfo()
    spwinfok = spwinfod.keys()
    spwinfok.sort(key=int)
    spwinfol = [spwinfod[k] for k in spwinfok]
    for s, spi in enumerate(spwinfol):
        print('processing spectral window {}'.format(spi['SpectralWindowId']))
        datams.selectinit(reset=True)
        staql = {'time': '', 'spw': ''}
        if not splitsel:
            # outputvis is identical to input visibility, do the selection
            if timerange and (type(timerange == str)):
                staql['time'] = timerange
            if spw and (type(spw) == str):
                staql['spw'] = spwlist[s]
            if not spw and not timerange:
                # data selection is not made
                print('selecting all spws and times')
                staql['spw'] = str(spi['SpectralWindowId'])
        else:
            # outputvis is splitted, selections have already applied, select all the data
            print('split the selected spws and times')
            staql['spw'] = str(spi['SpectralWindowId'])
        datams.msselect(staql)
        orec = datams.getdata(['data', 'time', 'axis_info'], ifraxis=True)
        npol, nchan, nbl, ntim = orec['data'].shape
        print('dimension of output data', orec['data'].shape)
        casalog.post('Number of baselines: ' + str(nbl))
        casalog.post('Number of spectral channels: ' + str(nchan))
        casalog.post('Number of time pixels: ' + str(ntim))

        try:
            if mode == 'linear':
                # define and check the background time ranges
                if subtime1 and (type(subtime1) == str):
                    [bsubtime1, esubtime1] = subtime1.split('~')
                    bsubtime1sec = qa.getvalue(
                        qa.convert(qa.totime(bsubtime1), 's'))
                    esubtime1sec = qa.getvalue(
                        qa.convert(qa.totime(esubtime1), 's'))
                    timebin1sec = esubtime1sec - bsubtime1sec
                    if timebin1sec < 0:
                        raise Exception(
                            'Negative timebin! Please check the "subtime1" parameter.'
                        )
                    casalog.post('Selected timerange 1: ' + subtime1 +
                                 ' as background for uv subtraction.')
                else:
                    raise Exception(
                        'Please enter at least one timerange as the background'
                    )
                if subtime2 and (type(subtime2) == str):
                    [bsubtime2, esubtime2] = subtime2.split('~')
                    bsubtime2sec = qa.getvalue(
                        qa.convert(qa.totime(bsubtime2), 's'))
                    esubtime2sec = qa.getvalue(
                        qa.convert(qa.totime(esubtime2), 's'))
                    timebin2sec = esubtime2sec - bsubtime2sec
                    if timebin2sec < 0:
                        raise Exception(
                            'Negative timebin! Please check the "subtime2" parameter.'
                        )
                    timebin2 = str(timebin2sec) + 's'
                    casalog.post('Selected timerange 2: ' + subtime2 +
                                 ' as background for uv subtraction.')
                    # plus 1s is to ensure averaging over the entire timerange
                else:
                    casalog.post(
                        'Timerange 2 not selected, using only timerange 1 as background'
                    )

                # Select the background indicated by subtime1
                ms.open(vis, nomodify=True)
                # Select the spw id
                # ms.msselect({'time': subtime1})
                staql0 = {'time': subtime1, 'spw': ''}
                if spw and (type(spw) == str):
                    staql0['spw'] = spwlist[s]
                else:
                    staql0['spw'] = staql['spw']
                ms.msselect(staql0)
                rec1 = ms.getdata(['data', 'time', 'axis_info'], ifraxis=True)
                # print('shape of the frequency matrix ',rec1['axis_info']['freq_axis']['chan_freq'].shape)
                sz1 = rec1['data'].shape
                print('dimension of selected background 1', rec1['data'].shape)
                # the data shape is (n_pol,n_channel,n_baseline,n_time), no need to reshape
                # rec1['data']=rec1['data'].reshape(sz1[0],sz1[1],sz1[2],nspw,sz1[3]/nspw,order='F')
                # print('reshaped rec1 ', rec1['data'].shape)
                rec1avg = np.average(rec1['data'], axis=3)
                casalog.post('Averaging the visibilities in subtime1: ' +
                             subtime1)
                ms.close()
                if subtime2 and (type(subtime2) == str):
                    ms.open(vis, nomodify=True)
                    # Select the spw id
                    staql0 = {'time': subtime2, 'spw': ''}
                    if spw and (type(spw) == str):
                        staql0['spw'] = spwlist[s]
                    else:
                        staql0['spw'] = staql['spw']
                    ms.msselect(staql0)
                    rec2 = ms.getdata(['data', 'time', 'axis_info'],
                                      ifraxis=True)
                    sz2 = rec2['data'].shape
                    print('dimension of selected background 2',
                          rec2['data'].shape)
                    # rec2['data']=rec2['data'].reshape(sz2[0],sz2[1],sz2[2],nspw,sz2[3]/nspw,order='F')
                    # print('reshaped rec1 ', rec2['data'].shape)
                    rec2avg = np.average(rec2['data'], axis=3)
                    ms.close()
                    casalog.post('Averaged the visibilities in subtime2: ' +
                                 subtime2)
                if subtime1 and (not subtime2):
                    casalog.post(
                        'Only "subtime1" is defined, subtracting background defined in subtime1: '
                        + subtime1)
                    t1 = (np.amax(rec1['time']) + np.amin(rec1['time'])) / 2.
                    print('t1: ',
                          qa.time(qa.quantity(t1, 's'), form='ymd', prec=10))
                    for i in range(ntim):
                        orec['data'][:, :, :, i] -= rec1avg
                        if reverse:
                            orec['data'][:, :, :,
                                         i] = -orec['data'][:, :, :, i]
                if subtime1 and subtime2 and (type(subtime2) == str):
                    casalog.post(
                        'Both subtime1 and subtime2 are specified, doing linear interpolation between "subtime1" and "subtime2"'
                    )
                    t1 = (np.amax(rec1['time']) + np.amin(rec1['time'])) / 2.
                    t2 = (np.amax(rec2['time']) + np.amin(rec2['time'])) / 2.
                    touts = orec['time']
                    print('t1: ',
                          qa.time(qa.quantity(t1, 's'), form='ymd', prec=10))
                    print('t2: ',
                          qa.time(qa.quantity(t2, 's'), form='ymd', prec=10))
                    for i in range(ntim):
                        tout = touts[i]
                        if tout > np.amax([t1, t2]):
                            tout = np.amax([t1, t2])
                        elif tout < np.amin([t1, t2]):
                            tout = np.amin([t1, t2])
                        orec['data'][:, :, :, i] -= (rec2avg - rec1avg) * (
                            tout - t1) / (t2 - t1) + rec1avg
                        if reverse:
                            orec['data'][:, :, :,
                                         i] = -orec['data'][:, :, :, i]
            elif mode == 'highpass':
                if smoothtype != 'flat' and smoothtype != 'hanning' and smoothtype != 'hamming' and smoothtype != 'bartlett' and smoothtype != 'blackman':
                    raise Exception('Unknown smoothtype ' + str(smoothtype))
                if smoothaxis == 'time':
                    if smoothwidth <= 0 or smoothwidth >= ntim:
                        raise Exception(
                            'Specified smooth width is <=0 or >= the total number of '
                            + smoothaxis)
                    else:
                        for i in range(orec['data'].shape[0]):
                            for j in range(nchan):
                                for k in range(nbl):
                                    orec['data'][i, j,
                                                 k, :] -= signalsmooth.smooth(
                                                     orec['data'][i, j, k, :],
                                                     smoothwidth, smoothtype)
                if smoothaxis == 'freq':
                    if smoothwidth <= 0 or smoothwidth >= nchan:
                        raise Exception(
                            'Specified smooth width is <=0 or >= the total number of '
                            + smoothaxis)
                    else:
                        for i in range(orec['data'].shape[0]):
                            for j in range(nbl):
                                for k in range(ntim):
                                    orec['data'][i, :, j,
                                                 k] -= signalsmooth.smooth(
                                                     orec['data'][i, :, j, k],
                                                     smoothwidth, smoothtype)
            elif mode == 'lowpass':
                if smoothtype != 'flat' and smoothtype != 'hanning' and smoothtype != 'hamming' and smoothtype != 'bartlett' and smoothtype != 'blackman':
                    raise Exception('Unknown smoothtype ' + str(smoothtype))
                if smoothaxis == 'time':
                    if smoothwidth <= 0 or smoothwidth >= ntim:
                        raise Exception(
                            'Specified smooth width is <=0 or >= the total number of '
                            + smoothaxis)
                    else:
                        for i in range(orec['data'].shape[0]):
                            for j in range(nchan):
                                for k in range(nbl):
                                    orec['data'][i, j,
                                                 k, :] = signalsmooth.smooth(
                                                     orec['data'][i, j, k, :],
                                                     smoothwidth, smoothtype)
                if smoothaxis == 'freq':
                    if smoothwidth <= 0 or smoothwidth >= nchan:
                        raise Exception(
                            'Specified smooth width is <=0 or >= the total number of '
                            + smoothaxis)
                    else:
                        for i in range(orec['data'].shape[0]):
                            for j in range(nbl):
                                for k in range(ntim):
                                    orec['data'][i, :, j,
                                                 k] = signalsmooth.smooth(
                                                     orec['data'][i, :, j, k],
                                                     smoothwidth, smoothtype)
            else:
                raise Exception('Unknown mode' + str(mode))
        except Exception as instance:
            print('*** Error ***', instance)

        # orec['data']=orec['data'].reshape(szo[0],szo[1],szo[2],szo[3],order='F')
        # put the modified data back into the output visibility set
        del orec['time']
        del orec['axis_info']
        # ms.open(outputvis,nomodify=False)
        # if not splitsel:
        # outputvis is identical to input visibility, do the selection
        #    if timerange and (type(timerange==str)):
        #        datams.msselect({'time':timerange})
        #    if spw and (type(spw)==str):
        #        datams.selectinit(datadescid=int(spwid))
        #        nchan=int(echan)-int(bchan)+1
        #        datams.selectchannel(nchan,int(bchan),1,1)
        #    if not spw and not timerange:
        # data selection is not made
        #        datams.selectinit(datadescid=0)
        # else:
        # outputvis is splitted, selections have already applied, select all the data
        #    datams.selectinit(datadescid=0)
        datams.putdata(orec)
    datams.close()
    datamsmd.done()
Exemple #33
0
def ksc_sim_gauss(projname='sim_7m_array_1GHz_gaus',
                  antennalist='ksc-7m.cfg',
                  dishdiam=7,
                  imagename=None,
                  indirection='J2000 14h26m46.0s -14d31m22.0s',
                  incell='1arcsec',
                  frequency='1.0GHz',
                  inwidth='1MHz',
                  radec_offset=[100., 100.],
                  flux=50.,
                  majoraxis='40arcsec',
                  minoraxis='27arcsec',
                  positionangle='45.0deg',
                  imsize=[512, 512]):
    """
    Simulate observation of an input Gaussian model
    :param projname: project name for simobserve
    :param antennalist: cfg file of the array configuration
    :param dishdiam: diameter of each dish, in meters
    :param imagename: name (and path) for output clean image, psf, etc.
    :param indirection: phase center of the observation
    :param incell: pixel scale of the model/simulated image
    :param frequency: central frequency
    :param inwidth: frequency bandwidth
    :param radec_offset: offset of the Gaussian source from the phasecenter, in arcsec
    :param flux: total flux of the Gaussian source, in solar flux unit (sfu)
    :param majoraxis: FWHM size of the Gaussian source along the major axis
    :param minoraxis: FWHM size of the Gaussian source along the minor axis
    :param positionangle: position angle of the Gaussian source
    :param imsize: size of the model/simulated image, in pixels (x and y)
    :return:
    """

    # set voltage patterns and primary beams for KSC 7 m. This is a placeholder for now (but required for PB correction)
    vp = vptool()
    if len(vp.getvp(telescope='KSC').keys()) == 0:
        vprec = vp.setpbairy(telescope='KSC',
                             dishdiam='{0:.1f}m'.format(dishdiam),
                             blockagediam='0.75m',
                             maxrad='1.784deg',
                             reffreq='1.0GHz',
                             dopb=True)

    # make a Gaussian source
    cl = cltool()
    ia = iatool()
    cl.addcomponent(dir=indirection,
                    flux=flux * 1e4,
                    fluxunit='Jy',
                    freq=frequency,
                    shape="Gaussian",
                    majoraxis=majoraxis,
                    minoraxis=minoraxis,
                    positionangle=positionangle)
    ia.fromshape("Gaussian.im", imsize + [1, 1], overwrite=True)
    cs = ia.coordsys()
    cs.setunits(['rad', 'rad', '', 'Hz'])
    cell_rad = qa.convert(qa.quantity(incell), "rad")['value']
    cs.setincrement([-cell_rad, cell_rad], 'direction')
    ra_ref = qa.toangle(indirection.split(' ')[1])
    dec_ref = qa.toangle(indirection.split(' ')[2])
    ra = ra_ref['value'] - radec_offset[0] / 3600.
    dec = dec_ref['value'] - radec_offset[1] / 3600.
    cs.setreferencevalue([
        qa.convert('{0:.4f}deg'.format(ra), 'rad')['value'],
        qa.convert('{0:.4f}deg'.format(dec), 'rad')['value']
    ],
                         type="direction")
    cs.setreferencevalue("1.0GHz", 'spectral')
    cs.setincrement('10MHz', 'spectral')
    ia.setcoordsys(cs.torecord())
    ia.setbrightnessunit("Jy/pixel")
    ia.modify(cl.torecord(), subtract=False)
    ia.close()

    simobserve(project=projname,
               skymodel='Gaussian.im',
               indirection=indirection,
               incell=incell,
               incenter=frequency,
               inwidth=inwidth,
               hourangle='transit',
               refdate='2014/11/01',
               totaltime='120s',
               antennalist=antennalist,
               obsmode='int',
               overwrite=True)

    if not imagename:
        imagename = projname + '/tst'
    tclean(vis=projname + '/' + projname + '.' + antennalist.split('.')[0] +
           '.ms',
           imagename=imagename,
           imsize=imsize,
           cell=incell,
           phasecenter=indirection,
           niter=200,
           interactive=False)

    viewer(projname + '/' + projname + '.' + antennalist.split('.')[0] +
           '.skymodel')
    viewer(imagename + '.psf')
    viewer(imagename + '.image')
Exemple #34
0
def ptclean3(vis, imageprefix, imagesuffix, ncpu, twidth, doreg, usephacenter,
             reftime, toTb, overwrite, selectdata, field, spw, timerange,
             uvrange, antenna, scan, observation, intent, datacolumn, imsize,
             cell, phasecenter, stokes, projection, startmodel, specmode,
             reffreq, nchan, start, width, outframe, veltype, restfreq,
             interpolation, gridder, facets, chanchunks, wprojplanes, vptable,
             usepointing, mosweight, aterm, psterm, wbawp, conjbeams, cfcache,
             computepastep, rotatepastep, pblimit, normtype, deconvolver,
             scales, nterms, smallscalebias, restoration, restoringbeam, pbcor,
             outlierfile, weighting, robust, npixels, uvtaper, niter, gain,
             threshold, nsigma, cycleniter, cyclefactor, minpsffraction,
             maxpsffraction, interactive, usemask, mask, pbmask,
             sidelobethreshold, noisethreshold, lownoisethreshold,
             negativethreshold, smoothfactor, minbeamfrac, cutthreshold,
             growiterations, dogrowprune, minpercentchange, verbose, restart,
             savemodel, calcres, calcpsf, parallel, subregion):
    if not (type(ncpu) is int):
        casalog.post('ncpu should be an integer')
        ncpu = 8

    if doreg:
        # check if ephem and msinfo exist. If not, generate one on the fly
        try:
            ephem = hf.read_horizons(vis=vis)
        except ValueError:
            print("error in obtaining ephemeris")
        try:
            msinfo = hf.read_msinfo(vis)
        except ValueError:
            print("error in getting ms info")
    else:
        ephem = None
        msinfo = None

    if imageprefix:
        workdir = os.path.dirname(imageprefix)
    else:
        workdir = './'
    tmpdir = workdir + '/tmp/'
    if not os.path.exists(tmpdir):
        os.makedirs(tmpdir)
    # get number of time pixels
    ms.open(vis)
    ms.selectinit()
    timfreq = ms.getdata(['time', 'axis_info'], ifraxis=True)
    tim = timfreq['time']
    ms.close()

    if twidth < 1:
        casalog.post('twidth less than 1. Change to 1')
        twidth = 1

    if twidth > len(tim):
        casalog.post(
            'twidth greater than # of time pixels in the dataset. Change to the timerange of the entire dateset'
        )
        twidth = len(tim)
    # find out the start and end time index according to the parameter timerange
    # if not defined (empty string), use start and end from the entire time of the ms
    if not timerange:
        btidx = 0
        etidx = len(tim) - 1
    else:
        try:
            (tstart, tend) = timerange.split('~')
            bt_s = qa.convert(qa.quantity(tstart, 's'), 's')['value']
            et_s = qa.convert(qa.quantity(tend, 's'), 's')['value']
            # only time is given but not date, add the date (at 0 UT) from the first record
            if bt_s < 86400. or et_s < 86400.:
                bt_s += np.fix(
                    qa.convert(qa.quantity(tim[0], 's'),
                               'd')['value']) * 86400.
                et_s += np.fix(
                    qa.convert(qa.quantity(tim[0], 's'),
                               'd')['value']) * 86400.
            btidx = np.argmin(np.abs(tim - bt_s))
            etidx = np.argmin(np.abs(tim - et_s))
            # make the indice back to those bracket by the timerange
            if tim[btidx] < bt_s:
                btidx += 1
            if tim[etidx] > et_s:
                etidx -= 1
            if etidx <= btidx:
                print("ending time must be greater than starting time")
                print("reinitiating to the entire time range")
                btidx = 0
                etidx = len(tim) - 1
        except ValueError:
            print("keyword 'timerange' has a wrong format")

    btstr = qa.time(qa.quantity(tim[btidx], 's'), prec=9, form='fits')[0]
    etstr = qa.time(qa.quantity(tim[etidx], 's'), prec=9, form='fits')[0]

    iterable = range(btidx, etidx + 1, twidth)
    print('First time pixel: ' + btstr)
    print('Last time pixel: ' + etstr)
    print(str(len(iterable)) + ' images to clean...')

    res = []
    # partition
    clnpart = partial(
        clean_iter, tim, vis, imageprefix, imagesuffix, twidth, doreg,
        usephacenter, reftime, ephem, msinfo, toTb, overwrite, selectdata,
        field, spw, uvrange, antenna, scan, observation, intent, datacolumn,
        imsize, cell, phasecenter, stokes, projection, startmodel, specmode,
        reffreq, nchan, start, width, outframe, veltype, restfreq,
        interpolation, gridder, facets, chanchunks, wprojplanes, vptable,
        usepointing, mosweight, aterm, psterm, wbawp, conjbeams, cfcache,
        computepastep, rotatepastep, pblimit, normtype, deconvolver, scales,
        nterms, smallscalebias, restoration, restoringbeam, pbcor, outlierfile,
        weighting, robust, npixels, uvtaper, niter, gain, threshold, nsigma,
        cycleniter, cyclefactor, minpsffraction, maxpsffraction, interactive,
        usemask, mask, pbmask, sidelobethreshold, noisethreshold,
        lownoisethreshold, negativethreshold, smoothfactor, minbeamfrac,
        cutthreshold, growiterations, dogrowprune, minpercentchange, verbose,
        restart, savemodel, calcres, calcpsf, parallel, subregion, tmpdir)
    timelapse = 0
    t0 = time()
    # parallelization
    if ncpu > 1:
        import multiprocessing as mprocs
        casalog.post('Perform clean in parallel ...')
        print('Perform clean in parallel ...')
        pool = mprocs.Pool(ncpu)
        res = pool.map(clnpart, iterable)
        pool.close()
        pool.join()
    else:
        casalog.post('Perform clean in single process ...')
        print('Perform clean in single process ...')
        for i in iterable:
            res.append(clnpart(i))

    t1 = time()
    timelapse = t1 - t0
    print('It took %f secs to complete' % timelapse)
    # repackage this into a single dictionary
    results = {
        'Succeeded': [],
        'BeginTime': [],
        'EndTime': [],
        'ImageName': []
    }
    for r in res:
        results['Succeeded'].append(r[0])
        results['BeginTime'].append(r[1])
        results['EndTime'].append(r[2])
        results['ImageName'].append(r[3])

    if os.path.exists(tmpdir):
        os.system('rm -rf ' + tmpdir)

    return results
Exemple #35
0
def predictcomp(objname=None, standard=None, epoch=None,
                minfreq=None, maxfreq=None, nfreqs=None, prefix=None,
                antennalist=None, showplot=None, savefig=None, symb=None,
                include0amp=None, include0bl=None, blunit=None, bl0flux=None):
    """
    Writes a component list named clist to disk and returns a dict of
    {'clist': clist,
     'objname': objname,
     'angdiam': angular diameter in radians (if used in clist),
     'standard': standard,
     'epoch': epoch,
     'freqs': pl.array of frequencies, in GHz,
     'uvrange': pl.array of baseline lengths, in m,
     'amps':  pl.array of predicted visibility amplitudes, in Jy,
     'savedfig': False or, if made, the filename of a plot.}
    or False on error.

    objname: An object supported by standard.
    standard: A standard for calculating flux densities, as in setjy.
              Default: 'Butler-JPL-Horizons 2010'
    epoch: The epoch to use for the calculations.   Irrelevant for
           extrasolar standards.
    minfreq: The minimum frequency to use.
             Example: '342.0GHz'
    maxfreq: The maximum frequency to use.
             Default: minfreq
             Example: '346.0GHz'
             Example: '', anything <= 0, or None: use minfreq.
    nfreqs:  The number of frequencies to use.
             Default: 1 if minfreq == maxfreq,
                      2 otherwise.
    prefix: The component list will be saved to
              prefix + 'spw0_<objname>_<minfreq><epoch>.cl'
            Default: ''
    antennalist: An array configuration file as used by simdata.
                 If given, a plot of S vs. |u| will be made.
                 Default: '' (None, just make clist.)
    showplot: Whether or not to show the plot on screen.
              Subparameter of antennalist.
              Default: Necessarily False if antennalist is not specified.
                       True otherwise.
    savefig: Filename for saving a plot of S vs. |u|.
             Subparameter of antennalist.
             Default: False (necessarily if antennalist is not specified)
             Examples: True (save to prefix + '.png')
                       'myplot.png' (save to myplot.png) 
    symb: One of matplotlib's codes for plot symbols: .:,o^v<>s+xDd234hH|_
          default: '.'
    include0amp: Force the lower limit of the amplitude axis to 0.
                 Default: False
    include0bl: Force the lower limit of the baseline length axis to 0.
    blunit: Unit of the baseline length 
    bl0flux: show zero baseline flux
    """
    retval = False
    try:
        casalog.origin('predictcomp')
        # some parameter minimally required
        if objname=='':
          raise Exception, "Error, objname is undefined"
        if minfreq=='':
          raise Exception, "Error, minfreq is undefined" 
        minfreqq = qa.quantity(minfreq)
        minfreqHz = qa.convert(minfreqq, 'Hz')['value']
        try:
            maxfreqq = qa.quantity(maxfreq)
        except Exception, instance:
            maxfreqq = minfreqq
        frequnit = maxfreqq['unit']
        maxfreqHz = qa.convert(maxfreqq, 'Hz')['value']
        if maxfreqHz <= 0.0:
            maxfreqq = minfreqq
            maxfreqHz = minfreqHz
        if minfreqHz != maxfreqHz:
            if nfreqs < 2:
                nfreqs = 2
        else:
            nfreqs = 1
        freqs = pl.linspace(minfreqHz, maxfreqHz, nfreqs)

        myme = metool()
        mepoch = myme.epoch('UTC', epoch)
        #if not prefix:
            ## meanfreq = {'value': 0.5 * (minfreqHz + maxfreqHz),
            ##             'unit': frequnit}
            ## prefix = "%s%s_%.7g" % (objname, epoch.replace('/', '-'),
            ##                         minfreqq['value'])
            ## if minfreqHz != maxfreqHz:
            ##     prefix += "to" + maxfreq
            ## else:
            ##     prefix += minfreqq['unit']
            ## prefix += "_"
        #    prefix = ''
        
        #
        if not prefix:
          if not os.access("./",os.W_OK):
            casalog.post("No write access in the current directory, trying to write cl to /tmp...","WARN")
            prefix="/tmp/"
            if not os.access(prefix, os.W_OK):
              casalog.post("No write access to /tmp to write cl file", "SEVERE")
              return False
        else:
          prefixdir=os.path.dirname(prefix)
          if not os.path.exists(prefixdir):
            prefixdirs = prefixdir.split('/')
            if prefixdirs[0]=="":
              rootdir = "/" + prefixdirs[1]
            else:
              rootdir = "./"
            if os.access(rootdir,os.W_OK):
              os.makedirs(prefixdir) 
            else:
              casalog.post("No write access to "+rootdir+" to write cl file", "SEVERE")
              return False
       
        # Get clist
        myim = imtool()
        if hasattr(myim, 'predictcomp'):
            casalog.post('local im instance created', 'DEBUG1')
        else:
            casalog.post('Error creating a local im instance.', 'SEVERE')
            return False
        #print "FREQS=",freqs
        if standard=='Butler-JPL-Horizons 2012':
            clist = predictSolarObjectCompList(objname, mepoch, freqs.tolist(), prefix)
        else:
            clist = myim.predictcomp(objname, standard, mepoch, freqs.tolist(), prefix)
        #print "created componentlist =",clist
        if os.path.isdir(clist):
            # The spw0 is useless here, but it is added by FluxStandard for the sake of setjy.
            casalog.post('The component list was saved to ' + clist)
            
            retval = {'clist': clist,
                      'objname': objname,
                      'standard': standard,
                      'epoch': mepoch,
                      'freqs (GHz)': 1.0e-9 * freqs,
                      'antennalist': antennalist}
            mycl = cltool()
            mycl.open(clist)
            comp = mycl.getcomponent(0)
            zeroblf=comp['flux']['value']
            if standard=='Butler-JPL-Horizons 2012':
              f0=comp['spectrum']['frequency']['m0']['value']
            else:
              f0=retval['freqs (GHz)'][0]
            casalog.post("Zero baseline flux %s @ %sGHz " % (zeroblf, f0),'INFO')
            mycl.close(False)               # False prevents the stupid warning.
            for k in ('shape', 'spectrum'):
                retval[k] = comp[k]
            if antennalist:
                retval['spectrum']['bl0flux']={}
                retval['spectrum']['bl0flux']['value']=zeroblf[0]
                retval['spectrum']['bl0flux']['unit']='Jy'
                retval['savedfig'] = savefig
                if not bl0flux:
                  zeroblf=[0.0]
                retval.update(plotcomp(retval, showplot, wantdict=True, symb=symb,
                                       include0amp=include0amp, include0bl=include0bl, blunit=blunit, bl0flux=zeroblf[0]))
            else:
                retval['savedfig'] = None
        else:
            casalog.post("There was an error in making the component list.",
                         'SEVERE')
Exemple #36
0
     if nspw > 1:
         casalog.post('Separate MS into %s spws'%nspw)
     config['nspw'] = nspw
     config['interpolation'] = interpolation
     if restfreq != '':
         config['restfreq'] = restfreq
     if outframe != '':
         config['outframe'] = outframe
     if phasecenter != '':
         config['phasecenter'] = phasecenter
     config['veltype'] = veltype
     config['preaverage'] = preaverage
     
 # Only parse timeaverage parameters when timebin > 0s
 if timeaverage:
     tb = qa.convert(qa.quantity(timebin), 's')['value']
     if not tb > 0:
         raise Exception, "Parameter timebin must be > '0s' to do time averaging"
                
 if timeaverage:
     casalog.post('Parse time averaging parameters')
     config['timeaverage'] = True
     config['timebin'] = timebin
     config['timespan'] = timespan
     config['maxuvwdistance'] = maxuvwdistance
     
 if docallib:
     casalog.post('Parse docallib parameters')
     mycallib = callibrary()
     mycallib.read(callib)
     config['calibration'] = True
Exemple #37
0
def read_msinfo(vis=None, msinfofile=None, use_scan_time=True):
    import glob
    # read MS information #
    msinfo = dict.fromkeys([
        'vis', 'scans', 'fieldids', 'btimes', 'btimestr', 'inttimes', 'ras',
        'decs', 'observatory'
    ])
    ms.open(vis)
    metadata = ms.metadata()
    observatory = metadata.observatorynames()[0]
    scans = ms.getscansummary()
    scanids = sorted(scans.keys(), key=lambda x: int(x))
    nscanid = len(scanids)
    btimes = []
    btimestr = []
    etimes = []
    fieldids = []
    inttimes = []
    dirs = []
    ras = []
    decs = []
    ephem_file = glob.glob(vis + '/FIELD/EPHEM*SUN.tab')
    if ephem_file:
        print('Loading ephemeris info from {}'.format(ephem_file[0]))
        tb.open(ephem_file[0])
        col_ra = tb.getcol('RA')
        col_dec = tb.getcol('DEC')
        col_mjd = tb.getcol('MJD')
        if use_scan_time:
            from scipy.interpolate import interp1d
            f_ra = interp1d(col_mjd, col_ra)
            f_dec = interp1d(col_mjd, col_dec)
            for idx, scanid in enumerate(scanids):
                btimes.append(scans[scanid]['0']['BeginTime'])
                etimes.append(scans[scanid]['0']['EndTime'])
                fieldid = scans[scanid]['0']['FieldId']
                fieldids.append(fieldid)
                inttimes.append(scans[scanid]['0']['IntegrationTime'])
            ras = f_ra(np.array(btimes))
            decs = f_dec(np.array(btimes))
            ras = qa.convert(qa.quantity(ras, 'deg'), 'rad')
            decs = qa.convert(qa.quantity(decs, 'deg'), 'rad')
        else:
            ras = qa.convert(qa.quantity(col_ra, 'deg'), 'rad')
            decs = qa.convert(qa.quantity(col_dec, 'deg'), 'rad')
    else:
        for idx, scanid in enumerate(scanids):
            btimes.append(scans[scanid]['0']['BeginTime'])
            etimes.append(scans[scanid]['0']['EndTime'])
            fieldid = scans[scanid]['0']['FieldId']
            fieldids.append(fieldid)
            inttimes.append(scans[scanid]['0']['IntegrationTime'])
            dir = ms.getfielddirmeas('PHASE_DIR', fieldid)
            dirs.append(dir)
            ras.append(dir['m0'])
            decs.append(dir['m1'])
    ms.close()
    btimestr = [
        qa.time(qa.quantity(btimes[idx], 'd'), form='fits', prec=10)[0]
        for idx in range(nscanid)
    ]
    msinfo['vis'] = vis
    msinfo['scans'] = scans
    msinfo['fieldids'] = fieldids
    msinfo['btimes'] = btimes
    msinfo['btimestr'] = btimestr
    msinfo['inttimes'] = inttimes
    msinfo['ras'] = ras
    msinfo['decs'] = decs
    msinfo['observatory'] = observatory
    if msinfofile:
        np.savez(msinfofile,
                 vis=vis,
                 scans=scans,
                 fieldids=fieldids,
                 btimes=btimes,
                 btimestr=btimestr,
                 inttimes=inttimes,
                 ras=ras,
                 decs=decs,
                 observatory=observatory)
    return msinfo
Exemple #38
0
def calc_phasecenter_from_solxy(vis,
                                timerange='',
                                xycen=None,
                                usemsphacenter=True):
    '''
    return the phase center in RA and DEC of a given solar coordinates

    :param vis: input measurement sets file
    :param timerange: can be a string or astropy.time.core.Time object, or a 2-element list of string or Time object
    :param xycen:  solar x-pos and y-pos in arcsec
    :param usemsphacenter:
    :return:
    phasecenter
    midtim: mid time of the given timerange
    '''
    tb.open(vis + '/POINTING')
    tst = Time(tb.getcell('TIME_ORIGIN', 0) / 24. / 3600., format='mjd')
    ted = Time(tb.getcell('TIME_ORIGIN',
                          tb.nrows() - 1) / 24. / 3600.,
               format='mjd')
    tb.close()
    datstr = tst.iso[:10]

    if isinstance(timerange, Time):
        try:
            (sttim, edtim) = timerange
        except:
            sttim = timerange
            edtim = sttim
    else:
        if timerange == '':
            sttim = tst
            edtim = ted
        else:
            try:
                (tstart, tend) = timerange.split('~')
                if tstart[2] == ':':
                    sttim = Time(datstr + 'T' + tstart)
                    edtim = Time(datstr + 'T' + tend)
                    # timerange = '{0}/{1}~{0}/{2}'.format(datstr.replace('-', '/'), tstart, tend)
                else:
                    sttim = Time(qa.quantity(tstart, 'd')['value'],
                                 format='mjd')
                    edtim = Time(qa.quantity(tend, 'd')['value'], format='mjd')
            except:
                try:
                    if timerange[2] == ':':
                        sttim = Time(datstr + 'T' + timerange)
                        edtim = sttim
                    else:
                        sttim = Time(qa.quantity(timerange, 'd')['value'],
                                     format='mjd')
                        edtim = sttim
                except ValueError:
                    print("keyword 'timerange' in wrong format")

    ms.open(vis)
    metadata = ms.metadata()
    observatory = metadata.observatorynames()[0]
    ms.close()

    midtim_mjd = (sttim.mjd + edtim.mjd) / 2.
    midtim = Time(midtim_mjd, format='mjd')
    eph = read_horizons(t0=midtim)
    if observatory == 'EOVSA' or (not usemsphacenter):
        print('This is EOVSA data')
        # use RA and DEC from FIELD ID 0
        tb.open(vis + '/FIELD')
        phadir = tb.getcol('PHASE_DIR').flatten()
        tb.close()
        ra0 = phadir[0]
        dec0 = phadir[1]
    else:
        ra0 = eph['ra'][0]
        dec0 = eph['dec'][0]

    if not xycen:
        # use solar disk center as default
        phasecenter = 'J2000 ' + str(ra0) + 'rad ' + str(dec0) + 'rad'
    else:
        x0 = np.radians(xycen[0] / 3600.)
        y0 = np.radians(xycen[1] / 3600.)
        p0 = np.radians(eph['p0'][0])  # p angle in radians
        raoff = -((x0) * np.cos(p0) - y0 * np.sin(p0)) / np.cos(eph['dec'][0])
        decoff = (x0) * np.sin(p0) + y0 * np.cos(p0)
        newra = ra0 + raoff
        newdec = dec0 + decoff
        phasecenter = 'J2000 ' + str(newra) + 'rad ' + str(newdec) + 'rad'
    return phasecenter, midtim
Exemple #39
0
def imreg(vis=None,
          ephem=None,
          msinfo=None,
          imagefile=None,
          timerange=None,
          reftime=None,
          fitsfile=None,
          beamfile=None,
          offsetfile=None,
          toTb=None,
          sclfactor=1.0,
          verbose=False,
          p_ang=False,
          overwrite=True,
          usephacenter=True,
          deletehistory=False,
          subregion=[],
          docompress=False):
    ''' 
    main routine to register CASA images
           Required Inputs:
               vis: STRING. CASA measurement set from which the image is derived
               imagefile: STRING or LIST. name of the input CASA image
               timerange: STRING or LIST. timerange used to generate the CASA image, must have the same length as the input images. 
                          Each element should be in CASA standard time format, e.g., '2012/03/03/12:00:00~2012/03/03/13:00:00'
           Optional Inputs:
               msinfo: DICTIONARY. CASA MS information, output from read_msinfo. If not provided, generate one from the supplied vis
               ephem: DICTIONARY. solar ephem, output from read_horizons. 
                      If not provided, query JPL Horizons based on time info of the vis (internet connection required)
               fitsfile: STRING or LIST. name of the output registered fits files
               reftime: STRING or LIST. Each element should be in CASA standard time format, e.g., '2012/03/03/12:00:00'
               offsetfile: optionally provide an offset with a series of solar x and y offsets with timestamps 
               toTb: Bool. Convert the default Jy/beam to brightness temperature?
               sclfactor: scale the image values up by its value (to compensate VLA 20 dB attenuator)
               verbose: Bool. Show more diagnostic info if True.
               usephacenter: Bool -- if True, correct for the RA and DEC in the ms file based on solar empheris.
                                     Otherwise assume the phasecenter is correctly pointed to the solar disk center
                                     (EOVSA case)
               subregion: Region selection. See 'help par.region' for details.
    Usage:
    >>> from suncasa.utils import helioimage2fits as hf
    >>> hf.imreg(vis='mydata.ms', imagefile='myimage.image', fitsfile='myimage.fits',
                 timerange='2017/08/21/20:21:10~2017/08/21/20:21:18')
    The output fits file is 'myimage.fits'

    History:
    BC (sometime in 2014): function was first wrote, followed by a number of edits by BC and SY
    BC (2019-07-16): Added checks for stokes parameter. Verified that for converting from Jy/beam to brightness temperature,
                     the convention of 2*k_b*T should always be used. I.e., for unpolarized source, stokes I, RR, LL, XX, YY, 
                     etc. in the output CASA images from (t)clean should all have same values of radio intensity 
                     (in Jy/beam) and brightness temperature (in K).

    '''

    if deletehistory:
        ms_clearhistory(vis)

    if not imagefile:
        raise ValueError('Please specify input image')
    if not timerange:
        raise ValueError('Please specify timerange of the input image')
    if type(imagefile) == str:
        imagefile = [imagefile]
    if type(timerange) == str:
        timerange = [timerange]
    if not fitsfile:
        fitsfile = [img + '.fits' for img in imagefile]
    if type(fitsfile) == str:
        fitsfile = [fitsfile]
    nimg = len(imagefile)
    if len(timerange) != nimg:
        raise ValueError(
            'Number of input images does not equal to number of timeranges!')
    if len(fitsfile) != nimg:
        raise ValueError(
            'Number of input images does not equal to number of output fits files!'
        )
    nimg = len(imagefile)
    if verbose:
        print(str(nimg) + ' images to process...')

    if reftime:  # use as reference time to find solar disk RA and DEC to register the image, but not the actual timerange associated with the image
        if type(reftime) == str:
            reftime = [reftime] * nimg
        if len(reftime) != nimg:
            raise ValueError(
                'Number of reference times does not match that of input images!'
            )
        helio = ephem_to_helio(vis,
                               ephem=ephem,
                               msinfo=msinfo,
                               reftime=reftime,
                               usephacenter=usephacenter)
    else:
        # use the supplied timerange to register the image
        helio = ephem_to_helio(vis,
                               ephem=ephem,
                               msinfo=msinfo,
                               reftime=timerange,
                               usephacenter=usephacenter)

    if toTb:
        (bmajs, bmins, bpas, beamunits,
         bpaunits) = getbeam(imagefile=imagefile, beamfile=beamfile)

    for n, img in enumerate(imagefile):
        if verbose:
            print('processing image #' + str(n) + ' ' + img)
        fitsf = fitsfile[n]
        timeran = timerange[n]
        # obtain duration of the image as FITS header exptime
        try:
            [tbg0, tend0] = timeran.split('~')
            tbg_d = qa.getvalue(qa.convert(qa.totime(tbg0), 'd'))[0]
            tend_d = qa.getvalue(qa.convert(qa.totime(tend0), 'd'))[0]
            tdur_s = (tend_d - tbg_d) * 3600. * 24.
            dateobs = qa.time(qa.quantity(tbg_d, 'd'), form='fits', prec=10)[0]
        except:
            print('Error in converting the input timerange: ' + str(timeran) +
                  '. Proceeding to the next image...')
            continue

        hel = helio[n]
        if not os.path.exists(img):
            warnings.warn('{} does not existed!'.format(img))
        else:
            if os.path.exists(fitsf) and not overwrite:
                raise ValueError(
                    'Specified fits file already exists and overwrite is set to False. Aborting...'
                )
            else:
                p0 = hel['p0']
                tb.open(img + '/logtable', nomodify=False)
                nobs = tb.nrows()
                tb.removerows([i + 1 for i in range(nobs - 1)])
                tb.close()
                ia.open(img)
                imr = ia.rotate(pa=str(-p0) + 'deg')
                if subregion is not []:
                    imr = imr.subimage(region=subregion)
                imr.tofits(fitsf, history=False, overwrite=overwrite)
                imr.close()
                imsum = ia.summary()
                ia.close()
                ia.done()

            # construct the standard fits header
            # RA and DEC of the reference pixel crpix1 and crpix2
            (imra, imdec) = (imsum['refval'][0], imsum['refval'][1])
            # find out the difference of the image center to the CASA phase center
            # RA and DEC difference in arcseconds
            ddec = degrees((imdec - hel['dec_fld'])) * 3600.
            dra = degrees((imra - hel['ra_fld']) * cos(hel['dec_fld'])) * 3600.
            # Convert into image heliocentric offsets
            prad = -radians(hel['p0'])
            dx = (-dra) * cos(prad) - ddec * sin(prad)
            dy = (-dra) * sin(prad) + ddec * cos(prad)
            if offsetfile:
                try:
                    offset = np.load(offsetfile)
                except:
                    raise ValueError(
                        'The specified offsetfile does not exist!')
                reftimes_d = offset['reftimes_d']
                xoffs = offset['xoffs']
                yoffs = offset['yoffs']
                timg_d = hel['reftime']
                ind = bisect.bisect_left(reftimes_d, timg_d)
                xoff = xoffs[ind - 1]
                yoff = yoffs[ind - 1]
            else:
                xoff = hel['refx']
                yoff = hel['refy']
            if verbose:
                print(
                    'offset of image phase center to visibility phase center (arcsec): dx={0:.2f}, dy={1:.2f}'
                    .format(dx, dy))
                print(
                    'offset of visibility phase center to solar disk center (arcsec): dx={0:.2f}, dy={1:.2f}'
                    .format(xoff, yoff))
            (crval1, crval2) = (xoff + dx, yoff + dy)
            # update the fits header to heliocentric coordinates

            hdu = pyfits.open(fitsf, mode='update')
            hdu[0].verify('fix')
            header = hdu[0].header
            dshape = hdu[0].data.shape
            ndim = hdu[0].data.ndim
            (cdelt1,
             cdelt2) = (-header['cdelt1'] * 3600., header['cdelt2'] * 3600.
                        )  # Original CDELT1, 2 are for RA and DEC in degrees
            header['cdelt1'] = cdelt1
            header['cdelt2'] = cdelt2
            header['cunit1'] = 'arcsec'
            header['cunit2'] = 'arcsec'
            header['crval1'] = crval1
            header['crval2'] = crval2
            header['ctype1'] = 'HPLN-TAN'
            header['ctype2'] = 'HPLT-TAN'
            header['date-obs'] = dateobs  # begin time of the image
            if not p_ang:
                hel['p0'] = 0
            try:
                # this works for pyfits version of CASA 4.7.0 but not CASA 4.6.0
                if tdur_s:
                    header.set('exptime', tdur_s)
                else:
                    header.set('exptime', 1.)
                header.set('p_angle', hel['p0'])
                header.set('hgln_obs', 0.)
                header.set('rsun_ref', sun.constants.radius.value)
                if sunpyver <= 1:
                    header.set(
                        'dsun_obs',
                        sun.sunearth_distance(Time(dateobs)).to(u.meter).value)
                    header.set(
                        'rsun_obs',
                        sun.solar_semidiameter_angular_size(
                            Time(dateobs)).value)
                    header.set(
                        'hglt_obs',
                        sun.heliographic_solar_center(Time(dateobs))[1].value)
                else:
                    header.set(
                        'dsun_obs',
                        sun.earth_distance(Time(dateobs)).to(u.meter).value)
                    header.set('rsun_obs',
                               sun.angular_radius(Time(dateobs)).value)
                    header.set('hglt_obs', sun.L0(Time(dateobs)).value)
            except:
                # this works for astropy.io.fits
                if tdur_s:
                    header.append(('exptime', tdur_s))
                else:
                    header.append(('exptime', 1.))
                header.append(('p_angle', hel['p0']))
                header.append(('hgln_obs', 0.))
                header.append(('rsun_ref', sun.constants.radius.value))
                if sunpyver <= 1:
                    header.append(
                        ('dsun_obs', sun.sunearth_distance(Time(dateobs)).to(
                            u.meter).value))
                    header.append(('rsun_obs',
                                   sun.solar_semidiameter_angular_size(
                                       Time(dateobs)).value))
                    header.append(('hglt_obs',
                                   sun.heliographic_solar_center(
                                       Time(dateobs))[1].value))
                else:
                    header.append(
                        ('dsun_obs',
                         sun.earth_distance(Time(dateobs)).to(u.meter).value))
                    header.append(
                        ('rsun_obs', sun.angular_radius(Time(dateobs)).value))
                    header.append(('hglt_obs', sun.L0(Time(dateobs)).value))

            # check if stokes parameter exist
            exist_stokes = False
            stokes_mapper = {
                'I': 1,
                'Q': 2,
                'U': 3,
                'V': 4,
                'RR': -1,
                'LL': -2,
                'RL': -3,
                'LR': -4,
                'XX': -5,
                'YY': -6,
                'XY': -7,
                'YX': -8
            }
            if 'CRVAL3' in header.keys():
                if header['CTYPE3'] == 'STOKES':
                    stokenum = header['CRVAL3']
                    exist_stokes = True
            if 'CRVAL4' in header.keys():
                if header['CTYPE4'] == 'STOKES':
                    stokenum = header['CRVAL4']
                    exist_stokes = True
            if exist_stokes:
                if stokenum in stokes_mapper.values():
                    stokesstr = list(stokes_mapper.keys())[list(
                        stokes_mapper.values()).index(stokenum)]
                else:
                    print('Stokes parameter {0:d} not recognized'.format(
                        stokenum))
                if verbose:
                    print('This image is in Stokes ' + stokesstr)
            else:
                print(
                    'STOKES Information does not seem to exist! Assuming Stokes I'
                )
                stokenum = 1

            # intensity units to brightness temperature
            if toTb:
                # get restoring beam info
                bmaj = bmajs[n]
                bmin = bmins[n]
                beamunit = beamunits[n]
                data = hdu[
                    0].data  # remember the data order is reversed due to the FITS convension
                keys = list(header.keys())
                values = list(header.values())
                # which axis is frequency?
                faxis = keys[values.index('FREQ')][-1]
                faxis_ind = ndim - int(faxis)
                # find out the polarization of this image
                k_b = qa.constants('k')['value']
                c_l = qa.constants('c')['value']
                # Always use 2*kb for all polarizations
                const = 2. * k_b / c_l**2
                if header['BUNIT'].lower() == 'jy/beam':
                    header['BUNIT'] = 'K'
                    header['BTYPE'] = 'Brightness Temperature'
                    for i in range(dshape[faxis_ind]):
                        nu = header['CRVAL' +
                                    faxis] + header['CDELT' + faxis] * (
                                        i + 1 - header['CRPIX' + faxis])
                        if header['CUNIT' + faxis] == 'KHz':
                            nu *= 1e3
                        if header['CUNIT' + faxis] == 'MHz':
                            nu *= 1e6
                        if header['CUNIT' + faxis] == 'GHz':
                            nu *= 1e9
                        if len(bmaj) > 1:  # multiple (per-plane) beams
                            bmajtmp = bmaj[i]
                            bmintmp = bmin[i]
                        else:  # one single beam
                            bmajtmp = bmaj[0]
                            bmintmp = bmin[0]
                        if beamunit == 'arcsec':
                            bmaj0 = np.radians(bmajtmp / 3600.)
                            bmin0 = np.radians(bmintmp / 3600.)
                        if beamunit == 'arcmin':
                            bmaj0 = np.radians(bmajtmp / 60.)
                            bmin0 = np.radians(bmintmp / 60.)
                        if beamunit == 'deg':
                            bmaj0 = np.radians(bmajtmp)
                            bmin0 = np.radians(bmintmp)
                        if beamunit == 'rad':
                            bmaj0 = bmajtmp
                            bmin0 = bmintmp
                        beam_area = bmaj0 * bmin0 * np.pi / (4. * log(2.))
                        factor = const * nu**2  # SI unit
                        jy_to_si = 1e-26
                        # print(nu/1e9, beam_area, factor)
                        factor2 = sclfactor
                        # if sclfactor:
                        #     factor2 = 100.
                        if faxis == '3':
                            data[:,
                                 i, :, :] *= jy_to_si / beam_area / factor * factor2
                        if faxis == '4':
                            data[
                                i, :, :, :] *= jy_to_si / beam_area / factor * factor2

            header = fu.headerfix(header)
            hdu.flush()
            hdu.close()

            if ndim - np.count_nonzero(np.array(dshape) == 1) > 3:
                docompress = False
                '''
                    Caveat: only 1D, 2D, or 3D images are currently supported by
                    the astropy fits compression. If a n-dimensional image data array
                    does not have at least n-3 single-dimensional entries,
                    force docompress to be False
                '''

                print(
                    'warning: The fits data contains more than 3 non squeezable dimensions. Skipping fits compression..'
                )
            if docompress:
                fitsftmp = fitsf + ".tmp.fits"
                os.system("mv {} {}".format(fitsf, fitsftmp))
                hdu = pyfits.open(fitsftmp)
                hdu[0].verify('fix')
                header = hdu[0].header
                data = hdu[0].data
                fu.write_compressed_image_fits(fitsf,
                                               data,
                                               header,
                                               compression_type='RICE_1',
                                               quantize_level=4.0)
                os.system("rm -rf {}".format(fitsftmp))
    if deletehistory:
        ms_restorehistory(vis)
    return fitsfile