############## script tested for CASA 6.2.1.7 - pipeline #############


### For running a selection of a few steps use:
#my_steps=[0,1,2,3,4,5,6,7,8,9,10,11,12,13]

### For running a row of many steps use:
# my_steps=range(0,8) # from 0 to 7

################# REQUIRES ANALYSIS UTILITIES ####################
### to obtain analysis scripts from NRAO site https://casaguides.nrao.edu/index.php/Analysis_Utilities
### open terminal and use following 2 bash commands:	
# wget ftp://ftp.cv.nrao.edu/pub/casaguides/analysis_scripts.tar
# tar xvf analysis_scripts.tar
##################################################################

pathToAU='YOUR PATH TO AU-FOLDER'

import sys
sys.path.append(pathToAU) 	
import analysisUtils as aU




my_vis = 'xx' 

if 0 in my_steps :

    ## Import the asdm in .ms
    
    os.system('rm -rf '+my_vis)                               # erase existing '*.ms'
    
    importasdm(asdm='xx',  # location of the raw data 
               vis=my_vis,                                       # name of the MeasurementSet to be created from the raw data
               lazy=True,                                        # use symbolic link between raw data and MeasurementSet 
               asis='*',                                         # copy all metadata available (antennae position, pointing information
               bdfflags=True)                                    # keep all existing flags of the raw data                     
    
    ## create summary of this EB
    
    os.system('rm -rf '+my_vis+'.listobs')                      # erase existing LISTOBS
    listobs(vis=my_vis,                                         # name of the MS to be summarized
            listfile=my_vis+'.listobs')                         # Filename containing the summary

    ## Visualize the array configuration at the time of the observations

    os.system('rm -rf '+my_vis+'.plotants.png')                 # erase existing plot
    plotants(vis=my_vis,                                        # name of the MS
             figfile=my_vis+'.plotants.png')                    # Filename of the output


    #####################################
    #### Summary of listobs/plotants ####
    #####################################
    #
    # ALMA Band-XX observations at ~ XX GHz with XX SpWs with XX channel each
    #
    #
    # CALIBRATE FLUX/AMPLI:  XX (ID:XX)    SpW: XX-XX-XX-XX 
    # CALIBRATE BANDPASS  :  XX (ID:XX)    SpW: XX-XX-XX-XX
    # CALIBRATE PHASE     :  XX (ID:XX)    SpW: XX-XX-XX-XX
    # TARGET              :  XX (ID:XX)    SpW: XX-XX-XX-XX  
    #
    # Tsys                : Scan XX      SpW:  XX
    #
    #
    # WVR                 :  xx           SpW: xx  
    #
    #
    # ARRAY CONFIGURATION : xx Antennae; Longest Baseline ~ XX m -> Synthesized Beam ~ xx arcsec
    #                                    Shortest Baseline ~ XX m -> largest angular scale ~ xx arcsec
    #
    #
    #####################################
    #####################################
    #####################################


    
