Ejemplo n.º 1
0
 def polarisation(self):
     """
     Produces individual images for Stokes Q,U, cleans them with the mask from Stokes I and combines them in a cube.
     Then uses RM-Synthesis to produce a Faraday cube and clean it.
     """
     subs_setinit.setinitdirs(self)
     subs_setinit.setdatasetnamestomiriad(self)
     logger.info(' Polarisation imaging is going to be implemented later')
Ejemplo n.º 2
0
 def reset(self):
     """
     Function to reset the current step and remove all generated data. Be careful! Deletes all data generated in
     this step!
     """
     subs_setinit.setinitdirs(self)
     subs_setinit.setdatasetnamestomiriad(self)
     logger.warning(' Deleting all self-calibrated data.')
     subs_managefiles.director(self, 'ch', self.selfcaldir)
     subs_managefiles.director(self, 'rm', self.selfcaldir + '/*')
Ejemplo n.º 3
0
 def reset(self):
     """
     Function to reset the current step and remove all generated data. Be careful! Deletes all data generated in
     this step!
     """
     subs_setinit.setinitdirs(self)
     subs_setinit.setdatasetnamestomiriad(self)
     logger.warning('Deleting all data products ready for transfer!')
     subs_managefiles.director(self, 'ch', self.basedir)
     subs_managefiles.director(self, 'rm', self.transferdir)
Ejemplo n.º 4
0
 def flagline(self):
     """
     Creates an image cube of the different chunks and measures the rms in each channel. All channels with an rms
     outside of a given sigma interval are flagged in the continuum calibration, but are still used for line imaging.
     """
     if self.selfcal_flagline:
         subs_setinit.setinitdirs(self)
         subs_setinit.setdatasetnamestomiriad(self)
         logger.info(' Automatic flagging of HI-line/RFI started')
         subs_managefiles.director(self, 'ch', self.selfcaldir)
         for chunk in self.list_chunks():
             subs_managefiles.director(self, 'ch', self.selfcaldir + '/' + str(chunk))
             logger.info('Looking through data chunk ' + str(chunk) + ' #')
             invert = lib.miriad('invert')
             invert.vis = chunk + '.mir'
             invert.map = 'map'
             invert.beam = 'beam'
             invert.imsize = self.selfcal_image_imsize
             invert.cell = self.selfcal_image_cellsize
             invert.stokes = 'ii'
             invert.slop = 1
             invert.go()
             if os.path.exists('map'):
                 fits = lib.miriad('fits')
                 fits.in_ = 'map'
                 fits.op = 'xyout'
                 fits.out = 'map.fits'
                 fits.go()
                 cube = pyfits.open('map.fits')
                 data = cube[0].data
                 std = np.nanstd(data, axis=(0, 2, 3))
                 median = np.median(std)
                 stdall = np.nanstd(std)
                 diff = std - median
                 detections = np.where(np.abs(self.selfcal_flagline_sigma * diff) > stdall)[0]
                 if len(detections) > 0:
                     logger.info('Found high noise in channel(s) ' + str(detections).lstrip('[').rstrip(']') + ' #')
                     for d in detections:
                         uvflag = lib.miriad('uvflag')
                         uvflag.vis = chunk + '.mir'
                         uvflag.flagval = 'flag'
                         uvflag.line = "'" + 'channel,1,' + str(d + 1) + "'"
                         uvflag.go()
                     logger.info(
                         'Flagged channel(s) ' + str(detections).lstrip('[').rstrip(']') + ' in data chunk ' + str(
                             chunk) + ' #')
                 else:
                     logger.info('No high noise found in data chunk ' + str(chunk) + ' #')
                 subs_managefiles.director(self, 'rm', self.selfcaldir + '/' + str(chunk) + '/' + 'map')
                 subs_managefiles.director(self, 'rm', self.selfcaldir + '/' + str(chunk) + '/' + 'map.fits')
                 subs_managefiles.director(self, 'rm', self.selfcaldir + '/' + str(chunk) + '/' + 'beam')
             else:
                 logger.info(' No data in chunk ' + str(chunk) + '!')
         logger.info(' Automatic flagging of HI-line/RFI done')
Ejemplo n.º 5
0
 def list_chunks(self):
     """
     Checks how many chunk directories exist and returns a list of them.
     """
     subs_setinit.setinitdirs(self)
     subs_setinit.setdatasetnamestomiriad(self)
     for n in range(100):
         if os.path.exists(self.selfcaldir + '/' + str(n).zfill(2)):
             pass
         else:
             break  # Stop the counting loop at the directory you cannot find anymore
     chunks = range(n)
     chunkstr = [str(i).zfill(2) for i in chunks]
     return chunkstr
Ejemplo n.º 6
0
    def check_starting_conditions(self):
        """
        Check that the miriad file from convert exists.

        If it does not exists, none of the subsequent tasks in go need to be executed.
        This seems necessary as not all the tasks do this check and they do not have
        to. A single task is enough.

        Not sure if it is necessary to add all the param variables from selfcal
        and set them False if the check fails. For now, just use the main one

        Args:
            self

        Return:
            (bool): True if file is found, otherwise False
        """

        logger.info(
            "Beam {}: Checking starting conditions for TRANSFER".format(
                self.beam))

        # initial setup
        subs_setinit.setinitdirs(self)
        subs_setinit.setdatasetnamestomiriad(self)

        # path to converted miriad file
        mir_file = os.path.join(self.crosscaldir, self.target)

        # check that the file exists
        if os.path.isdir(mir_file):
            # miriad file exists
            logger.info(
                "Beam {}: Checking starting conditions for TRANSFER ... Done: All good."
                .format(self.beam))
            return True
        else:
            # miriad file does not exists
            logger.warning(
                "Beam {}: Checking starting conditions for TRANSFER ... Done: Failed"
                .format(self.beam))
            logger.warning(
                "Beam {}: Did not find main miriad file in {}".format(
                    self.beam, mir_file))

            return False
