예제 #1
0
def test_statistics_gui_roi_spectrum(specviz_gui):
    # Ensure that the test is run on an unmodified workspace instance
    workspace = new_workspace(specviz_gui)
    hub = Hub(workspace=workspace)

    # Make region of interest cutout, using default cutout at .3 from the
    # middle in either direction
    specviz_gui.current_workspace.current_plot_window.plot_widget._on_add_linear_region()

    # Simulate cutout for truth data
    spectrum = extract_region(hub.plot_item._data_item.spectrum,
                              SpectralRegion(*hub.selected_region_bounds))

    # pull out stats dictionary
    stats_dict = specviz_gui.current_workspace._plugin_bars['Statistics'].stats

    # Generate truth comparisons
    truth_dict = {'mean': spectrum.flux.mean(),
                  'median': np.median(spectrum.flux),
                  'stddev': spectrum.flux.std(),
                  'centroid': centroid(spectrum, region=None),
                  'snr': "N/A",
                  'fwhm': fwhm(spectrum),
                  'ew': equivalent_width(spectrum),
                  'total': line_flux(spectrum),
                  'maxval': spectrum.flux.max(),
                  'minval': spectrum.flux.min()}

    # compare!
    assert stats_dict == truth_dict

    workspace.close()
예제 #2
0
def test_statistics_gui_roi_spectrum(specviz_gui):
    # Ensure that the test is run on an unmodified workspace instance
    workspace = new_workspace(specviz_gui)
    hub = Hub(workspace=workspace)

    # Make region of interest cutout, using default cutout at .3 from the
    # middle in either direction
    specviz_gui.current_workspace.current_plot_window.plot_widget._on_add_linear_region(
    )

    # Simulate cutout for truth data
    spectrum = extract_region(hub.plot_item._data_item.spectrum,
                              SpectralRegion(*hub.selected_region_bounds))

    # pull out stats dictionary
    stats_dict = specviz_gui.current_workspace._plugin_bars['Statistics'].stats

    # Generate truth comparisons
    truth_dict = {
        'mean': spectrum.flux.mean(),
        'median': np.median(spectrum.flux),
        'stddev': spectrum.flux.std(),
        'centroid': centroid(spectrum, region=None),
        'snr': "N/A",
        'fwhm': fwhm(spectrum),
        'ew': equivalent_width(spectrum),
        'total': line_flux(spectrum),
        'maxval': spectrum.flux.max(),
        'minval': spectrum.flux.min()
    }

    # compare!
    assert stats_dict == truth_dict

    workspace.close()
예제 #3
0
    def cut_edges(self, mini, maxi):
        """Cut the spectrum in wavelength range.

        Parameters
        ----------
        mini: float
            Lower limit to cut the spectrum.

        maxi: float
            Upper limit to cut the spectrum.

        Returns
        -------
        out: NirsdustSpectrum object
            Return a new instance of class NirdustSpectrum cut in wavelength.
        """
        region = su.SpectralRegion(mini * u.AA, maxi * u.AA)
        cutted_spec1d = sm.extract_region(self.spec1d, region)
        cutted_freq_axis = cutted_spec1d.spectral_axis.to(u.Hz)
        new_len = len(cutted_spec1d.flux)
        kwargs = attr.asdict(self)
        kwargs.update(
            spec1d=cutted_spec1d,
            spectrum_length=new_len,
            frequency_axis=cutted_freq_axis,
        )

        return NirdustSpectrum(**kwargs)
