def plot_spec(config, logger, contsub=False):
    """
    For each SPW and each science target amplitude vs channel and amplitude vs velocity are plotted.
    
    Input:
    config = The parameters read from the configuration file. (Ordered dictionary)
    """
    logger.info('Starting plotting amplitude spectrum.')
    plots_obs_dir = './plots/'
    cf.makedir(plots_obs_dir, logger)
    calib = config['calibration']
    targets = calib['target_names'][:]
    if calib['mosaic']:
        targets = list(set(calib['target_names']))
    src_dir = config['global']['src_dir'] + '/'
    for target in targets:
        if contsub:
            MS_list = glob.glob('{0}{1}.split.contsub'.format(src_dir, target))
        else:
            MS_list = glob.glob('{0}{1}.split'.format(src_dir, target))
        for MS in MS_list:
            if contsub:
                plot_file = plots_obs_dir + '{0}_contsub_amp_chn.png'.format(
                    target)
            else:
                plot_file = plots_obs_dir + '{0}_amp_chn.png'.format(target)
            logger.info(
                'Plotting amplitude vs channel to {}'.format(plot_file))
            plotms(vis=MS,
                   xaxis='chan',
                   yaxis='amp',
                   ydatacolumn='corrected',
                   plotfile=plot_file,
                   expformat='png',
                   overwrite=True,
                   showgui=False)
            if not contsub:
                plot_file = plots_obs_dir + '{0}_amp_vel.png'.format(target)
                logger.info(
                    'Plotting amplitude vs velocity to {}'.format(plot_file))
                plotms(vis=MS,
                       xaxis='velocity',
                       yaxis='amp',
                       ydatacolumn='corrected',
                       plotfile=plot_file,
                       expformat='png',
                       overwrite=True,
                       showgui=False,
                       freqframe='BARY',
                       restfreq=str(config['global']['rest_freq']),
                       veldef='OPTICAL')
    logger.info('Completed plotting amplitude spectrum.')
def plot_ants(msfile, logger):
    """
    Plots the layout of the antennae during the observations
    
    Input:
    msfile = Path to the MS. (String)
    """
    logger.info('Starting plotting antenna positions.')
    plots_obs_dir = './plots/'
    cf.makedir(plots_obs_dir, logger)
    plot_file = plots_obs_dir + '{0}_antpos.png'.format(msfile)
    logger.info('Plotting antenna positions to: {}'.format(plot_file))
    plotants(vis=msfile, figfile=plot_file)
    logger.info('Completed plotting antenna positions.')
def listobs_sum(msfile, config, config_raw, logger):
    """ 
    Write the listobs summary to file.
    
    Input:
    msfile = Path where the MS will be created. (String)
    """
    logger.info('Starting listobs summary.')
    sum_dir = './summary/'
    cf.makedir(sum_dir, logger)
    listobs_file = sum_dir + msfile + '.listobs.summary'
    cf.rmfile(listobs_file, logger)
    logger.info(
        'Writing listobs summary of data set to: {}'.format(listobs_file))
    listobs(vis=msfile, listfile=listobs_file)
    cf.check_casalog(config, config_raw, logger, casalog)
    logger.info('Completed listobs summary.')
def import_data(data_files, msfile, config, config_raw, logger):
    """ 
    Import VLA archive files from a location to a single MS.
    
    Input:
    data_files = Paths to the VLA archive files. (List/Array of Strings)
    msfile = Path where the MS will be created. (String)
    """
    logger.info('Starting import vla data')
    sum_dir = './summary/'
    cf.makedir(sum_dir, logger)
    cf.rmdir(msfile, logger)
    logger.info('Input files: {}'.format(data_files))
    logger.info('Output msfile: {}'.format(msfile))
    command = "importvla(archivefiles = {0}, vis = '{1}')".format(
        data_files, msfile)
    logger.info('Executing command: ' + command)
    exec(command)
    cf.check_casalog(config, config_raw, logger, casalog)
    logger.info('Completed import vla data')
def hanning_smooth(msfile, config, config_raw, config_file, logger):
    """
    Hanning smooths the dataset and replaces the previous version.
    
    Input:
    msfile = Path to the MS. (String)
    config = The parameters read from the configuration file. (Ordered dictionary)
    config_raw = The instance of the parser.
    config_file = Path to configuration file. (String)
    """
    logger.info('Starting Hanning smoothing.')
    importdata = config['importdata']
    command = "hanningsmooth(vis='{0}', outputvis='{0}_1')".format(msfile)
    logger.info('Executing command: ' + command)
    exec(command)
    cf.check_casalog(config, config_raw, logger, casalog)
    cf.rmdir(msfile + '.flagversions', logger)
    cf.makedir(msfile + '.flagversions', logger)
    cf.rmdir(msfile, logger)
    cf.mvdir(msfile + '_1', msfile, logger)
    logger.info('Completed Hanning smoothing.')
