Пример #1
0
def flagcaltar_ms(src_dir, msname, ATCA_band, pri, sec, tar):
    applycal(
        vis=msname,
        gaintable=[
            f"{src_dir}/cal_tables/cal_{pri}_{ATCA_band}.B1",
            f"{src_dir}/cal_tables/cal_{pri}_{ATCA_band}.F0",
        ],
        gainfield=[pri, pri, sec],
        field=tar,
        parang=True,
        flagbackup=False,
    )
    flagdata(
        vis=msname,
        mode="rflag",
        field=tar,
        datacolumn="corrected",
        action="apply",
        display="report",
        correlation="ABS_ALL",
        timedevscale=3.0,
        freqdevscale=3.0,
        winsize=3,
        combinescans=True,
        ntime="9999999min",
        extendflags=False,
        flagbackup=False,
    )
    return
Пример #2
0
def kc_cal(msin, model_cl):
    """Get gain and delay calibration solutions

    :param msin: Visibility dataset in measurement set format path
    :type msin: str
    :param model_cl: Point source model path
    :type model_cl: str

    :return: Calibration solutions tables
    :rtype: list
    """
    # Fill the model column
    ft(msin, complist=model_cl, usescratch=True)

    kc = calname(msin, 'K')  # Delays
    gc = calname(msin, 'G')  # Gains

    gaincal(vis=msin,
            caltable=kc,
            gaintype='K',
            solint='inf',
            refant='11',
            minsnr=1)
    # Ensure reference antenna exists and isn't faulty
    gaincal(vis=msin,
            caltable=gc,
            gaintype='G',
            solint='inf',
            refant='11',
            minsnr=1,
            calmode='ap',
            gaintable=kc)
    applycal(msin, gaintable=[kc, gc])
    return [kc, gc]
Пример #3
0
def apply_calibration(project: project.Project):
    """Applies the current calibration by using the tables written in the callib.
    """
    casatasks.applycal(vis=str(project.msfile),
                       docallib=True,
                       callib=str(project.caldir / "cal_library.txt"),
                       parang=True)
Пример #4
0
def bandpass_cal(msin):
    """Bandpass calbration

    :param msin: Visibility dataset in measurement set format path
    :type msin: str

    :return: Calibration solutions table
    :type: str
    """
    bc = calname(msin, 'B')
    bandpass(vis=msin, minsnr=1, solnorm=False, bandtype='B', caltable=bc)
    applycal(msin, gaintable=[bc])
    return bc
Пример #5
0
def applycal(msfile,
             gaintables,
             gainfield=None,
             targetfield=None,
             interp=None,
             spw=None,
             spwmap=None):
    """    
    
    Apply CASA calibration using calibration tables
    
    Example Usage: 
    applycal(msfile0, gaintables, targetfield=targetfield,
         gainfield=['', '', '', '', '', '', '', ''],
         interp=['linear', 'linear', 'linear', 'linear', 'linear,linearflag', 'linear', 'linear', 'linear'])
    
    """
    if not gainfield:
        gainfield = ['' for _ in range(len(gaintables))]

    if not interp:
        interp = ['' for _ in range(len(gaintables))]

    if not targetfield:
        targetfield = '1'

    if not spw:
        spw = ''
    print(spw)

    if not spwmap:
        spwmap = []

    tasks.applycal(vis=msfile,
                   gaintable=gaintables,
                   gainfield=gainfield,
                   field=targetfield,
                   interp=interp,
                   calwt=[False],
                   spw=spw,
                   spwmap=spwmap)
Пример #6
0
def self_calibration_from_final_pcal_model(project: project.Project,
                                           src_model: Path):
    raise NotImplementedError
    # Assumes the model is a CASA image
    for a_cal in project.phase_calibrators:
        calsc = project.caldir / f"{project.project_name.lower()}.{a_cal}.sc_final"
        # TODO: check if ft is in casatools or casatasks
        casatools.ft(vis=str(project.msfile),
                     field=a_cal,
                     model=str(src_model),
                     usescratch=True)
        casatasks.gaincal(vis=str(project.msfile),
                          caltable=str(calsc),
                          field=a_cal,
                          solint='3min',
                          refant=','.join(project.refants),
                          gaintype='G',
                          calmode='ap',
                          interp=['nearest'],
                          parang=True)
        casatasks.applycal()
