Пример #1
0
    def doTransform_pix(self, module, output, row, column, quarter, julianTime,
                        raPointing, decPointing, rollPointing):

        module = ru.make_col(np.array(module))
        output = ru.make_col(np.array(output))
        row = ru.make_col(np.array(row))
        column = ru.make_col(np.array(column))
        julianTime = ru.make_col(np.array(julianTime))
        raPointing = ru.make_col(np.array(raPointing))
        decPointing = ru.make_col(np.array(decPointing))
        rollPointing = ru.make_col(np.array(rollPointing))

        module = module.astype(int)
        output = output.astype(int)

        rtd = 180 / np.pi

        #        new_mod = [-1, 0:2, -1, 3:17, -1, 18:20, -1];
        new_mod = np.r_[-1, 0:3, -1, 3:18, -1, 18:21, -1]
        output = output + 4 * new_mod[module - 1]

        ra0 = raPointing
        dec0 = decPointing
        drot1 = rollPointing

        rot_3 = ra0
        # 3-rot corresponds to FOV at nominal RA.
        rot_2 = -dec0
        # 2-rot corresponds to FOV at nominal Dec. Note minus sign
        #    since +dec corresponds to -rot

        DCM11, DCM12, DCM13, DCM21, DCM22, DCM23, DCM31, DCM32, DCM33, DCM11c, DCM12c, DCM13c, DCM21c, DCM22c, DCM23c, DCM31c, DCM32c, DCM33c, chip_offset = self.get_direction_matrix(
            julianTime, quarter, drot1, rot_2, rot_3)

        # do conversion from pixels to RA and Dec
        quad = np.mod(output, 4)
        # need to find quadrant in module
        # now convert from row and column to chip lng and lat
        chip_n = np.floor((output + 1) / 2 + 0.1).astype(int) - 1
        # chip number index  NO -1 FOR MATLAB

        plate_scale = self.geomModel.get("plateScale")
        plateScaleCcd = plate_scale[0:plate_scale.size:2]
        plateScaleN = plateScaleCcd[chip_n]
        plateScaleN = np.reshape(plateScaleN, chip_n.shape)

        #   build a vector of pincushion corrections using the same approach as the vector of
        #   plate scales

        pincushionAll = self.geomModel.get("pincushion")
        pincushionAlternateOutputs = pincushionAll[0:pincushionAll.size:2]
        pincushionN = pincushionAlternateOutputs[chip_n]
        pincushionN = np.reshape(pincushionN, chip_n.shape)

        #   convert the row and column coordinates to coordinates centered on the notional center
        #   of the module, with unit vectors pointing towards the readout row/column of the
        #   odd-numbered output

        rowCentered = rm.get_parameters("nRowsImaging") + chip_offset[chip_n,
                                                                      1] - row
        colCentered = rm.get_parameters("nColsImaging") - column

        evenQuadIndex = np.where((quad == 0) | (quad == 2))
        colCentered[evenQuadIndex] = -1 * colCentered[evenQuadIndex]
        colCentered = colCentered + chip_offset[chip_n, 2]

        #   iteratively solve for the longitude and latitude coordinates in arcseconds, with
        #   origin at the notional center of the module; set the convergence tolerance to be
        #   somewhat larger than the eps for the class of the row variable

        convergenceTolerance = 8 * np.finfo(float).eps

        lngr, latm = self.compute_lat_long_iteratively(rowCentered,
                                                       colCentered,
                                                       plateScaleN,
                                                       pincushionN,
                                                       convergenceTolerance)
        lngr = ru.make_col(np.array(lngr))
        latm = ru.make_col(np.array(latm))

        latm = latm / 3600. / rtd
        # latm in radians
        lngm = lngr / np.cos(latm)
        # correct for cos effect going from spherical to rectangular coor
        # one deg of long at one deg of lat is smaller than one deg at zero lat
        # by cos(lat) , amounts to 1/2 arc sec = 1/8 pix
        lngm = lngm / 3600 / rtd
        # lngm in radians

        lpm = np.cos(lngm) * np.cos(latm)
        mpm = np.sin(lngm) * np.cos(latm)
        npm = np.sin(latm)

        #* transform from chip coor to FPA coor Do inverse of above transform (swap matrix row/coln indices)
        lpl = DCM11c[chip_n].reshape(
            chip_n.shape) * lpm + DCM21c[chip_n].reshape(
                chip_n.shape) * mpm + DCM31c[chip_n].reshape(
                    chip_n.shape) * npm
        mpl = DCM12c[chip_n].reshape(
            chip_n.shape) * lpm + DCM22c[chip_n].reshape(
                chip_n.shape) * mpm + DCM32c[chip_n].reshape(
                    chip_n.shape) * npm
        npl = DCM13c[chip_n].reshape(
            chip_n.shape) * lpm + DCM23c[chip_n].reshape(
                chip_n.shape) * mpm + DCM33c[chip_n].reshape(
                    chip_n.shape) * npm

        #* Transform from FPA to RA and Dec Again use inverse of transform matrix
        cosa = DCM11 * lpl + DCM21 * mpl + DCM31 * npl
        cosb = DCM12 * lpl + DCM22 * mpl + DCM32 * npl
        cosg = DCM13 * lpl + DCM23 * mpl + DCM33 * npl

        # Convert direction cosines to equatorial coordinate system
        ra = np.arctan2(cosb, cosa) * rtd
        # transformed RA in deg
        dec = np.arcsin(cosg) * rtd
        # transformed Dec in deg
        ra[np.where(ra < 0)] = ra[np.where(ra < 0)] + 360

        # Return column vectors
        return ra, dec