예제 #4
0
    def update_statistics(self):
        """
        Retrieves the current data item in the workspace and calculates the
        set of statistics on its information.
        """
        if self.hub.workspace is None or self.hub.plot_item is None:
            return self.clear_statistics()

        # If the plot item is not visible, don't bother updating stats
        if not self.hub.plot_item.visible:
            return self.clear_statistics()

        spec = self.hub.data_item.spectrum if self.hub.data_item is not None else None
        spectral_region = self._get_workspace_region()

        self._current_spectrum = spec
        self._reconnect_item_signals()

        # Check for issues and extract
        # region from input spectra:
        if spec is None:
            self.set_status("No data selected.")
            return self.clear_statistics()
        elif not isinstance(spec, Spectrum1D):
            self.set_status("Spectrum was not found.")
            return self.clear_statistics()
        else:
            spec = self._spectrum_with_plot_units(spec)

        if spectral_region is not None:
            if not check_unit_compatibility(spec, spectral_region):
                self.set_status("Region units are not compatible with "
                                "selected data's spectral axis units.")
                return self.clear_statistics()
            spectral_region = clip_region(spec, spectral_region)
            if spectral_region is None:
                self.set_status("Region out of bound.")
                return self.clear_statistics()
            try:
                idx1, idx2 = spectral_region.bounds
                if idx1 == idx2:
                    self.set_status("Region over single value.")
                    return self.clear_statistics()
                spec = extract_region(spec, spectral_region)
                if not len(spec.flux) > 0:
                    self.set_status("Regione range is too small.")
                    return self.clear_statistics()
            except ValueError as e:
                self.set_status("Region could not be extracted "
                                "from target data.")
                return self.clear_statistics()
        elif self._workspace_has_region():
            self.set_status("Region has no units")
            return self.clear_statistics()

        # Compute stats and update widget:
        self.stats = compute_stats(spec)
        self._update_stat_widgets(self.stats)
        self.set_status(self._get_target_name())
예제 #5
0
    def update_statistics(self):
        if self.hub.workspace is None or self.hub.plot_item is None:
            return self.clear_statistics()

        # If the plot item is not visible, don't bother updating stats
        if not self.hub.plot_item.visible:
            return self.clear_statistics()

        spec = self.hub.data_item.spectrum if self.hub.data_item is not None else None
        spectral_region = self._get_workspace_region()

        self._current_spectrum = spec

        # Check for issues and extract
        # region from input spectra:
        if spec is None:
            self.set_status("No data selected.")
            return self.clear_statistics()
        if spectral_region is not None:
            if not check_unit_compatibility(spec, spectral_region):
                self.set_status("Region units are not compatible with "
                                "selected data's spectral axis units.")
                return self.clear_statistics()
            spectral_region = clip_region(spec, spectral_region)
            if spectral_region is None:
                self.set_status("Region out of bound.")
                return self.clear_statistics()
            try:
                idx1, idx2 = spectral_region.bounds
                if idx1 == idx2:
                    self.set_status("Region over single value.")
                    return self.clear_statistics()
                spec = extract_region(spec, spectral_region)
            except ValueError as e:
                self.set_status("Region could not be extracted "
                                "from target data.")
                return self.clear_statistics()
        elif self._workspace_has_region():
            self.set_status("Region has no units")
            return self.clear_statistics()

        # Compute stats and update widget:
        self.stats = compute_stats(spec)
        self._update_stat_widgets(self.stats)
        self.set_status(self._get_target_name())
예제 #6
0
    def _add_fittable_model(self, model_type):
        if issubclass(model_type, models.Polynomial1D):
            text, ok = QInputDialog.getInt(self, 'Polynomial1D',
                                           'Enter Polynomial1D degree:')
            # User decided not to create a model after all
            if not ok:
                return

            model = model_type(int(text))
        else:
            model = model_type()

        # Grab any user-defined regions so we may initialize parameters only
        # for the selected data.
        inc_regs = self.hub.spectral_regions
        spec = self._get_selected_plot_data_item().data_item.spectrum

        if inc_regs is not None:
            spec = extract_region(spec, inc_regs)

        # Initialize the parameters
        model = initialize(model, spec.spectral_axis, spec.flux)

        self._add_model(model)
예제 #7
0
input_list = []
input_list.append(input('NII wavelengths:'))
input_list.append(input('HeI1 wavelengths:'))
input_list.append(input('FeII1 wavelengths:'))
input_list.append(input('OI1 wavelengths:'))