if 1 in my_steps :


    #####################################
    ###  A Priori Calibration: Tsys   ###
    #####################################

    
    ## Generation of the Tsys caltable using the task GENCAL
    
    # It is good practice to erase existing 'caltable' that
    # the forthcoming task will create. This avoids problems
    # when re-running a given calibration step 

    os.system('rm -rf '+my_vis+'.tsys')                       # erase existing TSYS CALTABLE
    
    # generate of Tsys caltable (naming convention name_ms.caltable_name)
    gencal(vis=my_vis,                                        # Name of the MS
           caltable=my_vis+'.tsys',                           # Name of the CALTABLE output by GENCAL
           caltype='xx')                                    # Tell GENCAL what we want to do 
    

    # Tsys measurements are known to be corrupted at the edges
    # of each SpWs. We must flag these channels in the Tsys CALTABLE
    # using the task FLAGDATA
    #
    # CASA convention:
    #        - '0:20,1:110'      --> SpW 0 channel 20 and SpW1 channel 110
    #        - '0;2:20;110'      --> SpW 0 and 2 and channel 20 and 110
    #        - '0~2:20;110'      --> SpW 0 to 2 channel 20 and 110
    #        - '0~2:20;110,3:50  --> SpW 0 to 2 channel 20 and 110 and SpW 3 channel 50
    #        - '0~2:20~110,3:50  --> SpW 0 to 2 channel 20 to 110 and SpW 3 channel 50
    
    flagdata(vis=my_vis+'.tsys',                              # Name of the MS or CALTABLE to be flagged
             mode='manual',                                   # 
             spw='xx',                    # SpW and Channel to be flagged
             flagbackup = False)                              # Do we want to keep a backup of the flag before the run 
             
    
    # We inspect these Tsys CALTABLE using the task PLOTBANDPASS, looking
    # for not well behaved antennae/scans. In case we find some, we will need
    # to flag the corresponding visibilities using FLAGDATA

    # plot for each antenna and each SPW, Tsys vs. Freq, overlaying all tsys scan together
    # and add the atmospheric transmission

    os.system('rm -rf '+my_vis+'.tsys.plots')       # delete old folder for plots 
    os.system('mkdir '+my_vis+'.tsys.plots')        # make new folder for plots

    aU.plotbandpass(caltable=my_vis+'.tsys',                   # name of the CALTABLE to use
                 xaxis='xx',                                
                 yaxis='xx',                                
                 antenna='',                                   # Which antennae do you want to inspect?
                 spw='',                                       # Which SpW do you want to inspect?
                 showatm=True,                                 # Show the atmospheric transmission?
                 overlay='xx',                               # 
                 figfile=my_vis+'.tsys.plots/'+my_vis,         # convention: put it in a folder name_ms.caltable_name/name_ms
                 interactive=False)
                 

    # Open all the files generated by PLOTBANDPASS
    # >> eog my_files* & 
    #
    # Inspect these plots and look for peculiar antennae/spw/scan
    #
    # Did you find any?   if yes, those have to be flagged with FLAGDATA
    # These flags can be added in step 4

    



if 2 in my_steps :

    #####################################
    ###   A Priori Calibration: WVR   ###
    #####################################

    
    ## Generation of the WVR caltable using the task WVRGCAL

    # erase existing WVR CALTABLE
    os.system('rm -rf '+my_vis+'.wvr')

    # generate WVR CALTABLE
    wvrgcal(vis=my_vis,                                       # Name of the MS to be process
            caltable=my_vis+'.wvr',                           # Name of the CALTABLE output by WRVGCAL 
            spw=[xx],                                # SpW to which solutions should be applied afterward
            smooth='xx',                                   # Smooth the calibration on the given timescale
            tie=[xx],                      # Prioritise tieing the phase of these sources as well as possible (typically phase cal and target)
            statsource=xx)                            # Compute the statistics (Phase RMS, Disc) on this source only
    

    # Check the output of WVRGCAL in the CASA logger
    # Check the PWV value
    #       PWV =  xx mm
    #
    # As written in Help(WVRGCAL), Disc > few hundreds
    # indicates that WVR corrections should not be applied
    #
    # Did you find such cases?
    #
    #
    # Antenna with peculiar values should be flagged in WVRGCAL (wvrflag=xx).
    #
    # Do you find such antenna ?
    #
    #


if 3 in my_steps :

    #############################################
    ###   A Priori Calibration: Application   ###
    #############################################

    
    ## Application of the WVR and Tsys CALTABLE using
    ## the task APPLYCAL
   
    # Application of these corrections on the field x

    applycal(vis=my_vis,                                      # Name of the MS to process
             field='xx',                                     # field ID to correct
             spw='xx',                               # SpW to be corrected (i.e., science SpWs)
             gaintable= [my_vis+'.xx',my_vis+'.xx'],       # name of CALTABLEs to use
             gainfield= ['xx','xx'],                           # ['Apply the Tsys from field x', 'Apply the WVR from field x']
             interp ='linear,linear',                         # 'Time-interpolation method,Frequency-interpolation-method'
             calwt= True,                                     # Applycal will scale weights of each visibility by 1/sqrt(Tsys(i) * Tsys(j))
             flagbackup = False,
             spwmap=[[xx],[xx]]) #[[apply Tsys SpW-x solutions to SpW-0, ... , Apply Tsys SpW-x solutions to SpW-i, ... , Apply Tsys SpW-x solutions to SpW-N],[same for WVR]]

    # your spw setup is
    # spws   = [0,1,2,3,4,5,6,7,8]
    # spwmap applies the solution from the spw specified at a given list index in spwmap 
    # to the spw at same list index in the spws list
    # spwmap = [0,0,2,2,4,4,6,7,8]


    ## Application of these corrections on the field x

    applycal(vis=my_vis,                                      # Name of the MS to process
             field='xx',                                     # field ID to correct
             spw='xx',                               # SpW to be corrected (i.e., science SpWs)
             gaintable= [my_vis+'.xx',my_vis+'.xx'],       # name of CALTABLE to use
             gainfield= ['xx','xx'],                             # [Apply the Tsys from field 'x', Apply the WVr from field 'x']
             interp ='linear,linear',                         # 'Time-interpolation method,Frequency-interpolation-method'
             calwt= True,                                     # Applycal will scale weights of each visibility by 1/sqrt(Tsys(i) * Tsys(j))
             flagbackup = False,
             spwmap=[[xx],[xx]]) #[[apply Tsys SpW-x solutions to SpW-0, ... , Apply Tsys SpW-x solutions to SpW-i, ... , Apply Tsys SpW-x solutions to SpW-N ],[same for WVR]]




    