Пример #2
0
    def ra_dec_2_pix(self,
                     ra,
                     dec,
                     mjds,
                     raPointing=None,
                     decPointing=None,
                     rollPointing=None,
                     deltaRa=None,
                     deltaDec=None,
                     deltaRoll=None,
                     aberrateFlag=True):

        ra = ru.make_col(np.array([ra]))
        dec = ru.make_col(np.array([dec]))
        mjds = ru.make_col(np.array([mjds]))
        isReturnMatrix = (ra.size > 1) & (mjds.size > 1)

        module = np.zeros((ra.size, mjds.size))
        output = np.zeros((ra.size, mjds.size))
        row = np.zeros((ra.size, mjds.size))
        column = np.zeros((ra.size, mjds.size))

        jds = mjds + rm.get_parameters("mjdOffset")

        if (np.all(raPointing == None)) | (np.all(raPointing == -1)):
            pointing = self.pointingModel.get_pointing(mjds)
            raPointing = pointing[0]
            decPointing = pointing[1]
            rollPointing = pointing[2]
        else:
            raPointing = ru.make_col(np.array([raPointing]))
            decPointing = ru.make_col(np.array([decPointing]))
            rollPointing = ru.make_col(np.array([rollPointing]))

        if np.any(deltaRa != None):
            raPointing = raPointing + ru.make_col(np.array([deltaRa]))
            decPointing = decPointing + ru.make_col(np.array([deltaDec]))
            rollPointing = rollPointing + ru.make_col(np.array([deltaRoll]))

        if isReturnMatrix:
            for itime in range(jds.size):
                pixData = self.RaDec2Pix(ra, dec, jds[itime],
                                         raPointing[itime], decPointing[itime],
                                         rollPointing[itime], aberrateFlag)
                module[:, itime] = pixData[0].ravel()
                output[:, itime] = pixData[1].ravel()
                row[:, itime] = pixData[2].ravel()
                column[:, itime] = pixData[3].ravel()
        else:
            pixData = self.RaDec2Pix(ra, dec, jds, raPointing, decPointing,
                                     rollPointing, aberrateFlag)
            module = pixData[0]
            output = pixData[1]
            row = pixData[2]
            column = pixData[3]

        # Adjust inputs to move center of pixel to (0.0, 0.0);
        #
        row = row - 0.5
        column = column - 0.5

        # RaDec2Pix gives row/col on the visable silicon.  Adjust the outputs to be on total accumulation memory:
        #
        row = row + rm.get_parameters("nMaskedSmear")
        column = column + rm.get_parameters("nLeadingBlack")

        #        return module, output, row, column
        if module.size == 1:
            return module[0, 0].astype(int), output[0, 0].astype(int), row[
                0, 0], column[0, 0]
        elif module.shape[1] == 1:
            return module[:, 0].astype(int), output[:, 0].astype(
                int), row[:, 0], column[:, 0]
        else:
            return module.astype(int), output.astype(int), row, column