ew_list = []
cont_lst = []
##iterate through each observation to calculate Intensity.
for cont, spec in zip(cont_list, data):
    ew_iter = []
    cont_iter = []
    for inp, region in zip(input_list, region_list):
        cont_iter.append(
            extract_region(cont,
                           SpectralRegion(region[0] * u.AA,
                                          region[1] * u.AA)).flux)
        ew_iter.append(
            equivalent_width(spec,
                             regions=SpectralRegion(
                                 int(inp.split(' ')[0]) * u.AA,
                                 int(inp.split(' ')[1]) * u.AA),
                             continuum=extract_region(
                                 cont,
                                 SpectralRegion(region[0] * u.AA,
                                                region[1] * u.AA)).flux))
    ew_list.append(ew_iter)
    cont_lst.append(cont_iter)

ew1 = []
ew2 = []
예제 #8
0
    def __init__(self,
                 spectrumIn,
                 wline,
                 band,
                 polyOrder=1,
                 widthFactor=4.,
                 verbose=0):
        # =======================================================================
        # Initial check in spectral_axis
        # =======================================================================
        if not (isinstance(spectrumIn.spectral_axis, u.Quantity)
                and isinstance(spectrumIn.flux, u.Quantity)):
            raise ValueError("Spectral axis must be a `Quantity` object.")
            if not spectrumIn.spectral_axis.unit == u.um:
                raise ValueError("Spectral axis is not in units of microns")

        self.polyOrder = polyOrder
        resv = self.get_spec_resolution(int(band[1]),
                                        np.array(wline, dtype=float))
        # =======================================================================
        # Convert delta velocity to delta lambda in microns with astropy units equivalencies
        # =======================================================================
        # c_kms = const.c.to('km/s')
        # fwhmum = (resv * u.kilometer/ u.s / c_kms) * wline
        rest_wline = wline * u.um
        fwhmum_q = (resv * u.km / u.s).to(
            u.um, equivalencies=u.doppler_optical(rest_wline)) - rest_wline
        fwhmum = fwhmum_q.value
        fwhm_to_sigma = 1. / (8 * np.log(2))**0.5
        lineWidthEstimate = fwhmum * fwhm_to_sigma
        wmin, wmax = wline[0] - (widthFactor *
                                 fwhmum), wline[-1] + (widthFactor * fwhmum)
        if verbose:
            print("wline, wmin, wmax, resv, fwhmum, lineWidthEstimate: ",
                  wline, wmin, wmax, resv, fwhmum, lineWidthEstimate)

        self.wmin = wmin
        self.wmax = wmax
        self.spectrumIn = spectrumIn
        # =======================================================================
        # mask non finite elements
        # =======================================================================
        spectrum = self.__finite(spectrumIn, verbose=verbose)
        self.spectrum = spectrum

        wunit = self.spectrum.spectral_axis.unit
        region = SpectralRegion(self.wmin * wunit, self.wmax * wunit)
        spectrum_region = extract_region(self.spectrum, region)

        # =======================================================================
        # Compute peak flux estimates for model parameters starting values in the region
        # =======================================================================
        peakFluxEstimate = []
        for wsline in wline:
            wave = spectrum_region.spectral_axis.value  #just the ndarray and not Quantity
            flux = spectrum_region.flux.value
            wdist = np.abs(wsline - wave)
            if verbose: print(wsline, min(wdist), max(wdist))
            indexLine = np.where(wdist == min(wdist))[0][0]
            if verbose: print("indexLine= {}".format(indexLine))
            peakEstimate = np.mean(flux[indexLine - 1:indexLine + 1])
            if verbose:
                print('Estimates for peak init {}'.format(peakEstimate))
            cont_sample = np.concatenate((flux[:5], flux[-5:]), axis=None)
            continuumEstimate = np.median(
                np.concatenate((flux[:5], flux[-5:]), axis=None))
            peakFluxEstimate = np.append(peakFluxEstimate,
                                         peakEstimate - continuumEstimate)
            if verbose:
                print('Estimates for peak & continuum {}, {}'.format(
                    peakFluxEstimate, continuumEstimate))

        # =======================================================================
        # Construct model compound (branching off lines+continuum or continuum)
        # =======================================================================

        try:
            lineModel_init = models.Polynomial1D(self.polyOrder,
                                                 c0=continuumEstimate,
                                                 name='cont')
            for xi in range(len(wline)):
                lineModel_init += models.Gaussian1D(
                    amplitude=peakFluxEstimate[xi],
                    mean=wline[xi],
                    stddev=lineWidthEstimate[xi],
                    name='g{}'.format(xi + 1))
            fitter = LevMarLSQFitter()
            lineModel = fit_lines(self.spectrum,
                                  lineModel_init,
                                  fitter=fitter,
                                  window=region)
            fitResult = lineModel(self.spectrum.spectral_axis)
            findLine = 1

            self.flux = []
            self.sigma = []

            for idx in range(len(wline)):
                #momentarily taking advantage of astropy units for conversion
                line_amp = (lineModel.unitless_model[idx + 1].amplitude.value *
                            u.Jy).to(u.Watt / u.m**2 / u.Hz)
                line_sig = (lineModel.unitless_model[idx + 1].stddev.value *
                            u.um).to(u.Hz, equivalencies=u.spectral())
                self.flux = np.append(self.flux, (line_amp * line_sig *
                                                  np.sqrt(2. * np.pi)).value)
                self.sigma = np.append(self.sigma, line_sig.value)
        except:
            if verbose: print('Exception')
            lineModel_init = models.Polynomial1D(self.polyOrder,
                                                 c0=continuumEstimate,
                                                 name='cont')
            fitter = LevMarLSQFitter()
            lineModel = fit_lines(
                self.spectrum, lineModel_init, fitter=fitter, window=region
            )  #the problem is narrow window where the contribution of the continuum sample is small
            fitResult = lineModel(self.spectrum.spectral_axis)
            findLine = 0
        self.model = lineModel
        self.fitResult = fitResult
        self.findLine = findLine
        self.fitter = fitter
        # =======================================================================
        # Preserve continuum Polynomial model
        # =======================================================================
        # there are two types of models, those that are based on
        # `~astropy.modeling.models.PolynomialModel` and therefore
        # require the ``degree`` parameter when instantiating the
        # class , and "everything else" that does not require an
        # "extra" parameter for class instantiation.
        compound_model = lineModel.n_submodels > 1
        if compound_model:
            self.continuumModel = lineModel.unitless_model[0]
        else:
            self.continuumModel = lineModel.unitless_model
        if findLine:
            self.continuum = []
            self.peak = []
            self.centre = []
            self.sigma = []
            self.fwhm = []
            self.chiSquared = (self.fitter.fit_info['fvec']**2).sum() / (
                len(self.fitter.fit_info['fvec']) -
                len(self.fitter.fit_info['param_cov'].data))
            self.stddev = np.sqrt(
                np.diag(fitter.fit_info['cov_x']
                        ))  #standard deviations pertaining to all parameters.
            params_idx = [
                int(param.split('_', -1)[-1])
                for param in self.model.param_names
            ]
            self.fluxError = []
            self.fluxErrorRelative = []
            for idx in range(len(wline)):
                self.continuum = np.append(
                    self.continuum,
                    self.continuumModel(
                        lineModel.unitless_model[idx + 1].mean.value))
                self.peak = np.append(
                    self.peak,
                    lineModel.unitless_model[idx + 1].amplitude.value)
                self.centre = np.append(
                    self.centre, lineModel.unitless_model[idx + 1].mean.value)
                self.sigma = np.append(
                    self.sigma, lineModel.unitless_model[idx + 1].stddev.value)
                self.fwhm = np.append(self.fwhm, self.sigma / fwhm_to_sigma)
                line_amp = (lineModel.unitless_model[idx + 1].amplitude.value *
                            u.Jy).to(u.Watt / u.m**2 / u.Hz)
                line_sig = (lineModel.unitless_model[idx + 1].stddev.value *
                            u.um).to(u.Hz, equivalencies=u.spectral())
                param_idx = [
                    i for i, value in enumerate(params_idx)
                    if value == (idx + 1)
                ]
                self.fluxErrorRelative = np.append(
                    self.fluxErrorRelative,
                    np.sqrt(
                        np.sum((self.stddev / self.model.parameters)[np.array(
                            [param_idx])][np.array([0, -1])]**2.)))
            self.fluxError = self.fluxErrorRelative * self.flux
            self.width = self.fwhm
        else:
            self.continuum = np.array(
                [np.median(flux) for i in range(len(wline))])
            self.flux = self.peak = self.sigma = self.fwhm = self.width = np.array(
                [0. for i in range(len(wline))])
            self.centre = wline
            if verbose:
                print('Line Not Detected. Continuum: {}'.format(
                    self.continuum))
        self.line_spec = self.get_line_spec()
        self.chiSquared = (self.fitter.fit_info['fvec']**2).sum() / (
            len(self.fitter.fit_info['fvec']) -
            len(self.fitter.fit_info['param_cov'].data))

        return
