Esempio n. 1
0
    def Read(self, firstVis=None):
        err_msg = "Error reading UV file '%s'" % self.name

        # NOTE(bcotton)
        # There is a quirk in the order things are done it
        # that causes what you are trying to misbehave.
        # If you want purely sequential access
        # (probably all you will ever want), simply leave off
        # the firstVis=firstVis.  Alternatively, in your script
        # uv.Read(err, firstVis=firstVis-(nvispio-1)) will do
        # what you want. The problem is that internally,
        # the low level I/O routine is expecting that the value
        # it gets for firstVis is from the last call and it
        # updates it assuming sequential access before reading
        # the file. If you want to use this option to specify
        # where in the file to read, I'll need to find a safe way
        # to make it more obvious without breaking something else.
        if firstVis:
            nvispio = self.uv.List.Dict['nVisPIO'][2][0]
            firstVis = firstVis - (nvispio - 1)

        try:
            self.uv.Read(self._err, firstVis=firstVis)
        except Exception:
            raise Exception(err_msg)

        handle_obit_err(err_msg, self._err)
Esempio n. 2
0
    def write(self):
        """ Writes the appropriate row of the AIPS Table """
        if self._row is None:
            return

        self._table.WriteRow(self._rownr, self._row, self._err)
        handle_obit_err("Error writing row '%s'" % self._rownr, self._err)
Esempio n. 3
0
    def FitMF(self, out_path, **kwargs):
        """
        Fit spectrum to each pixel of an ImageMF.

        Uses ImageMF.PFitSpec2 and passes kwargs (from ImageMF.PFitSpec2 docstring).

        Parameters
        ----------
        out_path : :class:`AIPSPath`
            AIPS catalog entry to write output
        antSize  : float
            If > 0 make primary beam corrections assuming antenna
            diameter (m) antSize (default: 0.0)
        nterm   : int
            Order of fit, 1=intensity, 2=spectral index,
            3=also curvature (default: 2)
        corAlpha : float
            Spectral index correction to apply before fitting
            (default: 0.0)
        """

        err_msg = "Unable to fit pixel spectra to image '%s'." % self.name

        # Check we have the right type of image
        if self.isObitImageMF():
            with img_factory(aips_path=out_path, mode='rw') as out_img:
                try:
                    # Copy the structure of self.img to out_img
                    self.img.Clone(out_img.img, self._err)
                    # Use an imgMF pointer for PFitSpec2
                    ImageMF.PFitSpec2(self.imgMF, out_img.imgMF, self._err,
                                      **kwargs)
                except Exception:
                    raise Exception(err_msg)
                handle_obit_err(err_msg)
Esempio n. 4
0
    def _open_logic(self, uv, err, **kwargs):
        """
        Peforms logic for opening a UV file

        * Opening the UV File if given an AIPS path.
        * Setting up the AIPS Path if given a UV file.
        * Open any Tables attached to the UV file.

        Parameters
        ----------
        uv: :class:`UV` or :class:`AIPSPath`
            Either a Obit UV object or an AIPSPath describing it
        """

        # Given an AIPSPath. open it.
        if isinstance(uv, AIPSPath):
            self._aips_path = uv
            mode = kwargs.pop('mode', 'r')
            self._uv = uv = open_uv(uv, mode=mode)
        # Given an Obit UV file.
        # Construct an AIPSPath
        elif isinstance(uv, UV.UV):
            # FITS and AIPS files have different properties
            if uv.FileType == "FITS":
                name = uv.FileName
                aclass = None
                seq = None
            elif uv.FileType == "AIPS":
                name = uv.Aname
                aclass = uv.Aclass
                seq = uv.Aseq
            else:
                raise ValueError("Invalid FileType '%s'" % uv.FileType)

            self._aips_path = AIPSPath(name,
                                       uv.Disk,
                                       aclass,
                                       seq,
                                       dtype=uv.FileType)

            self._uv = uv
        else:
            raise TypeError("Invalid type '%s'. "
                            "Must be Obit UV object "
                            "or an AIPSPath." % type(uv))

        # Open tables attached to this UV file.
        tables = TableList.PGetList(uv.TableList, err)
        handle_obit_err("Error getting '%s' table list" % self.name)

        # History tables don't work like the other tables
        ignored_tables = ["AIPS HI"]

        self._tables = {
            name: AIPSTable(uv, name, version, 'r', err)
            for version, name in tables if name not in ignored_tables
        }

        self._tables["AIPS HI"] = AIPSHistory(uv, err)