Ejemplo n.º 7
0
 def reset(self):
     """
     Function to reset the current step and remove all generated data. Be careful! Deletes all data generated in
     this step!
     """
     subs_setinit.setinitdirs(self)
     subs_setinit.setdatasetnamestomiriad(self)
     if os.path.isdir(self.mosdir):
         logger.warning('Deleting all mosaicked data products.')
         subs_managefiles.director(self, 'ch', self.basedir)
         subs_managefiles.director(self, 'rm', self.mosdir)
         logger.warning(
             'Deleting all parameter file entries for MOSAIC module')
         subs_param.del_param(self, 'mosaic_continuum_mf_status')
         subs_param.del_param(self, 'mosaic_continuum_mf_continuumstatus')
         subs_param.del_param(self, 'mosaic_continuum_mf_copystatus')
         subs_param.del_param(self, 'mosaic_continuum_mf_convolstatus')
         subs_param.del_param(self,
                              'mosaic_continuum_mf_continuumbeamparams')
         subs_param.del_param(self,
                              'mosaic_continuum_mf_continuumimagestats')
     else:
         logger.warning('Mosaicked data products are not present!')
Ejemplo n.º 8
0
    def splitdata(self):
        """
        Applies calibrator corrections to data, splits the data into chunks in frequency and bins it to the given
        frequency resolution for the self-calibration
        """
        if self.selfcal_splitdata:
            subs_setinit.setinitdirs(self)
            subs_setinit.setdatasetnamestomiriad(self)
            subs_managefiles.director(self, 'ch', self.selfcaldir)
            logger.info(' Splitting of target data into individual frequency chunks started')
            if os.path.exists(self.selfcaldir + '/' + self.target):
                logger.info('Calibrator corrections already seem to have been applied #')
            else:
                logger.info('Applying calibrator solutions to target data before averaging #')
                uvaver = lib.miriad('uvaver')
                uvaver.vis = self.crosscaldir + '/' + self.target
                uvaver.out = self.selfcaldir + '/' + self.target
                uvaver.go()
                logger.info('Calibrator solutions to target data applied #')
            if self.selfcal_flagantenna != '':
                uvflag = lib.miriad('uvflag')
                uvflag.vis = self.selfcaldir + '/' + self.target
                uvflag.flagval = 'flag'
                uvflag.select = 'antenna(' + str(self.selfcal_flagantenna) + ')'
                uvflag.go()
            else:
                pass
            try:
                uv = aipy.miriad.UV(self.selfcaldir + '/' + self.target)
            except RuntimeError:
                raise ApercalException(' No data in your selfcal directory!')

            try:
                nsubband = len(uv['nschan'])  # Number of subbands in data
            except TypeError:
                nsubband = 1  # Only one subband in data since exception was triggered
            logger.info('Found ' + str(nsubband) + ' subband(s) in target data #')
            counter = 0  # Counter for naming the chunks and directories
            for subband in range(nsubband):
                logger.info('Started splitting of subband ' + str(subband) + ' #')
                if nsubband == 1:
                    numchan = uv['nschan']
                    finc = np.fabs(uv['sdf'])
                else:
                    numchan = uv['nschan'][subband]  # Number of channels per subband
                    finc = np.fabs(uv['sdf'][subband])  # Frequency increment for each channel
                subband_bw = numchan * finc  # Bandwidth of one subband
                subband_chunks = round(subband_bw / self.selfcal_splitdata_chunkbandwidth)
                # Round to the closest power of 2 for frequency chunks with the same bandwidth over the frequency
                # range of a subband
                subband_chunks = int(np.power(2, np.ceil(np.log(subband_chunks) / np.log(2))))
                if subband_chunks == 0:
                    subband_chunks = 1
                chunkbandwidth = (numchan / subband_chunks) * finc
                logger.info('Adjusting chunk size to ' + str(
                    chunkbandwidth) + ' GHz for regular gridding of the data chunks over frequency #')
                for chunk in range(subband_chunks):
                    logger.info(
                        'Starting splitting of data chunk ' + str(chunk) + ' for subband ' + str(subband) + ' #')
                    binchan = round(
                        self.selfcal_splitdata_channelbandwidth / finc)  # Number of channels per frequency bin
                    chan_per_chunk = numchan / subband_chunks
                    if chan_per_chunk % binchan == 0:  # Check if the freqeuncy bin exactly fits
                        logger.info('Using frequency binning of ' + str(
                            self.selfcal_splitdata_channelbandwidth) + ' for all subbands #')
                    else:
                        # Increase the frequency bin to keep a regular grid for the chunks
                        while chan_per_chunk % binchan != 0:
                            binchan = binchan + 1
                        else:
                            # Check if the calculated bin is not larger than the subband channel number
                            if chan_per_chunk >= binchan:
                                pass
                            else:
                                # Set the frequency bin to the number of channels in the chunk of the subband
                                binchan = chan_per_chunk
                        logger.info('Increasing frequency bin of data chunk ' + str(
                            chunk) + ' to keep bandwidth of chunks equal over the whole bandwidth #')
                        logger.info('New frequency bin is ' + str(binchan * finc) + ' GHz #')
                    nchan = int(chan_per_chunk / binchan)  # Total number of output channels per chunk
                    start = 1 + chunk * chan_per_chunk
                    width = int(binchan)
                    step = int(width)
                    subs_managefiles.director(self, 'mk', self.selfcaldir + '/' + str(counter).zfill(2))
                    uvaver = lib.miriad('uvaver')
                    uvaver.vis = self.selfcaldir + '/' + self.target
                    uvaver.out = self.selfcaldir + '/' + str(counter).zfill(2) + '/' + str(counter).zfill(2) + '.mir'
                    uvaver.select = "'" + 'window(' + str(subband + 1) + ')' + "'"
                    uvaver.line = "'" + 'channel,' + str(nchan) + ',' + str(start) + ',' + str(width) + ',' + str(
                        step) + "'"
                    uvaver.go()
                    counter = counter + 1
                    logger.info('Splitting of data chunk ' + str(chunk) + ' for subband ' + str(subband) + ' done #')
                logger.info('Splitting of data for subband ' + str(subband) + ' done #')
            logger.info(' Splitting of target data into individual frequency chunks done')
