Beispiel #1
0
def Period(current,start_time):
    start=Time(start_time,format='mjd',scale='utc').mjd
    current=start+(float(current)/(60*60*24))
    eph1957 = ELL1Ephemeris('psrj1959.par')
    jpleph = JPLEphemeris(de405)
    mjd = Time(current, format='mjd', scale='utc',
           lon=(74*u.deg+02*u.arcmin+59.07*u.arcsec).to(u.deg).value,
           lat=(19*u.deg+05*u.arcmin+47.46*u.arcsec).to(u.deg).value)

    time=mjd.tdb.mjd #start time in mjd
    time_jd=mjd.tdb.jd #start time in jd
    f_p=eph1957.evaluate('F',time,t0par='PEPOCH')#pulse frequency
    f_dot=eph1957.evaluate('FDOT',time,t0par='PEPOCH')
    P_0=1./f_p #pulse period
    P_1000=1000*P_0 #scale up to get output every 1000 periods
    
    # orbital delay and velocity (lt-s and v/c)
    d_orb = eph1957.orbital_delay(time)
    v_orb = eph1957.radial_velocity(time)

    # direction to target
    dir_1957 = eph1957.pos(time)

    # Delay from and velocity of centre of earth to SSB (lt-s and v/c)
    posvel_earth = jpleph.compute('earth', time_jd)
    pos_earth = posvel_earth[:3]/c.to(u.km/u.s).value
    vel_earth = posvel_earth[3:]/c.to(u.km/u.day).value

    d_earth = np.sum(pos_earth*dir_1957, axis=0)
    v_earth = np.sum(vel_earth*dir_1957, axis=0)

    #GMRT from tempo2-2013.3.1/T2runtime/observatory/observatories.dat
    xyz_gmrt = (1656318.94, 5797865.99, 2073213.72)
    # Rough delay from observatory to center of earth
    # mean sidereal time (checked it is close to rf_ephem.utc_to_last)
    lmst = (observability.time2gmst(mjd)/24. + mjd.lon/360.)*2.*np.pi
    coslmst, sinlmst = np.cos(lmst), np.sin(lmst)
    # rotate observatory vector
    xy = np.sqrt(xyz_gmrt[0]**2+xyz_gmrt[1]**2)
    pos_gmrt = np.array([xy*coslmst, xy*sinlmst,
                         xyz_gmrt[2]*np.ones_like(lmst)])/c.si.value
    vel_gmrt = np.array([-xy*sinlmst, xy*coslmst,
                          np.zeros_like(lmst)]
                        )*2.*np.pi*366.25/365.25/c.to(u.m/u.day).value
    # take inner product with direction to pulsar
    d_topo = np.sum(pos_gmrt*dir_1957, axis=0)
    v_topo = np.sum(vel_gmrt*dir_1957, axis=0)
    
    #total relative velocity
    total_rv = - v_topo - v_earth + v_orb

    L=(1./(1+total_rv))#multiplying factor to find doppler frequency
    f_dp=f_p*L #doppler shifted frequency
    P_dp=1./f_dp #doppler shifted period
    total_delay = d_topo + d_earth + d_orb
    
    period=P_dp
    
    return period
Beispiel #2
0
def wave_to_vel(restWave, wave, flux, fluxError=None, delta=False):
    if delta is True:
        vel = (wave / restWave) * c.to('km/s').value
    else:
        vel = ((wave - restWave) / restWave) * c.to('km/s').value
    flux = flux * (restWave / c.to('km/s').value)
    if fluxError is not None:
        fluxError = fluxError * (restWave / c.to('km/s').value)
        return vel, flux, fluxError
    else:
        return vel, flux
Beispiel #3
0
def vel_to_wave(restWave, vel, flux, fluxError=None, delta=False):
    if delta is True:
        wave = (vel / c.to('km/s').value) * restWave
    else:
        wave = (vel / c.to('km/s').value) * restWave + restWave
    flux = flux / (restWave / c.to('km/s').value)
    if fluxError is not None:
        fluxError = fluxError / (restWave / c.to('km/s').value)
        return vel, flux, fluxError
    else:
        return wave, flux
Beispiel #4
0
 def light_travel_time(self):
     """
     The time in seconds it takes for light to travel from the body to
     the observer.
     """
     return (self.distance_observer_to_body().to(u.m) / c.to(u.m / u.s)).to(
         u.s)
Beispiel #5
0
    def mag2flux(self, spec_in=None):
        """
        Convert magnitudes to flux units. This is important for dealing with standards
        and files from IRAF, which are stored in AB mag units. To be clear, this converts
        to "PHOTFLAM" units in IRAF-speak. Assumes the common flux zeropoint used in IRAF.

        Parameters
        ----------
        spec_in: a Spectrum1D object, optional
            An input spectrum with wavelength of the data points in Angstroms
            as the ``spectral_axis`` and magnitudes of the data as the ``flux``.

        Returns
        -------
        spec_out: specutils.Spectrum1D
            Containing both ``flux`` and ``spectral_axis`` data in which
        the ``flux`` has been properly converted from mag->flux.

        """
        if spec_in is None:
            spec_in = self.object_spectrum

        lamb = spec_in.spectral_axis
        mag = spec_in.flux

        flux = (10.0**((mag + self.zeropt) /
                       (-2.5))) * (cc.to('AA/s').value / lamb**2.0)
        flux = flux * u.erg / u.s / u.angstrom / (u.cm * u.cm)

        spec_out = Spectrum1D(spectral_axis=lamb, flux=flux)

        return spec_out
Beispiel #6
0
def scale_dependence_modification(cosmo, redshift):
    r"""Return the scale-dependence modification kernel :math:`A(k,z)` for
    a given cosmological model.

    Parameters
    ----------
    cosmo : :class:`nbodykit.cosmology.cosmology.Cosmology`
        Cosmological model.
    redshift : float
        Redshift at which quantities are evaluated.

    Returns
    -------
    callable
        Scale-dependence modification kernel as a function of wavenumber
        (in :math:`h`/Mpc).

    """
    SPHERICAL_COLLAPSE_CRITICAL_OVERDENSITY = 1.686
    SPEED_OF_LIGHT_IN_KM_PER_S = c.to('km/s').value
    GROWTH_FACTOR_NORMALISATION = 1.3

    num_factors = GROWTH_FACTOR_NORMALISATION \
        * 3 * cosmo.Omega0_m * SPHERICAL_COLLAPSE_CRITICAL_OVERDENSITY \
        * (cosmo.H0 / SPEED_OF_LIGHT_IN_KM_PER_S) ** 2

    transfer_func = cosmology.power.transfers.CLASS(cosmo, redshift=redshift)

    return lambda k: num_factors / (k**2 * transfer_func(k))
Beispiel #7
0
	def solve_v(self):
		"""
		Solve for the velocity of the line given the expected wavelength.
		The result is returned in km s-1.
		"""
		line_center = self.Params[self.current_component]['Peak'] * self.wavelength.unit
		return c.to(u.km / u.second) * (line_center - self.wavelength) / self.wavelength
Beispiel #8
0
    def ABVega(self):
        """
        Compute AB-Vega conversion
        """
        from astropy.constants import c
        import astropy.units as u
        try:
            import grizli.utils_c
            interp = grizli.utils_c.interp.interp_conserve_c
        except ImportError:
            interp = utils.interp_conserve

        # Union of throughput and Vega spectrum arrays
        full_x = np.hstack([self.wave, VEGA['WAVELENGTH']])
        full_x = full_x[np.argsort(full_x)]

        # Vega spectrum, units of f-lambda flux density, cgs
        # Interpolate to wavelength grid, no extrapolation
        vega_full = interp(full_x,
                           VEGA['WAVELENGTH'],
                           VEGA['FLUX'],
                           left=0,
                           right=0)

        thru_full = interp(full_x, self.wave, self.throughput, left=0, right=0)

        # AB = 0, same units
        absp = 3631 * 1e-23 * c.to(u.m / u.s).value * 1.e10 / full_x**2

        # Integrate over the bandpass, flam dlam
        num = np.trapz(vega_full * thru_full, full_x)
        den = np.trapz(absp * thru_full, full_x)

        return -2.5 * np.log10(num / den)
Beispiel #9
0
def ra_dec_z(x, v, cosmo=None):
    """
    Calculate ra, dec, and redshift for a mock assuming an observer placed at (0,0,0).
    
    Parameters
    ----------
    x: array_like
        Npts x 3 numpy array containing 3-d positions in Mpc/h units
    
    v: array_like
        Npts x 3 numpy array containing 3-d velocities of shape (N,3) in km/s
    
    cosmo: astropy.cosmology object, optional
        default is FlatLambdaCDM(H0=0.7, Om0=0.3)
    
    Returns
    -------
    ra: np.array
        right accession in radians
    dec: np.array
        declination in radians
    z: np.array
        redshift
    """

    #calculate the observed redshift
    if cosmo == None:
        cosmo = cosmology.FlatLambdaCDM(H0=0.7, Om0=0.3)
    c_km_s = c.to('km/s').value

    #remove h scaling from position so we can use the cosmo object
    x = x / cosmo.h

    #compute comoving distance from observer
    r = np.sqrt(x[:, 0]**2 + x[:, 1]**2 + x[:, 2]**2)

    #compute radial velocity
    ct = x[:, 2] / r
    st = np.sqrt(1.0 - ct**2)
    cp = x[:, 0] / np.sqrt(x[:, 0]**2 + x[:, 1]**2)
    sp = x[:, 1] / np.sqrt(x[:, 0]**2 + x[:, 1]**2)
    vr = v[:, 0] * st * cp + v[:, 1] * st * sp + v[:, 2] * ct

    #compute cosmological redshift and add contribution from perculiar velocity
    yy = np.arange(0, 1.0, 0.001)
    xx = cosmo.comoving_distance(yy).value
    f = interp1d(xx, yy, kind='cubic')
    z_cos = f(r)
    redshift = z_cos + (vr / c_km_s) * (1.0 + z_cos)

    #calculate spherical coordinates
    theta = np.arccos(x[:, 2] / r)
    phi = np.arccos(cp)  #atan(y/x)

    #convert spherical coordinates into ra,dec
    ra = phi
    dec = (np.pi / 2.0) - theta

    return ra, dec, redshift
Beispiel #10
0
def ra_dec_z(x, v, cosmo=None):
    """
    Calculate ra, dec, and redshift for a mock assuming an observer placed at (0,0,0).
    
    Parameters
    ----------
    x: array_like
        Npts x 3 numpy array containing 3-d positions in Mpc/h units
    
    v: array_like
        Npts x 3 numpy array containing 3-d velocities of shape (N,3) in km/s
    
    cosmo: astropy.cosmology object, optional
        default is FlatLambdaCDM(H0=0.7, Om0=0.3)
    
    Returns
    -------
    ra: np.array
        right accession in radians
    dec: np.array
        declination in radians
    z: np.array
        redshift
    """

    # calculate the observed redshift
    if cosmo == None:
        cosmo = cosmology.FlatLambdaCDM(H0=0.7, Om0=0.3)
    c_km_s = c.to("km/s").value

    # remove h scaling from position so we can use the cosmo object
    x = x / cosmo.h

    # compute comoving distance from observer
    r = np.sqrt(x[:, 0] ** 2 + x[:, 1] ** 2 + x[:, 2] ** 2)

    # compute radial velocity
    ct = x[:, 2] / r
    st = np.sqrt(1.0 - ct ** 2)
    cp = x[:, 0] / np.sqrt(x[:, 0] ** 2 + x[:, 1] ** 2)
    sp = x[:, 1] / np.sqrt(x[:, 0] ** 2 + x[:, 1] ** 2)
    vr = v[:, 0] * st * cp + v[:, 1] * st * sp + v[:, 2] * ct

    # compute cosmological redshift and add contribution from perculiar velocity
    yy = np.arange(0, 1.0, 0.001)
    xx = cosmo.comoving_distance(yy).value
    f = interp1d(xx, yy, kind="cubic")
    z_cos = f(r)
    redshift = z_cos + (vr / c_km_s) * (1.0 + z_cos)

    # calculate spherical coordinates
    theta = np.arccos(x[:, 2] / r)
    phi = np.arccos(cp)  # atan(y/x)

    # convert spherical coordinates into ra,dec
    ra = phi
    dec = (np.pi / 2.0) - theta

    return ra, dec, redshift