Пример #3
0
    def do_transform(self, ra, dec, quarter, julianTime, raPointing,
                     decPointing, rollPointing):

        ra = ru.make_col(np.array(ra))
        dec = ru.make_col(np.array(dec))
        julianTime = ru.make_col(np.array(julianTime))
        raPointing = ru.make_col(np.array(raPointing))
        decPointing = ru.make_col(np.array(decPointing))
        rollPointing = ru.make_col(np.array(rollPointing))

        chnNum = rm.get_channel_numbers()

        ra0 = raPointing
        # use input FOV right ascension
        dec0 = decPointing
        # use input FOV dec
        drot1 = rollPointing
        # use input FOV rotation offset

        # Initialize output arrays
        #
        module = np.zeros(ra.shape)
        output = np.zeros(ra.shape)
        row = np.zeros(ra.shape)
        column = np.zeros(ra.shape)

        rot3 = ra0
        # 3-rot corresponds to FOV at nominal RA.
        rot2 = -dec0
        # 2-rot corresponds to FOV at nomial Dec. Note minus sign.
        #    since +dec corresponds to -rot

        # Get the direction cosine matrix and chip geometry constants for the
        # input julian times.
        #
        DCM11, DCM12, DCM13, DCM21, DCM22, DCM23, DCM31, DCM32, DCM33, DCM11c, DCM12c, DCM13c, DCM21c, DCM22c, DCM23c, DCM31c, DCM32c, DCM33c, chipOffset = self.get_direction_matrix(
            julianTime, quarter, drot1, rot2, rot3)

        deg2rad = np.pi / 180.0
        rad2deg = 180 / np.pi
        trar = deg2rad * ra
        # target right ascension (radians) optionally array of values
        tdecr = deg2rad * dec
        # target declination (radians) optionally array of values

        cosa = np.cos(trar) * np.cos(tdecr)
        cosb = np.sin(trar) * np.cos(tdecr)
        cosg = np.sin(tdecr)

        # Now do coordinate transformation: get direction cosines in FPA coordinates
        #
        lpf = DCM11 * cosa + DCM12 * cosb + DCM13 * cosg
        mpf = DCM21 * cosa + DCM22 * cosb + DCM23 * cosg
        npf = DCM31 * cosa + DCM32 * cosb + DCM33 * cosg

        # Convert dir cosines to longitude and lat in FPA coor system
        #
        lat = rad2deg * np.arcsin(npf)
        # transformed  lat +Z' in deg
        lng = rad2deg * np.arctan2(mpf, lpf)
        # transformed long +Y' in deg

        # find which channel this falls onto (+5 to center on the 10-output grid,
        # +1 for 1-offset matlab arrays).  The chnI and chnJ vars are the row and
        # column indices into this 10x10 grid.
        #
        chnI = np.floor(
            lat / rm.get_parameters("halfOffsetModuleAngleDegrees")) + 5
        chnJ = np.floor(
            lng / rm.get_parameters("halfOffsetModuleAngleDegrees")) + 5
        chnI = np.reshape(chnI, (chnI.size, 1))
        chnJ = np.reshape(chnJ, (chnI.size, 1))

        # Find inputs that are outside the FOV
        #
        outOfFov = np.where((chnI < 0) | (chnI > 9) | (chnJ < 0)
                            | (chnJ > 9)  # off FOV
                            | ((chnI <= 1) & (chnJ <= 1))  # exclude module 1
                            | ((chnI <= 1) & (chnJ >= 8))  # exclude module 5
                            | ((chnI >= 8) & (chnJ <= 1))  # exclude module 21
                            | ((chnI >= 8) & (chnJ >= 8)))
        # exclude module 25
        outOfFov = outOfFov[0]

        offFovCode = -1

        row = np.zeros(chnI.shape)
        column = np.zeros(chnI.shape)
        module = np.zeros(chnI.shape)
        output = np.zeros(chnI.shape)

        module[outOfFov, 0] = offFovCode
        output[outOfFov, 0] = offFovCode
        row[outOfFov, 0] = offFovCode
        column[outOfFov, 0] = offFovCode

        inFov = np.where(module != offFovCode)
        # In FOV means it hasn't been set to "out" yet.
        inFov = inFov[0]

        if inFov.size > 0:
            fovDat = self.process_in_FOV(inFov, chnI, chnJ, chnNum, DCM11c,
                                         DCM12c, DCM13c, DCM21c, DCM22c,
                                         DCM23c, DCM31c, DCM32c, DCM33c, lpf,
                                         mpf, npf, chipOffset)
            module[inFov] = fovDat[0].reshape(inFov.size, 1)
            output[inFov] = fovDat[1].reshape(inFov.size, 1)
            row[inFov] = fovDat[2].reshape(inFov.size, 1)
            column[inFov] = fovDat[3].reshape(inFov.size, 1)

        output = 1 + np.mod(output - 1, 4)

        return module, output, row, column