예제 #9
0
###input values to integrate EW through
input_list = []
input_list.append(input('Ha wavelengths:'))
input_list.append(input('HeI2 wavelengths:'))
input_list.append(input('HeI3 wavelengths:'))
input_list.append(input('FeII2 wavelengths:'))


ew_list = []
cont_lst = []
##iterate through each observation to calculate Intensity.
for cont,spec in zip(cont_list,data):
    ew_iter = []
    cont_iter = []
    for inp ,region in zip(input_list,region_list):
        cont_iter.append(extract_region(cont, SpectralRegion(region[0] * u.AA, region[1] * u.AA)).flux)
        ew_iter.append(equivalent_width(spec, regions=SpectralRegion(int(inp.split(' ')[0]) * u.AA, int(inp.split(' ')[1]) * u.AA), continuum=extract_region(cont, SpectralRegion(region[0] * u.AA, region[1] * u.AA)).flux))
    ew_list.append(ew_iter)
    cont_lst.append(cont_iter)


ew1 = []
ew2 = []
ew3 = []
ew4 = []
for i in ew_list:
    ew1.append(np.mean(np.array(i[0])))
    ew2.append(np.mean(np.array(i[1])))
    ew3.append(np.mean(np.array(i[2])))
    ew4.append(np.mean(np.array(i[3])))