Пример #7
0
def applycal_ms(src_dir, msname, ATCA_band, pri, sec, tar):
    applycal(
        vis=msname,
        gaintable=[
            f"{src_dir}/cal_tables/cal_{pri}_{ATCA_band}.B1",
            f"{src_dir}/cal_tables/cal_{pri}_{ATCA_band}.F0",
        ],
        gainfield=[pri, pri, pri],
        field=f"{pri}",
        parang=True,
        flagbackup=False,
    )
    applycal(
        vis=msname,
        gaintable=[
            f"{src_dir}/cal_tables/cal_{pri}_{ATCA_band}.B1",
            f"{src_dir}/cal_tables/cal_{pri}_{ATCA_band}.F0",
        ],
        gainfield=[pri, pri, sec],
        field=f"{sec},{tar}",
        parang=True,
        flagbackup=False,
    )
    return
Пример #8
0
def run_all_uvstats(myvis,
                    out_path,
                    uv_threshold=3,
                    uv_nsigma=3,
                    try_phase_selfcal=True,
                    cleanup_calsplit=True,
                    cleanup_phaseselfcal=True,
                    remake_split=True):

    if not os.path.isdir(out_path):
        os.mkdir(out_path)

    from casatasks import split, gaincal, applycal
    from casaplotms import plotms

    # from taskinit import msmdtool, casalog
    # from taskinit import msmdtool, casalog

    from casatools import ms

    myms = ms()

    # msmd = msmdtool()
    # get metadata

    myms.open(myvis)
    mymsmd = myms.metadata()

    # mymsmd.open(myvis)
    cal_fields = np.unique(mymsmd.fieldsforintent('CALIBRATE*'))
    field_names = mymsmd.namesforfields(cal_fields)
    myms.close()

    # split calibrator visibilities
    field_str = ','.join([str(f) for f in cal_fields])

    output_cal_ms = out_path + '/cal_fields.ms'

    if os.path.exists(output_cal_ms) and remake_split:
        os.system('rm -r {0}'.format(output_cal_ms))

    if not os.path.exists(output_cal_ms):
        split(vis=myvis,
              field=field_str,
              keepflags=True,
              timebin='0s',
              outputvis=output_cal_ms)

    # There are the flux cals which have built in models in CASA.
    skip_fields = ['3C286', '3C48', '3C147', '3C138']

    gaincal_tables = []

    for field_name in field_names:

        if np.any([field_name in skip1 for skip1 in skip_fields]):
            continue

        plotms_outfile = out_path + '/plotms_amp_uvwave_field_{0}.txt'.format(
            field_name)
        casalog.post(
            message='Exporting from plotms: {0}'.format(plotms_outfile),
            origin='run_all_uvstats')

        if not os.path.exists(plotms_outfile):
            plotms(vis=out_path + '/cal_fields.ms',
                   field=field_name,
                   xaxis='UVwave',
                   yaxis='Amp',
                   ydatacolumn='data',
                   averagedata=True,
                   scalar=False,
                   avgchannel='4096',
                   avgtime='1000',
                   avgscan=False,
                   correlation='RR,LL',
                   plotfile=plotms_outfile,
                   showgui=False,
                   overwrite=True)
        else:
            casalog.post(message='File {0} already exists. Skipping'.format(
                plotms_outfile),
                         origin='run_all_uvstats')

        infile = out_path + '/plotms_amp_uvwave_field_{0}.txt'.format(
            field_name)
        casalog.post(message='Analyzing UV stats for {0}'.format(infile),
                     origin='run_all_uvstats')

        # Read in txt from plotms
        dat, median_flux = get_uvdata(infile)
        # n_scans = len(np.unique(dat['scan']))
        binned_dat = bin_uvdata(dat)
        binned_dat_perscan = bin_uvdata_perscan(dat)
        if binned_dat.shape[1] == 0:
            continue
        if binned_dat_perscan.shape[1] == 0:
            continue
        plot_uvdata_perscan(binned_dat_perscan,
                            binned_dat,
                            infile,
                            bin_type='combined')

        # try phase-only selfcal
        if try_phase_selfcal:

            gaincal_table = out_path + '/cal_field_{0}.g'.format(field_name)

            try:
                gaincal(vis=output_cal_ms,
                        caltable=gaincal_table,
                        field=field_name,
                        solint='int',
                        refant='',
                        calmode='p')
                applycal(vis=output_cal_ms,
                         gaintable=gaincal_table,
                         field=field_name,
                         calwt=False)

                gaincal_tables.append(gaincal_table)

                plotms_outfile = out_path + '/plotms_amp_uvwave_cal_field_{0}.txt'.format(
                    field_name)
                casalog.post(message='Exporting from plotms: {0}'.format(
                    plotms_outfile),
                             origin='run_all_uvstats')

                if not os.path.exists(plotms_outfile):

                    plotms(vis=output_cal_ms,
                           field=field_name,
                           xaxis='UVwave',
                           yaxis='Amp',
                           ydatacolumn='corrected',
                           averagedata=True,
                           scalar=False,
                           avgchannel='4096',
                           avgtime='1000',
                           avgscan=False,
                           correlation='RR,LL',
                           plotfile=plotms_outfile,
                           showgui=False,
                           overwrite=True)

                else:
                    casalog.post(
                        message='File {0} already exists. Skipping'.format(
                            plotms_outfile),
                        origin='run_all_uvstats')

                infile = out_path + '/plotms_amp_uvwave_cal_field_{0}.txt'.format(
                    field_name)
                casalog.post(
                    message='Analyzing UV stats for {0}'.format(infile),
                    origin='run_all_uvstats')

                dat, median_flux = get_uvdata(infile)
                # n_scans = len(np.unique(dat['scan']))
                binned_dat = bin_uvdata(dat)
                binned_dat_perscan = bin_uvdata_perscan(dat)
                if binned_dat.shape[1] == 0:
                    continue
                if binned_dat_perscan.shape[1] == 0:
                    continue
                plot_uvdata_perscan(binned_dat_perscan,
                                    binned_dat,
                                    infile,
                                    bin_type='combined')

            except:
                casalog.post(
                    message='Problem calibrating field {0}'.format(field_name),
                    origin='run_all_uvstats')

    # Delete calibrator split
    if cleanup_calsplit:
        os.system("rm -r {}".format(output_cal_ms))
        os.system("rm -r {}.flagversions".format(output_cal_ms))

    # Delete gaincal tables
    if cleanup_phaseselfcal:
        for gaincal_table in gaincal_tables:
            os.system("rm -r {}".format(gaincal_table))