Esempio n. 5
0
    def __getitem__(self, index):
        record = self._table.ReadRec(index + 1, self._err)
        if not record:
            raise IndexError("No history record at index %d" % index + 1)
        handle_obit_err("Error reading history table record at index %d" %
                        index + 1)

        return record
Esempio n. 6
0
    def Write(self, firstVis=None):
        err_msg = "Error writing UV file '%s'" % self.name

        try:
            self.uv.Write(self._err, firstVis=firstVis)
        except Exception:
            raise Exception(err_msg)

        handle_obit_err(err_msg, self._err)
Esempio n. 7
0
    def Open(self, mode):
        err_msg = "Error opening Image file '%s'" % self.name

        try:
            self.img.Open(mode, self._err)
        except Exception:
            raise Exception(err_msg)

        handle_obit_err(err_msg, self._err)
Esempio n. 8
0
    def Open(self, mode):
        err_msg = "Error opening UV file '%s'" % self.name

        try:
            self.uv.Open(mode, self._err)
        except Exception:
            raise Exception

        handle_obit_err(err_msg, self._err)
Esempio n. 9
0
    def Zap(self):
        err_msg = "Error zapping UV file '%s'" % self.name

        try:
            self.uv.Zap(self._err)
        except Exception:
            raise Exception(err_msg)

        handle_obit_err(err_msg, self._err)
        self._clear_uv()
Esempio n. 10
0
    def _open_logic(self, img, err, **kwargs):
        """
        Peforms logic for opening a Image file

        * Opening the Image File if given an AIPS path.
        * Setting up the AIPS Path if given a Image file.
        * Open any Tables attached to the Image file.
        """
        self.mode = kwargs.pop('mode', 'r')
        # Given an AIPSPath. open it.
        if isinstance(img, AIPSPath):
            self._aips_path = img
            self._img = img = open_img(img, mode=self.mode)
        # Given an Obit Image file.
        # Construct an AIPSPath
        elif isinstance(img, Image.Image):
            # FITS and AIPS files have different properties
            if img.FileType == "FITS":
                name = img.FileName
                aclass = None
                seq = None
            elif img.FileType == "AIPS":
                name = img.Aname
                aclass = img.Aclass
                seq = img.Aseq
            else:
                raise ValueError("Invalid FileType '%s'" % img.FileType)

            self._aips_path = AIPSPath(name,
                                       img.Disk,
                                       aclass,
                                       seq,
                                       atype='MA',
                                       label=img.GetName(),
                                       dtype=img.FileType)

            self._img = img
        else:
            raise TypeError("Invalid type '%s'. "
                            "Must be Obit Image object "
                            "or an AIPSPath." % type(img))

        # Open tables attached to this UV file.
        tables = TableList.PGetList(img.TableList, err)
        handle_obit_err("Error getting '%s' table list" % self.name)

        # History tables don't work like the other tables
        ignored_tables = ["AIPS HI"]

        self._tables = {
            name: AIPSTable(img, name, version, 'r', err)
            for version, name in tables if name not in ignored_tables
        }

        self._tables["AIPS HI"] = AIPSHistory(img, err)
Esempio n. 11
0
    def Zap(self):
        err_msg = "Exception zapping image file '%s'" % self.name

        try:
            self.img.Zap(self._err)
        except Exception:
            raise Exception(err_msg)

        handle_obit_err("Error deleting Image file '%s'" % self.name,
                        self._err)
        self._clear_img()