def plot_elevation(msfile, config, logger):
    """
    Plots the elevation of the fields in each SPW as a function of time.
    
    Input:
    msfile = Path to the MS. (String)
    config = The parameters read from the configuration file. (Ordered dictionary)
    """
    logger.info('Starting plotting elevation.')
    plots_obs_dir = './plots/'
    cf.makedir(plots_obs_dir, logger)
    plot_file = plots_obs_dir + '{0}_elevation.png'.format(msfile)
    logger.info('Plotting elevation to: {}'.format(plot_file))
    avgtime = 16
    width = 900
    min_elev = 0
    max_elev = 90
    showgui = False
    plotms(vis=msfile,
           xaxis='time',
           yaxis='elevation',
           correlation='',
           coloraxis='field',
           symbolsize=5,
           plotrange=[-1, -1, min_elev, max_elev],
           averagedata=True,
           avgtime=str(avgtime),
           plotfile=plot_file,
           expformat='png',
           customsymbol=True,
           symbolshape='circle',
           overwrite=True,
           showlegend=False,
           showgui=showgui,
           exprange='all',
           iteraxis='spw')
    logger.info('Completed plotting elevation.')
Exemple #7
0
def image(config,config_raw,config_file,logger):
    """
    Generates a clean (continuum subtracted) image of each science target.
    Checks that the CLEANing scales and line emission channels are set (may prompt user if in interactive mode).
    Makes varies check on the ratio of pixel size to beam size and the scales and the maximum baseline (may prompt user if in interactive mode).
    Exports the final images as fits cubes (after regridding to J2000 if necessary).
    
    Input:
    config = The parameters read from the configuration file. (Ordered dictionary)
    config_raw = The instance of the parser.
    config_file = Path to configuration file. (String)
    """
    noises = noise_est(config,logger)
    cln_param = config['clean']
    if config_raw.has_option('clean','noise'):
        noises = cln_param['noise'][:]
        logger.info('Noise level(s) set manually as {0} Jy.'.format(noises))
    calib = config['calibration']
    contsub = config['continuum_subtraction']
    rest_freq = config['global']['rest_freq']
    targets = calib['target_names'][:]
    fields = calib['targets'][:]
    for i in range(len(targets)):
        target = targets[i]
        if 'spw' in target:
            inx = target.index('.spw')
            target_name = target[:inx]
            if target_name in calib['target_names'][i-1]:
                fields.insert(i,fields[i-1])
    if calib['mosaic']:
        targets = list(set(targets))
    src_dir = config['global']['src_dir']+'/'
    img_dir = config['global']['img_dir']+'/'
    cf.makedir('./'+img_dir,logger)
    logger.info('Starting generation of clean image(s).')
    reset_cln = False
    reset_cln = False
    if len(cln_param['line_ch']) == 0 or len(cln_param['line_ch']) != len(targets):
        if not interactive:
            logger.critical('The number of line channel ranges provided does not match the number of targets.')
            logger.info('Pixel sizes: {}'.format(cln_param['line_ch']))
            logger.info('Targets: {}'.format(targets))
            sys.exit(-1)
        reset_cln = True
        if len(cln_param['line_ch']) < len(targets):
            logger.warning('There are more target fields than channel ranges. Appending blank ranges.')
            while len(cln_param['line_ch']) < len(targets):
                cln_param['line_ch'].append('')
        elif len(cln_param['line_ch']) > len(targets):
            logger.warning('There are more channel ranges than target fields.')
            logger.info('Current channel ranges: {}'.format(cln_param['line_ch']))
            logger.warning('The channel range list will now be truncated to match the number of targets.')
            cln_param['line_ch'] = cln_param['line_ch'][:len(targets)]
    elif interactive:
        print('Current image channels set as:')
        for i in range(len(cln_param['line_ch'])):
            print('{0}: {1}'.format(targets[i],cln_param['line_ch'][i]))
        resp = str(raw_input('Do you want revise the channels that will be imaged (y/n): '))
        if resp.lower() in ['yes','ye','y']:
            reset_cln = True
    if reset_cln and interactive:
        print('For each target enter the channels you want to image in the following format:\nspwID:min_ch~max_ch')
        for i in range(len(targets)):
            print('Note: The continuum channels for this target were set to: {}'.format(contsub['linefree_ch'][i]))
            cln_param['line_ch'][i] = cf.uinput('Channels to image for {}: '.format(targets[i]), cln_param['line_ch'][i])
            logger.info('Setting image channels for {0} as: {1}.'.format(targets[i], cln_param['line_ch'][i]))
        logger.info('Updating config file to set channels to be imaged.')
        config_raw.set('clean','line_ch',cln_param['line_ch'])
        configfile = open(config_file,'w')
        config_raw.write(configfile)
        configfile.close()
    logger.info('Line emission channels set as: {}.'.format(cln_param['line_ch']))
    logger.info('For the targets: {}.'.format(targets))
    if numpy.any(cln_param['multiscale']):
        algorithm = 'multiscale'
        logger.info('Setting CLEAN algorithm to MS-CLEAN.')
        if not numpy.all(cln_param['multiscale']):
            logger.info('However, some targets will still use Hogbom CLEAN.')
        reset_cln = False
        if cln_param['beam_scales'] == []:
            reset_cln = True
            logger.warning('MS-CLEAN scales not set.')
        elif 0 not in cln_param['beam_scales']:
            logger.warning('MS-CLEAN scales do not include point sources. This is highly recommended.')
            if interactive:
                resp = str(raw_input('Do you want revise MS-CLEAN scales (y/n): '))
                if resp.lower() in ['yes','ye','y']:
                    reset_cln = True
            else:
                logger.info('Adding point source to MS-CLEAN scales.')
                cln_param['beam_scales'].append(0)
                reset_cln = True
        if reset_cln:
            if interactive:
                print('Current scales set to: {} beam diameters.'.format(cln_param['beam_scales']))
                cln_param['beam_scales'] = cf.uinput('Enter new scales: ', cln_param['beam_scales'])
            logger.info('Setting MS-CLEAN scales as {} beams.'.format(cln_param['beam_scales']))
            logger.info('Updating config file to set MS-CLEAN scales.')
            config_raw.set('clean','scales',cln_param['beam_scales'])
            configfile = open(config_file,'w')
            config_raw.write(configfile)
            configfile.close()
            reset_cln = False
        scales = cln_param['beam_scales']
    else:
        algorithm = 'hogbom'
        logger.info('Setting CLEAN algorithm to Hogbom.')
        scales = None
    for i in range(len(targets)):
        target = targets[i]
        field = fields[i]
        if numpy.all(cln_param['multiscale']):
            ms_clean = True
            algorithm = 'multiscale'
        elif type(cln_param['multiscale']) != type(True):
            ms_clean = cln_param['multiscale'][i]
            if ms_clean:
                algorithm = 'multiscale'
            else:
                algorithm = 'hogbom'
        else:
            ms_clean = False
            algorithm = 'hogbom'
        logger.info('Starting {} image.'.format(target))
        reset_cln = False
        ia.open(img_dir+target+'.dirty.image')
        rest_beam = ia.restoringbeam()
        ia.close()
        if rest_beam['minor']['unit'] not in cln_param['pix_size'][i]:
            logger.error('The pixel size and beam size have diffent units.')
            if ms_clean:
                logger.error('MS-CLEAN scales will likely be incorrect.')
            logger.info('Pixel size: {}'.format(cln_param['pix_size'][i]))
            logger.info('Beam size units: {}'.format(rest_beam['minor']['unit']))
        pix_size = cln_param['pix_size'][i]
        pix_size = float(pix_size[:pix_size.find(rest_beam['minor']['unit'])])
        if pix_size > 0.2*rest_beam['minor']['value']:
            logger.warning('There are fewer than 5 pixels across the beam minor axis. Consider decreasing the pixel size.')
            if interactive:
                print('Beam dimensions:')
                print('Major: {0:.2f} {1}'.format(rest_beam['major']['value'],rest_beam['major']['unit']))
                print('Minor: {0:.2f} {1}'.format(rest_beam['minor']['value'],rest_beam['minor']['unit']))
                print('Pixel size: {}'.format(cln_param['pix_size']))
                resp = str(raw_input('Do you want revise the pixel size (y/n): '))
                if resp.lower() in ['yes','ye','y']:
                    reset_cln = True
        if reset_cln and interactive:
            print('Enter the desired pixel size:')
            cln_param['pix_size'][i] = cf.uinput('Pixel size for {}: '.format(target), cln_param['pix_size'][i])
            logger.info('Setting pixel size for {0} as: {1}.'.format(target, cln_param['pix_size'][i]))
            resp = str(raw_input('Would you also like to revise the image size: '))
            if resp.lower() in ['yes','ye','y']:
                cln_param['im_size'][i] = cf.uinput('Image size for {}: '.format(target), cln_param['im_size'][i])
            logger.info('Setting image size for {0} as: {1}.'.format(target, cln_param['im_size'][i]))
            logger.info('Updating config file to set pixel (image) size.')
            config_raw.set('clean','pix_size',cln_param['pix_size'])
            config_raw.set('clean','im_size',cln_param['im_size'])
            configfile = open(config_file,'w')
            config_raw.write(configfile)
            configfile.close()
            reset_cln = False
        if cln_param['automask_sl'] == '':
            cln_param['automask_sl'] == 2.0
            logger.warning('Automasking sidelobe threshold not set. Using default value: {}'.format(cln_param['automask_sl']))
        if cln_param['automask_ns'] == '':
            cln_param['automask_ns'] == 4.25
            logger.warning('Automasking noise threshold not set. Using default value: {}'.format(cln_param['automask_ns']))
        if cln_param['automask_lns'] == '':
            cln_param['automask_lns'] == 1.5
            logger.warning('Automasking low noise threshold not set. Using default value: {}'.format(cln_param['automask_lns']))
        if cln_param['automask_mbf'] == '':
            cln_param['automask_mbf'] == 0.3
            logger.warning('Automasking minimum beam fraction not set. Using default value: {}'.format(cln_param['automask_mbf']))
        if cln_param['automask_neg'] == '':
            cln_param['automask_neg'] == 15.0
            logger.warning('Automasking negative threshold not set. Using default value: {}'.format(cln_param['automask_neg']))
        logger.info('Automasking parameters set as:')
        logger.info('sidelobethreshold = {}'.format(cln_param['automask_sl']))
        logger.info('noisethreshold = {}'.format(cln_param['automask_ns']))
        logger.info('lownoisethreshold = {}'.format(cln_param['automask_lns']))
        logger.info('minbeamfraction = {}'.format(cln_param['automask_mbf']))
        logger.info('negativethreshold = {}'.format(cln_param['automask_neg']))
        if ms_clean:
            pix_size = cln_param['pix_size'][i]
            pix_size = float(pix_size[:pix_size.find(rest_beam['minor']['unit'])])
            pix_per_beam = rest_beam['major']['value']/pix_size
            scales = cln_param['beam_scales']
            scales = list(numpy.array(numpy.array(scales)*pix_per_beam,dtype='int'))
            B_min = au.getBaselineLengths('{0}{1}.split.contsub'.format(src_dir,target), sort=True)[0][1]
            msmd.open('{0}{1}.split.contsub'.format(src_dir,target))
            spws = msmd.spwsforfield(field)
            f_min = None
            for spw in spws:
                if f_min == None or f_min > min(msmd.chanfreqs(spw=spw,unit='Hz')):
                    f_min = min(msmd.chanfreqs(spw=spw,unit='Hz'))
            msmd.close()
            max_scale = 180.*3600.*299792458./(1.2*numpy.pi*f_min*B_min)
            logger.info('The maximum recoverable scale for {0} is {1} arcsec.'.format(target,int(max_scale)))
            if 'arcsec' not in cln_param['pix_size'][i]:
                logger.warning('Pixel size not in arcsec. Maximum scale not checked.')
            else:
                pix_size = cln_param['pix_size'][i]
                pix_size = float(pix_size[:pix_size.find('arcsec')])
                if max(scales)*pix_size > max_scale:
                    logger.warning('Some MS-CLEAN scale(s) is (are) larger than largest recoverable angular scales.')
                    logger.info('Removing offending scales.')
                    scales = list(set(numpy.where(numpy.array(scales)*pix_size <= max_scale,scales,0)))
            logger.info('CLEANing with scales of {} pixels.'.format(scales))
        logger.info('CLEANing {0} to a threshold of {1} Jy.'.format(target,noises[i]*cln_param['thresh']))
        if cln_param['automask']:
            mask = 'auto-multithresh'
        else:
            mask = 'pb'
        gridder = 'wproject'
        if calib['mosaic']:
            for target_name in targets:
                inx = [j for j in range(len(calib['target_names'])) if target_name in calib['target_names'][j]]
                fields = numpy.array(calib['targets'],dtype='str')[inx]
            field = ','.join(fields)
            gridder = 'mosaic'
        command = "tclean(vis='{0}{1}'+'.split.contsub', field='{2}', spw='{3}', imagename='{4}{1}', cell='{5}', imsize=[{6},{6}], specmode='cube', outframe='bary', veltype='radio', restfreq='{7}', gridder='{8}', wprojplanes=-1, pblimit=0.1, normtype='flatnoise', deconvolver='{9}', scales={10}, restoringbeam='common', pbcor=True, weighting='briggs', robust={11}, niter=100000, gain=0.1, threshold='{12}Jy', usemask='{13}', phasecenter='{14}', sidelobethreshold={15}, noisethreshold={16}, lownoisethreshold={17}, minbeamfrac={18}, negativethreshold={19}, cyclefactor=2.0,interactive=False)".format(src_dir,target,field,cln_param['line_ch'][i],img_dir,cln_param['pix_size'][i],cln_param['im_size'][i],rest_freq,gridder,algorithm,scales,cln_param['robust'],noises[i]*cln_param['thresh'],mask,cln_param['phasecenter'],cln_param['automask_sl'],cln_param['automask_ns'],cln_param['automask_lns'],cln_param['automask_mbf'],cln_param['automask_neg'])
        logger.info('Executing command: '+command)
        exec(command)
        cf.check_casalog(config,config_raw,logger,casalog)
        logger.info('CLEANing finished. Image cube saved as {}.'.format(target+'.image'))
        ia.open(img_dir+target+'.dirty.image')
        coords = ia.coordsys()
        coord_chn = False
        if 'J2000' not in coords.referencecode()[0]:
            coord_chn = True
            logger.info('Coordinate system not J2000. Image will be regridded.')
            command = "imregrid(imagename='{0}{1}'+'.image', template='J2000', output='{0}{1}'+'.image.J2000', asvelocity=True, interpolation='linear', decimate=10, overwrite=True)".format(img_dir,target)
            logger.info('Executing command: '+command)
            exec(command)
            cf.check_casalog(config,config_raw,logger,casalog)
            logger.info('{} regridded in J2000 coordinates.'.format(target+'.image.J2000'))
            command = "imregrid(imagename='{0}{1}'+'.image.pbcor', template='J2000', output='{0}{1}'+'.image.pbcor.J2000', asvelocity=True, interpolation='linear', decimate=10, overwrite=True)".format(img_dir,target)
            logger.info('Executing command: '+command)
            exec(command)
            cf.check_casalog(config,config_raw,logger,casalog)
            logger.info('{} regridded in J2000 coordinates.'.format(target+'.image.pbcor.J2000'))
        coords.done()
        ia.close()
        fitsname = target+'_HI.fits'
        logger.info('Saving image cube as {}'.format(fitsname))
        if coord_chn:
            imagename = target+'.image.J2000'
        else:
            imagename = target+'.image'
        command = "exportfits(imagename='{0}{1}', fitsimage='{0}{2}', velocity=True,optical=False,overwrite=True,dropstokes=True,stokeslast=True,history=True,dropdeg=True)".format(img_dir,imagename,fitsname)
        logger.info('Executing command: '+command)
        exec(command)
        cf.check_casalog(config,config_raw,logger,casalog)
        fitsname = target+'_HI.pbcor.fits'
        logger.info('Saving primary beam corrected image cube as {}'.format(fitsname))
        if coord_chn:
            imagename = target+'.image.pbcor.J2000'
        else:
            imagename = target+'.image.pbcor'
        command = "exportfits(imagename='{0}{1}', fitsimage='{0}{2}', velocity=True,optical=False,overwrite=True,dropstokes=True,stokeslast=True,history=True,dropdeg=True)".format(img_dir,imagename,fitsname)
        logger.info('Executing command: '+command)
        exec(command)
        cf.check_casalog(config,config_raw,logger,casalog)
        coord_chn = False
    logger.info('Completed generation of clean image(s).')