Пример #4
0
    def get_direction_matrix(self, julianTime, seasonInt, drot1, rot2, rot3):
        drot1 = np.array(drot1)
        rot2 = np.array(rot2)
        rot3 = np.array(rot3)

        # Determine the season and roll offset based on the julianTime.
        rollTimeData = self.rollTimeModel.get(julianTime,
                                              ["rollOffsets", "seasons"])
        rollOffset = rollTimeData[:, 0]
        seasonInt = rollTimeData[:, 1]

        deg2rad = np.pi / 180.0

        # Calculate the Direction Cosine Matrix to transform from RA and Dec to FPA coordinates
        rot1 = rm.get_parameters(
            'nominalClockingAngle') + rollOffset + seasonInt * 90.0
        rot1 = rot1 + drot1
        # add optional offset in X'-axis rotation
        rot1 = rot1 + 180
        # Need to account for 180 deg rotation of field due to imaging of mirror
        rot1 = np.fmod(rot1, 360)
        # make small if rot1 < -360 or rot1 > 360

        if (rot1.size != rot2.size) | (rot1.size != rot3.size):
            rot2 = np.tile(rot2, rot1.shape)
            rot3 = np.tile(rot3, rot1.shape)

        rot1 = ru.make_col(rot1)
        rot2 = ru.make_col(rot2)
        rot3 = ru.make_col(rot3)

        srac = np.sin(rot3 * deg2rad)
        # sin phi 3 rotation
        crac = np.cos(rot3 * deg2rad)
        # cos phi
        sdec = np.sin(rot2 * deg2rad)
        # sin theta 2 rotation Note 2 rotation is negative of dec in right hand sense
        cdec = np.cos(rot2 * deg2rad)
        # cos theta
        srotc = np.sin(rot1 * deg2rad)
        # sin psi 1 rotation
        crotc = np.cos(rot1 * deg2rad)
        # cos psi

        # Extract the focal plane geometry constants
        geometryData = self.geomModel.get(["chipTrans", "chipOffset"])
        chipTrans = np.transpose(
            np.reshape(geometryData[:, 0], (3, 42), order='F').copy())
        chipOffset = np.transpose(
            np.reshape(geometryData[:, 1], (3, 42), order='F').copy())

        #     DCM for a 3-2-1 rotation, Wertz p764
        DCM11 = cdec * crac
        DCM12 = cdec * srac
        DCM13 = -sdec
        DCM21 = -crotc * srac + srotc * sdec * crac
        DCM22 = crotc * crac + srotc * sdec * srac
        DCM23 = srotc * cdec
        DCM31 = srotc * srac + crotc * sdec * crac
        DCM32 = -srotc * crac + crotc * sdec * srac
        DCM33 = crotc * cdec

        #     Calculate DCM for each chip relative to center of FOV
        nModules2 = rm.get_parameters('nModules') * 2
        DCM11c = np.zeros((nModules2, 1))
        DCM12c = np.zeros((nModules2, 1))
        DCM13c = np.zeros((nModules2, 1))
        DCM21c = np.zeros((nModules2, 1))
        DCM22c = np.zeros((nModules2, 1))
        DCM23c = np.zeros((nModules2, 1))
        DCM31c = np.zeros((nModules2, 1))
        DCM32c = np.zeros((nModules2, 1))
        DCM33c = np.zeros((nModules2, 1))

        #    print(chipTrans)
        for i in range(nModules2):  # step through each chip
            srac = np.sin(deg2rad * chipTrans[i, 0])
            # sin phi 3 rotation
            crac = np.cos(deg2rad * chipTrans[i, 0])
            # cos phi
            sdec = np.sin(deg2rad * chipTrans[i, 1])
            # sin theta 2 rotation
            cdec = np.cos(deg2rad * chipTrans[i, 1])
            # cos theta
            srotc = np.sin(deg2rad * (chipTrans[i, 2] + chipOffset[i, 0]))
            # sin psi 1 rotation includes rotation offset
            crotc = np.cos(deg2rad * (chipTrans[i, 2] + chipOffset[i, 0]))
            # cos psi

            # DCM for a 3-2-1 rotation, Wertz p762
            DCM11c[i, 0] = cdec * crac
            DCM12c[i, 0] = cdec * srac
            DCM13c[i, 0] = -sdec
            DCM21c[i, 0] = -crotc * srac + srotc * sdec * crac
            DCM22c[i, 0] = crotc * crac + srotc * sdec * srac
            DCM23c[i, 0] = srotc * cdec
            DCM31c[i, 0] = srotc * srac + crotc * sdec * crac
            DCM32c[i, 0] = -srotc * crac + crotc * sdec * srac
            DCM33c[i, 0] = crotc * cdec

        return DCM11, DCM12, DCM13, DCM21, DCM22, DCM23, DCM31, DCM32, DCM33, DCM11c, DCM12c, DCM13c, DCM21c, DCM22c, DCM23c, DCM31c, DCM32c, DCM33c, chipOffset