Пример #9
0
def flagcal(msfile, params, niters=1, flagger='default', interactive=False):
    '''
    This function takes an initially flagged msfile and goes through the flagging and calibration loops. It does delaycal, bandpass and a amplitude and phase cals. It then flags the data and then continues to the calibration cycle. The loops continue till niters end or in the interactive mode when the user is satisfied. The calibration in then applied to the source and it is mildly flagged using Rflag and splitted in a seperate msfile. 
    '''
    
    fcals = ','.join(fluxcal) # joining the fluxcals in a casa readable format
     
    
    # Main flagcal loops begin
    
    flagcal_fin = 'n' # a flag to denote finished flagging
    loop = 1 # Keeping a track of number of iterations 
    while flagcal_fin == 'n':
        # Beginning with an empty gaintable list, which will be succesively appended after every calibration.  
        gaintables = []
        params['calibration'].update({'gaintables': gaintables})
        prms.write(params, 'parameters.yaml') # writes the gaintables column in the parameters file. 
        cts.setjy(msfile, field=fcals, scalebychan=True, standard='Perley-Butler 2017', listmodels=False, usescratch=False)
    
        clb.delaycal(msfile, params, field=fcals)
        #append the caltable and save the params file
        params['calibration']['gaintables'].append(params['calibration']['delaytable'])
        prms.write(params, 'parameters.yaml')
        if interactive:
            caltable = params['calibration']['delaytable']
            subprocess.run('casaplotms vis={} field={}'.format(caltable, fcals), shell=True, check=True) 
            antflag = input("Do you want to flag any antenna(s) ? [y/n] \n If yes, append the bad antennas in the params file now.")
            if antflag == 'y':
                flg.badantflag(msfile, params)
            else:
                print('No flagging after delaycal.') 

        else:
            None

        clb.bpasscal(msfile, params, field=fcals) # Using fluxcals for bandpass calibration
        params['calibration']['gaintables'].append(params['calibration']['bpasstable'])
        prms.write(params, 'parameters.yaml')
             
        # Joining all the calibrators and doing amplitutde and phase calibration
        phasecal = params['general']['phasecal']
        print('Phasecal is ', phasecal)
        allcals = fluxcal + [phasecal]

        #for i in allcals:
        #    clb.apcal(msfile, params, field=i)
        
        allcals2 = ','.join(allcals)  
        clb.apcal(msfile, params, field=allcals2)

        # Adding the amplitude and phase calibration tables in gaintables
        params['calibration']['gaintables'].append(params['calibration']['apgaintable'])
        prms.write(params, 'parameters.yaml')
        
        
        uvran = params['general']['uvran']
        
        # GETJY
        print('Setting the absolute fluxscale for ', phasecal)
        fluxtbl = params['calibration']['fluxscaletable']
        
        phasecal_flux = cts.fluxscale(msfile, caltable=params['calibration']['apgaintable'], fluxtable=fluxtbl, reference=fcals, transfer=phasecal, incremental=False, append=False)
        print('The flux density of {}'.format(phasecal)+'is',phasecal_flux['1']['0']['fluxd'][0], '+/-', phasecal_flux['1']['0']['fluxdErr'][0] )
        #Replace the apgaintable with fluxscale table
        params['calibration']['gaintables'].remove(params['calibration']['apgaintable'])
        params['calibration']['gaintables'].append(fluxtbl)
        prms.write(params, 'parameters.yaml')
        subprocess.run('rm -r {}'.format(params['calibration']['apgaintable']), shell=True, check=True)
        
        # Applying the calibrations on flux cal
        for i in fluxcal:
            print('Applying the calibration table to ', i)
            
            cts.applycal(msfile, field=i, spw=spw, gaintable=gaintables, gainfield=['','',i], uvrange=uvran, interp=['','','linear'], calwt=[False], parang=False)
       
        # Apply the calibration on phase cal
        cts.applycal(msfile, field=phasecal, uvrange=uvran, gaintable=gaintables, gainfield=['','',phasecal], interp=['','','linear'], calwt=[False], parang=False)


        # Flagging after calibration
        def clip_est(fluxscale, nsigma, loop, beta):
            return [fluxscale - nsigma/loop**beta, fluxscale + nsigma/loop**beta]
        
        fluxscale_list = [15, 22.5, 3.3]
        uplims_list = [20, 20, 20] 
        beta=[0.5, 0.6, 0.6]
        tcut_list = [6, 6, 10]
        fcut_list = [6, 6, 10]
        if flagger == 'default':
            for j,i in enumerate(allcals):
                flg.clipper(msfile, params, field=i, cliplevel=clip_est(fluxscale_list[j], uplims_list[j], loop, beta[j]), instance='postcal')
                flg.tfcropper(msfile, params, field=i, tcut=tcut_list[j], fcut=fcut_list[j], instance='postcal')
                flg.extend(msfile, params, field=i, grow=80, instance='postcal')
                print('Flagged', i, 'postcalibration.')
            # Flag the phasecal using rflag
            flg.rflagger(msfile, params, field=phasecal, tcut=10, fcut=10, instance='postcal')
            flg.extend(msfile, params, field=phasecal, grow=80, instance='postcal')

        else:
            print('No flagging.')

        if interactive:
            subprocess.run('casaplotms vis={} field={}'.format(msfile, fluxcal[0]), shell=True, check=True)
            flagcal_fin = input('Are you satisfied with the calibration?[y/n] ')
            # Remove the old cal tables before continuing 
            for i in gaintables:
                subprocess.run('rm -r {}'.format(i), shell=True, check=True)
            
            continue
        else:
            print('Flagcal running in automode.')
            niters = niters - 1
            loop = loop + 1

            if niters < 1:
                print('Flagcal loops finished.')
                break
            else:
                # Remove all the old cal tables before continuing. 
                print('Clearing the corrected column and fluxcal model...')
                cts.clearcal(msfile) # Removes the corrected datacolumn
                cts.delmod(msfile) # Removes the setjy model
                
                print('Clearing all the gaintables...')
                for i in gaintables:
                    subprocess.run('rm -r {}'.format(i), shell=True, check=True)
                
                continue

    else:
        print('Calibration of flux and phase calibrators done.')

    # apply the calibrations on the target
    target = params['general']['target']
    print('Applying the calibration tables to the target...') 
    cts.applycal(msfile, field=target, uvrange=uvran, gaintable=gaintables, gainfield=['','',phasecal], interp=['','','linear'], calwt=[False], parang=False)

    
    # rflag the data
    print('Mildly Rflagging the target at cutoff of 10 sigma...')
    flg.rflagger(msfile, params, field=target, tcut=10, fcut=10, instance='postcal')
    flg.extend(msfile, params, field=target, grow=80, instance='postcal')

    # split the calibrated target data
    out_cal_file = params['general']['targetcalfile']
    
    print('Splitting the target...')
    cts.mstransform(msfile, field=target, spw=spw, chanaverage=False, datacolumn='corrected', outputvis=out_cal_file)
    
    return print('Flagcal script done.')