Beispiel #11
0
    def get_corrected_rv(self, obs):
        """Compute a corrected radial velocity for the given observation"""

        # Compute the raw offset: difference between Halpha centroid and true
        # wavelength value
        x0 = obs.measurements[0].x0 * u.angstrom
        raw_offset = (x0 - self.Halpha)

        # precision estimate from line centroid error
        precision = (obs.measurements[0].x0_error *
                     u.angstrom) / self.Halpha * c.to(u.km / u.s)

        # For each sky line (that passes certain quality checks), compute the
        # offset between the predicted wavelength and measured centroid
        # TODO: generalize these quality cuts - see also above in
        # _compute_offset_corrections
        sky_offsets = np.full(3, np.nan) * u.angstrom
        for j, meas in enumerate(obs.measurements[1:]):
            sky_offset = meas.x0 * u.angstrom - meas.info.wavelength
            if (meas.amp > 16 and meas.std_G < 2 and meas.std_G > 0.3
                    and np.abs(sky_offset) <
                    3.3 * u.angstrom):  # MAGIC NUMBER: quality cuts
                sky_offsets[j] = sky_offset

        # final sky offset to apply
        flag = 0
        sky_offset = np.nanmean(sky_offsets)
        if np.isnan(sky_offset.value):
            logger.debug("not correcting with sky line for {0}".format(obs))
            sky_offset = 0 * u.angstrom
            flag = 1

        # apply global sky offset correction - see _compute_offset_corrections()
        sky_offset -= self._night_polys[obs.night](obs.utc_hour) * u.angstrom

        # compute radial velocity and correct for sky line
        rv = (raw_offset - sky_offset) / self.Halpha * c.to(u.km / u.s)

        # correct for offset of median of ∆RV distribution from targets with
        # prior/known RV's
        rv -= self._night_final_offsets[obs.night]

        # rv error
        err = np.sqrt(self._abs_err**2 + precision**2)

        return rv, err, flag
Beispiel #12
0
def mag2flux(mag, wave):
    """Convert flux from AB mag to erg.s-1.cm-2.A-1

    wave is the wavelength in A

    """
    cs = c.to('Angstrom/s').value  # speed of light in A/s
    return 10 ** (-0.4 * (mag + 48.60)) * cs / wave ** 2
Beispiel #13
0
def LOS_velocity(wv,data,hw=0.01,band=False):
    """
    Calculte the Line-of-Sight velocity of given data.
    
    Parameters
    ----------
    wv : ~numpy.ndarray
        A Calibrated wavelength.
    data : ~numpy.ndarray
        n (n>=2) dimensional spectral profile data, 
        the last dimension component must be the spectral component,
        and the size is equal to the size of wv.
    hw : float
        A half width of the horizontal line segment.
    band : str
        A string of the wavelength band.
        It must be the 4 characters in Angstrom unit. ex) '6562', '8542'
        
    Returns
    -------
    losv : ~numpy.ndarray
        n-1 (n>=2) dimensional Line-of_sight velocity value, where n is the
        dimension of the given data.
        
    Example
    -------
    >>> from fisspy.doppler import LOS_velocity
    >>> mask = np.abs(wv) < 1
    >>> losv = LOS_velocity(wv[mask],data[:,:,mask],hw=0.03,band='6562')
    """
    if not band :
        raise ValueError("Please insert the parameter band (str)")
        
    wc, intc =  lambdameter(wv,data,hw,wvinput=True)
    
    if band == '6562' :
        return wc*c.to('km/s').value/6562.817
    elif band == '8542' :
        return wc*c.to('km/s').value/8542.09
    elif band == '5890' :
        return wc*c.to('km/s').value/5890.9399
    elif band == '5434' :
        return wc*c.to('km/s').value/5434.3398
    else:
        raise ValueError("Value of band must be one among"
                         "'6562', '8542', '5890', '5434'")
Beispiel #14
0
def LOS_velocity(wv, data, hw=0.01, band=False):
    """
    Calculte the Line-of-Sight velocity of given data.
    
    Parameters
    ----------
    wv : 1d ndarray
        A Calibrated wavelength.
    data : nd ndarray
        n (n>=2) dimensional spectral profile data, 
        the last dimension component must be the spectral component,
        and the size is equal to the size of wv.
    hw : float
        A half width of the horizontal line segment.
    band : str
        A string of the wavelength band.
        It must be the 4 characters in Angstrom unit. ex) '6562', '8542'
        
    Returns
    -------
    losv : nd ndarray
        n-1 (n>=2) dimensional Line-of_sight velocity value, where n is the
        dimension of the given data.
        
    Example
    -------
    >>> from fisspy.doppler import LOS_velocity
    >>> mask = np.abs(wv) < 1
    >>> losv = LOS_velocity(wv[mask],data[:,:,mask],hw=0.03,band='6562')
    """
    if not band:
        raise ValueError("Please insert the parameter band (str)")

    wc, intc = lambdameter(wv, data, hw, wvinput=True)

    if band == '6562':
        return wc * c.to('km/s').value / 6562.817
    elif band == '8542':
        return wc * c.to('km/s').value / 8542.09
    elif band == '5890':
        return wc * c.to('km/s').value / 5890.9399
    elif band == '5434':
        return wc * c.to('km/s').value / 5434.3398
    else:
        raise ValueError("Value of band must be one among"
                         "'6562', '8542', '5890', '5434'")
def v_to_z(v):
    '''
    Convert km/s to redshift assuming all are using special relativity

    @param v: velocity in km/s

    @return Redshift of object with speed in km/s
    '''
    ckms = c.to('km/s').value
    return np.sqrt((1 + v / ckms) / (1 - v / ckms)) - 1
def z_to_v(z):
    '''
    Convert redshift to km/s assuming shift is due to velocity using special relativity

    @param z: Redshift

    @return speed in km/s assuming shift is due to motion using special relativity
    '''
    ckms = c.to('km/s').value
    return (ckms * ((z + 1)**2 - 1) / ((z + 1)**2 + 1))
Beispiel #17
0
def compute_photon_rate(mag, tic_params, emulate_signal=False):
    """Compute the number of photons/s/cm^2/angstrom for an object of magnitude
    <mag> in a specific passband.
    The result is returned as a `~astropy.units.Quantity` object or None if this
    can't be calculated. If [emulate_signal] is set to True, then it will use a
    lower precision value of h (Planck's constant) to emulate the IAC's SIGNAL
    code (http://catserver.ing.iac.es/signal/)

    In order to work, this routine need a dictionary, <tic_params>, for the
    telecope, instrument, camera parameters. For this routine, the needed entries
    are:
        'flux_mag0'  : the flux in Janskys of a mag=0 object in this band (u.Jy)
        'wavelength' : the central wavelength of the band involved (normally u.nm,
                       although astropy.units wavelength should work)
    """

    if emulate_signal:
        # Equivalent original code below
        # 6.6 magic no. is the mantissa part of Planck's constant(rounded). Most of the
        # exponent part (10^-34) is cancelled by Jansky->erg conversion (10^-23) and
        # erg->Watts (10^-7)
        # m_0 = tic_params['flux_mag0'] * 10000.0/6.6/tic_params['wavelength']

        # Need new version of h at same low precision as SIGNAL's original code
        hc = (6.6e-27 * h.cgs.unit) * c.to(u.angstrom / u.s)

        # Photon energy in ergs/photon
        photon_energy = (hc /
                         tic_params['wavelength'].to(u.angstrom)) / u.photon

        # Convert flux in Janskys (=10^-23 ergs s^-1 cm^-2 Hz^-1) to an energy density per second
        energy_density = tic_params['flux_mag0'].to(
            u.erg / (u.s * u.cm**2 * u.Hz)) * tic_params['wavelength'].to(
                u.Hz, equivalencies=u.spectral())

        # Divide by the energy-per-photon at this wavelength and the wavelength to give us
        # photons per second per cm**2 per Angstrom, matching the astropy version below
        m_0 = energy_density / photon_energy / tic_params['wavelength'].to(
            u.AA)
    else:
        m_0 = tic_params['flux_mag0'].to(u.photon / u.cm**2 / u.s / u.angstrom,
                                         equivalencies=u.spectral_density(
                                             tic_params['wavelength']))

    rate = None
    try:
        rate = m_0 * 10.0**(-0.4 * mag)
    except u.UnitTypeError:
        # astropy.units Quantity, take value
        rate = m_0 * 10.0**(-0.4 * mag.value)
    except TypeError:
        pass

    return rate
Beispiel #18
0
def dv2df(f0, dv):
    """
    Convert a velocity delta to a frequency delta given a central frequency.
    
    :param f0: Rest frequency.
    :type f0: float
    :param dv: Velocity delta in m/s.
    :type dv: float
    :returns: For the given velocity delta the equivalent frequency delta.
    :rtype: float
    """

    return dv * f0 / c.to('m/s').value
Beispiel #19
0
def flux2mag(flux, err_flux, wave):
    """Convert flux from erg.s-1.cm-2.A-1 to AB mag.

    wave is the wavelength in A

    """
    if flux > 0:
        cs = c.to('Angstrom/s').value  # speed of light in A/s
        mag = -48.60 - 2.5 * np.log10(wave ** 2 * flux / cs)
        err_mag = np.abs(2.5 * err_flux / (flux * np.log(10)))
        return (mag, err_mag)
    else:
        return (99, np.inf)
Beispiel #20
0
def df2dv(f0, df):
    """
    Convert a frequency delta to a velocity delta given a central frequency.
    
    :param f0: Rest frequency.
    :type f0: float
    :param df: Frequency delta.
    :type df: float
    :returns: The equivalent velocity delta for the given frequency delta.
    :rtype: float in :math:`\mbox{m s}^{-1}`
    """

    return c.to('m/s').value * (df / f0)
Beispiel #21
0
    def _update_parameter_names(self):
        """
        Update the model parameter names based on the current metadata.
        """

        # Profile parameter names.
        func, parameter_names = self._profiles[self.metadata["profile"]]
        parameter_names = list(parameter_names)

        # Continuum coefficients.
        parameter_names += ["c{0}".format(i) \
            for i in range(self.metadata["continuum_order"] + 1)]

        # Update the bounds.
        bounds = {}
        if self.metadata["profile"] == "gaussian":
            bounds.update({
                "sigma": (-0.5, 0.5),
                "amplitude": (0, 1),
            })

        elif self.metadata["profile"] == "voigt":
            bounds["fwhm"] = (-0.5, 0.5)


        if self.metadata["wavelength_tolerance"] is not None \
        or self.metadata["velocity_tolerance"] is not None:

            # Convert velocity tolerance into wavelength.
            wavelength = self.transitions["wavelength"]
            try:
                wavelength = wavelength[0]
            except IndexError:
                None
            vt = abs(self.metadata.get("velocity_tolerance", None) or np.inf)
            wt = abs(self.metadata.get("wavelength_tolerance", None) or np.inf)

            bound = np.nanmin(
                [wt, wavelength * vt / speed_of_light.to("km/s").value])

            bounds["mean"] = (wavelength - bound, wavelength + bound)

        else:
            # TODO: Allow the wavelength to be fixed.
            raise NotImplementedError("wavelength cannot be fixed yet; "
                                      "set a small tolerance on wavelength")

        self._parameter_names = parameter_names
        self._parameter_bounds = bounds

        return True