Пример #5
0
    def process_in_FOV(self, inFov, chnI, chnJ, chnNum, DCM11c, DCM12c, DCM13c,
                       DCM21c, DCM22c, DCM23c, DCM31c, DCM32c, DCM33c, lpf,
                       mpf, npf, chipOffset):

        chnI = np.array(chnI, dtype=int)
        chnJ = np.array(chnJ, dtype=int)

        lpf = np.reshape(lpf, (chnI.size, 1))
        mpf = np.reshape(mpf, (chnI.size, 1))
        npf = np.reshape(npf, (chnI.size, 1))

        # Inernal function to perform the transformation calc into chipspace.
        #

        chnN = np.zeros(chnI.shape)
        chnN[inFov, 0] = chnNum[chnI[inFov, 0], chnJ[inFov, 0]]
        chnN = np.reshape([chnN], (chnI.size, 1))

        chipN = np.zeros(chnI.shape, dtype=int)
        chipN[inFov, 0] = np.fix((chnN[inFov, 0] + 1) / 2).astype(int) - 1
        # chip number index,

        # set up temporary variables to speed the transform lines DAC 16 Mar 2005
        lpFOV = lpf[inFov, 0]
        mpFOV = mpf[inFov, 0]
        npFOV = npf[inFov, 0]
        chipNFov = chipN[inFov, 0]
        lpFOV = np.reshape(lpFOV, (lpFOV.size, 1))
        mpFOV = np.reshape(mpFOV, (lpFOV.size, 1))
        npFOV = np.reshape(npFOV, (npFOV.size, 1))
        inFov = np.reshape(inFov, (inFov.size, 1))

        lpm = DCM11c[chipNFov] * lpFOV + DCM12c[chipNFov] * mpFOV + DCM13c[
            chipNFov] * npFOV
        mpm = DCM21c[chipNFov] * lpFOV + DCM22c[chipNFov] * mpFOV + DCM23c[
            chipNFov] * npFOV
        npm = DCM31c[chipNFov] * lpFOV + DCM32c[chipNFov] * mpFOV + DCM33c[
            chipNFov] * npFOV

        # Define chip coor as: rotation about the center of the module(field flattener lens) &
        #     angular row and column from this center then column 1100 is angle zero
        #     and decreases up and down with increasing angle towards readout amp on
        #     each corner and row 1024 starts after a gap of 39 pixels decreasing
        #     with increasing angle
        #
        rad2deg = 180 / np.pi
        latm = np.arcsin(npm)
        # transformed lat +Z' to chip coor in radians
        lngm = rad2deg * np.arctan2(mpm, lpm) * 3600.
        # transformed long +Y' to chip coor in arc sec
        lngr = lngm * np.cos(latm)
        # correct for cos effect going from spherical to rectangular coor
        # one deg of long at one deg of lat is smaller than one deg at zero lat
        # by cos(lat) , amounts to 1/2 arc sec=1/8 pix
        latm = rad2deg * latm * 3600
        # latm in arc sec

        # Now convert to row and column
        #

        #   obtain the plate scales and generate a vector of plate scales which goes with the
        #   vector of latitude / longitude coordinates.  Note that we are using 1 plate scale per
        #   CCD here -- the "even-numbered" mod/out's plate scale is used for both even and odd
        #   mod/outs.

        plateScalesAll = self.geomModel.get("plateScale")
        plateScaleN = np.reshape(plateScalesAll[(chipNFov) * 2], lngr.shape)

        #   obtain the pincushion parameters and reshape them along the same lines as the plate
        #   scales
        #   there is only one geometry model.

        pincushionAll = self.geomModel.get("pincushion")
        pincushionN = np.reshape(pincushionAll[(chipNFov) * 2], lngr.shape)

        chipOffsetWork2 = np.reshape(chipOffset[chipNFov, 1], lngr.shape)
        chipOffsetWork3 = np.reshape(chipOffset[chipNFov, 2], lngr.shape)

        #   convert the longitude and latitude from arcsec to pixels, and take into account the
        #   pincushion aberration -- these are equivalent to row and column, but with an origin of
        #   coordinates at the notional center of the module

        radius2 = lngr**2 + latm**2
        rowCentered = lngr / plateScaleN * (1 + pincushionN * radius2)
        colCentered = latm / plateScaleN * (1 + pincushionN * radius2)

        #   apply fixed offsets to get to the correct origin of coordinates
        row = np.zeros(chnI.shape)
        column = np.zeros(chnI.shape)
        module = np.zeros(chnI.shape)
        output = np.zeros(chnI.shape)

        pRow = rm.get_parameters(
            "nRowsImaging") - rowCentered + chipOffsetWork2
        row[inFov, 0] = pRow

        colRecentered = colCentered - chipOffsetWork3

        pColn = np.zeros(colRecentered.shape)
        # positive side of chip
        gez = np.where(colRecentered >= 0.0)[0]
        pColn[gez] = rm.get_parameters("nColsImaging") - colRecentered[gez]
        # bottom half of chip
        chnN[inFov[gez], 0] = np.fix((chnN[inFov[gez], 0] - 1) / 2) * 2 + 1

        # negative side of chip
        lz = np.where(colRecentered < 0.0)[0]
        pColn[lz] = rm.get_parameters("nColsImaging") + colRecentered[lz]

        # top half of chip
        chnN[inFov[lz], 0] = np.fix((chnN[inFov[lz], 0] + 1) / 2) * 2

        # set column & output values
        column[inFov, 0] = pColn
        output[inFov, 0] = chnN[inFov, 0]

        # determine module number
        mtemp = np.ceil(output[inFov, 0] / 4) + 1

        mtemp[mtemp >= 5] = mtemp[mtemp >= 5] + 1
        # add one to account for missing module 5
        mtemp[mtemp >= 21] = mtemp[mtemp >= 21] + 1
        # add one again to account for missing module 21
        module[inFov, 0] = mtemp

        # Return the nonzero calculated data:
        #
        nonZeroIndex = module != 0
        module = module[nonZeroIndex]
        output = output[nonZeroIndex]
        row = row[nonZeroIndex]
        column = column[nonZeroIndex]

        return module, output, row, column