Пример #10
0
def imagecal(targetcalfile, params, nloops=1, ploops=5, aploops=2, flagger='default', interactive=False):
    
    '''
    This function takes in a calibrated target file (usually the channel averaged file) and goes through "niters" of imagecal loops. A imagecal loop is defined as first making a image using imgr.tcleaner. Then "ploops" of phase-only self-cal and "aploops" of a&p selfcal. Then the continuum image is subtracted from the UV data and the residuals are flagged. After having gone through all the "niters" loop it spits out a final continuum image.
    '''

    imaging_params = params['imagecal']
    outimage = imaging_params['outimage']
    target = params['general']['target']
    threshold_range = imaging_params['threshold_range']
    threshold_final = imaging_params['threshold_final']
    solints = imaging_params['solints']
    niter_range = imaging_params['niter_range']  
    #temp_dir = params['general']['temp']
    
    # Preparing the ranges of different parameters for the loops
    solint_range = np.linspace(solints[0], solints[1], ploops)
    solint_range = [str(i)+'min' for i in solint_range]
    threshold_range = np.linspace(threshold_range[0], threshold_range[1], ploops)
    threshold_range = [str(i)+'mJy' for i in threshold_range]
    
    niter_range = np.linspace(niter_range[0], niter_range[1], ploops)
    niter_range = [int(i) for i in niter_range]

    while nloops >= 1:
        #subprocess.run('rm -r {}'.format(temp_dir), shell=True, check=True) # Clearing the temp directory
        #subprocess.run('mkdir {}'.format(temp_dir), shell=True, check=True) 
        ploop_index = 1 + np.arange(ploops) #This gives the index to the cont image and cal files created later
        sc_p_msfile = targetcalfile # Initially begin with the avspc file, and then change this file name to the running self-cal file
        for pindex in ploop_index: # Run all the ploops
            print('Self-cal phase-only loop', pindex)
            imgr.tcleaner(sc_p_msfile, params, threshold=threshold_range[pindex - 1], niter=niter_range[pindex - 1], outimage='../RGG_5_sc_p.'+str(pindex), interactive=interactive) 
            clb.selfcal(sc_p_msfile, params, mode='p', in_gaintable=[], out_gaintable='sc_p.gcal.'+str(pindex), solint=solint_range[pindex - 1], solnorm = False)
            gaintable = ['sc_p.gcal.'+str(pindex)] # Change the gaintable to the latest
            cts.applycal(sc_p_msfile, gaintable=gaintable, field='', gainfield='', applymode='calonly', interp=['linear'], calwt=False, parang=False)
            cts.mstransform(sc_p_msfile, field='0', spw='0', datacolumn='corrected', outputvis='sc_p_'+str(pindex)+'.ms')
            sc_p_msfile = 'sc_p_'+str(pindex)+'.ms' 
        
        aploop_index = 1 + np.arange(aploops) #This gives the index to the cont image and cal files created later
        sc_ap_msfile = sc_p_msfile # Initially begin with the avspc file, and then change this file name to the running self-cal file
        niter_ap = niter_range[-1] # The last object in pcal niters
        threshold_ap = threshold_range[-1]
        solint_ap = solint_range[-1]
        for apindex in aploop_index: # Run all the aploops
            print('Self-cal a&p loop', apindex)
            imgr.tcleaner(sc_ap_msfile, params, threshold=threshold_ap, niter=niter_ap, outimage='../RGG5_sc_ap.'+str(apindex), interactive=interactive)
            clb.selfcal(sc_ap_msfile, params, mode='a&p', in_gaintable=[], out_gaintable='sc_ap.gcal.'+str(apindex), solint=solint_ap, solnorm=True)
            gaintable = ['sc_ap.gcal.'+str(apindex)] # Change the gaintable to the latest
            cts.applycal(sc_ap_msfile, gaintable=gaintable, field='', gainfield='', applymode='calonly', interp=['linear'], calwt=False, parang=False)
            cts.mstransform(sc_ap_msfile, field='0', spw='0', datacolumn='corrected', outputvis='sc_ap_'+str(apindex)+'.ms')
            sc_ap_msfile = 'sc_ap_'+str(apindex)+'.ms'

        
        # Add some r-flagging on the residuals and then continue the loops.
        
        nloops = nloops - 1 
    else:
        print('Self-cal loops over.')

    print('Making a final continuum  image...') 
    
    imaging_params = params['imagecal']
    outimage = imaging_params['outimage']
    target = params['general']['target']
    imsize = imaging_params['imsize']
    cell = imaging_params['cell']
    robust = imaging_params['robust'] 
    weighting = imaging_params['weighting']
    uvran = imaging_params['uvran']
    uvtaper = imaging_params['uvtaper']
    nterms = imaging_params['nterms']
    niter = 5000 #niter_ap
    threshold = threshold_final    
    wprojplanes = imaging_params['wprojplanes']
    scales = imaging_params['scales']
    
    cts.tclean(sc_ap_msfile, imagename=outimage+'_final', field=target, spw='0', imsize=imsize, cell=cell, robust=robust, weighting=weighting, uvrange=uvran, uvtaper=uvtaper, 
            specmode='mfs',	nterms=nterms, niter=niter, usemask='auto-multithresh', minbeamfrac=0.1, sidelobethreshold = 1.5,
	    smallscalebias=0.6, threshold= threshold, aterm =True, pblimit=-1,
	    deconvolver='mtmfs', gridder='wproject', wprojplanes=wprojplanes, scales=scales,wbawp=False,
	    restoration = True, savemodel='modelcolumn', cyclefactor = 0.5, parallel=False,
       	    interactive=False)


    print('Imaging and self-calibration done.')

    return gaintable 