Ejemplo n.º 9
0
 def __init__(self, file_=None, **kwargs):
     self.default = lib.load_config(self, file_)
     subs_setinit.setinitdirs(self)
     subs_setinit.setdatasetnamestomiriad(self)
Ejemplo n.º 10
0
 def run_continuum_minoriteration(self, chunk, majc, minc, drmin, theoretical_noise_threshold):
     """
     Does a selfcal minor iteration for the standard mode
     chunk: The frequency chunk to image and calibrate
     maj: Current major iteration
     min: Current minor iteration
     drmin: maximum dynamic range for minor iteration
     theoretical_noise_threshold: calculated theoretical noise threshold
     """
     subs_setinit.setinitdirs(self)
     subs_setinit.setdatasetnamestomiriad(self)
     logger.info('Minor self-calibration cycle ' + str(minc) + ' for frequency chunk ' + chunk + ' started #')
     if minc == 0:
         invert = lib.miriad('invert')  # Create the dirty image
         invert.vis = chunk + '.mir'
         invert.map = str(majc).zfill(2) + '/map_' + str(minc).zfill(2)
         invert.beam = str(majc).zfill(2) + '/beam_' + str(minc).zfill(2)
         invert.imsize = self.selfcal_image_imsize
         invert.cell = self.selfcal_image_cellsize
         invert.stokes = 'ii'
         invert.options = 'mfs,double'
         invert.slop = 1
         invert.robust = -2
         invert.go()
         imax = self.calc_imax(str(majc).zfill(2) + '/map_' + str(minc).zfill(2))
         noise_threshold = self.calc_noise_threshold(imax, minc, majc)
         dynamic_range_threshold = calc_dynamic_range_threshold(imax, drmin,
                                                                     self.selfcal_standard_minorcycle0_dr)
         mask_threshold, mask_threshold_type = calc_mask_threshold(theoretical_noise_threshold, noise_threshold,
                                                                        dynamic_range_threshold)
         logger.info('Mask threshold for major/minor cycle ' + str(majc) + '/' + str(minc) + ' set to ' + str(
             mask_threshold) + ' Jy/beam #')
         logger.info('Mask threshold set by ' + str(mask_threshold_type) + ' #')
         if majc == 0:
             maths = lib.miriad('maths')
             maths.out = str(majc).zfill(2) + '/mask_' + str(minc).zfill(2)
             maths.exp = '"<' + str(majc).zfill(2) + '/map_' + str(minc).zfill(2) + '>"'
             maths.mask = '"<' + str(majc).zfill(2) + '/map_' + str(minc).zfill(2) + '>.gt.' + str(
                 mask_threshold) + '"'
             maths.go()
             logger.info('Mask with threshold ' + str(mask_threshold) + ' Jy/beam created #')
         else:
             subs_managefiles.director(self, 'cp', str(majc).zfill(2) + '/mask_' + str(minc).zfill(2),
                                       file_=str(majc - 1).zfill(2) + '/mask_' + str(
                                           self.selfcal_standard_minorcycle - 1).zfill(2))
             logger.info('Mask from last minor iteration of last major cycle copied #')
         clean_cutoff = self.calc_clean_cutoff(mask_threshold)
         logger.info('Clean threshold at major/minor cycle ' + str(majc) + '/' + str(minc) + ' was set to ' + str(
             clean_cutoff) + ' Jy/beam #')
         clean = lib.miriad('clean')  # Clean the image down to the calculated threshold
         clean.map = str(majc).zfill(2) + '/map_' + str(0).zfill(2)
         clean.beam = str(majc).zfill(2) + '/beam_' + str(0).zfill(2)
         clean.out = str(majc).zfill(2) + '/model_' + str(minc).zfill(2)
         clean.cutoff = clean_cutoff
         clean.niters = 1000000
         clean.region = '"' + 'mask(' + str(majc).zfill(2) + '/mask_' + str(minc).zfill(2) + ')' + '"'
         clean.go()
         logger.info('Major/minor cycle ' + str(majc) + '/' + str(minc) + ' cleaning done #')
         restor = lib.miriad('restor')
         restor.model = str(majc).zfill(2) + '/model_' + str(minc).zfill(2)
         restor.beam = str(majc).zfill(2) + '/beam_' + str(0).zfill(2)
         restor.map = str(majc).zfill(2) + '/map_' + str(0).zfill(2)
         restor.out = str(majc).zfill(2) + '/image_' + str(minc).zfill(2)
         restor.mode = 'clean'
         restor.go()  # Create the cleaned image
         logger.info('Cleaned image for major/minor cycle ' + str(majc) + '/' + str(minc) + ' created #')
         restor.mode = 'residual'
         restor.out = str(majc).zfill(2) + '/residual_' + str(minc).zfill(2)
         restor.go()
         logger.info('Residual image for major/minor cycle ' + str(majc) + '/' + str(minc) + ' created #')
         logger.info('Peak of the residual image is ' + str(
             self.calc_imax(str(majc).zfill(2) + '/residual_' + str(minc).zfill(2))) + ' Jy/beam #')
         logger.info('RMS of the residual image is ' + str(
             self.calc_irms(str(majc).zfill(2) + '/residual_' + str(minc).zfill(2))) + ' Jy/beam #')
     else:
         imax = self.calc_imax(str(majc).zfill(2) + '/map_' + str(0).zfill(2))
         noise_threshold = self.calc_noise_threshold(imax, minc, majc)
         dynamic_range_threshold = calc_dynamic_range_threshold(imax, drmin,
                                                                     self.selfcal_standard_minorcycle0_dr)
         mask_threshold, mask_threshold_type = calc_mask_threshold(theoretical_noise_threshold, noise_threshold,
                                                                        dynamic_range_threshold)
         logger.info('Mask threshold for major/minor cycle ' + str(majc) + '/' + str(minc) + ' set to ' + str(
             mask_threshold) + ' Jy/beam #')
         logger.info('Mask threshold set by ' + str(mask_threshold_type) + ' #')
         maths = lib.miriad('maths')
         maths.out = str(majc).zfill(2) + '/mask_' + str(minc).zfill(2)
         maths.exp = '"<' + str(majc).zfill(2) + '/image_' + str(minc - 1).zfill(2) + '>"'
         maths.mask = '"<' + str(majc).zfill(2) + '/image_' + str(minc - 1).zfill(2) + '>.gt.' + str(
             mask_threshold) + '"'
         maths.go()
         logger.info('Mask with threshold ' + str(mask_threshold) + ' Jy/beam created #')
         clean_cutoff = self.calc_clean_cutoff(mask_threshold)
         logger.info('Clean threshold at major/minor cycle ' + str(majc) + '/' + str(minc) + ' was set to ' + str(
             clean_cutoff) + ' Jy/beam #')
         clean = lib.miriad('clean')  # Clean the image down to the calculated threshold
         clean.map = str(majc).zfill(2) + '/map_' + str(0).zfill(2)
         clean.beam = str(majc).zfill(2) + '/beam_' + str(0).zfill(2)
         clean.model = str(majc).zfill(2) + '/model_' + str(minc - 1).zfill(2)
         clean.out = str(majc).zfill(2) + '/model_' + str(minc).zfill(2)
         clean.cutoff = clean_cutoff
         clean.niters = 1000000
         clean.region = '"' + 'mask(' + str(majc).zfill(2) + '/mask_' + str(minc).zfill(2) + ')' + '"'
         clean.go()
         logger.info('Major/minor cycle ' + str(majc) + '/' + str(minc) + ' cleaning done #')
         restor = lib.miriad('restor')
         restor.model = str(majc).zfill(2) + '/model_' + str(minc).zfill(2)
         restor.beam = str(majc).zfill(2) + '/beam_' + str(0).zfill(2)
         restor.map = str(majc).zfill(2) + '/map_' + str(0).zfill(2)
         restor.out = str(majc).zfill(2) + '/image_' + str(minc).zfill(2)
         restor.mode = 'clean'
         restor.go()  # Create the cleaned image
         logger.info('Cleaned image for major/minor cycle ' + str(majc) + '/' + str(minc) + ' created #')
         restor.mode = 'residual'
         restor.out = str(majc).zfill(2) + '/residual_' + str(minc).zfill(2)
         restor.go()
         logger.info('Residual image for major/minor cycle ' + str(majc) + '/' + str(minc) + ' created #')
         logger.info('Peak of the residual image is ' + str(
             self.calc_imax(str(majc).zfill(2) + '/residual_' + str(minc).zfill(2))) + ' Jy/beam #')
         logger.info('RMS of the residual image is ' + str(
             self.calc_irms(str(majc).zfill(2) + '/residual_' + str(minc).zfill(2))) + ' Jy/beam #')
     logger.info('Minor self-calibration cycle ' + str(minc) + ' for frequency chunk ' + chunk + ' finished #')