Beispiel #22
0
def freq2vel(f0, f):
    """
    Convert a frequency axis to a velocity axis given a central frequency.
    Uses the radio definition of velocity.
    
    :param f0: Rest frequency for the conversion. (Hz)
    :type f0: float
    :param f: Frequencies to be converted to velocity. (Hz)
    :type f: numpy array
    :returns: f converted to velocity given a rest frequency :math:`f_{0}`.
    :rtype: numpy array
    """

    return c.to('m/s').value * (1. - f / f0)
Beispiel #23
0
 def lambdaMeter(self, hw= 0.03, sp= 5e3, wvRange= False,
                 wvinput= True, shift2velocity= False):
     """
     """
     lineShift, intensity = lambdameter(self.wv, self.frame,
                                        ref_spectrum= self.refProfile,
                                        wvRange= wvRange, hw= hw,
                                        wvinput= wvinput)
     
     if shift2velocity:
         LOSvelocity = lineShift * c.to('km/s').value/self.centralWavelength
         return LOSvelocity, intensity
     else:
         return lineShift, intensity
Beispiel #24
0
def jy2Tsr(f, bm=1.0, mK=False):
    """Return [K sr] / [Jy] vs. frequency (in Hz)
    Arguments:
        f = frequencies (Hz)
        bm = Reference solid angle in steradians (Defaults to 1)
        mK = Return in mK sr instead of K sr
    """
    c_cmps = c.to("cm/s").value  # cm/s
    k_boltz = 1.380658e-16  # erg/K
    lam = c_cmps / f  # cm
    fac = 1.0
    if mK:
        fac = 1e3
    return 1e-23 * lam**2 / (2 * k_boltz * bm) * fac
Beispiel #25
0
def vel2freq(f0, vel):
    """
    Convert a velocity axis to a frequency axis given a central frequency.
    Uses the radio definition, :math:`\\nu=f_{0}(1-v/c)`.
    
    :param f0: Rest frequency in Hz.
    :type f0: float
    :param vel: Velocity to convert in m/s.
    :type vel: float or array
    :returns: The frequency which is equivalent to vel.
    :rtype: float or array
    """

    return f0 * (1. - vel / c.to('m/s').value)
Beispiel #26
0
def compare_z(z1, z2, dv):
    """Return true if the difference between z1 and z2 is within dv at
    the mean redshift. Otherwise return False. dv has to be much
    smaller and speed of light as the function does not account for
    relativity."""
    z1 = np.array(z1)
    z2 = np.array(z2)
    dv = np.array(dv)

    dz = np.fabs(z1 - z2)
    z = np.mean([z1, z2])
    if dz / (1. + z) < dv / C.to('km/s').value:
        return True
    else:
        return False
Beispiel #27
0
def compare_z(z1, z2, dv):
    """Return true if the difference between z1 and z2 is within dv at
    the mean redshift. Otherwise return False. dv has to be much
    smaller and speed of light as the function does not account for
    relativity."""
    z1 = np.array(z1)
    z2 = np.array(z2)
    dv = np.array(dv)

    dz = np.fabs(z1 - z2)
    z = np.mean([z1, z2])
    if dz / (1. + z) < dv / C.to('km/s').value:
        return True
    else:
        return False
Beispiel #28
0
def add_6df(simplifiedmastercat, sixdf, tol=1*u.arcmin):
    """
    Adds entries in the catalog for the 6dF survey, or updates v when missing
    """
    from astropy import table
    from astropy.coordinates import SkyCoord
    from astropy.constants import c

    ckps = c.to(u.km/u.s).value

    catcoo = SkyCoord(simplifiedmastercat['RA'].view(np.ndarray)*u.deg, simplifiedmastercat['Dec'].view(np.ndarray)*u.deg)
    sixdfcoo = SkyCoord(sixdf['obsra'].view(np.ndarray)*u.deg, sixdf['obsdec'].view(np.ndarray)*u.deg)

    idx, dd, d3d = sixdfcoo.match_to_catalog_sky(catcoo)
    msk = dd < tol

    sixdfnomatch = sixdf[~msk]

    t = table.Table()
    t.add_column(table.MaskedColumn(name='RA', data=sixdfnomatch['obsra']))
    t.add_column(table.MaskedColumn(name='Dec', data=sixdfnomatch['obsdec']))
    t.add_column(table.MaskedColumn(name='PGC#', data=-np.ones(len(sixdfnomatch), dtype=int), mask=np.ones(len(sixdfnomatch), dtype=bool)))
    t.add_column(table.MaskedColumn(name='NSAID', data=-np.ones(len(sixdfnomatch), dtype=int), mask=np.ones(len(sixdfnomatch), dtype=bool)))
    t.add_column(table.MaskedColumn(name='othername', data=sixdfnomatch['targetname']))
    t.add_column(table.MaskedColumn(name='vhelio', data=sixdfnomatch['z_helio']*ckps))
    #t.add_column(table.MaskedColumn(name='vhelio_err', data=sixdfnomatch['zfinalerr']*ckps))
    t.add_column(table.MaskedColumn(name='distance', data=WMAP9.luminosity_distance(sixdfnomatch['z_helio']).value))

    #fill in anything else needed with -999 and masked
    for nm in simplifiedmastercat.colnames:
        if nm not in t.colnames:
            t.add_column(table.MaskedColumn(name=nm, data=-999*np.ones(len(sixdfnomatch), dtype=int), mask=np.ones(len(sixdfnomatch), dtype=bool)))

    t = table.vstack([simplifiedmastercat, t], join_type='exact')

    #now update anything that *did* match but doesn't have another velocity
    tcoo = SkyCoord(t['RA'].view(np.ndarray)*u.deg, t['Dec'].view(np.ndarray)*u.deg)

    idx, dd, d3d = sixdfcoo.match_to_catalog_sky(tcoo)
    msk = dd < tol

    catmatch = t[idx[msk]]
    sixdfmatch = sixdf[msk]

    msk2 = t['vhelio'][idx[msk]].mask
    t['vhelio'][idx[msk&msk2]] = sixdf['z_helio'][msk2]*ckps

    return t
Beispiel #29
0
def distant_observer_redshift(x, v, period=None, cosmo=None):
    """
    Calculate observed redshifts using the distant observer approximation.
    
    The cosmological redshift is estimated as:
    
    z_cosmo = z*H0/c
    
    where z is the 'z' position, H0 is the Hubble constant at z=0, and c is the speed of
    light.  Note that this is an approximation
    
    Parameters
    ----------
    x: array_like
        Npts x 3 numpy array containing 3-d positions in Mpc/h units
    
    v: array_like
        Npts x 3 numpy array containing 3-d velocities of shape (N,3) in km/s
    
    period: array_like, optional
        periodic boundary conditions of simulation box
    
    Returns
    -------
    redshift: np.array
        'observed' redshift.
    """

    c_km_s = c.to('km/s').value

    #get the peculiar velocity component along the line of sight direction (z direction)
    v_los = v[:, 2]

    #compute cosmological redshift (h=1, note that positions are in Mpc/h)
    z_cos = x[:, 2] * 100.0 / c_km_s

    #redshift is combination of cosmological and peculiar velocities
    z = z_cos + (v_los / c_km_s) * (1.0 + z_cos)

    #reflect galaxies around PBC
    if period is not None:
        z_cos_max = period[2] * 100.00 / c_km_s  #maximum cosmological redshift
        flip = (z > z_cos_max)
        z[flip] = z[flip] - z_cos_max
        flip = (z < 0.0)
        z[flip] = z[flip] + z_cos_max

    return z
Beispiel #30
0
def distant_observer_redshift(x, v, period=None, cosmo=None):
    """
    Calculate observed redshifts using the distant observer approximation.
    
    The cosmological redshift is estimated as:
    
    z_cosmo = z*H0/c
    
    where z is the 'z' position, H0 is the Hubble constant at z=0, and c is the speed of
    light.  Note that this is an approximation
    
    Parameters
    ----------
    x: array_like
        Npts x 3 numpy array containing 3-d positions in Mpc/h units
    
    v: array_like
        Npts x 3 numpy array containing 3-d velocities of shape (N,3) in km/s
    
    period: array_like, optional
        periodic boundary conditions of simulation box
    
    Returns
    -------
    redshift: np.array
        'observed' redshift.
    """

    c_km_s = c.to("km/s").value

    # get the peculiar velocity component along the line of sight direction (z direction)
    v_los = v[:, 2]

    # compute cosmological redshift (h=1, note that positions are in Mpc/h)
    z_cos = x[:, 2] * 100.0 / c_km_s

    # redshift is combination of cosmological and peculiar velocities
    z = z_cos + (v_los / c_km_s) * (1.0 + z_cos)

    # reflect galaxies around PBC
    if period is not None:
        z_cos_max = period[2] * 100.00 / c_km_s  # maximum cosmological redshift
        flip = z > z_cos_max
        z[flip] = z[flip] - z_cos_max
        flip = z < 0.0
        z[flip] = z[flip] + z_cos_max

    return z
Beispiel #31
0
def test_distant_observer():
    """
    test distant observer function
    """
    redshifts = distant_observer_redshift(x,v)
    
    assert len(redshifts)==N, "redshift array is not the correct size"
    
    redshifts = distant_observer_redshift(x,v,period=period)
    
    from astropy.constants import c
    c_km_s = c.to('km/s').value
    z_cos_max = period[2]*100.00/c_km_s
    
    assert len(redshifts)==N, "redshift array is not the correct size"
    assert np.max(redshifts)<=z_cos_max, "PBC is not handeled correctly for redshifts"
Beispiel #32
0
def romer_delay(xyzEarth, xyzObj):
    """
    Calculate Rømer delay (classical light travel time correction) in units of
    days

    Notes:
    ------
    https://en.wikipedia.org/wiki/Ole_R%C3%B8mer
    https://en.wikipedia.org/wiki/R%C3%B8mer%27s_determination_of_the_speed_of_light

    """
    # ephemeris units is in km / s .   convert to m / (julian) day
    convf = c.to('km/day').value
    delay = (xyzEarth * xyzObj).sum(1) / convf

    return delay