Пример #11
0
def slefcal_ms(src_dir, imagems, imagename, ATCA_band, n_spw):
    print(
        "+ + + + + + + + + + + + + + + + +\n+  Self Cal Round 1  +\n+ + + + + + + + + + + + + + + + +"
    )
    mode = "mfs"
    nterms = 2
    niter = 3000
    antenna = "0~6,0~6"
    n_spw = n_spw
    if ATCA_band == "L":
        imsize = 2250
        solint = "60s"
        minsnr = 3.0
        cell = "1arcsec"
        minblperant = 3
    if ATCA_band == "C":
        imsize = 2250
        solint = "60s"
        minsnr = 3.0
        minblperant = 3
        cell = "0.5arcsec"
    if ATCA_band == "X":
        imsize = 1152
        solint = "60s"
        minsnr = 3.0
        minblperant = 3
        cell = "0.2arcsec"
    uvrange = ""
    stokes = "I"
    weighting = "briggs"
    robust = 0.5
    interactive = False
    gain = 0.01
    threshold = "5e-4Jy"
    # if os.path.exists(f"{src_dir}/cal_tables/pcal1_{imagename}"):
    rmtables(f"{src_dir}/cal_tables/pcal1_{imagename}")
    gaincal(
        vis=imagems,
        caltable=f"{src_dir}/cal_tables/pcal1_{imagename}",
        combine="scan,spw",
        spwmap=[0] * n_spw,
        gaintype="G",
        calmode="p",
        solint=solint,
        minsnr=minsnr,
        minblperant=minblperant,
    )
    applycal(
        vis=imagems,
        gaintable=f"{src_dir}/cal_tables/pcal1_{imagename}",
        spwmap=[0] * n_spw,
        parang=True,
        applymode="calonly",
        flagbackup=False,
    )
    flagmanager(vis=imagems, mode="save", versionname="post self1")

    for i in range(0, n_spw):
        spw = str(i)
        # if os.path.exists(f"{src_dir}/casa_files/{imagename}_{spw}_self1*"):
        os.system(
            f"rm -r {src_dir}/casa_files/{imagename}_{spw}_self1*"
        )
        print("Cleaning on band: " + str(spw))
        tclean(
            vis=imagems,
            imagename=f"{src_dir}/casa_files/{imagename}_{spw}_self1",
            selectdata=True,
            mask=f"{src_dir}/casa_files/{imagename}_mfs.mask",
            spw=spw,
            startmodel=f"{src_dir}/casa_files/{imagename}_{spw}_preself.model",
            gain=gain,
            specmode=mode,
            nterms=nterms,
            niter=niter,
            threshold=threshold,
            imsize=imsize,
            cell=cell,
            stokes=stokes,
            weighting=weighting,
            robust=robust,
            antenna=antenna,
            interactive=interactive,
            savemodel="modelcolumn",
            pbcor=False,
            uvrange=uvrange,
        )
        tclean(
            vis=imagems,
            imagename=f"{src_dir}/casa_files/{imagename}_{spw}_self1",
            selectdata=True,
            mask="",
            spw=spw,
            gain=gain,
            specmode=mode,
            nterms=nterms,
            niter=0,
            threshold=threshold,
            imsize=imsize,
            cell=cell,
            stokes=stokes,
            weighting=weighting,
            robust=robust,
            antenna=antenna,
            interactive=interactive,
            pbcor=False,
            savemodel="modelcolumn",
            calcres=False,
            calcpsf=False,
            uvrange=uvrange,
        )

    threshold = "5e-5Jy"
    # if os.path.exists(f"{src_dir}/cal_tables/pcal2_{imagename}"):
    rmtables(f"{src_dir}/cal_tables/pcal2_{imagename}")
    print(
        "+ + + + + + + + + + + + + + + + +\n+  Self Cal Round 2  +\n+ + + + + + + + + + + + + + + + +"
    )

    gaincal(
        vis=imagems,
        caltable=f"{src_dir}/cal_tables/pcal2_{imagename}",
        gaintable=f"{src_dir}/cal_tables/pcal1_{imagename}",
        combine="scan,spw",
        spwmap=[0] * n_spw,
        gaintype="G",
        calmode="p",
        solint=solint,
        minsnr=minsnr,
        minblperant=minblperant,
    )
    applycal(
        vis=imagems,
        gaintable=[
            f"{src_dir}/cal_tables/pcal1_{imagename}",
            f"{src_dir}/cal_tables/pcal2_{imagename}",
        ],
        spwmap=[[0] * n_spw, [0] * n_spw],
        parang=True,
        applymode="calonly",
        flagbackup=False,
    )
    flagmanager(vis=imagems, mode="save", versionname="post self2")
    for i in range(0, n_spw):
        spw = str(i)
        # if os.path.exists(f"{src_dir}/casa_files/{imagename}_{spw}_self2*"):
        os.system(f"rm -r {src_dir}/casa_files/{imagename}_{spw}_self2*")
        print("Cleaning on band: " + str(spw))
        tclean(
            vis=imagems,
            imagename=f"{src_dir}/casa_files/{imagename}_{spw}_self2",
            selectdata=True,
            mask=f"{src_dir}/casa_files/{imagename}_mfs.mask",
            spw=spw,
            startmodel=f"{src_dir}/casa_files/{imagename}_{spw}_self1.model",
            gain=gain,
            specmode=mode,
            nterms=nterms,
            niter=niter,
            threshold=threshold,
            imsize=imsize,
            cell=cell,
            stokes=stokes,
            weighting=weighting,
            robust=robust,
            antenna=antenna,
            interactive=interactive,
            savemodel="modelcolumn",
            pbcor=False,
            uvrange=uvrange,
        )
        tclean(
            vis=imagems,
            imagename=f"{src_dir}/casa_files/{imagename}_{spw}_self2",
            selectdata=True,
            mask="",
            spw=spw,
            gain=gain,
            specmode=mode,
            nterms=nterms,
            niter=0,
            threshold=threshold,
            imsize=imsize,
            cell=cell,
            stokes=stokes,
            weighting=weighting,
            robust=robust,
            antenna=antenna,
            interactive=interactive,
            pbcor=False,
            savemodel="modelcolumn",
            calcres=False,
            calcpsf=False,
            uvrange=uvrange,
        )

    threshold = "5e-6Jy"
    print(
        "+ + + + + + + + + + + + + + + + +\n+  Self Cal Round 3  +\n+ + + + + + + + + + + + + + + + +"
    )

    rmtables(f"{src_dir}/cal_tables/pcal3_{imagename}")
    gaincal(
        vis=imagems,
        caltable=f"{src_dir}/cal_tables/pcal3_{imagename}",
        gaintable=[
            f"{src_dir}/cal_tables/pcal1_{imagename}",
            f"{src_dir}/cal_tables/pcal2_{imagename}",
        ],
        combine="scan,spw",
        spwmap=[[0] * n_spw, [0] * n_spw],
        gaintype="G",
        calmode="p",
        solint=solint,
        minsnr=minsnr,
        minblperant=minblperant,
    )
    applycal(
        vis=imagems,
        gaintable=[
            f"{src_dir}/cal_tables/pcal1_{imagename}",
            f"{src_dir}/cal_tables/pcal2_{imagename}",
            f"{src_dir}/cal_tables/pcal3_{imagename}",
        ],
        spwmap=[[0] * n_spw, [0] * n_spw, [0] * n_spw],
        parang=True,
        applymode="calonly",
        flagbackup=False,
    )
    flagmanager(vis=imagems, mode="save", versionname="post self3")
    for i in range(0, n_spw):
        spw = str(i)
        # if os.path.exists(f"{src_dir}/casa_files/{imagename}_{spw}_self3*"):
        os.system(f"rm -r {src_dir}/casa_files/{imagename}_{spw}_self3*")
        print("Cleaning on band: " + str(spw))
        # imagename = f"{src_dir}/casa_files/{imagename}_{spw}"
        tclean(
            vis=imagems,
            imagename=f"{src_dir}/casa_files/{imagename}_{spw}_self3",
            selectdata=True,
            mask=f"{src_dir}/casa_files/{imagename}_mfs.mask",
            startmodel=f"{src_dir}/casa_files/{imagename}_{spw}_self2.model",
            spw=spw,
            gain=gain,
            specmode=mode,
            nterms=nterms,
            niter=niter,
            threshold=threshold,
            imsize=imsize,
            cell=cell,
            stokes=stokes,
            weighting=weighting,
            robust=robust,
            antenna=antenna,
            interactive=interactive,
            savemodel="modelcolumn",
            pbcor=False,
            uvrange=uvrange,
        )
        tclean(
            vis=imagems,
            imagename=f"{src_dir}/casa_files/{imagename}_{spw}_self3",
            selectdata=True,
            mask="",
            spw=spw,
            gain=gain,
            specmode=mode,
            nterms=nterms,
            niter=0,
            threshold=threshold,
            imsize=imsize,
            cell=cell,
            stokes=stokes,
            weighting=weighting,
            robust=robust,
            antenna=antenna,
            interactive=interactive,
            pbcor=False,
            savemodel="modelcolumn",
            calcres=False,
            calcpsf=False,
            uvrange=uvrange,
        )
    return
# Display the new residual image
dispImage('try3.residual')

# This image shows artifacts from gain errors (different from the pure noise-like errors in the previous simulation)
#
# Calculate gain solutions (since we have already saved the model)

# In[498]:

bandpass(vis='sim_data.ms', caltable='sc.tab', solint='int')

# Apply gain solutions

# In[499]:

applycal(vis='sim_data.ms', gaintable='sc.tab')

# In[500]:

## Plot Calibrated data
plotData(myplot='corr_spectrum')

# Compare with the above uncalibrated data. Also, compare with visibilities simulated just with noise. Subsequent imaging should use the corrected_data column.

# In[501]:

# Call tclean to image the corrected data
os.system('rm -rf try4.*')

tclean(
    vis='sim_data.ms',