Ejemplo n.º 11
0
 def selfcal_standard(self):
     """
     Executes the standard method of self-calibration with the given parameters
     """
     subs_setinit.setinitdirs(self)
     subs_setinit.setdatasetnamestomiriad(self)
     logger.info(' Starting standard self calibration routine')
     subs_managefiles.director(self, 'ch', self.selfcaldir)
     for chunk in self.list_chunks():
         logger.info('Starting standard self-calibration routine on frequency chunk ' + chunk + ' #')
         subs_managefiles.director(self, 'ch', self.selfcaldir + '/' + chunk)
         if os.path.isfile(self.selfcaldir + '/' + chunk + '/' + chunk + '.mir/visdata'):
             theoretical_noise = calc_theoretical_noise(self.selfcaldir + '/' + chunk + '/' + chunk + '.mir')
             logger.info('Theoretical noise for chunk ' + chunk + ' is ' + str(theoretical_noise) + ' Jy/beam #')
             theoretical_noise_threshold = self.calc_theoretical_noise_threshold(theoretical_noise)
             logger.info('Your theoretical noise threshold will be ' + str(
                 self.selfcal_standard_nsigma) + ' times the theoretical noise corresponding to ' + str(
                 theoretical_noise_threshold) + ' Jy/beam #')
             dr_list = calc_dr_maj(self.selfcal_standard_drinit, self.selfcal_standard_dr0,
                                        self.selfcal_standard_majorcycle, self.selfcal_standard_majorcycle_function)
             logger.info(
                 'Your dynamic range limits are set to ' + str(dr_list) + ' for the major self-calibration cycles #')
             for majc in range(self.selfcal_standard_majorcycle):
                 logger.info(
                     'Major self-calibration cycle ' + str(majc) + ' for frequency chunk ' + chunk + ' started #')
                 subs_managefiles.director(self, 'mk', self.selfcaldir + '/' + str(chunk) + '/' + str(majc).zfill(2))
                 # Calculate the dynamic ranges during minor cycles
                 dr_minlist = self.calc_dr_min(dr_list, majc, self.selfcal_standard_minorcycle,
                                               self.selfcal_standard_minorcycle_function)
                 logger.info('The minor cycle dynamic range limits for major cycle ' + str(majc) + ' are ' + str(
                     dr_minlist) + ' #')
                 for minc in range(self.selfcal_standard_minorcycle):
                     try:
                         self.run_continuum_minoriteration(chunk, majc, minc, dr_minlist[minc],
                                                           theoretical_noise_threshold)
                     except Exception:
                         logger.warning('Chunk ' + chunk + ' does not seem to contain data to image #')
                         break
                 try:
                     logger.info('Doing self-calibration with uvmin=' + str(
                         self.selfcal_standard_uvmin[majc]) + ', uvmax=' + str(
                         self.selfcal_standard_uvmax[majc]) + ', solution interval=' + str(
                         self.selfcal_standard_solint[majc]) + ' minutes for major cycle ' + str(majc).zfill(
                         2) + ' #')
                     selfcal = lib.miriad('selfcal')
                     selfcal.vis = chunk + '.mir'
                     selfcal.select = '"' + 'uvrange(' + str(self.selfcal_standard_uvmin[majc]) + ',' + str(
                         self.selfcal_standard_uvmax[majc]) + ')"'
                     selfcal.model = str(majc).zfill(2) + '/model_' + str(minc).zfill(2)
                     selfcal.interval = self.selfcal_standard_solint[majc]
                     # Choose reference antenna if given
                     if self.selfcal_refant == '':
                         pass
                     else:
                         selfcal.refant = self.selfcal_refant
                     # Enable amplitude calibration if triggered
                     if not self.selfcal_standard_amp:  # See if we want to do amplitude calibration
                         selfcal.options = 'mfs,phase'
                     elif self.selfcal_standard_amp:
                         selfcal.options = 'mfs,amp'
                     elif self.selfcal_standard_amp == 'auto':
                         modelflux = self.calc_isum(str(majc).zfill(2) + '/model_' + str(minc).zfill(2))
                         if modelflux >= self.selfcal_standard_amp_auto_limit:
                             logger.info(
                                 'Flux of clean model is ' + str(modelflux) + ' Jy. Doing amplitude calibration. #')
                             selfcal.options = 'mfs,amp'
                         else:
                             selfcal.options = 'mfs,phase'
                     if self.selfcal_standard_nfbin >= 1:
                         selfcal.nfbin = self.selfcal_standard_nfbin
                     selfcal.go()
                     logger.info('Major self-calibration cycle ' + str(
                         majc) + ' for frequency chunk ' + chunk + ' finished #')
                 except Exception:
                     logger.warning(
                         'Model for self-calibration not found. No further calibration on this chunk possible!')
                     break
             logger.info('Standard self-calibration routine for chunk ' + chunk + ' finished #')
         else:
             logger.warning('No data in chunk ' + chunk + '. Maybe all data is flagged? #')
     logger.info(' Standard self calibration routine finished')