def dirty_cont_image(config, config_raw, config_file, logger):
    """
    Generates a dirty image of each science target including the continuum emission.
    Checks that the pixel size and image size are set (will prompt user if in interactive mode).
    
    Input:
    config = The parameters read from the configuration file. (Ordered dictionary)
    config_raw = The instance of the parser.
    config_file = Path to configuration file. (String)
    """
    logger.info('Starting making dirty continuum image.')
    calib = config['calibration']
    rest_freq = config['global']['rest_freq']
    targets = calib['target_names'][:]
    fields = calib['targets'][:]
    for i in range(len(targets)):
        target = targets[i]
        if 'spw' in target:
            inx = target.index('.spw')
            target_name = target[:inx]
            if target_name in calib['target_names'][i - 1]:
                fields.insert(i, fields[i - 1])
    if calib['mosaic']:
        targets = list(set(calib['target_names']))
    cln_param = config['clean']
    src_dir = config['global']['src_dir'] + '/'
    img_dir = config['global']['img_dir'] + '/'
    cf.makedir('/.' + img_dir, logger)
    logger.info('Removing any existing dirty continuum images.')
    del_list = glob.glob(img_dir + '*cont.dirty*')
    for file_path in del_list:
        logger.info('Deleting: ' + file_path)
        shutil.rmtree(file_path)
    logger.info('Checking clean parameters for dirty image (inc. continuum).')
    reset_cln = False
    if (len(cln_param['pix_size'])
            == 0) or (len(cln_param['pix_size']) != len(targets)):
        if not interactive:
            logger.critical(
                'The number of pixel sizes provided does not match the number of targets.'
            )
            logger.info('Pixel sizes: {}'.format(cln_param['pix_size']))
            logger.info('Targets: {}'.format(targets))
            sys.exit(-1)
        reset_cln = True
        if len(cln_param['pix_size']) < len(targets):
            logger.warning(
                'There are more target fields than pixel sizes. Appending blanks.'
            )
            while len(cln_param['pix_size']) < len(targets):
                cln_param['pix_size'].append('')
        elif len(cln_param['pix_size']) > len(targets):
            logger.warning('There are more pixel sizes than target fields.')
            logger.info('Current pixel sizes: {}'.format(
                cln_param['pix_size']))
            logger.warning(
                'The pixel size list will now be truncated to match the number of targets.'
            )
            cln_param['pix_size'] = cln_param['pix_size'][:len(targets)]
    elif interactive:
        print('Current pixel sizes set as:')
        for i in range(len(cln_param['pix_size'])):
            print('{0}: {1}'.format(targets[i], cln_param['pix_size'][i]))
        resp = str(raw_input('Do you want revise the pixel sizes (y/n): '))
        if resp.lower() in ['yes', 'ye', 'y']:
            reset_cln = True
    if reset_cln and interactive:
        print('For each target enter the desired pixel size:')
        for i in range(len(targets)):
            cln_param['pix_size'][i] = cf.uinput(
                'Pixel size for {}: '.format(targets[i]),
                cln_param['pix_size'][i])
            logger.info('Setting pixel size for {0} as: {1}.'.format(
                targets[i], cln_param['pix_size'][i]))
        logger.info('Updating config file to set pixel sizes.')
        config_raw.set('clean', 'pix_size', cln_param['pix_size'])
        configfile = open(config_file, 'w')
        config_raw.write(configfile)
        configfile.close()
    logger.info('Pixel sizes set as: {}.'.format(cln_param['pix_size']))
    logger.info('For the targets: {}.'.format(targets))
    reset_cln = False
    if len(cln_param['im_size']) == 0 or len(
            cln_param['im_size']) != len(targets):
        if not interactive:
            logger.critical(
                'The number of image sizes provided does not match the number of targets.'
            )
            logger.info('Image sizes: {}'.format(cln_param['im_size']))
            logger.info('Targets: {}'.format(targets))
            sys.exit(-1)
        reset_cln = True
        if len(cln_param['im_size']) < len(targets):
            logger.warning(
                'There are more target fields than image sizes. Appending blanks.'
            )
            while len(cln_param['im_size']) < len(targets):
                cln_param['im_size'].append('')
        elif len(cln_param['im_size']) > len(targets):
            logger.warning('There are more image sizes than target fields.')
            logger.info('Current image sizes: {} pixels.'.format(
                cln_param['im_size']))
            logger.warning(
                'The image size list will now be truncated to match the number of targets.'
            )
            cln_param['im_size'] = cln_param['im_size'][:len(targets)]
    elif interactive:
        print('Current images sizes set as:')
        for i in range(len(cln_param['im_size'])):
            print('{0}: {1}'.format(targets[i], cln_param['im_size'][i]))
        resp = str(raw_input('Do you want revise the image sizes (y/n): '))
        if resp.lower() in ['yes', 'ye', 'y']:
            reset_cln = True
    if reset_cln and interactive:
        print('For each target enter the desired image size:')
        for i in range(len(targets)):
            print('Note: The pixel size for this target was set to: {}'.format(
                cln_param['pix_size'][i]))
            cln_param['im_size'][i] = cf.uinput(
                'Image size for {}: '.format(targets[i]),
                cln_param['im_size'][i])
            logger.info('Setting image size for {0} as: {1} x {2}.'.format(
                targets[i], cln_param['im_size'][i], cln_param['pix_size'][i]))
        logger.info('Updating config file to set image sizes.')
        config_raw.set('clean', 'im_size', cln_param['im_size'])
        configfile = open(config_file, 'w')
        config_raw.write(configfile)
        configfile.close()
    logger.info('Image sizes set as: {} pixels.'.format(cln_param['im_size']))
    logger.info('For the targets: {}.'.format(targets))
    for i in range(len(targets)):
        target = targets[i]
        field = fields[i]
        gridder = 'wproject'
        if calib['mosaic']:
            for target_name in targets:
                inx = [
                    j for j in range(len(calib['target_names']))
                    if target_name in calib['target_names'][j]
                ]
                fields = numpy.array(calib['targets'], dtype='str')[inx]
            field = ','.join(fields)
            gridder = 'mosaic'
        logger.info(
            'Making dirty image of {} (inc. continuum).'.format(target))
        command = "tclean(vis='{0}{1}.split', field='{2}', imagename='{3}{1}.cont.dirty', cell='{4}', imsize=[{5},{5}], specmode='cube', outframe='bary', veltype='radio', restfreq='{6}', gridder='{7}', wprojplanes=-1, pblimit=0.1, normtype='flatnoise', deconvolver='hogbom', weighting='briggs', robust={8}, niter=0, phasecenter='{9}', interactive=False)".format(
            src_dir, target, field, img_dir, cln_param['pix_size'][i],
            cln_param['im_size'][i], rest_freq, gridder, cln_param['robust'],
            cln_param['phasecenter'])
        logger.info('Executing command: ' + command)
        exec(command)
        cf.check_casalog(config, config_raw, logger, casalog)
    logger.info('Completed making dirty continuum image.')
