Ejemplo n.º 1
0
def spectrum_linear_fit(spec: Spectrum,
                        wl_low: float = None,
                        wl_high: float = None) -> Tuple[float, float]:
    """
    Applies a linear fit to a Specturm over the specified wavelength range.  If no wl_ values are passed,
    the entirely of the spectrum range is used.
    
    Returns a tuple of ( m, b ) for:
    
    Flux Density = m * Wavelength + b
    
    :param spec: Spectrum to slope fit
    :type spec: Spectrum
    :param wl_low: Low limit of wavelength range.  Defaults to None
    :type wl_low: float
    :param wl_high: Upper limit of wavelength range.  Defaults to None
    :type wl_high: float
    :return: ( m, b ) 
    :rtype: tuple
    """
    wls = spec.getWavelengths()
    if wl_low is not None:
        wls = filter(lambda wl: wl >= wl_low, wls)
    if wl_high is not None:
        wls = filter(lambda wl: wl <= wl_high, wls)
    fluxdata = [
        spec.getFlux(wl) for wl in wls
    ]  # Can't use .getFluxlist here in clase wavelength limits used
    return generic_linear_fit(wls, fluxdata)
Ejemplo n.º 2
0
def source_bin(spec: Spectrum,
               step: float = None,
               init_wl: float = None) -> Spectrum:
    """
    Bins a spectrum beginning given initial wavelength and desired bin spacing (step).  If step and init_wl are not
    passed, this method will detrmine them directly from the source spectrum such that the rest frame spectrum has
    integer wavelengths spaced by 1 Angstrom steps.

    Intended to be used to bin a source spectrum which will then be shifted back into rest frame (via
    binned_source_to_rest).  The rest frame spectrum will already be binned as a result.  
    
    :param step: Desired source frame bin spacing.  Will call source_frame_step( spec, 1 ) if this is not passed.
    :param init_wl: Desired inital bin wavelength.  Will call init_source_wl( spec ) if this is not passed.
    :type spec: Spectrum
    :type step: float
    :type init_wl: float
    :return: Binned source spectrum
    :rtype: Spectrum
    """
    from numpy import std, mean

    step = step or source_frame_step(spec, 1)
    oldwls = spec.getWavelengths()
    if init_wl is None:
        init_wl = init_source_wl(spec)

    max_wl = oldwls[-1]

    newwls = [init_wl]

    flxlist = []
    errlist = []
    newi = 0
    oldi = 0

    neww = newwls[newi]
    oldw = oldwls[oldi]
    while neww + step < max_wl:  # Run until the last wavelength in spec is binned
        flux = []  # clear the current range of flux values
        while oldw < neww + step:  # while the old wl is in the current bin, get its flux and advance to the next
            flux.append(spec.getFlux(oldw))
            oldi += 1
            oldw = oldwls[oldi]

        # see if the flux has more than one value (if so, take the mean and set the err as std deviation)
        # otherwise, assign it that value and error
        if len(flux) > 1:
            err = std(flux)
            flux = float(mean(flux))
        elif len(flux) == 1:
            err = spec.getErr(oldwls[oldi - 1])
            flux = flux[0]

        # if there were no values in this bin range (i.e. the flux variable is still a list, albiet an empty one)
        # then something's wrong.
        if type(flux) == float:
            flxlist.append(flux)
            errlist.append(err)
            while neww + step < oldw:
                neww += step
            newwls.append(neww)
        else:
            print(
                "Well, this is awkward.  You're probably caught in an infinte loop."
            )
            print(
                f"New WL:{new}, Last old wl:{oldw} on spectrun:{spec.getNS()}")

    spec = spec.cpy_info()
    spec.setDict(newwls[:-1], flxlist, errlist)

    return spec