예제 #10
0
def centroid_offsets(targ_bounds, data_wave, data_flux, sky_cents):
    """Returns amount by which extracted skylines are offset from model and the nearest wavelength value to each.
    
    Parameters
    ----------
    targ_bounds : tuple
        List of tuples defining bounds of region around each skyline to examine
    data_wave : tuple
        Wavelength array
    data_flux : tuple
        Flux array
    sky_cents : tuple
        Skymodel centroids
        
    Returns
    -------
    nearest_waves : tuple
        Nearest wavelength value to centroid
    offsets : tuple
        Offset between data and skymodel
    """
    
    regions = SpectralRegion(targ_bounds[0][0]*u.Angstrom,targ_bounds[0][-1]*u.Angstrom)
    for i in range(1, len(targ_bounds)):
        regions += SpectralRegion(targ_bounds[i][0]*u.Angstrom, targ_bounds[i][-1]*u.Angstrom)

    #Normalize data
    targ_norm_wave, targ_norm_flux, targ_norm_noise = continuum_normalize(np.min(data_wave), np.max(data_wave), data_flux, 
                                                                          data_wave, np.zeros(len(data_flux)))
    
    
    #Find offsets
    target = Spectrum1D(spectral_axis=targ_norm_wave*u.Angstrom, flux=targ_norm_flux*u.ct)
    sub_spec = extract_region(target, regions)
    offsets = np.zeros(len(sky_cents))
    nearest_waves = np.zeros(len(sky_cents))
    for i, sub in enumerate(sub_spec):
        an_disp = sub.flux.max()
        an_ampl = sub.flux.min()
        an_mean = sub.spectral_axis[sub.flux.argmax()]
        nearest_waves[i] = an_mean.value
        an_stdv = np.sqrt(np.sum((sub.spectral_axis - an_mean)**2) / (len(sub.spectral_axis) - 1))

        plt.figure()
        plt.scatter(an_mean.value, an_disp.value, marker='o', color='#e41a1c', s=100, label='data')
        plt.scatter(sky_cents[i], an_disp.value, marker='o', color='k', s=100, label='archive')
        plt.vlines([an_mean.value - an_stdv.value, an_mean.value + an_stdv.value],
                    sub.flux.min().value, sub.flux.max().value,
                    color='#377eb8', ls='--', lw=2)
        g_init = ( models.Const1D(an_disp) +
                  models.Gaussian1D(amplitude=(an_ampl - an_disp),
                                mean=an_mean, stddev=an_stdv) )
        g_fit = fit_lines(sub, g_init)
        line_fit = g_fit(sub.spectral_axis)
        plt.plot(sub.spectral_axis, sub.flux, color='#e41a1c', lw=2)
        plt.plot(sub.spectral_axis, line_fit, color='#377eb8', lw=2)

        plt.axvline(an_mean.value, color='#e41a1c', ls='--', lw=2)
        plt.legend()
        offsets[i] = an_mean.value - sky_cents[i].value
        
    return nearest_waves, offsets