def transform_data(msfile, config, config_raw, config_file, logger):
    """
    Allows the user to alter the data set by selection only specific observations, fields, and SPWs.
    
    Input:
    msfile = Path to the MS. (String)
    config = The parameters read from the configuration file. (Ordered dictionary)
    config_raw = The instance of the parser.
    config_file = Path to configuration file. (String)
    """
    logger.info('Starting data transform.')
    importdata = config['importdata']
    chanavg = False
    if not importdata['mstransform']:
        if interactive:
            print(
                'You may want to review the listobs summary of the imported data to decide if certain observations, SPWs, or fields should be removed.'
            )
            resp = ''
            while (resp.lower() not in [
                    'yes', 'ye', 'y'
            ]) and (resp.lower() not in ['no', 'n']):
                resp = str(
                    raw_input('Do you want to transform the data set (y/n): '))
            if resp.lower() in ['yes', 'ye', 'y']:
                importdata['mstransform'] = True
    if importdata['mstransform']:
        if interactive:
            print(
                'Select which observations, SPWs, and fields to keep in the MS.'
            )
            print('Blank strings mean all.')
            importdata['keep_obs'] = [
                cf.uinput('The following observations will be kept: ',
                          importdata['keep_obs'])
            ]
            importdata['keep_spws'] = [
                cf.uinput('The following SPWs will be kept: ',
                          importdata['keep_spws'])
            ]
            importdata['keep_fields'] = [
                cf.uinput('The following fields will be kept: ',
                          importdata['keep_fields'])
            ]
            resp = ''
            while (resp.lower() not in [
                    'yes', 'ye', 'y'
            ]) and (resp.lower() not in ['no', 'n']):
                resp = str(
                    raw_input(
                        'Do you want to perform channel averaging (y/n): '))
            if resp.lower() in ['yes', 'ye', 'y']:
                chanavg = True
                importdata['chanavg'] = int(
                    cf.uinput(
                        'Enter the number of channels to be averaged together: ',
                        importdata['chanavg']))
        command = "mstransform(vis='{0}', outputvis='{0}_1', field='{1}', spw='{2}', observation='{3}', datacolumn='data'".format(
            msfile, ','.join(importdata['keep_fields']),
            ','.join(importdata['keep_spws']),
            ','.join(importdata['keep_obs']))
        if config_raw.has_option('importdata', 'hanning'):
            if config['importdata']['hanning']:
                command += ', hanning=True'
        if config_raw.has_option('importdata', 'chanavg') or chanavg:
            if importdata['chanavg'] > 1:
                command += ', chanaverage=True, chanbin=' + str(
                    importdata['chanavg'])
        command += ')'
        logger.info('Executing command: ' + command)
        exec(command)
        cf.check_casalog(config, config_raw, logger, casalog)
        logger.info(
            'Updating config file ({0}) to set mstransform values.'.format(
                config_file))
        config_raw.set('importdata', 'keep_obs', importdata['keep_obs'])
        config_raw.set('importdata', 'keep_spws', importdata['keep_spws'])
        config_raw.set('importdata', 'keep_fields', importdata['keep_fields'])
        if config_raw.has_option('importdata', 'chanavg') or chanavg:
            config_raw.set('importdata', 'chanavg', importdata['chanavg'])
        configfile = open(config_file, 'w')
        config_raw.write(configfile)
        configfile.close()
        cf.rmdir(msfile + '.flagversions', logger)
        cf.makedir(msfile + '.flagversions', logger)
        cf.rmdir(msfile, logger)
        cf.mvdir(msfile + '_1', msfile, logger)
        logger.info('Completed data transformation.')
        listobs_sum(msfile, config, config_raw, logger)
    else:
        logger.info('No transformation made.')