Ejemplo n.º 12
0
    def parametric(self):
        """
        Parametric self calibration using an NVSS/FIRST skymodel and calculating spectral indices by source matching
        with WENSS.
        """
        if self.selfcal_parametric:
            subs_setinit.setinitdirs(self)
            subs_setinit.setdatasetnamestomiriad(self)
            logger.info(' Doing parametric self calibration')
            subs_managefiles.director(self, 'ch', self.selfcaldir)
            for chunk in self.list_chunks():
                logger.info('Starting parametric self calibration routine on chunk ' + chunk + ' #')
                subs_managefiles.director(self, 'ch', self.selfcaldir + '/' + chunk)
                subs_managefiles.director(self, 'mk', self.selfcaldir + '/' + chunk + '/' + 'pm')
                parametric_textfile = lsm.lsm_model(chunk + '.mir', self.selfcal_parametric_skymodel_radius,
                                                    self.selfcal_parametric_skymodel_cutoff,
                                                    self.selfcal_parametric_skymodel_distance)
                lsm.write_model(self.selfcaldir + '/' + chunk + '/' + 'pm' + '/model.txt', parametric_textfile)
                logger.info('Creating model from textfile model.txt for chunk ' + chunk + ' #')
                uv = aipy.miriad.UV(self.selfcaldir + '/' + chunk + '/' + chunk + '.mir')
                freq = uv['sfreq']
                uvmodel = lib.miriad('uvmodel')
                uvmodel.vis = chunk + '.mir'
                parametric_modelfile = open(self.selfcaldir + '/' + str(chunk) + '/' + 'pm' + '/model.txt', 'r')
                for n, source in enumerate(parametric_modelfile.readlines()):
                    if n == 0:
                        uvmodel.options = 'replace,mfs'
                    else:
                        uvmodel.options = 'add,mfs'
                    uvmodel.offset = source.split(',')[0] + ',' + source.split(',')[1]
                    uvmodel.flux = source.split(',')[2] + ',i,' + str(freq) + ',' + source.split(',')[4].rstrip(
                        '\n') + ',0,0'
                    uvmodel.out = 'pm/tmp' + str(n)
                    uvmodel.go()
                    uvmodel.vis = uvmodel.out
                subs_managefiles.director(self, 'rn', 'pm/model', uvmodel.out)  # Rename the last modelfile to model
                subs_managefiles.director(self, 'rm', 'pm/tmp*')  # Remove all the obsolete modelfiles

                logger.info('Doing parametric self-calibration on chunk {} with solution interval {} min'
                            'and uvrange limits of {}~{} klambda #'.format(chunk, self.selfcal_parametric_solint,
                                                                           self.selfcal_parametric_uvmin,
                                                                           self.selfcal_parametric_uvmax))

                selfcal = lib.miriad('selfcal')
                selfcal.vis = chunk + '.mir'
                selfcal.model = 'pm/model'
                selfcal.interval = self.selfcal_parametric_solint
                selfcal.select = "'" + 'uvrange(' + str(self.selfcal_parametric_uvmin) + ',' + str(
                    self.selfcal_parametric_uvmax) + ')' + "'"
                # Choose reference antenna if given
                if self.selfcal_refant == '':
                    pass
                else:
                    selfcal.refant = self.selfcal_refant
                # Do amplitude calibration if wanted
                if self.selfcal_parametric_amp:
                    selfcal.options = 'mfs,amp'
                else:
                    selfcal.options = 'mfs'
                selfcal.go()
                logger.info('Parametric self calibration routine on chunk ' + chunk + ' done! #')
            logger.info(' Parametric self calibration done')
        else:
            logger.info(' Parametric self calibration disabled')