Beispiel #33
0
def main():
    tmpname = 'data/templates/F0_+0.5_Dwarf.fits'
    model = Model(tmpname)

    # ftargetname = 'data/spec-4961-55719-0378.fits'
    ftargetname = '/home/zzx/workspace/data/xiamen/P200-Hale_spec/blue/reduce_second/specdir/fawftbblue0073.fits'
    # new_wo, new_fo, new_eo = specio.read_sdss(ftargetname, lw=3660, rw=10170)
    new_wo, new_fo, new_eo = specio.read_iraf(ftargetname)
    unit = func.get_unit(new_fo)
    new_fo = new_fo / unit
    new_eo = new_eo / unit
    # new_wo, new_fo, new_eo = specio.read_iraf(targetname)
    result = fit(model, new_wo, new_fo, new_eo, show=True, isprint=True)

    residual = model.residual

    out_parms = result.params
    # spec_fit = model.get_spectrum(out_parms, new_wo)
    scalepar = model.get_scale_par(out_parms)
    parshift = model.get_shift_par(out_parms)
    print(parshift[1])
    velocity = str(parshift[1] * c.to('km/s'))
    print('shift = ' + velocity)
    myscale = model.get_scale(new_wo, scalepar)

    plt.figure()
    plt.plot(new_wo, myscale)
    plt.show()

    emcee_params = result.params.copy()
    # emcee_params.add('__lnsigma', value=np.log(0.1), min=np.log(1.0e-20),
    #                  max=np.log(1.0e20))
    result_emcee = minimize(residual,
                            params=emcee_params,
                            args=(new_wo, new_fo, new_eo),
                            method='emcee',
                            nan_policy='omit',
                            steps=1000)
    report_fit(result_emcee)
    plt.plot(new_wo, new_fo)
    # plt.plot(new_wo, spec_fit)
    spec_emcee = model.get_spectrum(result_emcee.params, new_wo)
    plt.plot(new_wo, spec_emcee)
    corner.corner(result_emcee.flatchain,
                  labels=result_emcee.var_names,
                  truths=list(result_emcee.params.valuesdict().values()))
    plt.show()
    def BpC_flux(self, spectrum=None, parameters=None):
        """
        Analytic model of the high-order Balmer lines, making up the Pseudo continuum near 3666 A.
    
        Line profiles are Gaussians (for now).  The line ratios are fixed to Storey &^ Hummer 1995, case B, n_e = 10^10 cm^-3.
        This component has 3 parameters:
        
        parameter1 : The flux normalization near the Balmer Edge lambda = 3666 A, F(3666)
        parameter4 : A shift of the line centroids
        parameter5 : The width of the Gaussians
        parameter6 : The log of the electron density
        
        note that all constants, and the units, are absorbed in the
        parameter F(3656 A).  
        
        priors:
        p1 :  Flat, between 0 and the observed flux F(3656).
        p4 :  Determined from Hbeta, if applicable.
        p5 :  Determined from Hbeta, if applicable.
        p6 :  Flat between 2 and 14.
                
        note that all constants, and the units, are absorbed in the
        parameter F(3656 A).  
        """
        normalization = parameters[self.parameter_index("bc_norm")]
        Te = parameters[self.parameter_index("bc_Te")]
        tauBE = parameters[self.parameter_index("bc_tauBE")]
        loffset = parameters[self.parameter_index("bc_loffset")]
        lwidth = parameters[self.parameter_index("bc_lwidth")]
        logNe = parameters[self.parameter_index("bc_logNe")]
        #        lscale         = parameters[self.parameter_index("lscale")]

        c_kms = c.to("km/s")
        edge_wl = balmer_edge * (1 - loffset / c_kms.value)

        n_e = 10.**logNe
        bpc_flux = self.makelines(spectrum.wavelengths, Te, n_e,
                                  loffset / c_kms.value, lwidth / c_kms.value)

        norm_index = find_nearest_index(spectrum.wavelengths, edge_wl)

        fnorm = bpc_flux[norm_index]
        bpc_flux[spectrum.wavelengths <= spectrum.wavelengths[norm_index]] = 0
        bpc_flux *= normalization / fnorm
        #        bpc_flux *= lscale

        return bpc_flux
Beispiel #35
0
def test_distant_observer():
    """
    test distant observer function
    """
    redshifts = distant_observer_redshift(x, v)

    assert len(redshifts) == N, "redshift array is not the correct size"

    redshifts = distant_observer_redshift(x, v, period=period)

    from astropy.constants import c
    c_km_s = c.to('km/s').value
    z_cos_max = period[2] * 100.00 / c_km_s

    assert len(redshifts) == N, "redshift array is not the correct size"
    assert np.max(
        redshifts) <= z_cos_max, "PBC is not handeled correctly for redshifts"
Beispiel #36
0
    def ComovingDistance(self, ze):
        # Function that returns the Comoving Radial Distance to an object at a given redshift
        # Distance to a galaxy that is moving with the Hubble Flow (expanding universe) at a given redshift
        # Input:    Redshift emitted (ze)
        # Output:   DC in Mpc

        # define an array with redshifts, spaced  in intervals of 0.001
        # Note that if you want redshifts smaller than 0.001 you'll need to refine this
        zrange = np.arange(0, ze, 1e-3)

        # 1/H(zrange)*speed of light
        # Speed of light is loaded in modules from astropy, but in units of m/s --> need in km/s
        # FILL THIS IN
        y = 1 / self.HubbleParameter(zrange) * c.to(u.km / u.s)

        # Integrate y numerically over zrange and return in units of Mpc
        # FILL THIS IN
        return simps(y, zrange) * u.Mpc
Beispiel #37
0
def test_distant_observer():
    
    N=100
    x = np.random.random((N,3))
    v = np.random.random((N,3))*0.1
    period = np.array([1,1,1])
    
    redshifts = distant_observer_redshift(x,v)
    
    assert len(redshifts)==N, "redshift array is not the correct size"
    
    redshifts = distant_observer_redshift(x,v,period=period)
    
    from astropy.constants import c
    c_km_s = c.to('km/s').value
    z_cos_max = period[2]*100.00/c_km_s
    
    assert len(redshifts)==N, "redshift array is not the correct size"
    assert np.max(redshifts)<=z_cos_max, "PBC is not handeled correctly for redshifts"
Beispiel #38
0
    def set_transition(self, i, j, fr=-1, ang=0):
        """
        Sets parameters of transition to read
        """
        from astropy.constants import c
        cc = c.to('Angstrom / s')

        self.d.i = i - 1
        self.d.j = j - 1
        self.d.isline = self.atom.ilin[self.d.i, self.d.j] != 0
        self.d.iscont = self.atom.icon[self.d.i, self.d.j] != 0

        if self.d.isline:
            self.d.kr = self.atom.ilin[self.d.i, self.d.j] - 1
            self.d.nnu = self.line[self.d.kr].nnu
            self.d.nu = np.copy(self.line[self.d.kr].nu) * u.Hz
            self.d.l = (cc / self.d.nu).to('Angstrom')
            self.d.dl = (cc * (1.0 / self.d.nu -
                               1.0 / self.line[self.d.kr].nu0)).to('Angstrom')
            self.d.ired = self.line[self.d.kr].ired
        elif self.d.iscont:
            self.d.kr = self.atom.icon[self.d.i, self.d.j] - 1
            self.d.nnu = self.cont[self.d.kr].nnu
            self.d.nu = np.copy(self.cont[self.d.kr].nu) * u.Hz
            self.d.l = (cc / self.d.nu).to('Angstrom')
            self.d.dl = None
            self.d.ired = self.cont[self.d.kr].ired
        else:
            raise RuntimeError('upper and lower level %i, %i are not connected'
                               ' with a radiative transition.' % (i, j))
        if fr == -1:
            self.d.ff = -1
        else:
            self.d.ff = self.d.ired + fr
        self.d.ang = ang

        if self.printinfo:
            print('transition parameters are set to:')
            print(' i   =', self.d.i)
            print(' j   =', self.d.j)
            print(' kr  =', self.d.kr)
            print(' ff  =', self.d.ff)
            print(' ang =', self.d.ang)
Beispiel #39
0
def manually_tweak_simplified_catalog(simplifiedcat):
    """
    This just updates a few entries in the catalog that seem to be missing
    velocities for unclear reasons.

    No longer needed with `add_6df`: they are present.
    """
    from astropy.coordinates import SkyCoord
    from astropy.constants import c

    infolines = """
    46.480833  54.266111   2051.8    No velocity in NED PGC 011632
    46.704583  54.588333   2859.3    No velocity in NED
    50.288333  66.921667   2637.1    Velocity in NED, but no LEDA entry
    99.794583 -1.5075000   2887.9    No velocity in NED
    102.57375 -2.8605556   2699.9    No velocity in NED
    102.93875 -3.6077778   2867.4    No velocity in NED
    114.40708 -26.746667   2964.5    Velocity in NED, LEDA source, but not HyperLeda
    116.32750 -32.516667   2162.0    Velocity in NED, LEDA source, but not HyperLeda
    123.74833 -30.866667   1761.0    Velocity in NED, PGC 023091 (note in NED re; position error?)
    """.split('\n')[1:-1]

    ras = []
    decs = []
    vels = []
    for l in infolines:
        ls = l.split()
        ras.append(float(ls[0]))
        decs.append(float(ls[1]))
        vels.append(float(ls[2]))

    updatecoos = SkyCoord(ras*u.deg, decs*u.deg)
    catcoos = SkyCoord(simplifiedcat['RA'].view(np.ndarray)*u.deg,
                   simplifiedcat['Dec'].view(np.ndarray)*u.deg)
    idx, dd, d3d = updatecoos.match_to_catalog_sky(catcoos)

    simplifiedcat = simplifiedcat.copy()
    simplifiedcat['vhelio'][idx] = vels = np.array(vels)
    simplifiedcat['distance'][idx] = WMAP9.luminosity_distance(
        vels / c.to(u.km / u.s).value).to(u.Mpc).value

    return simplifiedcat
Beispiel #40
0
def manually_tweak_simplified_catalog(simplifiedcat):
    """
    This just updates a few entries in the catalog that seem to be missing
    velocities for unclear reasons.

    No longer needed with `add_6df`: they are present.
    """
    from astropy.coordinates import SkyCoord
    from astropy.constants import c

    infolines = """
    46.480833  54.266111   2051.8    No velocity in NED PGC 011632
    46.704583  54.588333   2859.3    No velocity in NED
    50.288333  66.921667   2637.1    Velocity in NED, but no LEDA entry
    99.794583 -1.5075000   2887.9    No velocity in NED
    102.57375 -2.8605556   2699.9    No velocity in NED
    102.93875 -3.6077778   2867.4    No velocity in NED
    114.40708 -26.746667   2964.5    Velocity in NED, LEDA source, but not HyperLeda
    116.32750 -32.516667   2162.0    Velocity in NED, LEDA source, but not HyperLeda
    123.74833 -30.866667   1761.0    Velocity in NED, PGC 023091 (note in NED re; position error?)
    """.split('\n')[1:-1]

    ras = []
    decs = []
    vels = []
    for l in infolines:
        ls = l.split()
        ras.append(float(ls[0]))
        decs.append(float(ls[1]))
        vels.append(float(ls[2]))

    updatecoos = SkyCoord(ras * u.deg, decs * u.deg)
    catcoos = SkyCoord(simplifiedcat['RA'].view(np.ndarray) * u.deg,
                       simplifiedcat['Dec'].view(np.ndarray) * u.deg)
    idx, dd, d3d = updatecoos.match_to_catalog_sky(catcoos)

    simplifiedcat = simplifiedcat.copy()
    simplifiedcat['vhelio'][idx] = vels = np.array(vels)
    simplifiedcat['distance'][idx] = WMAP9.luminosity_distance(
        vels / c.to(u.km / u.s).value).to(u.Mpc).value

    return simplifiedcat