Пример #6
0
    def pix_2_ra_dec(self,
                     module,
                     output,
                     row,
                     column,
                     mjds,
                     raPointing=None,
                     decPointing=None,
                     rollPointing=None,
                     deltaRa=None,
                     deltaDec=None,
                     deltaRoll=None,
                     aberrateFlag=True):

        module = ru.make_col(np.array([module]))
        output = ru.make_col(np.array([output]))
        row = ru.make_col(np.array([row]))
        column = ru.make_col(np.array([column]))
        mjds = ru.make_col(np.array([mjds]))

        isReturnMatrix = (module.size > 1) & (mjds.size > 1)

        jds = mjds + rm.get_parameters("mjdOffset")

        ra = np.zeros((module.size, mjds.size))
        dec = np.zeros((module.size, mjds.size))

        if (np.all(raPointing == None)) | (np.all(raPointing == -1)):
            pointing = self.pointingModel.get_pointing(mjds)
            raPointing = pointing[0]
            decPointing = pointing[1]
            rollPointing = pointing[2]
        else:
            raPointing = ru.make_col(np.array([raPointing]))
            decPointing = ru.make_col(np.array([decPointing]))
            rollPointing = ru.make_col(np.array([rollPointing]))

        if np.any(deltaRa != None):
            raPointing = raPointing + ru.make_col(np.array([deltaRa]))
            decPointing = decPointing + ru.make_col(np.array([deltaDec]))
            rollPointing = rollPointing + ru.make_col(np.array([deltaRoll]))

        # Adjust inputs to move center of pixel to (0.0, 0.0);
        #
        row = row + 0.5
        column = column + 0.5

        # Adjust the pixel inputs in CCD coordinates to the coordinates on visible silicon:
        #
        row = row - rm.get_parameters("nMaskedSmear")
        column = column - rm.get_parameters("nLeadingBlack")

        if isReturnMatrix:
            for itime in range(jds.size):
                pixData = self.Pix2RaDec(module, output, row, column,
                                         jds[itime], raPointing[itime],
                                         decPointing[itime],
                                         rollPointing[itime], aberrateFlag)
                ra[:, itime] = pixData[0].ravel()
                dec[:, itime] = pixData[1].ravel()
        else:
            pixData = self.Pix2RaDec(module, output, row, column, jds,
                                     raPointing, decPointing, rollPointing,
                                     aberrateFlag)
            ra = pixData[0]
            dec = pixData[1]

        if ra.size == 1:
            return ra[0, 0], dec[0, 0]
        elif ra.shape[1] == 1:
            return ra[:, 0], dec[:, 0]
        else:
            return ra, dec