Ejemplo n.º 13
0
    def convert_selfcaluv2uvfits(self):
        """
        Looks for the last self-calibrated uv-fits file, copies its gains over to the original file, applies them and coverts to UVFITS format
        """
        subs_setinit.setinitdirs(self)

        sbeam = 'selfcal_B' + str(self.beam).zfill(2)
        tbeam = 'transfer_B' + str(self.beam).zfill(2)

        # Create the parameters for the parameter file for the conversion of the UVFITS-files

        transfertargetbeamsselfcaluv2uvfitsstatus = get_param_def(
            self, tbeam + '_targetbeams_selfcaluv2uvfits_status', False)

        if self.transfer_convert_selfcaluv2uvfits:
            subs_setinit.setinitdirs(self)
            subs_setinit.setdatasetnamestomiriad(self)
            subs_managefiles.director(self,
                                      'ch',
                                      self.transferdir,
                                      verbose=True)
            if not transfertargetbeamsselfcaluv2uvfitsstatus:
                # Get the status of the selfcal for the specified beam
                selfcaltargetbeamsphasestatus = get_param_def(
                    self, sbeam + '_targetbeams_phase_status', False)
                selfcaltargetbeamsampstatus = get_param_def(
                    self, sbeam + '_targetbeams_amp_status', False)
                datasetname_amp = os.path.join(
                    self.selfcaldir, self.target).rstrip('.mir') + '_amp.mir'
                datasetname_phase = os.path.join(self.selfcaldir, self.target)
                logger.debug("Setting amplitude selfcal file name: {}".format(
                    datasetname_amp))
                logger.debug("Setting phase selfcal file name: {}".format(
                    datasetname_phase))
                # datasetname_amp = self.get_target_path().rstrip('.mir') + '_amp.mir'
                # datasetname_phase = self.get_target_path()
                if os.path.isdir(
                        datasetname_amp) and selfcaltargetbeamsampstatus:
                    logger.info('Beam ' + self.beam +
                                ': Using amplitude self-calibrated dataset!')
                    dataset = datasetname_amp
                elif os.path.isdir(
                        datasetname_phase) and selfcaltargetbeamsphasestatus:
                    logger.info(
                        'Beam ' + self.beam +
                        ': Using phase self-calibrated dataset. Amplitude calibration was not successful or not wanted!'
                    )
                    dataset = datasetname_phase
                else:
                    dataset = None

                if dataset is not None:
                    # Copy the raw dataset to the transfer directory
                    subs_managefiles.director(
                        self,
                        'cp',
                        self.transferdir + '/' + self.target,
                        file_=self.crosscaldir + '/' + self.target)
                    if selfcaltargetbeamsampstatus:
                        gpcopy = lib.miriad('gpcopy')
                        gpcopy.vis = datasetname_phase
                        gpcopy.out = self.transferdir + '/' + self.target
                        gpcopy.go()
                        uvaver = lib.miriad('uvaver')
                        uvaver.vis = self.transferdir + '/' + self.target
                        uvaver.out = self.transferdir + '/' + \
                            self.target.rstrip('.mir') + '_phase.mir'
                        uvaver.go()
                        gpcopy = lib.miriad('gpcopy')
                        gpcopy.vis = datasetname_amp
                        gpcopy.out = self.transferdir + '/' + \
                            self.target.rstrip('.mir') + '_phase.mir'
                        gpcopy.go()
                        fits = lib.miriad('fits')
                        fits.op = 'uvout'
                        fits.in_ = self.transferdir + '/' + \
                            self.target.rstrip('.mir') + '_phase.mir'
                        fits.out = self.transferdir + '/' + \
                            self.target.rstrip('.mir') + '.UVFITS'
                        fits.go()
                        if os.path.isfile(self.transferdir + '/' +
                                          self.target.rstrip('.mir') +
                                          '.UVFITS'):
                            subs_managefiles.director(
                                self, 'rm',
                                self.transferdir + '/' + self.target)
                            subs_managefiles.director(
                                self, 'rm', self.transferdir + '/' +
                                self.target.rstrip('.mir') + '_phase.mir')
                            transfertargetbeamsselfcaluv2uvfitsstatus = True
                        else:
                            logger.error(
                                'Beam ' + self.beam +
                                ': Conversion was not successful. No UVFITS-file generated!'
                            )
                            transfertargetbeamsselfcaluv2uvfitsstatus = False
                    elif selfcaltargetbeamsphasestatus:
                        gpcopy = lib.miriad('gpcopy')
                        gpcopy.vis = datasetname_phase
                        gpcopy.out = self.transferdir + '/' + self.target
                        gpcopy.go()
                        fits = lib.miriad('fits')
                        fits.op = 'uvout'
                        fits.in_ = self.transferdir + '/' + self.target
                        fits.out = self.transferdir + '/' + \
                            self.target.rstrip('.mir') + '.UVFITS'
                        fits.go()
                        if os.path.isfile(self.transferdir + '/' +
                                          self.target.rstrip('.mir') +
                                          '.UVFITS'):
                            subs_managefiles.director(
                                self, 'rm',
                                self.transferdir + '/' + self.target)
                            transfertargetbeamsselfcaluv2uvfitsstatus = True
                        else:
                            logger.error(
                                'Beam ' + self.beam +
                                ': Conversion was not successful. No UVFITS-file generated!'
                            )
                            transfertargetbeamsselfcaluv2uvfitsstatus = False
                else:
                    logger.error(
                        'Beam ' + self.beam +
                        ': Self-calibration was not successful. No conversion to UVFITS-format possible!'
                    )
                    transfertargetbeamsselfcaluv2uvfitsstatus = False
            else:
                logger.info(
                    'Beam ' + self.beam +
                    ': Conversion of final calibrated data to UVFITS-format already successfully executed!'
                )
        else:
            logger.info(
                'Beam ' + self.beam +
                ': Conversion of final calibrated data to UVFITS-format not selected!'
            )

        # Save the derived parameters to the parameter file

        subs_param.add_param(self,
                             tbeam + '_targetbeams_selfcaluv2uvfits_status',
                             transfertargetbeamsselfcaluv2uvfitsstatus)