if 4 in my_steps :

    #############################################
    ###    A Priori Calibration: Flagging     ###
    #############################################

    ## We flag things which not anymore needed
    ## using the task FLAGDATA


          
          ### optional but skip for now: probably see suspicious antennas in autocorr ###
          #                                                                             #
          #    plotms(vis=my_vis,                                                       #
          #        xaxis='frequency',                                                   #
          #        yaxis='amp',                                                         #
          #        field='0~2',                                                         #
          #        spw='9,11,13,15',                                                    # Tsys channels
          #        uvrange='',                                                          #
          #        antenna='*&&&',	                                                    # auto-correlations
          #        avgtime='360',                                                       # scan length
          #        avgfield=True,                                                       # average over all fields
          #        iteraxis='baseline',                                                 # iterate over baseline
          #        coloraxis='corr',                                                    # colour of data points = correlation
          #        showgui=True,                                                        #
          #        plotfile='field-0-1-2-amp-freq.png',                                 #
          #        overwrite=True)                                                      #
          #                                                                             #
          ###############################################################################
          


    # We flag auto-correlation visibilities (i.e., antenna-i correlated with antenna-i)

    flagdata(vis = my_vis,  # Name of the MS
             mode = 'xx',                                 # Mode to be used
             spw = 'xx',                                    # everything but the WVR SpW
             autocorr = True,
             flagbackup = False)

    
    # We flag un-necessary scans (POINTING, SIDEBAND_RATIO, ATMOSPHERE)
    
    flagdata(vis = my_vis,  # Name of the MS
             mode = 'xx',
             intent = 'xx',
             flagbackup = False)

    
    # We flag visibilities coming from antennae which are shadowed by an other one.
    
    flagdata(vis = my_vis,
             mode = 'xx',
             flagbackup = False)
   


    ## Additional flagging up to the students:
    ## Found while looking at Tsys  
    
    flagdata(vis = my_vis,
             mode = 'xx',
             spw = 'xx',
             antenna='xx',
             correlation='xx',
             flagbackup = False)




if 5 in my_steps :

    ###################################################
    ###   SPLIT I: slim down data for calibration   ###
    ###################################################

    ## We now extract the Tsys and WVR corrected data of the science channels and drop the rest.
    ## In this way, the make the data easier to process for the main calibration.

    os.system('rm -rf '+my_vis+'.split')                      # erase existing '*.ms.split'
                                                              
    mstransform(vis = my_vis,                                 # Name of the input MS
        outputvis = my_vis+'.split',                          # Name of the output MS
        datacolumn = 'xx',                             # only data with the the Tsys and WVR tables applied
        spw = 'xx',                                  # science SpW typically
        keepflags = True)                                     # keep flagged rows in the output
            
    
    ## We generate a listobs of the splitted data set which will be more tidy and easier to skim than the inital listobs.
    
    os.system('rm -rf '+my_vis+'.split.listobs')              # erase existing LISTOBS
    
    listobs(vis = my_vis+'.split',
        listfile = my_vis+'.split.listobs')
   
    ## Scan and field IDs are the same, SpW Ids are renamed (compare frequencies)!
    #
    ## SpW 17 -> 0
    ## SpW 19 -> 1
    ## SpW 21 -> 2
    ## SpW 23 -> 3
    #
    ##############################################################################