Esempio n. 12
0
    def writefits(self, disk, output, tables_to_copy=['AIPS CC', 'AIPS SN']):
        """ Write the image to a FITS file """

        err_msg = "Unable to write image to %s" % output

        outImage = Image.newPFImage("FITS Image DATA", output, disk, False,
                                    self._err)
        Image.PCopy(self._img, outImage, self._err)
        Image.PCopyTables(self._img, outImage, ['AIPS HI'], tables_to_copy,
                          self._err)
        handle_obit_err(err_msg, self._err)
Esempio n. 13
0
    def Copy(self, to_path):
        """ Copy this image to a new file in to_path.
        """
        err_msg = "Error copying Image file '%s' to '%s'" % (self.name,
                                                             to_path)
        to_img = img_factory(aips_path=to_path, mode='rw')
        try:
            self.img.Copy(to_img.img, self._err)
        except Exception:
            raise Exception(err_msg)

        handle_obit_err(err_msg, self._err)
Esempio n. 14
0
    def PutPlane(self, array, plane=[1, 1, 1, 1, 1]):
        """
        Put the FArray in array in specified image plane.
        """
        err_msg = ("Error putting plane '%s' "
                   "into image '%s'" % (plane, self.name))
        try:
            self.img.PutPlane(array, plane, self._err)
        except Exception:
            raise Exception(err_msg)

        handle_obit_err(err_msg, self._err)
Esempio n. 15
0
    def close(self):
        """ Close the AIPS table """

        # Flush
        Table.PDirty(self._table)

        self._table.Open(Table.READWRITE, self._err)
        handle_obit_err("Error opening table '%s' for flush" % self._name,
                        self._err)
        # Close
        self._table.Close(self._err)
        handle_obit_err("Error closing '%s' table" % self._name, self._err)
Esempio n. 16
0
    def __init__(self, uv, name, version, mode, err, **kwargs):
        """
        Creates an AIPS Table object

        Parameters
        ----------
        uv: :class:`UV`
            Obit UV object associated with this table.
        name: string
            Table name. e.g. "AIPS AN"
        version: integer
            Table version
        mode: string
            "r" to read, "w" to write.
        err: :class:`OErr`
            Obit error stack
        **kwargs (optional): integer, usually
            Additional keyword arguments to pass in to
            the table constructor. For example, the "AIPS FQ"
            frequency table takes a `numIF` keyword argument
            specified the number of spectral windows.
        """
        self._err = err

        if 'w' in mode:
            self._clobber_old_tables(uv, name, err)

        self._table = table = uv.NewTable(Table.READWRITE, name, version, err,
                                          **kwargs)
        handle_obit_err("Error creating table '%s'" % name, err)

        self._table.Open(Table.READWRITE, err)
        handle_obit_err("Error opening table '%s'" % name, err)

        desc = table.Desc.Dict

        nrow = desc['nrow']
        self._name = name = desc['Table name']
        self._version = desc['version']

        self._keywords = AIPSTableKeywords(self._table, name)
        self._fields = fields = self._get_field_defs(desc)
        self._default_row = self._get_row_definitions(self._name, fields)

        self._rows = AIPSTableRows(table, nrow, self._default_row, err)
Esempio n. 17
0
    def close(self):
        """ Closes the wrapped UV file """

        # Close all attached tables
        for table in self._tables.values():
            table.close()

        self._tables = {}

        try:
            self._uv.Close(self._err)
        except AttributeError:
            # Closed
            return
        except Exception:
            raise Exception("Exception closing uv file '%s'" % self.name)

        handle_obit_err("Error closing uv file '%s'" % self.name, self._err)
        self._clear_uv()
Esempio n. 18
0
    def _clobber_old_tables(self, uv, name, err):
        """
        Removes all previously existing versions of table.

        Parameters
        ----------
        uv: :class:`UV`
            Obit UV object
        name: string
            AIPS Table name, "AIPS AN" for instance.
        err: :class:`OErr`
            Obit error stack object
        """
        prev_ver = uv.GetHighVer(name)

        while prev_ver > 0:
            uv.ZapTable(name, prev_ver, err)
            handle_obit_err("Error removing old '%s' table" % name, err)
            prev_ver = uv.GetHighVer(name)