Ejemplo n.º 14
0
    def mosaic_continuum_mf(self):
        """Looks for all available stacked continuum images and mosaics them into one large image."""
        subs_setinit.setinitdirs(self)
        subs_setinit.setdatasetnamestomiriad(self)

        ##########################################################################################################
        # Check if the parameter is already in the parameter file and load it otherwise create the needed arrays #
        ##########################################################################################################

        mosaiccontinuummfstatus = get_param_def(
            self, 'mosaic_continuum_mf_status',
            False)  # Status of the continuum mf mosaic
        mosaiccontinuummfcontinuumstatus = get_param_def(
            self, 'mosaic_continuum_mf_continuumstatus',
            np.full(self.NBEAMS, False))  # Status of the continuum imaging
        mosaiccontinuummfcopystatus = get_param_def(
            self, 'mosaic_continuum_mf_copystatus',
            np.full(self.NBEAMS, False))  # Status of the copy of the images
        mosaiccontinuummfconvolstatus = get_param_def(
            self, 'mosaic_continuum_mf_convolstatus',
            np.full(self.NBEAMS, False))  # Status of the convolved images
        mosaiccontinuummfcontinuumbeamparams = get_param_def(
            self, 'mosaic_continuum_mf_continuumbeamparams',
            np.full((self.NBEAMS, 3),
                    np.nan))  # Beam sizes of the input images
        mosaiccontinuummfcontinuumimagestats = get_param_def(
            self, 'mosaic_continuum_mf_continuumimagestats',
            np.full((self.NBEAMS, 3),
                    np.nan))  # Image statistics of the input images

        # Start the mosaicking of the stacked continuum images
        if self.mosaic_continuum_mf:
            subs_setinit.setinitdirs(self)
            subs_setinit.setdatasetnamestomiriad(self)
            subs_managefiles.director(self, 'ch', self.mosdir + '/continuum')
            if not mosaiccontinuummfstatus:
                logger.info('Mosaicking multi-frequency continuum images')
                # Acquire the results and statistics from continuum mf imaging
                for b in range(self.NBEAMS):
                    mosaiccontinuummfcontinuumstatus[b] = get_param_def(
                        self, 'continuum_B' + str(b).zfill(2) +
                        '_targetbeams_mf_status', False)
                    if mosaiccontinuummfcontinuumstatus[b]:
                        finalminor = get_param_def(
                            self, 'continuum_B' + str(b).zfill(2) +
                            '_targetbeams_mf_final_minorcycle', np.nan)
                        subs_managefiles.director(
                            self,
                            'cp',
                            str(b).zfill(2) + '.fits',
                            file_=self.basedir + str(b).zfill(2) + '/' +
                            self.contsubdir + '/' + 'image_mf_' +
                            str(finalminor).zfill(2) + '.fits')
                        if os.path.isfile(str(b).zfill(2) + '.fits'):
                            mosaiccontinuummfcopystatus[b] = True
                            subs_convim.fitstomir(
                                str(b).zfill(2) + '.fits',
                                str(b).zfill(2))
                            subs_managefiles.director(
                                self, 'rm',
                                str(b).zfill(2) + '.fits')
                        else:
                            mosaiccontinuummfcopystatus[b] = False
                            logger.warning('Beam ' + str(b).zfill(2) +
                                           ' was not copied successfully!')
                # Copy the images over to the mosaic directory
                for b in range(self.NBEAMS):
                    if mosaiccontinuummfcontinuumstatus[
                            b] and mosaiccontinuummfcopystatus[b]:
                        # Get the image beam parameters and the image statistics
                        mosaiccontinuummfcontinuumimagestats[
                            b, :] = subs_imstats.getimagestats(
                                self,
                                str(b).zfill(2))
                        mosaiccontinuummfcontinuumbeamparams[
                            b, :] = subs_readmirhead.getbeamimage(
                                str(b).zfill(2))
                    else:
                        logger.warning(
                            'Skipping Beam ' + str(b).zfill(2) +
                            '! Continuum mf-imaging was not successful or continuum image not available!'
                        )
                # Calculate the synthesised beam and reject outliers (algorithm needs to be updated)
                rejbeams, beamparams = subs_combim.calc_synbeam(
                    mosaiccontinuummfcontinuumbeamparams)
                # Convolve all the images to the calculated beam
                for b in range(self.NBEAMS):
                    if mosaiccontinuummfcontinuumstatus[
                            b] and mosaiccontinuummfcopystatus[b]:
                        try:
                            convol = lib.miriad('convol')
                            convol.map = str(b).zfill(2)
                            convol.fwhm = str(beamparams[0]) + ',' + str(
                                beamparams[1])
                            convol.pa = str(beamparams[2])
                            convol.options = 'final'
                            convol.out = str(b).zfill(2) + '_cv'
                            convol.go()
                            if os.path.isdir(str(b).zfill(2) + '_cv'):
                                mosaiccontinuummfconvolstatus[b] = True
                            else:
                                mosaiccontinuummfconvolstatus[b] = False
                                logger.warning(
                                    'Beam ' + str(b).zfill(2) +
                                    ' could not be convolved to the calculated beam size! File not there!'
                                )
                        except:
                            mosaiccontinuummfconvolstatus[b] = False
                            logger.warning(
                                'Beam ' + str(b).zfill(2) +
                                ' could not be convolved to the calculated beam size!'
                            )
                # Combine all the images using linmos (needs to be updated with proper primary beam model)
                linmosimages = ''
                linmosrms = ''
                for b in range(self.NBEAMS):
                    if mosaiccontinuummfcontinuumstatus[
                            b] and mosaiccontinuummfcopystatus[
                                b] and mosaiccontinuummfconvolstatus[b]:
                        linmosimages = linmosimages + str(b).zfill(2) + '_cv,'
                        linmosrms = linmosrms + str(
                            subs_imstats.getimagestats(
                                self,
                                str(b).zfill(2) + '_cv')[2]) + ','
                linmos = lib.miriad('linmos')
                linmos.in_ = linmosimages.rstrip(',')
                linmos.rms = linmosrms.rstrip(',')
                linmos.out = self.target.rstrip('.MS') + '_mf'
                linmos.go()
                if os.path.isdir(self.target.rstrip('.MS') + '_mf'):
                    mosaiccontinuummfstatus = True
                    subs_convim.mirtofits(
                        self.target.rstrip('.MS') + '_mf',
                        self.target.rstrip('.MS') + '_mf.fits')
                    logger.info(
                        'Mosaicking of multi-frequency image successful!')
                else:
                    mosaiccontinuummfstatus = False
                    logger.error(
                        'Multi-freqeuncy mosaic was not created successfully!')
            else:
                mosaiccontinuummfstatus = True
                logger.info(
                    'Multi-frequency continuum mosaic was already successfully created!'
                )

        # Save the derived parameters to the parameter file

        subs_param.add_param(self, 'mosaic_continuum_mf_status',
                             mosaiccontinuummfstatus)
        subs_param.add_param(self, 'mosaic_continuum_mf_continuumstatus',
                             mosaiccontinuummfcontinuumstatus)
        subs_param.add_param(self, 'mosaic_continuum_mf_copystatus',
                             mosaiccontinuummfcopystatus)
        subs_param.add_param(self, 'mosaic_continuum_mf_convolstatus',
                             mosaiccontinuummfconvolstatus)
        subs_param.add_param(self, 'mosaic_continuum_mf_continuumbeamparams',
                             mosaiccontinuummfcontinuumbeamparams)
        subs_param.add_param(self, 'mosaic_continuum_mf_continuumimagestats',
                             mosaiccontinuummfcontinuumimagestats)