예제 #11
0
def line_fit(spec,
             spec_err,
             wave_obj,
             dwave=10. * u.AA,
             dwave_cont=100. * u.AA,
             sigmamax=14. * u.AA):
    '''
    Function to fit a 1D gaussian to a HETDEX spectrum from get_spec.py

    Parameters
    ----------
    spec
        1D spectrum from a row in the table provided by get_spec.py.
        Will assume unit of 10**-17*u.Unit('erg cm-2 s-1 AA-1') if no units
        are provided.
    spec_err
        1D spectral uncertainty from table provided by get_spec.py.
        Will assume unit of 10**-17*u.Unit('erg cm-2 s-1 AA-1') if no units
        are provided.
    wave_obj
        wavelength you want to fit, an astropy quantity
    dwave
        spectral region above and below wave_obj to fit a line, an astropy quantity.
        Default is 10.*u.AA
    dwave_cont
        spectral region to fit continuum. Default is +/- 100.*u.AA
    sigmamax
        Maximum linewidth (this is sigma/stdev of the gaussian fit) to allow
        for a fit. Assumes unit of u.AA if not given

    Returns
    -------

    '''

    try:
        spectrum = Spectrum1D(flux=spec,
                              spectral_axis=(2.0 * np.arange(1036) + 3470.) *
                              u.AA,
                              uncertainty=StdDevUncertainty(spec_err),
                              velocity_convention=None)
    except ValueError:
        spectrum = Spectrum1D(
            flux=spec * 10**-17 * u.Unit('erg cm-2 s-1 AA-1'),
            spectral_axis=(2.0 * np.arange(1036) + 3470.) * u.AA,
            uncertainty=StdDevUncertainty(spec_err * 10**-17 *
                                          u.Unit('erg cm-2 s-1 AA-1')),
            velocity_convention=None)

    # measure continuum over 2*dwave_cont wide window first:
    cont_region = SpectralRegion((wave_obj - dwave_cont),
                                 (wave_obj + dwave_cont))
    cont_spectrum = extract_region(spectrum, cont_region)
    cont = np.median(cont_spectrum.flux)

    if np.isnan(cont):
        #set continuum if its NaN
        print('Continuum fit is NaN. Setting to 0.0')
        cont = 0.0 * cont_spectrum.unit

    # now get region to fit the continuum subtracted line

    sub_region = SpectralRegion((wave_obj - dwave), (wave_obj + dwave))
    sub_spectrum = extract_region(spectrum, sub_region)

    try:
        line_param = estimate_line_parameters(sub_spectrum - cont,
                                              models.Gaussian1D())
    except:
        return None

    if np.isnan(line_param.amplitude.value):
        print('Line fit yields NaN result. Exiting.')
        return None

    try:
        sigma = np.minimum(line_param.stddev, sigmamax)
    except ValueError:
        sigma = np.minimum(line_param.stddev, sigmamax * u.AA)

    if np.isnan(sigma):
        sigma = sigmamax

    g_init = models.Gaussian1D(amplitude=line_param.amplitude,
                               mean=line_param.mean,
                               stddev=sigma)

    #    lineregion = SpectralRegion((wave_obj-2*sigma), (wave_obj+2*sigma))
    #    cont = fit_generic_continuum(sub_spectrum, exclude_regions=lineregion,
    #                                 model=models.Linear1D(slope=0))

    #r1 = SpectralRegion((wave_obj-dwave), (wave_obj-2*sigma))
    #r2 = SpectralRegion((wave_obj+2*sigma), (wave_obj+dwave))
    #fitcontregion = r1 + r2

    #fit_cont_spectrum = extract_region(sub_spectrum, fitcontregion)
    #cont = np.mean(np.hstack([fit_cont_spectrum[0].flux, fit_cont_spectrum[1].flux]))

    #contspec = cont(sub_spectrum.spectral_axis)

    g_fit = fit_lines(sub_spectrum - cont, g_init)

    x = np.arange(wave_obj.value - dwave.value, wave_obj.value + dwave.value,
                  0.5) * u.AA
    y_fit = g_fit(x)

    line_flux_model = np.sum(y_fit * 0.5 * u.AA)

    chi2 = calc_chi2(sub_spectrum - cont, g_fit)

    sn = np.sum(np.array(sub_spectrum.flux)) / np.sqrt(
        np.sum(sub_spectrum.uncertainty.array**2))

    line_flux_data = line_flux(sub_spectrum - cont).to(u.erg * u.cm**-2 *
                                                       u.s**-1)

    line_flux_data_err = np.sqrt(np.sum(sub_spectrum.uncertainty.array**2))

    #fitted_region = SpectralRegion((line_param.mean - 2*sigma),
    #                               (line_param.mean + 2*sigma))

    #fitted_spectrum = extract_region(spectrum, fitted_region)

    #line_param = estimate_line_parameters(fitted_spectrum, models.Gaussian1D())

    #sn = np.sum(np.array(fitted_spectrum.flux)) / np.sqrt(np.sum(
    #    fitted_spectrum.uncertainty.array**2))

    #line_flux_data = line_flux(fitted_spectrum).to(u.erg * u.cm**-2 * u.s**-1)

    #line_flux_data_err = np.sqrt(np.sum(fitted_spectrum.uncertainty.array**2))

    return line_param, sn, chi2, sigma, line_flux_data, line_flux_model, line_flux_data_err, g_fit, cont