Beispiel #41
0
def test_distant_observer():

    N = 100
    x = np.random.random((N, 3))
    v = np.random.random((N, 3)) * 0.1
    period = np.array([1, 1, 1])

    redshifts = distant_observer_redshift(x, v)

    assert len(redshifts) == N, "redshift array is not the correct size"

    redshifts = distant_observer_redshift(x, v, period=period)

    from astropy.constants import c
    c_km_s = c.to('km/s').value
    z_cos_max = period[2] * 100.00 / c_km_s

    assert len(redshifts) == N, "redshift array is not the correct size"
    assert np.max(
        redshifts) <= z_cos_max, "PBC is not handeled correctly for redshifts"
Beispiel #42
0
    def HorizonDistance(self, zo):
        # Compute the proper distance to the horizon at a given redshift
        # DC(zo,ze)/(1+zo)
        # input: Redshift of the observer
        # Returns the proper distance (Mpc)

        # define an array with redshifts, spaced  in intervals of 0.001
        # Note that if you want redshifts smaller than 0.001 you'll need to refine this
        zrange = np.arange(zo, 5000, 1e-3)

        # 1/H(zrange)*speed of light
        # Speed of light is loaded in modules from astropy, but in units of m/s --> need in km/s
        # FILL THIS IN
        y = c.to(u.km / u.s) * (1.0 / self.HubbleParameter(zrange))

        # Integrate y numerically over zrange and return in units of Mpc
        # FILL THIS IN
        Comoving = simps(y, zrange) * u.Mpc

        # Proper distance Comoving/(1+z)
        return Comoving / (1 + zo)
Beispiel #43
0
def calc_mag_ab(targetSN, w1, w2):
    """Calculates the AB magnitudes of the bins"""
    for field, sn in zip(fields, targetSN):
        os.chdir(os.path.join(data_dir, "combined_{0}".format(field)))
        fits = "binned_sn{0}_res2.95.fits".format(sn)
        data = pf.getdata(fits, 0)
        w = wavelength_array(fits, axis=1, extension=0) * u.angstrom
        idx = np.where(((w >= w1 * u.angstrom) & (w < w2 * u.angstrom)))
        data = data[:,idx]
        w = w[idx]
        bins = wavelength_array(fits, axis=2, extension=0)
        lines = []
        for i, bin in enumerate(bins):
            f_lambda = data[i]  * np.power(10., -20) * u.erg / u.s / u.cm / u.cm / u.angstrom
            f_lambda = f_lambda.to("erg * s**-1 * cm**-3")
            f_nu = f_lambda * w.to("cm") * w.to("cm") / c.to("cm * Hz")
            m_ab = -2.5 * np.log10(np.median(f_nu.to("Jy")/ (3631 * u.Jy)))
            mv = m_ab - 3
            id = "{0}_bin{1:04d}".format(field, bin)
            line = "{0:20s}{1:10.4f}{2:10.4f}".format(id, m_ab, mv)
            lines.append(line)
        with open("magab_w{0}_{1}.dat".format(w1, w2), "w") as f:
            f.write("\n".join(lines))
Beispiel #44
0
from astropy.constants import c
from astropy.units import km, s
from astropy.io import ascii

from matplotlib.transforms import blended_transform_factory

from collections import defaultdict

from math import ceil

import numpy as np

import sys
import os

c_kms = c.to(km / s).value  # speed of light in km/s
atom = AtomDat()  # atomic data

# Panel label inset format:
bbox = dict(facecolor='w', edgecolor='None')