Esempio n. 19
0
    def attach_CL_from_NX_table(self, max_ant_nr):
        """
        Creates a CL table associated with this UV file
        from an NX table.

        Parameters
        ----------
        max_ant_nr : integer
            Maximum antenna number written to the AIPS AN table.
        """
        err_msg = ("Error creating CL table "
                   "from NX table on UV file '%s'" % self.name)

        try:
            UV.PTableCLfromNX(self.uv, max_ant_nr, self._err)
        except Exception:
            raise Exception(err_msg)

        handle_obit_err(err_msg, self._err)
Esempio n. 20
0
    def close(self):
        """ Closes the wrapped Image file """

        # Close all attached tables
        for table in self._tables.values():
            table.close()

        self._tables = {}

        err_msg = "Exception closing image file '%s'" % self.name

        try:
            self._img.Close(self._err)
        except AttributeError:
            # Already closed
            return
        except Exception:
            raise Exception(err_msg)

        handle_obit_err(err_msg, self._err)
        self._clear_img()
Esempio n. 21
0
    def GetPlane(self, array=None, plane=[1, 1, 1, 1, 1]):
        """
        Get an image plane and store it in array.
        Use self.FArray if array is None.
        Default to first image plane.
        Return the opened plane.
        """
        err_msg = ("Error getting plane '%s' "
                   "from image '%s'" % (plane, self.name))

        try:
            self.img.GetPlane(array, plane, self._err)
            if array is None:
                # Plane is retrieved to self.img.FArray
                # Return a deep copy.
                array = FArray.PCopy(self.img.FArray, self._err)
        except Exception:
            raise Exception(err_msg)

        handle_obit_err(err_msg, self._err)
        return array
Esempio n. 22
0
def parse_aips_config(aips_cfg_file):
    """
    Parses an AIPS config file into a
    dictionary with schema
    :code:`{ option: [type, dimensions, value]}`

    :code:`type_` is an enum. Look at ObitTypes.h
    to figure it out.

    :code:`dims` indicate dimensionality of input
    For scalar types :code:`[64,1,1,1,1]` indicates
    a 1D array of length 64 floats.

    String dims need to be handled slightly differently
    First dimension indicates string length so for e.g.
    :code:`["obit", "    ", "abcd"]` has dims :code:`[4,3,1,1,1]`
    So a :code:`[4,1,1,1,1]` implies one string of length 4

    :code:`value` will always be a list and is probably
    nested if :code:`dims is setup appropriately.

    Parameters
    ----------
    aips_cfg_file : str
        AIPS configuration file

    Returns
    -------
    dict
        A dictionary of AIPS configuration options
    """
    err = obit_err()
    info_list = InfoList.InfoList()
    ParserUtil.PParse(aips_cfg_file, info_list, err)
    handle_obit_err(
        "Error parsing Obit configuration file '{}'".format(aips_cfg_file),
        err)

    return InfoList.PGetDict(info_list)
Esempio n. 23
0
def next_seq_nr(aips_path):
    """
    Returns the highest available sequence number for which
    a catalogue entry does not exist

    Parameters
    ----------
    aips_path : :class:`AIPSPath`
        An AIPS path

    Returns
    -------
    integer
        Highest sequence number
    """
    from AIPSDir import PHiSeq, PTestCNO
    from OSystem import PGetAIPSuser

    err = obit_err()
    aips_user = PGetAIPSuser()

    hi_seq = PHiSeq(Aname=aips_path.name, user=aips_user,
                    disk=aips_path.disk, Aclass=aips_path.aclass,
                    Atype=aips_path.atype, err=err)

    handle_obit_err("Error finding highest sequence number", err)

    while True:
        cno = PTestCNO(disk=aips_path.disk, user=aips_user,
                       Aname=aips_path.name, Aclass=aips_path.aclass,
                       Atype=aips_path.atype, seq=hi_seq, err=err)

        handle_obit_err("Error finding catalogue entry", err)

        if cno == -1:
            return hi_seq

        hi_seq += 1