예제 #12
0
	def gaussian_fit(self,spectrum,submin,submax,star_name):	
		

		#noise_region=SpectralRegion(2.26*u.um,2.3*u.um)
		#spectrum=noise_region_uncertainty(spectrum,noise_region)
		#lines = find_lines_threshold(spectrum, noise_factor=4)
		
		#print(lines[lines['line_type'] == 'emission'])
		#print(lines[lines['line_type'] == 'absorption'])
		
		#amp=0.00075
		#centre=2.1675
		
		#sub region defined from function parameters
		
		sub_region=SpectralRegion(submin*u.um,submax*u.um)
		
		#spectrum extracted from subregion
		
		sub_spectrum=extract_region(spectrum,sub_region)
		
		#continuum fitted
		
		g1_fit=fit_generic_continuum(spectrum)
		
		y_continuum_fitted=g1_fit(sub_spectrum.spectral_axis)
		
		#continuum fit plotted with subregion spectrum
		
		plt.plot(sub_spectrum.spectral_axis,sub_spectrum.flux)
		plt.plot(sub_spectrum.spectral_axis,y_continuum_fitted)
		plt.title('Continuum Fitting')
		plt.grid(True)
		plt.show()
		
		#continuum substracted to show intensity
		
		sub_spectrum=sub_spectrum-y_continuum_fitted
		
		#initial gaussian fitted to estimate parameters for more accurate fitting
		
		estimates=estimate_line_parameters(sub_spectrum,models.Gaussian1D())
		
		#new gauss_axis variable created for a smooth fit
		
		gauss_axis=np.linspace(min(sub_spectrum.spectral_axis),max(sub_spectrum.spectral_axis),2000)
		
		#gaussian fit from previous estimates produced
		
		g_init=estimates
		
		g_fit=fit_lines(sub_spectrum,g_init)
		
		y_fit=g_fit(gauss_axis)
		
		#fit plotted
		
		plt.plot(sub_spectrum.spectral_axis,sub_spectrum.flux)
		plt.plot(gauss_axis,y_fit)
		
		#linestrength found
		
		strength=(max(y_fit))
		
		#f=open('brackett_strengths.txt','a')
		#f.write(star_name + ' - '+ str(strength) + 'Jy') 
		#f.close()
		
		plt.title('Single fit peak')
		plt.grid(True)
		plt.legend('Original Spectrum','Specutils Fit Result')
		
		plt.show()