def make_velocity_scale(vmin, vmax, observed_wavelength, wavelength):
    """
    Makes a velocity scale for a spectrum, with the zero velocity
    defined by the observed wavelength of some spectral feature.

    Parameters
    ----------
    vmin, vmax : float
        Minimum and maximum velocity for the scale.
Beispiel #45
0
    spectral_gaps = []

else:  # this is for the casual user
    lsf='COS_LP1' # not being used, is it?
    instr=['COS','COS']
    lsfranges=np.array([[1130,1450],[1450,1800]])
    gratings=['G130M','G160M']
    cen_wave=['1291','1611']
    slits=['NA','NA']
    lps=['2','2']
    spectral_gaps = [[0,1162.5], [1198,1201.5], [1213.3, 1217.93], [1299.3,1321.6],[1596,1612.8],[1782,2000]]

# fundamental constants
echarge = 4.803204505713468e-10
m_e = 9.10938291e-28
c = C.to('cm/s').value
c2 = 29979245800.0

# store LSFs and FGs
lsfs=[]
fgs=[]
wavegroups=[]
wgidxs=[]
uqwgidxs=[]

outputdir = './'

VPparoutfile = outputdir + field + '_VP.dat'
VPmodeloutfile = outputdir + field + 'VPmodel.fits'
contoutfile = outputdir + 'continua.dat'
largeVPparfile = outputdir + '_VP_log.dat'
Beispiel #46
0
def distant_observer_redshift(x, v, period=None, cosmo=None):
    """
    Calculate observed redshifts, :math:`z_{\\rm obs}`, assuming the distant observer approximation.
    
    The line-of-sight (LOS) is assumed to be the z-direction.
    
    Parameters
    ----------
    x: array_like
        Npts x 3 array containing 3-d positions in Mpc/h units
    
    v: array_like
        Npts x 3 array containing 3-d velocity components of galaxies in km/s
    
    period : array_like, optional
        Length-3 array defining axis-aligned periodic boundary conditions. If only 
        one number, Lbox, is specified, period is assumed to be [Lbox]*3.
    
    Returns
    -------
    redshift : np.array
        array of "observed" redshifts.
    
    Notes
    -----
    This function convolves the peculiar velocities of galaxies with the comological 
    redshift.  The cosmological redshift is estimated as:
    
    .. math::
        z_{\\rm cosmo} = z \\times H_0/c
    
    where :math:`z` is the z-position of the galaxy, :math:`H_0` is the Hubble constant 
    at z=0, and :math:`c` is the speed of light.
    
    The observed redshift is:
    
    .. math::
        z_{\\rm obs} = z_{\\rm cosmo}+(v_{\\rm LOS}/c) \\times (1.0+z_{\\rm cosmo})
    
    where :math:`v_{\\rm LOS}` is the LOS component of the peculiar velocoty of the 
    galaxy.
    
    When ``period`` is not None, and a galaxy's observed redshift, :math:`z_{\\rm obs}`, 
    exceeds the cosmological redshift of period[2], :math:`z_{\\rm cosmo, max}`:
    
    .. math::
        z_{\\rm cosmo, max} = \\text{period[2]}\\times H_0/c
    
    or is less than 0.0, the observed redshift is shifted to lay within the periodic 
    boundaries such that 
    :math:`z^{\\prime}_{\\rm obs} = {z}_{\\rm obs} - z_{\\rm cosmo, max}`
    or :math:`z^{\\prime}_{\\rm obs} = {z}_{\\rm obs} + z_{\\rm cosmo, max}`, 
    respectively.
    
    Examples
    --------
    For demonstration purposes we create a randomly distributed set of points within a 
    periodic unit cube. 
    
    >>> Npts = 1000
    >>> Lbox = 1.0
    >>> period = np.array([Lbox,Lbox,Lbox])
    
    >>> x = np.random.random(Npts)
    >>> y = np.random.random(Npts)
    >>> z = np.random.random(Npts)
    
    We transform our *x, y, z* points into the array shape used by the pair-counter by 
    taking the transpose of the result of `numpy.vstack`. This boilerplate transformation 
    is used throughout the `~halotools.mock_observables` sub-package:
    
    >>> coords = np.vstack((x,y,z)).T
    
    We do the same thing to assign random peculiar velocities:
    
    >>> vx,vy,vz = (np.random.random(Npts),np.random.random(Npts),np.random.random(Npts))
    >>> vels = np.vstack((vx,vy,vz)).T
    
    >>> redshifts = distant_observer_redshift(coords, vels)
    
    """
    
    c_km_s = c.to('km/s').value
    
    #get the peculiar velocity component along the line of sight direction (z direction)
    v_los = v[:,2]
    
    #compute cosmological redshift (h=1, note that positions are in Mpc/h)
    z_cos = x[:,2]*100.0/c_km_s
    
    #redshift is combination of cosmological and peculiar velocities
    z = z_cos+(v_los/c_km_s)*(1.0+z_cos)
    
    #reflect galaxies around PBC
    if period is not None:
        z_cos_max = period[2]*100.00/c_km_s #maximum cosmological redshift
        flip = (z > z_cos_max)
        z[flip] = z[flip] - z_cos_max
        flip = (z < 0.0)
        z[flip] = z[flip] + z_cos_max
    
    return z
Beispiel #47
0
def ra_dec_z(x, v, cosmo=None):
    """
    Calculate the ra, dec, and redshift assuming an observer placed at (0,0,0).
    
    Parameters
    ----------
    x: array_like
        Npts x 3 numpy array containing 3-d positions in Mpc/h
    
    v: array_like
        Npts x 3 numpy array containing 3-d velocities in km/s
    
    cosmo : object, optional
        Instance of an Astropy `~astropy.cosmology` object.  The default is 
        FlatLambdaCDM(H0=0.7, Om0=0.3)
    
    Returns
    -------
    ra : np.array
        right accession in radians
    
    dec : np.array
        declination in radians
    
    redshift : np.array
        "observed" redshift
    
    Examples
    --------
    For demonstration purposes we create a randomly distributed set of points within a 
    periodic unit cube. 
    
    >>> Npts = 1000
    >>> Lbox = 1.0
    >>> period = np.array([Lbox,Lbox,Lbox])
    
    >>> x = np.random.random(Npts)
    >>> y = np.random.random(Npts)
    >>> z = np.random.random(Npts)
    
    We transform our *x, y, z* points into the array shape used by the pair-counter by 
    taking the transpose of the result of `numpy.vstack`. This boilerplate transformation 
    is used throughout the `~halotools.mock_observables` sub-package:
    
    >>> coords = np.vstack((x,y,z)).T
    
    We do the same thing to assign random peculiar velocities:
    
    >>> vx,vy,vz = (np.random.random(Npts),np.random.random(Npts),np.random.random(Npts))
    >>> vels = np.vstack((vx,vy,vz)).T
    
    >>> from astropy.cosmology import WMAP9 as cosmo
    >>> ra, dec, redshift = ra_dec_z(coords, vels, cosmo = cosmo)
    """
    
    #calculate the observed redshift
    if cosmo==None:
        cosmo = cosmology.FlatLambdaCDM(H0=0.7, Om0=0.3)
    c_km_s = c.to('km/s').value
    
    #remove h scaling from position so we can use the cosmo object
    x = x/cosmo.h
    
    #compute comoving distance from observer
    r = np.sqrt(x[:,0]**2+x[:,1]**2+x[:,2]**2)
    
    #compute radial velocity
    ct = x[:,2]/r
    st = np.sqrt(1.0 - ct**2)
    cp = x[:,0]/np.sqrt(x[:,0]**2 + x[:,1]**2)
    sp = x[:,1]/np.sqrt(x[:,0]**2 + x[:,1]**2)
    vr = v[:,0]*st*cp + v[:,1]*st*sp + v[:,2]*ct
    
    #compute cosmological redshift and add contribution from perculiar velocity
    yy = np.arange(0,1.0,0.001)
    xx = cosmo.comoving_distance(yy).value
    f = interp1d(xx, yy, kind='cubic')
    z_cos = f(r)
    redshift = z_cos+(vr/c_km_s)*(1.0+z_cos)

    #calculate spherical coordinates
    theta = np.arccos(x[:,2]/r)
    phi   = np.arccos(cp) #atan(y/x)
    
    #convert spherical coordinates into ra,dec
    ra  = phi
    dec = (np.pi/2.0) - theta
    
    return ra, dec, redshift
Beispiel #48
0
	def __init__(self, splot, obs=None, ion=None, function='Voigt', **kwargs):
		"""
		Build widget elements based on a spectrum plotted in `splot` (type SPlot).
		`splot` may also be a Spectrum object (for which a SPlot will be created).

		Make initial guesses at parameters, build widgets, render the figure.
		"""
		try:

			options = Options( kwargs, {

					'kind'      : 'cubic' , # given to interp1d for continuum
					'bandwidth' : 0.1*u.nm, # user should provide this!
                    'linecolor' : 'k'       # color passed to plt.plot() for lines
				})

			kind      = options('kind')
			bandwidth = options('bandwidth')
			linecolor = options('linecolor')

		except OptionsError as err:
			print(' --> OptionsError:', err)
			raise ProfileError('Unrecognized option given to FittingGUI.__init__()!')

		if function not in ['Voigt', 'Lorentzian', 'Gaussian']:
			raise ProfileError('The only currently implemented functions '
			'for fitting profiles are `Voigt`, `Lorentzian` and `Gaussian`!')

		# grab and/or create the SPlot
		if isinstance(splot, Spectrum):
			splot = SPlot(splot, marker='k-', label='spectrum')

		elif not isinstance(splot, SPlot):
			raise ProfileError('FittingGUI() expects the `splot` argument to '
			'either be a Spectrum or a SPlot!')

		# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
		# if the profile `function` is `Voigt` and we have necessary parameters,
		# show a preview for `b` and `N` and `v`.
		self.any_line_parameters = True if obs or  ion else False
		self.has_line_parameters = True if obs and ion else False
		if self.any_line_parameters and not self.has_line_parameters:
			raise ProfileError('From FittingGUI.__init__(), if the absoption line '
			'parameters `obs` or `ion` are provided, both must be given!')

		if self.has_line_parameters:

			if function != 'Voigt':
				raise ProfileError('From FittingGUI.__init__(), in order to compute the '
				'broadening from the instrument profile of the `obs`ervatory and the '
				'column density for the `ion`, it is expected that we try to fit a `Voigt` '
				'profile `function`!')

			if not isinstance(obs, Observatory):
				raise ProfileError('From FittingGUI.__init__(), if `obs` is provided it should '
				'be of type Observatory!')

			if not hasattr(obs, 'resolution'):
				raise ProfileError('From FittingGUI.__init__(), if an observatory `obs` is '
				'provided, it needs to have a member `resolution`!')

			if not hasattr(ion, 'wavelength') or not hasattr(ion.wavelength, 'unit'):
				raise ProfileError('From FittingGUI.__init__(), the provided `ion` either '
				'did not have a `wavelength` attribute or it has one without units!')

			if not hasattr(ion, 'fvalue'):
				raise ProfileError('From FittingGUI.__init__(), the provide `ion` does not '
				'have an `fvalue` (oscillator strength) attribute!')

			if hasattr(ion.fvalue, 'unit') and ion.fvalue.unit != u.dimensionless_unscaled:
				raise ProfileError('From FittingGUI.__init__(), the osciallator strength, '
				'`fvalue` for an ion must be a dimensionless Quantity!')

			if not hasattr(ion, 'A') or not ion.A:
				raise ProfileError('From FittingGUI.__init__(), the provided `ion` does not '
				'have an `A` (transition probability) attribute!')

			if hasattr(ion.A, 'unit') and ion.A.unit != u.Unit('s-1'):
				raise ProfileError('From FittingGUI.__init__(), the transition probability, '
				'`A`, from the `ion` must be in units of `s-1` if units are present!')

			# the instrument broadening is from R = lambda / delta_lambda
			# FWHM = 2 sqrt( 2 log 2) sigma for the Gaussian instrument profile
			self.R = obs.resolution
			self.sigma_instrument = (ion.wavelength / self.R) / (2 * np.sqrt(2 * np.log(2)))
			self.sigma_instrument_squared = self.sigma_instrument.value ** 2

			# save parameters for later
			self.wavelength = ion.wavelength
			self.fvalue     = ion.fvalue
			self.A          = ion.A

			# the FWHM of the intrinsic line profile (Lorentzian) is proportional to the
			# transition probability (Einstein coeff.) `A`...
			# convert from km s-1 to wavelength units
			self.gamma = (ion.wavelength * (ion.wavelength * ion.A / (2 * np.pi)).to(u.km / u.s) /
				c.si).to(ion.wavelength.unit).value

			# the leading constant in the computation of `N` (per Angstrom per cm-2)
			# self.leading_constant = (m_e.si * c.si / (np.sqrt(np.pi) * e.si**2 * ion.fvalue *
			# 	ion.wavelength.to(u.Angstrom))).value
			self.leading_constant = 1 / (ion.fvalue * ion.wavelength.to(u.AA)**2 * np.pi *
				e.emu**2 / (m_e.si * c.to(u.km/u.s)**2)).value

			# setting `function` to `ModifiedVoigt` only makes a change in how the `Voigt`
			# profile is evaluated by using `self.gamma` instead of self.Params[...]['Gamma']
			function = 'ModifiedVoigt'

		# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

		print('\n We need to extract the lines from the continuum before we '
		'begin the fitting process.')

		# extract the line, continuum, rms from the spectrum
		self.line, self.continuum = Extract(splot, bandwidth=bandwidth, kind=kind)
		self.rms = self.continuum.rms

		print('\n Now select the peaks of each line to be fit.')
		print(' Initial guesses will be made for each line markered.')
		input(' Press <Return> after making your selections ... ')

		# grab all the selected points
		global selected
		points = np.array([
        	[ entry.value for entry in selected['wave'] ],
        	[ entry.value for entry in selected['data'] ]
			])

		# point pairs in ascending order by wavelength
		points = points[:, points[0].argsort()]

		# domain size of the line and the number of components
		self.domainsize = self.line.wave.value[-1] - self.line.wave.value[0]
		self.numlines   = np.shape(points)[1] - 4

		if self.numlines < 1:
			raise ProfileError('FittingGUI() expects at least one line to '
			'be selected for fitting!')

		# final spectral line profile is convolution of the LSP and the
		# line profile function. Gaussian on Gaussian, Gaussian on Lorentzian,
		# etc ... Set the functional form given requested profile function
		self.Evaluate = self.SetFunction(function)

		# initial guesses for parameters given the line locations,
		# containing `L1`, `L2`, etc ... the values of which are themselves
		# dictionaries of parameters (e.g., `FWHM`, `Depth`, etc...) whose values
		# are the initial guesses for those parameters given the location of
		# it`s peak and the number of peaks within the `line`s domain.
		self.Params = {

				'L' + str(line + 1) : self.Parameterize(function, loc)
				for line, loc in enumerate(points[:, 2:-2].T)

			}

		# grab the actual Figure object and it's axis to keep references
		self.splot = splot
		self.fig   = splot.fig
		self.ax    = splot.ax

		# refresh image, but keep any changes in axis limits
		splot.xlim( *splot.ax.get_xlim() )
		splot.ylim( *splot.ax.get_ylim() )
		splot.draw()

		# bring up plot to make room for sliders
		plt.subplots_adjust(bottom = 0.30)

		# resample continuum onto line domain
		self.continuum = self.continuum.copy()
		self.continuum.resample(self.line)

		# common domain for plotting, strip units, wavelengths from continuum
		self.x         = self.continuum.wave.value
		self.continuum = self.continuum.data.value

		# copy of continuum allows for adjustments
		self.y = self.continuum.copy()

		# save the mid-level of the continuum to avoid over-calculation
		self.continuum_level = self.continuum.mean()

		# add plots of each line, keep dictionary of handles
		self.Component = {
			line : plt.plot(self.x, self.y - self.Evaluate(self.x, **parameters),
                linecolor+'--')[0] for line, parameters in self.Params.items()
		}

		# add plot of the continuum
		self.Continuum, = plt.plot(self.x, self.y, 'r-', lw=2)

		# add plot of superposition of each component
		self.Combination, = plt.plot(self.x, self.y - self.SuperPosition(), 'g-')

		# fix the limits on plot
		xmin, xmax = splot.ax.get_xlim()
		ymin, ymax = splot.ax.get_ylim()
		plt.axis([xmin, xmax, ymin, ymax])

		# color scheme for sliders
		theme = {

			'light': {'bg': 'white', 'fg': 'blue'},
			'dark' : {'bg': 'black', 'fg': 'red'}
		}

		# axes for parameter sliders
		self.Axis = {

			# key : axis     xpos , ypos + dy       , xsize, ysize
			line  : plt.axes([0.10, 0.05 + (k+1) * 0.03, 0.65, 0.02], axisbg = 'black')
			for k, line in enumerate( self.Params['L1'].keys() )
		}

		# add an axis to make adjustments to the continuum
		self.Axis['Continuum'] = plt.axes([0.10, 0.05, 0.65, 0.02], axisbg='black')

		# create the sliders for the parameters
		self.Slider = {

			# Slider `key` and widget
			param : widgets.Slider(

				self.Axis[param],    # which axis to put slider on
				param,               # name of parameter (and the slider)
				self.Minimum(param), # set the minimum of the slider
				self.Maximum(param), # set the maximum of the slider
				valinit = self.Params['L1'][param], # initial value
				facecolor = 'c'
			)

			# create a slider for each parameter
			for param in self.Params['L1'].keys()
		}

		# create the slider for the continuum (10% adjustments)
		self.Slider['Continuum'] = widgets.Slider(self.Axis['Continuum'],
			'Continuum', 0.90 * self.continuum_level, 1.10 *
			self.continuum_level, valinit = self.continuum_level,
			facecolor = 'c')

		# connect sliders to update function
		for slider in self.Slider.values():
			slider.on_changed(self.Update)

		# create axis for radio buttons
		self.RadioAxis = plt.axes([0.85, 0.01, 0.1, 0.2],
			axisbg = 'black', frameon = False)

		# create the radio button widget
		self.Radio = widgets.RadioButtons(self.RadioAxis,
			tuple(['L' + str(i+1) for i in range(self.numlines)]),
			active = 0, activecolor = 'c')

		# connect the radio button to it's update function
		self.Radio.on_clicked(self.ToggleComponent)

		# set current component as the first line
		self.current_component = 'L1'

		# make currently selected line bold
		self.Component['L1'].set_linewidth(2)

		# variable allows for the radio buttons to not screw-up the sliders/graphs
		# when switching between lines
		self.stall = False

		# add the initial text for `N` and `b` if applicable.
		# text is along 20% below the y-axis
		if self.has_line_parameters:
			# self.b, self.N, self.v = self.solve_b(), self.solve_N(), self.solve_v()
			self.preview = self.ax.text(xmin, ymin - 0.1 * (ymax - ymin),
				'v: {:>10.4f}        km s-1            b: {:>10.4f}    km s-1'
				'       W: {:>10.4f}\nN:   {:>10.4e}    cm-2      tau_0: {:>10.4f}'.format(
				self.solve_v().value, self.solve_b().value, self.solve_W(), self.solve_N().value,
				self.solve_tau0()), va = 'top')

		# display the text
		self.fig.canvas.draw_idle()
Beispiel #49
0
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg
from matplotlib.transforms import blended_transform_factory

from astropy.table import Table
from astropy.constants import c
from astropy.units import km, s
from astropy.io import ascii

from math import ceil

import numpy as np

import sys
import os

c_kms = c.to(km / s).value
atom = AtomDat()

# Panel label inset format:
bbox = dict(facecolor='w', edgecolor='None')

info = """
The following keypress options are available:

space   Set the zero velocity at the position of the cursor and re-draw.
b       Print a VPFIT fitting region based on two cursor positions
        (requires pressing 'b' twice, once at each extrema).
l       Print a VPFIT line entry at the position of the cursor, guessing the
        column density (assumes b = 20 km/s).
z       Move the plot to a new redshift.
S       Save the figure.
Beispiel #50
0
        mjd = Time(mjd, format='mjd', scale='utc', 
                   lon=(74*u.deg+02*u.arcmin+59.07*u.arcsec).to(u.deg).value,
                   lat=(19*u.deg+05*u.arcmin+47.46*u.arcsec).to(u.deg).value)
        q+=steps


    # orbital delay and velocity (lt-s and v/c)
    d_orb = eph1957.orbital_delay(mjd.tdb.mjd)
    v_orb = eph1957.radial_velocity(mjd.tdb.mjd)

    # direction to target
    dir_1957 = eph1957.pos(mjd.tdb.mjd)

    # Delay from and velocity of centre of earth to SSB (lt-s and v/c)
    posvel_earth = jpleph.compute('earth', mjd.tdb.jd)
    pos_earth = posvel_earth[:3]/c.to(u.km/u.s).value
    vel_earth = posvel_earth[3:]/c.to(u.km/u.day).value

    d_earth = np.sum(pos_earth*dir_1957, axis=0)
    v_earth = np.sum(vel_earth*dir_1957, axis=0)

    #GMRT from tempo2-2013.3.1/T2runtime/observatory/observatories.dat
    xyz_gmrt = (1656318.94, 5797865.99, 2073213.72)
    # Rough delay from observatory to center of earth
    # mean sidereal time (checked it is close to rf_ephem.utc_to_last)
    lmst = (observability.time2gmst(mjd)/24. + mjd.lon/360.)*2.*np.pi
    coslmst, sinlmst = np.cos(lmst), np.sin(lmst)
    # rotate observatory vector
    xy = np.sqrt(xyz_gmrt[0]**2+xyz_gmrt[1]**2)
    pos_gmrt = np.array([xy*coslmst, xy*sinlmst,
                         xyz_gmrt[2]*np.ones_like(lmst)])/c.si.value
def plotEnergySolution(file_name, res_id=None, pixel=[], axis=None):
    '''
    Plot the phase to energy solution for a pixel from the wavlength calibration solution
    file 'file_name'. Provide either the pixel location pixel=(row, column) or the res_id
    for the resonator.

    Args:
        file_name: the wavecal solution file including the path (string)
        res_id: the resonator ID for the plotted pixel. Can use pixel keyword-arg
                instead. (integer)
        pixel: the pixel row and column for the plotted pixel. Can use res_id keyword-arg
               instead. (length 2 list of integers)
        axis: matplotlib axis object on which to display the plot. If no axis is provided
              a new figure will be made.
    '''
    # load file_name
    wave_cal = tb.open_file(file_name, mode='r')
    wavelengths = wave_cal.root.header.wavelengths.read()[0]
    info = wave_cal.root.header.info.read()
    model_name = info['model_name'][0].decode('utf-8')
    calsoln = wave_cal.root.wavecal.calsoln.read()
    debug = wave_cal.root.debug.debug_info.read()
    beamImage = wave_cal.root.header.beamMap.read()

    # parse inputs
    if len(pixel) != 2 and res_id is None:
        wave_cal.close()
        raise ValueError('please supply resonator location or res_id')
    if len(pixel) == 2 and res_id is None:
        row = pixel[0]
        column = pixel[1]
        res_id = beamImage[row][column]
        index = np.where(res_id == np.array(calsoln['resid']))
    elif res_id is not None:
        index = np.where(res_id == np.array(calsoln['resid']))
        if len(index[0]) != 1:
            wave_cal.close()
            raise ValueError("res_id must exist and be unique")
        row = calsoln['pixel_row'][index][0]
        column = calsoln['pixel_col'][index][0]

    # load data
    if len(calsoln['polyfit'][index]) == 0:
        print('pixel has no data')
        return
    poly = calsoln['polyfit'][index][0]
    flag = calsoln['wave_flag'][index][0]
    centers = []
    errors = []
    energies = []
    for ind, wavelength in enumerate(wavelengths):
        hist_fit = debug['hist_fit' + str(ind)][index][0]
        hist_cov = debug['hist_cov' + str(ind)][index][0]
        hist_flag = debug['hist_flag'][index, ind][0]
        if hist_flag == 0:
            if model_name == 'gaussian_and_exp':
                energies.append(h.to('eV s').value * c.to('nm/s').value /
                                np.array(wavelength))

                centers.append(hist_fit[3])
                errors.append(np.sqrt(hist_cov.reshape((5, 5))[3, 3]))
            else:
                raise ValueError("{0} is not a valid fit model name"
                                 .format(model_name))
    wave_cal.close()
    energies = np.array(energies)
    centers = np.array(centers)
    errors = np.array(errors)

    if len(energies) == 0:
        print('pixel has no data')
        return

    R0 = calsoln['R'][index]
    R0[R0 == -1] = np.nan
    with warnings.catch_warnings():
        # rows with all nan values will give an unnecessary RuntimeWarning
        warnings.simplefilter("ignore", category=RuntimeWarning)
        R = np.nanmedian(R0)

    # plot data
    show = False
    if axis is None:
        fig, axis = plt.subplots()
        show = True
    axis.set_xlabel('phase [deg]')
    axis.set_ylabel('energy [eV]')
    axis.errorbar(centers, energies, xerr=errors, linestyle='--', marker='o',
                  markersize=5, markeredgecolor='black', markeredgewidth=0.5,
                  ecolor='black', capsize=3, elinewidth=0.5)

    ylim = [0.95 * min(energies), max(energies) * 1.05]
    axis.set_ylim(ylim)
    xlim = [1.05 * min(centers - errors), 0.92 * max(centers + errors)]
    axis.set_xlim(xlim)

    if poly[0] != -1:
        xx = np.arange(-180, 0, 0.1)
        axis.plot(xx, np.polyval(poly, xx), color='orange')

    xmax = xlim[1]
    ymax = ylim[1]
    dx = xlim[1] - xlim[0]
    dy = ylim[1] - ylim[0]
    flag_dict = pipelineFlags.waveCal
    axis.text(xmax - 0.05 * dx, ymax - 0.05 * dy,
              '{0} : ({1}, {2})'.format(res_id, row, column), ha='right', va='top')
    if poly[0] == -1:
        axis.text(xmax - 0.05 * dx, ymax - 0.1 * dy, flag_dict[flag],
                  color='red', ha='right', va='top')
    else:
        if flag == 9:
            axis.text(xmax - 0.05 * dx, ymax - 0.1 * dy, flag_dict[flag], color='red',
                      ha='right', va='top')
        else:
            axis.text(xmax - 0.05 * dx, ymax - 0.1 * dy, flag_dict[flag],
                      ha='right', va='top')
    axis.text(xmax - 0.05 * dx, ymax - 0.15 * dy, "Median R = {0}".format(round(R, 2)),
              ha='right', va='top')
    if show:
        plt.show(block=False)
    else:
        return axis
Beispiel #52
0
from joebvp import utils as jbu
import os
from linetools.spectra.io import readspec
import numpy as np
from astropy.constants import c

from matplotlib.figure import Figure
from matplotlib.backends.backend_qt5agg import (
    FigureCanvasQTAgg as FigureCanvas,
    NavigationToolbar2QT as NavigationToolbar)

modpath=os.path.abspath(os.path.dirname(__file__))
print os.path.abspath(os.path.dirname(__file__))
Ui_MainWindow, QMainWindow = loadUiType(modpath+'/mainvpwindow.ui')

c= c.to('km/s').value

class LineParTableModel(QAbstractTableModel):
    def __init__(self,fitpars,fiterrors,parinfo,linecmts=None,parent=None):
            QAbstractTableModel.__init__(self,parent)
            self.fitpars=fitpars
            self.fiterrors=fiterrors
            self.parinfo=parinfo
            self.linecmts=linecmts
            self.headers=['Wavelength','Species','z','N','sig(N)','b','sig(b)','v','sig(v)','rely','comment']

    def rowCount(self,parent):
        return len(self.fitpars[0])

    def columnCount(self, parent):
        return 11
Beispiel #53
0
import logging
import sys
from datetime import datetime
from typing import Dict, List, Any, Union

import astropy.units as u
import matplotlib.pyplot as plt
import numpy as np
from astropy.constants import c
from mpl_toolkits.axes_grid1 import host_subplot

from utils.parse import parse_paramfile
from utils.rv_utils import RV, JulianDate, prepare_mass_params, generate_companion_label
from utils.rv_utils import strtimes2jd, join_times, check_core_parameters

c_km_s = c.to(u.kilometer / u.second)  # Speed of light in km/s


def parse_args(args):
    # type: List[str] -> argparse.Namespace
    """RV Argparse parser."""
    parser = argparse.ArgumentParser(description='Radial velocity plotting')
    parser.add_argument('params', help='RV parameters filename', type=str)
    parser.add_argument('-d', '--date', default=None,
                        help='Reference date in format YYYY-MM-DD [HH:MM:SS]. Default=None uses time of now.')
    # parser.add_argument('-r', '--rv_diff', help='RV difference threshold to find')
    parser.add_argument('-o', '--obs_times', help='Times of previous observations YYYY-MM-DD format',
                        nargs='+', default=None)
    parser.add_argument('-l', '--obs_list', help='File with list of obs times.', type=str, default=None)
    # parser.add_argument('-f', '--files', help='Params and obs-times are file'
    #                    ' names to open', action='store_true')
rv=[] #empty array to hold relative velocities of the system
time_elapsed=[]
time_orig=start
real_time=[]
while time_orig<finish:
    time=time_orig
    print "Time left: {0}\n".format(finish-time) 
    f_p=eph1957.evaluate('F',time,t0par='PEPOCH')#pulse frequency
    P_0=1./f_p #pulse period

     # direction to target
    dir_1957 = eph1957.pos(time)

    # Delay from and velocity of centre of earth to SSB (lt-s and v/c)
    posvel_earth = jpleph.compute('earth', time_jd)
    pos_earth = posvel_earth[:3]/c.to(u.km/u.s).value
    vel_earth = posvel_earth[3:]/c.to(u.km/u.day).value

    d_earth = np.sum(pos_earth*dir_1957, axis=0)
    v_earth = np.sum(vel_earth*dir_1957, axis=0)
    
    time+=d_earth/(3600*24)
    time_jd+=d_earth/(3600*24)

    mjd = Time(time, format='mjd', scale='utc',
           lon=(74*u.deg+02*u.arcmin+59.07*u.arcsec).to(u.deg).value,
           lat=(19*u.deg+05*u.arcmin+47.46*u.arcsec).to(u.deg).value)

    #GMRT from tempo2-2013.3.1/T2runtime/observatory/observatories.dat
    xyz_gmrt = (1656318.94, 5797865.99, 2073213.72)
    # Rough delay from observatory to center of earth
Beispiel #55
0
from scipy.interpolate import interp1d

import numpy as np

import os

__all__ = ['read_x1d', 'read_lsf', 'limiting_equivalent_width',
           'significance_level']

datapath = os.path.split(os.path.abspath(__file__))[0] + '/'