def moment0(config,config_raw,config_file,logger):
    """
    Generates a moment zero map of each science target.
    
    Input:
    config = The parameters read from the configuration file. (Ordered dictionary)
    config_raw = The instance of the parser.
    config_file = Path to configuration file. (String)
    """
    noises = noise_est(config,logger)
    cln_param = config['clean']
    calib = config['calibration']
    if config_raw.has_option('clean','noise'):
        noises = cln_param['noise'][:]
        logger.info('Noise level(s) set manually as {0} Jy.'.format(noises))
    moment = config['moment']
    thresh = moment['mom_thresh']
    chans = moment['mom_chans']
    targets = config['calibration']['target_names']
    if calib['mosaic']:
        targets = list(set(targets))
    img_dir = config['global']['img_dir']+'/'
    mom_dir = config['global']['mom_dir']+'/'
    cf.makedir('./'+mom_dir,logger)
    
    change_made = False
    if len(chans) == 0 or len(chans) != len(targets):
        if len(chans) < len(targets):
            logger.warning('There are more target fields than channel ranges for moments.')
            while len(chans) < len(targets):
                chans.append('')
        elif len(chans) > len(targets):
            logger.warning('There are more moment channel ranges than target fields.')
            logger.info('Current channel ranges: {}'.format(chans))
            logger.warning('The channel range list will now be truncated to match the number of targets.')
            chans = chans[:len(targets)]
        change_made = True
    if interactive:
        print('Current moment channel ranges set as:')
        print(chans)
        print('For the targets:')
        print(targets)
        resp = ''
        while (resp.lower() not in ['yes','ye','y']) and (resp.lower() not in ['no','n']) :
            resp = str(raw_input('Do you want to revise these channel ranges (y/n): '))
        if resp.lower() in ['yes','ye','y']:
            change_made = True
            print('Please specify the channel ranges in the format: chan1~chan2.')
            for i in range(len(chans)):
                chans[i] = cf.uinput('Enter channel range for target {}: '.format(targets[i]), chans[i])
        else:
            pass
    if change_made:
        logger.info('Updating config file to set new moment channel ranges.')
        config_raw.set('moment','mom_chans',chans)
        configfile = open(config_file,'w')
        config_raw.write(configfile)
        configfile.close()
        
    logger.info('Starting generation of moment map(s).')
    
    J2000 = False
    img_list = glob.glob(img_dir+'*.image.J2000')
    if len(img_list) > 0:
        J2000 = True
    for i in range(len(targets)):
        if J2000:
            imagename = targets[i]+'.image.J2000'
        else:
            imagename = targets[i]+'.image'
        command = "immoments(imagename='{0}{1}',includepix=[{2},{3}],chans='{4}',outfile='{5}{6}.mom0')".format(img_dir,imagename,thresh*noises[i],thresh*1E6*noises[i],chans[i],mom_dir,targets[i])
        logger.info('Executing command: '+command)
        exec(command)
        cf.check_casalog(config,config_raw,logger,casalog)
        command = "exportfits(imagename='{0}{1}.mom0', fitsimage='{0}{1}.mom0.fits',overwrite=True,dropstokes=True,stokeslast=True,history=True,dropdeg=True)".format(mom_dir,targets[i])
        logger.info('Executing command: '+command)
        exec(command)
        cf.check_casalog(config,config_raw,logger,casalog)
    logger.info('Completed generation of moment map(s).')