예제 #13
0
def fit_line(name, wave, flux, err, z):

    rest_wave = wave
    uncertainty = StdDevUncertainty(err * u.Jy)
    spec1 = Spectrum1D(spectral_axis=rest_wave * u.AA,
                       flux=flux * u.Jy,
                       uncertainty=uncertainty)
    spec = box_smooth(spec1, width=3)
    nev_region = SpectralRegion(3395 * u.AA, 3408 * u.AA) + SpectralRegion(
        3440 * u.AA, 3456 * u.AA)

    nev_lineregion = SpectralRegion(3415 * u.AA, 3435 * u.AA)

    nev_spec = extract_region(spec, SpectralRegion(3390 * u.AA, 3460 * u.AA))

    line_spec = extract_region(nev_spec, nev_lineregion)
    #    nev_spec = extract_region(spec,nev_region)
    #    SNR1 = snr(line_spec)   ###median snr

    line_cont = fit_generic_continuum(nev_spec, exclude_regions=nev_lineregion)
    cont_fit = line_cont(nev_spec.spectral_axis)

    #    peak1 = centroid(nev_spec)
    norm_nev_spec = Spectrum1D(spectral_axis=nev_spec.spectral_axis,
                               flux=nev_spec.flux / cont_fit)
    sub_nev_spec = Spectrum1D(spectral_axis=nev_spec.spectral_axis,
                              flux=nev_spec.flux - cont_fit)

    line_fit = kmpfit.Fitter(residuals = _residuals,data = (sub_nev_spec.spectral_axis/u.AA,\
                                                            sub_nev_spec.flux/u.Jy,\
                                                                nev_spec.uncertainty.array))

    line_fit_ini = [0, 3426, 3]
    line_fit.parinfo = [{
        'limits': (0., 10.**10)
    }, {
        'limits': (3416, 3436)
    }, {
        'limits': (0, 6)
    }]
    line_fit.fit(params0=line_fit_ini)
    snrregion = SpectralRegion(
        (line_fit.params[1] - 2 * line_fit.params[2]) * u.AA,
        (line_fit.params[1] + 2 * line_fit.params[2]) * u.AA)
    #    print(snrregion)
    calc_spectrum = extract_region(nev_spec, snrregion)

    flux = calc_spectrum.flux
    uncertainty = calc_spectrum.uncertainty.array * nev_spec.uncertainty.unit
    SNR = np.median(flux / uncertainty, axis=-1)

    peak = line_fit.params[1]

    wave = nev_spec.spectral_axis / u.AA
    #    print(snr(nev_spec,snrregion).value)
    plt.figure()
    plt.plot(nev_spec.spectral_axis, nev_spec.flux)
    plt.plot(nev_spec.spectral_axis, cont_fit, 'orange')
    plt.plot(nev_spec.spectral_axis, nev_spec.uncertainty.array, 'grey')
    plt.plot(sub_nev_spec.spectral_axis, sub_nev_spec.flux, 'green')
    plt.axvline(3426.)
    plt.plot(nev_spec.spectral_axis / u.AA,
             onegauss(nev_spec.spectral_axis / u.AA, line_fit.params), 'r')
    plt.savefig('/Users/k/Documents/MMT_spec/MMT_LockmanHole/NeV/24b_NeV/' +
                name + '.eps',
                format='eps',
                dpi=300)
    #    plt.close()

    return SNR, line_fit.params[1]