dw_orig = dict(G130M=0.00997, G160M=0.01223, G140L=0.083, G185M=0.034,
               G225M=0.034, G285M=0.04, G230L=0.39)

c_kms = c.to(km / s)

# Cache for the LSF values:
cache_lsf = {}


def read_x1d(filename):
    """ Reads an x1d format spectrum from CalCOS.

    Parameters
    ----------
    filename : str
        x1d filename.

    Returns
    -------
Beispiel #56
0
quality = []

for comp_name in comps.keys():
    name += [comp_name]
    ion += [comp_name.split('_')[1]]
    comment += [comps[comp_name]['Comment']]
    wrest += [comps[comp_name]['wrest']]
    zfit_aux = comps[comp_name]['zfit']
    zfit += [zfit_aux]  # component redshift from fit
    zcmp_aux = comps[comp_name]['zcomp']
    zcmp += [zcmp_aux]  # middle of component vlim
    vlim_zcmp = np.array((comps[comp_name]['vlim']))  # w/r zcmp
    vmin_zcmp += [vlim_zcmp[0]]
    vmax_zcmp += [vlim_zcmp[1]]

    zlim_zcmp = zcmp_aux + vlim_zcmp * (1 + zcmp_aux) / c.to('km/s').value  # w/r zcmp
    vlim_zfit = (zlim_zcmp - zfit_aux) * c.to('km/s').value / (1 + zfit_aux)  # w/r zfit
    vmin_zfit += [vlim_zfit[0]]
    vmax_zfit += [vlim_zfit[1]]

    # quantities that are independent of redshift
    logn += [comps[comp_name]['Nfit']]
    b += [comps[comp_name]['bfit']]
    quality += [comps[comp_name]['Quality']]

# Create table
comp_table = Table()
comp_table.add_column(Column(name='name', data=name))
comp_table.add_column(Column(name='ion', data=ion))
comp_table.add_column(Column(name='comment', data=comment))
comp_table.add_column(Column(name='zcmp', data=zcmp))
Beispiel #57
0
    # mjd = Time('2013-05-16 23:45:00', scale='utc').mjd+np.linspace(0.,finish, steps)
    # mjd = Time(mjd, format='mjd', scale='utc',
    #          lon=(74*u.deg+02*u.arcmin+59.07*u.arcsec).to(u.deg).value,
    #         lat=(19*u.deg+05*u.arcmin+47.46*u.arcsec).to(u.deg).value)
    #    time+=steps

    # orbital delay and velocity (lt-s and v/c)
    d_orb = eph1957.orbital_delay(mjd.tdb.mjd)
    v_orb = eph1957.radial_velocity(mjd.tdb.mjd)

    # direction to target
    dir_1957 = eph1957.pos(mjd.tdb.mjd)

    # Delay from and velocity of centre of earth to SSB (lt-s and v/c)
    posvel_earth = jpleph.compute("earth", mjd.tdb.jd)
    pos_earth = posvel_earth[:3] / c.to(u.km / u.s).value
    vel_earth = posvel_earth[3:] / c.to(u.km / u.day).value

    d_earth = np.sum(pos_earth * dir_1957, axis=0)
    v_earth = np.sum(vel_earth * dir_1957, axis=0)

    # GMRT from tempo2-2013.3.1/T2runtime/observatory/observatories.dat
    xyz_gmrt = (1656318.94, 5797865.99, 2073213.72)
    # Rough delay from observatory to center of earth
    # mean sidereal time (checked it is close to rf_ephem.utc_to_last)
    lmst = (observability.time2gmst(mjd) / 24.0 + mjd.lon / 360.0) * 2.0 * np.pi
    coslmst, sinlmst = np.cos(lmst), np.sin(lmst)
    # rotate observatory vector
    xy = np.sqrt(xyz_gmrt[0] ** 2 + xyz_gmrt[1] ** 2)
    pos_gmrt = np.array([xy * coslmst, xy * sinlmst, xyz_gmrt[2] * np.ones_like(lmst)]) / c.si.value
    vel_gmrt = (
Beispiel #58
0
def CartesianToSky(pos, cosmo, velocity=None, observer=[0,0,0], zmax=100., frame='icrs'):
    r"""
    Convert Cartesian position coordinates to RA/Dec and redshift,
    using the specified cosmology to convert radial distances from
    the origin into redshift.

    If velocity is supplied, the returned redshift accounts for the
    additional peculiar velocity shift.

    Users should ensure that ``zmax`` is larger than the largest possible
    redshift being considered to avoid an interpolation exception.

    .. note::
        Cartesian coordinates should be in units of Mpc/h and velocity
        should be in units of km/s.

    Parameters
    ----------
    pos : dask array
        a N x 3 array holding the Cartesian position coordinates in Mpc/h
    cosmo : :class:`~nbodykit.cosmology.cosmology.Cosmology`
        the cosmology used to meausre the comoving distance from ``redshift``
    velocity : array_like
        a N x 3 array holding velocity in km/s
    observer : array_like, optional
        a length 3 array holding the observer location
    zmax : float, optional
        the maximum possible redshift, should be set to a reasonably large
        value to avoid interpolation failure going from comoving distance
        to redshift
    frame : string ('icrs' or 'galactic')
        speciefies which frame the Cartesian coordinates is. Useful if you know
        the simulation (usually cartesian) is in galactic units but you want
        to convert to the icrs (ra, dec) usually used in surveys.

    Returns
    -------
    ra, dec, z : dask array
        the right ascension (in degrees), declination (in degrees), and
        redshift coordinates. RA will be in the range [0,360] and DEC in the
        range [-90, 90]

    Notes
    -----
    If velocity is provided, redshift-space distortions are added to the
    real-space redshift :math:`z_\mathrm{real}`, via:

    .. math::

            z_\mathrm{redshift} = ( v_\mathrm{pec} / c ) (1 + z_\mathrm{reals})

    Raises
    ------
    TypeError
        If the input columns are not dask arrays
    """
    from astropy.constants import c
    from scipy.interpolate import interp1d

    if not isinstance(pos, da.Array):
        pos = da.from_array(pos, chunks=100000)

    pos = pos - observer
    # RA,dec coordinates (in degrees)
    ra, dec = CartesianToEquatorial(pos, frame=frame)

    # the distance from the origin
    r = da.linalg.norm(pos, axis=-1)

    def z_from_comoving_distance(x):
        zgrid = numpy.logspace(-8, numpy.log10(zmax), 1024)
        zgrid = numpy.concatenate([[0.], zgrid])
        rgrid = cosmo.comoving_distance(zgrid)
        return interp1d(rgrid, zgrid)(x)

    # invert distance - redshift relation
    z = r.map_blocks(z_from_comoving_distance)

    # add in velocity offsets?
    if velocity is not None:

        vpec = (pos * velocity).sum(axis=-1) / r

        z += vpec / c.to('km/s').value * (1 + z)

    return da.stack((ra, dec, z), axis=0)
Beispiel #59
0
import astropy.units as apu
from astropy.constants import h, c, u
import numpy as np

one_arcsec = 1.0/3600.0

erg_per_eV = apu.eV.to("erg")
erg_per_keV = erg_per_eV * 1.0e3
keV_per_erg = 1.0 / erg_per_keV
eV_per_erg = 1.0 / erg_per_eV

hc = (h*c).to("keV*angstrom").value
clight = c.to("cm/s").value
ckms = c.to_value("km/s")

sigma_to_fwhm = 2.*np.sqrt(2.*np.log(2.))
sqrt2pi = np.sqrt(2.*np.pi)

m_u = u.to("g").value

elem_names = ["", "H", "He", "Li", "Be", "B", "C", "N", "O",
              "F", "Ne", "Na", "Mg", "Al", "Si", "P", "S",
              "Cl", "Ar", "K", "Ca", "Sc", "Ti", "V", "Cr",
              "Mn", "Fe", "Co", "Ni", "Cu", "Zn"]

cosmic_elem = [1, 2, 3, 4, 5, 9, 11, 15, 17, 19,
               21, 22, 23, 24, 25, 27, 29, 30]
metal_elem = [6, 7, 8, 10, 12, 13, 14, 16, 18, 20, 26, 28]

atomic_weights = np.array([0.0, 1.00794, 4.00262, 6.941, 9.012182, 10.811,
                           12.0107, 14.0067, 15.9994, 18.9984, 20.1797,
Beispiel #60
0
def HelioCorrect( obs, *spectra, **kwargs ):
    """
    Perform heliocentric velocity corrects on `spectra` based on
    `obs`ervatory information (longitude, latitude, altitude) and the
    member attributes, ra (right ascension), dec (declination), and jd
    (julian date) from the `spectra`.
    """
    try:

        # define function parameters
        options = Options( kwargs,
            {
                'verbose': False # display messages, progress
            })

        # assign parameters
        verbose = options('verbose')

        # check `obs` type
        if not issubclass( type(obs), Observatory):
            raise VelocityError('HelioCorrect() expects its first argument to '
            'be derived from the Observatory class.')
        elif ( not hasattr(obs, 'latitude') or not hasattr(obs,'longitude') or
            not hasattr(obs, 'altitude') ):
            raise VelocityError('HelioCorrect expects `obs`ervatory to have '
            'all three: latitude, longitude, and altitude attributes.')

        # check `spectra` arguments
        for a, spectrum in enumerate(spectra):
            if type(spectrum) is not Spectrum:
                raise VelocityError('HelioCorrect() expects all `spectrum` '
                'arguments to be of type Spectrum.')
            if not spectrum.ra or not spectrum.dec or not spectrum.jd:
                raise VelocityError('Spectrum {} lacks one or all of `ra`, '
                '`dec`, and `jd`; from HelioCorrect().'.format(a))
            if not hasattr(spectrum.ra, 'unit'):
                raise VelocityError('From HelioCorrect(), in spectrum {}, '
                '`ra` doesn`t have units!'.format(a))
            if not hasattr(spectrum.dec, 'unit'):
                raise VelocityError('From HelioCorrect(), in spectrum {}, '
                '`dec` doesn`t have units!'.format(a))
            if not hasattr(spectrum.jd, 'unit'):
                raise VelocityError('From HelioCorrect(), in spectrum {}, '
                '`jd` doesn`t have units!'.format(a))

        if verbose:
            display = Monitor()
            print(' Running HelioCorrect on {} spectra ...'
                .format(len(spectra)))

        for a, spectrum in enumerate(spectra):

            # heliocentric velocity correction in km s^-1,
            # the `astrolibpy...helcorr` function doesn't work with units,
            # so I convert to appropriate units and strip them.
            hcorr = helcorr(
                    obs.longitude.to(u.degree).value,
                    obs.latitude.to(u.degree).value,
                    obs.altitude.to(u.meter).value,
                    spectrum.ra.to(u.hourangle).value,
                    spectrum.dec.to(u.degree).value,
                    spectrum.jd.to(u.day).value
                )[1] * u.km / u.second

            # apply correction to wave vector,
            # del[Lambda] / Lambda = del[V] / c
            spectrum.wave -= spectrum.wave * hcorr / c.to(u.km / u.second)

            # show progress if desired
            if verbose: display.progress(a, len(spectra))

        # finalize progress bar (erase)
        if verbose: display.complete()

    except OptionsError as err:
        print(' --> OptionsError:', err)
        raise VelocityError('Failed to perform HelioCorrect() task.')

    except DisplayError as err:
        print(' --> DisplayError:', err)
        raise VelocityError('Exception from Display.Monitor in HelioCorrect().')