Esempio n. 24
0
    def MergeCC(self):
        """
        Merge the positionally coincidental clean components in the
        attached CC table and attach the merged table.
        """
        err_msg = "Exception merging CC Table in '%s'" % self.name

        cctab = self.tables["AIPS CC"]
        init_nrow = cctab.nrow
        # Create an empty table to hold the merged table
        merged_cctab = self.img.NewTable(Table.READWRITE, "AIPS CC",
                                         cctab.version + 1, self._err)
        try:
            TableUtil.PCCMerge(cctab._table, merged_cctab, self._err)
        except Exception:
            raise Exception(err_msg)
        handle_obit_err(err_msg, self._err)

        # Attach merged version of CC Table
        self.attach_table("AIPS CC", cctab.version + 1)
        merged_cctab = self.tables["AIPS CC"]
        log.info("Merged %d CCs to %d for %s", init_nrow, merged_cctab.nrow,
                 self.name)
        return merged_cctab
Esempio n. 25
0
    def update_descriptor(self, descriptor):
        """
        Update the UV descriptor.

        Parameters
        ----------
        descriptor: dict
            Dictionary containing updates applicable to
            :code:`uv.Desc.Dict`.
        """
        uv = self.uv

        desc = uv.Desc.Dict
        desc.update(descriptor)
        uv.Desc.Dict = desc

        err_msg = "Error updating descriptor on UV file '%s'" % self.name

        try:
            uv.UpdateDesc(self._err)
        except Exception:
            raise Exception(err_msg)

        handle_obit_err(err_msg, self._err)
Esempio n. 26
0
 def __init__(self, uv, err):
     self._err = err
     self._table = History.History('AIPS HI', uv.List, self._err)
     handle_obit_err("Error accessing history table", err)
     self._table.Open(Table.READWRITE, err)
     handle_obit_err("Error opening history table", err)
Esempio n. 27
0
 def close(self):
     self._table.Close(self._err)
     handle_obit_err("Error closing history table", self._err)
Esempio n. 28
0
 def append(self, record):
     self._table.WriteRec(0, record, self._err)
     handle_obit_err("Error appending history table record")
Esempio n. 29
0
 def tablelist(self):
     tables = TableList.PGetList(self.img.TableList, self._err)
     handle_obit_err("Error getting '%s' table list" % self.name)
     return tables
Esempio n. 30
0
def open_img(aips_path, mode=None, MF=False):
    """
    Opens an AIPS/FITS Image file and returns a wrapped :class:`ImageFacade` object.

    Parameters
    ----------
    aips_path: :class:`AIPSPath`
        Obit file object.
    mode(optional): str
        "r" to read, "w" to write, "rw" to read and write.
        Defaults to "r"
    MF(optional): boolean
        Open as an ImageMF?

    Returns
    -------
    :class:`Image`
        An Obit Image object
    """

    err = obit_err()

    if mode is None:
        mode = "r"

    img_mode = img_file_mode(mode)
    exists = False  # Test if the file exists

    if aips_path.dtype == "AIPS":
        if MF:
            img_open = ImageMF.newPAImage
        else:
            img_open = Image.newPAImage
        try:
            img = img_open(aips_path.label, aips_path.name, aips_path.aclass,
                           aips_path.disk, aips_path.seq, exists, err)
        except Exception:
            raise ValueError("Error calling newPAImage on '%s'" % aips_path)
    elif aips_path.dtype == "FITS":
        raise NotImplementedError("newPFImage calls do not currently work")

        try:
            img = Image.newPFImage(aips_path.label, aips_path.name,
                                   aips_path.disk, exists, err)
        except Exception:
            raise ValueError("Error calling newPFImage on '%s'" % aips_path)
    else:
        raise ValueError("Invalid dtype '{}'".format(aips_path.dtype))

    handle_obit_err("Error opening '%s'" % aips_path, err)

    err_msg = "Error opening '%s'" % aips_path

    try:
        img.Open(img_mode, err)
    except Exception:
        raise ValueError(err_msg)

    handle_obit_err(err_msg, err)

    return img