Exemplo n.º 1
0
    def __init__(self, nu, dnu, phi, weights=None):
        """
        RMSynth(nu, dnu, phi, weights=None, isl2=False)

        Initializes the RMSynth class.  For an image, this needs only be done
        once.  Each LOS may be inverted individually using the
        compute_dirty_image method.

        Inputs:
            nu-     A vector containing frequency(Hz) values. Either way they
                    must be ordered from lowest to highest value.
            dnu-    Width of the frequency channels (in Hz).
            phi-    The requested phi axis.  Use numpy.arange to construct.
            weights-A vector containing weights. Must be the same length as nu.
                    Values should be between 0 and 1.  If no weights vector is
                    given, it will be assumed that each value has weight 1.

        Outputs:
            None
        """
        # parameters used for gridding
        self.m = 6  # number of grid cells overwhich the GCF spans
        self.alpha = 1.5  # oversampling ratio

        self.dphi = phi[1] - phi[0]
        self.nphi = len(phi)

        self.dl2 = 1. / self.nphi / self.dphi / self.alpha
        self.nl2 = self.alpha * self.nphi

        stdout.write('RMSynth Initializing... ')
        stdout.flush()

        # equal weighting for all frequencies by default.
        if weights is None:
            weights = numpy.ones(len(nu))

        if len(nu) != len(weights):
            msg = 'The length of weight and frequency vectors must be equal!'
            raise IndexError(msg)

        # for now store the ungridded l2s (for diagnostics)
        self.l2_nonuni = self.convert_nu_to_l2(nu, dnu)

        self.weights_nonuni = numpy.flipud(weights)

        # another gridding parameter, derived from m and alpha
        self.beta = numpy.pi *\
            numpy.sqrt((self.m / self.alpha) ** 2. *
                       (self.alpha - 0.5) ** 2 - 0.8)

        self.l20 = self.compute_l20()
        self.l2i = self.l2_nonuni[0] - self.m * self.dl2 * numpy.pi

        # this axis is actually \lambda^2/\pi
        self.l2 = numpy.arange(0, self.nl2, 1) * self.dl2 + self.l2i / numpy.pi
        self.l2_beam = numpy.arange(0, self.nl2 * 2., 1) * self.dl2 / 2. \
            + self.l2i / numpy.pi

        self.phi = -self.dphi * self.nphi * 0.5 \
            + numpy.arange(0, self.nphi, 1) * self.dphi

        self.grid_corr = G.gridnorm(self.phi, self.dl2, self.m, self.beta)
        self.tndx_phi = int(0.5 * self.nphi * (self.alpha - 1))

        [self.rmsf, self.rmsf_phi] = self.compute_rmsf()

        stdout.write('Complete.\n')
Exemplo n.º 2
0
    def compute_rmsf(self):
        """
        RMSynth.compute_rmsf()

        Inverts the given polarization vector to arrive at the dirty dispersion
        function.

        Inputs:
            None
        Outputs:
            1-  A map containing the RMSF.  A numpy array of complex values.
            2-  A map containing the RMSF phi axis.
        """

        # RMSF image size must be twice that of the df image for CLEANing
        phi_center = 0.5 * ((numpy.max(self.phi) + self.dphi) +
                            numpy.min(self.phi))
        phi_range = (numpy.max(self.phi) + self.dphi) - numpy.min(self.phi)

        rmsf_phi = phi_center - phi_range +\
            numpy.arange(2 * self.nphi) * self.dphi

        try:

            # Convolve weights with the GCF
            [l2_grid, w_grid] = G.grid_1d(self.weights_nonuni,
                                          self.l2_nonuni / numpy.pi,
                                          self.dl2 / 2., self.m, self.alpha)

            # Put the convolved points on a grid
            weights4rmsf = G.sample_grid(self.l2_beam, l2_grid, w_grid)

        except TypeError:
            print type(self.weights)
            print len(self.weights)
            print type(self.l2_nonuni)
            print len(self.l2_nonuni)
            print self.dphi
            print self.nphi * 2.
            raise

        rmsf = numpy.fft.fftshift(numpy.fft.fft(weights4rmsf))
        tndx_phi = int(self. nphi * (self.alpha - 1))
        rmsf = rmsf[tndx_phi:tndx_phi + 2 * self.nphi]

        #for indx in range(2 * self.nphi):
            #rot = 2. * (self.l20 - self.l2i) * rmsf_phi[indx]
            ## shift results by the L20 and by the initial l2 value to account
            ## for the fact that we start at L2!=0 as FFT expects
            #rmsf[indx] = numpy.complex(math.cos(rot), math.sin(rot)) *\
                #rmsf[indx]

        rot = 2. * (self.l20 - self.l2i) * rmsf_phi
        # shift results by the L20 and by the initial l2 value to account
        # for the fact that we start at L2!=0 as FFT expects
        rmsf *= numpy.exp(complex(0, 1) * rot)

        gridnorm = G.gridnorm(rmsf_phi, self.dl2 / 2., self.m, self.beta)

        rmsf = rmsf / gridnorm

        # The normalization should be as such that the rmsf has a peak
        # value of 1
        self.K = 1. / abs(rmsf[self.nphi])

        # normalize the rmsf
        rmsf = rmsf * self.K

        # adjust the normalization
        # because the rmsf has twice as many pixels as the image
        self.K = 2. * self.K

        return rmsf, rmsf_phi