Exemple #1
0
def ElectronIC(pars, data):

    # Match parameters to ECPL properties, and give them the appropriate units
    amplitude = pars[0] / u.eV
    alpha = pars[1]
    e_cutoff = (10**pars[2]) * u.TeV

    # Initialize instances of the particle distribution and radiative model
    ECPL = ExponentialCutoffPowerLaw(amplitude, 10. * u.TeV, alpha, e_cutoff)
    IC = InverseCompton(ECPL,
                        seed_photon_fields=[
                            'CMB', ['FIR', 26.5 * u.K, 0.415 * u.eV / u.cm**3]
                        ])

    # compute flux at the energies given in data['energy'], and convert to
    # units of flux data
    model = IC.flux(data, distance=1.0 * u.kpc)

    # Save this realization of the particle distribution function
    elec_energy = np.logspace(11, 15, 100) * u.eV
    nelec = ECPL(elec_energy)

    # Compute and save total energy in electrons above 1 TeV
    We = IC.compute_We(Eemin=1 * u.TeV)

    # The first array returned will be compared to the observed spectrum for
    # fitting. All subsequent objects will be stores in the sampler metadata
    # blobs.
    return model, (elec_energy, nelec), We
Exemple #2
0
def ElectronSynIC(pars, data):

    # Match parameters to ECPL properties, and give them the appropriate units
    amplitude = 10**pars[0] / u.eV
    alpha = pars[1]
    e_cutoff = (10**pars[2]) * u.TeV
    B = pars[3] * u.uG

    # Initialize instances of the particle distribution and radiative models
    ECPL = ExponentialCutoffPowerLaw(amplitude, 10. * u.TeV, alpha, e_cutoff)
    # Compute IC on CMB and on a FIR component with values from GALPROP for the
    # position of RXJ1713
    IC = InverseCompton(ECPL,
                        seed_photon_fields=[
                            'CMB', ['FIR', 26.5 * u.K, 0.415 * u.eV / u.cm**3]
                        ],
                        Eemin=100 * u.GeV)
    SYN = Synchrotron(ECPL, B=B)

    # compute flux at the energies given in data['energy']
    model = (IC.flux(data, distance=1.0 * u.kpc) +
             SYN.flux(data, distance=1.0 * u.kpc))

    # The first array returned will be compared to the observed spectrum for
    # fitting. All subsequent objects will be stored in the sampler metadata
    # blobs.
    return model, IC.compute_We(Eemin=1 * u.TeV)
def diff_spectrum_leptonic(self, time):
    self.dist = self.distance()
    ELECTRONS = self.spectrum_electron(time)
    IC = InverseCompton(ELECTRONS, seed_photon_fields=['CMB'])
    GAMMAS = IC.sed(self.ENERGY, self.dist * u.kpc)
    GAMMAS_TeV = GAMMAS.to(u.TeV / (u.cm**2 * u.s))
    return GAMMAS_TeV
Exemple #4
0
def ElectronEblAbsorbedSynIC(pars, data):

    # Match parameters to ECPL properties, and give them the appropriate units
    amplitude = 10**pars[0] / u.eV
    e_break = (10**pars[1]) * u.TeV
    alpha1 = pars[2]
    alpha2 = pars[3]
    B = pars[4] * u.uG

    # Define the redshift of the source, and absorption model
    redshift = pars[5] * u.dimensionless_unscaled
    EBL_transmitance = EblAbsorptionModel(redshift, 'Dominguez')

    # Initialize instances of the particle distribution and radiative models
    BPL = BrokenPowerLaw(amplitude, 1. * u.TeV, e_break, alpha1, alpha2)

    # Compute IC on a CMB component
    IC = InverseCompton(
        BPL,
        seed_photon_fields=['CMB'],
        Eemin=10 * u.GeV)
    SYN = Synchrotron(BPL, B=B)

    # compute flux at the energies given in data['energy']
    model = (EBL_transmitance.transmission(data) * IC.flux(data, distance=1.0 * u.kpc) +
             SYN.flux(data, distance=1.0 * u.kpc))

    # The first array returned will be compared to the observed spectrum for
    # fitting. All subsequent objects will be stored in the sampler metadata
    # blobs.
    return model, IC.compute_We(Eemin=1 * u.TeV)
Exemple #5
0
def ElectronSynIC(pars, data):

    # Match parameters to ECPL properties, and give them the appropriate units
    amplitude = 10 ** pars[0] / u.eV
    alpha = pars[1]
    e_cutoff = (10 ** pars[2]) * u.TeV
    B = pars[3] * u.uG

    # Initialize instances of the particle distribution and radiative models
    ECPL = ExponentialCutoffPowerLaw(amplitude, 10.0 * u.TeV, alpha, e_cutoff)
    # Compute IC on CMB and on a FIR component with values from GALPROP for the
    # position of RXJ1713
    IC = InverseCompton(
        ECPL,
        seed_photon_fields=[
            "CMB",
            ["FIR", 26.5 * u.K, 0.415 * u.eV / u.cm ** 3],
        ],
        Eemin=100 * u.GeV,
    )
    SYN = Synchrotron(ECPL, B=B)

    # compute flux at the energies given in data['energy']
    model = IC.flux(data, distance=1.0 * u.kpc) + SYN.flux(
        data, distance=1.0 * u.kpc
    )

    # The first array returned will be compared to the observed spectrum for
    # fitting. All subsequent objects will be stored in the sampler metadata
    # blobs.
    return model, IC.compute_We(Eemin=1 * u.TeV)
Exemple #6
0
def ElectronEblAbsorbedSynIC(pars, data):

    # Match parameters to ECPL properties, and give them the appropriate units
    amplitude = 10**pars[0] / u.eV
    e_break = (10**pars[1]) * u.TeV
    alpha1 = pars[2]
    alpha2 = pars[3]
    B = pars[4] * u.uG

    # Define the redshift of the source, and absorption model
    redshift = pars[5] * u.dimensionless_unscaled
    EBL_transmitance = EblAbsorptionModel(redshift, "Dominguez")

    # Initialize instances of the particle distribution and radiative models
    BPL = BrokenPowerLaw(amplitude, 1.0 * u.TeV, e_break, alpha1, alpha2)

    # Compute IC on a CMB component
    IC = InverseCompton(BPL, seed_photon_fields=["CMB"], Eemin=10 * u.GeV)
    SYN = Synchrotron(BPL, B=B)

    # compute flux at the energies given in data['energy']
    model = EBL_transmitance.transmission(data) * IC.flux(
        data, distance=1.0 * u.kpc) + SYN.flux(data, distance=1.0 * u.kpc)

    # The first array returned will be compared to the observed spectrum for
    # fitting. All subsequent objects will be stored in the sampler metadata
    # blobs.
    return model, IC.compute_We(Eemin=1 * u.TeV)
Exemple #7
0
def ElectronIC(pars, data):

    # Match parameters to ECPL properties, and give them the appropriate units
    amplitude = pars[0] / u.eV
    alpha = pars[1]
    e_cutoff = (10 ** pars[2]) * u.TeV

    # Initialize instances of the particle distribution and radiative model
    ECPL = ExponentialCutoffPowerLaw(amplitude, 10.0 * u.TeV, alpha, e_cutoff)
    # Compute IC on CMB and on a FIR component with values from GALPROP for the
    # position of RXJ1713
    IC = InverseCompton(
        ECPL,
        seed_photon_fields=[
            "CMB",
            ["FIR", 26.5 * u.K, 0.415 * u.eV / u.cm ** 3],
        ],
        Eemin=100 * u.GeV,
    )

    # compute flux at the energies given in data['energy'], and convert to units
    # of flux data
    model = IC.flux(data, distance=1.0 * u.kpc).to(data["flux"].unit)

    # Save this realization of the particle distribution function
    elec_energy = np.logspace(11, 15, 100) * u.eV
    nelec = ECPL(elec_energy)

    # Compute and save total energy in electrons above 1 TeV
    We = IC.compute_We(Eemin=1 * u.TeV)

    # The first array returned will be compared to the observed spectrum for
    # fitting. All subsequent objects will be stores in the sampler metadata
    # blobs.
    return model, (elec_energy, nelec), We
Exemple #8
0
def ElectronIC(pars, data):
    """
    Define particle distribution model, radiative model, and return model flux
    at data energy values
    """

    ECPL = ExponentialCutoffPowerLaw(pars[0] / u.eV, 10. * u.TeV, pars[1],
                                     10**pars[2] * u.TeV)
    IC = InverseCompton(ECPL, seed_photon_fields=['CMB'])

    return IC.flux(data, distance=1.0 * u.kpc)
Exemple #9
0
def ElectronIC(pars, data):
    """
    Define particle distribution model, radiative model, and return model flux
    at data energy values
    """

    ECPL = ExponentialCutoffPowerLaw(pars[0] / u.eV, 10.0 * u.TeV, pars[1],
                                     10**pars[2] * u.TeV)
    IC = InverseCompton(ECPL, seed_photon_fields=["CMB"])

    return IC.flux(data, distance=1.0 * u.kpc)
Exemple #10
0
def emission(electrons, B, Rb, ssc):
    warnings.filterwarnings('ignore', category=DeprecationWarning)

    SYN = Synchrotron(
        electrons,
        B=B.to((u.erg * pcm)**(1 / 2)).value * u.G,
        Eemax=max(electrons.e_break, electrons.e_cutoff),
        Eemin=electrons.e_0,
        nEed=50,
    )

    E_ph = np.logspace(-7, 9, 100) * u.eV
    L_syn = SYN.flux(E_ph, distance=0 * u.cm)
    phn_syn = L_syn / (4 * np.pi * Rb**2 * c) * 2.24 * float(ssc)
    IC = InverseCompton(
        electrons,
        seed_photon_fields=[
            ["SSC", E_ph, phn_syn],
        ],
        Eemax=max(electrons.e_break, electrons.e_cutoff),
        Eemin=electrons.e_0,
        nEed=50,
    )

    return SYN, IC
Exemple #11
0
    def setup(self):
        self.functionName = "ElectronIC"
        self.formula = r"$f(E)=A(E/E_{\rm piv}}^\gamma}$"

        self.parameters = collections.OrderedDict()
        self.parameters["gamma"] = Parameter("gamma",
                                             -2.,
                                             -10.,
                                             10,
                                             0.1,
                                             fixed=False,
                                             nuisance=False,
                                             dataset=None)
        self.parameters["logA"] = Parameter("logA",
                                            -4.,
                                            -40.,
                                            30,
                                            0.1,
                                            fixed=False,
                                            nuisance=False,
                                            dataset=None)
        self.parameters["Epiv"] = Parameter("Epiv",
                                            1.,
                                            1e-10,
                                            1e10,
                                            1.,
                                            fixed=True,
                                            unit="keV")
        self.parameters["dist"] = Parameter("dist",
                                            1.,
                                            1e-10,
                                            1e10,
                                            1.,
                                            fixed=True)
        self.ncalls = 0

        self.pdist_unit = 1. / u.Unit(m_e * c**2)
        self.PL = PowerLaw(1 * self.pdist_unit, 1 * u.keV, -2.5)
        self.IC = InverseCompton(
            self.PL,
            seed_photon_fields=[
                'CMB', ['FIR', 26.5 * u.K, 0.415 * u.eV / u.cm**3]
            ],
            Eemin=1 * u.TeV)
Exemple #12
0
def f(rho, B):
    ECPL = ExponentialCutoffPowerLaw(1e36 * rho * u.Unit('1/eV'), 1 * u.TeV,
                                     2.0, 13 * u.TeV)
    SYN = Synchrotron(ECPL, B=1000 * B * u.uG)

    # Define energy array for synchrotron seed photon field and compute
    # Synchroton luminosity by setting distance to 0.
    Esy = np.logspace(-6, 6, 100) * u.eV
    Lsy = SYN.flux(Esy, distance=0 * u.cm)

    # Define source radius and compute photon density
    R = 2 * u.pc
    phn_sy = Lsy / (4 * np.pi * R**2 * c) * 2.26

    # Create IC instance with CMB and synchrotron seed photon fields:
    IC = InverseCompton(
        ECPL, seed_photon_fields=['CMB', 'FIR', 'NIR', ['SSC', Esy, phn_sy]])

    # Compute SEDs
    spectrum_energy = np.logspace(13, 14, 1) * u.eV
    sed_IC = IC.sed(spectrum_energy, distance=1.5 * u.kpc)

    return sed_IC.value
Exemple #13
0
def flare_rad(index, LE_cutoff, Ee_syn_max, B_flare, Ecut_0):
    ECPL = ExponentialCutoffPowerLaw(amplitude=amp0 / u.eV,
                                     e_0=1 * u.TeV,
                                     alpha=index,
                                     e_cutoff=Ecut_0)
    SYN = Synchrotron(ECPL, B=B_flare, Eemin=LE_cutoff, Eemax=Ee_syn_max)
    amp_cor = fitfactor(data_flare, SYN)  # Fit particle distribution prefactor
    # Fit particle cutoff, with analytic initial value
    Ecut_flare = fitcutoff(Ecut_0, data_flare, amp0 * amp_cor, index, B_flare,
                           LE_cutoff, Ee_syn_max)
    print('Correct ecut: ', Ecut_flare.to(u.PeV))
    # Final particle spectrum and synchrotron
    ECPL = ExponentialCutoffPowerLaw(amplitude=amp0 * amp_cor / u.eV,
                                     e_0=1 * u.TeV,
                                     alpha=index,
                                     e_cutoff=Ecut_flare)
    SYN = Synchrotron(ECPL, B=B_flare, Eemin=LE_cutoff, Eemax=Ee_syn_max)
    if flarename == '2011':
        Rflare = 2.8e-4 * u.pc  ## 3.2 * u.pc, 2.8e-4, 1.7e-4
    elif flarename == '2013':
        Rflare = 1.7e-4 * u.pc
    else:
        Rflare == 3.2 * u.pc
    Esy = np.logspace(0.0, 12, 100) * u.eV  #np.exp(14)
    Lsy = SYN.flux(Esy, distance=0 * u.cm)  # use distance 0 to get luminosity
    phn_sy = Lsy / (4 * np.pi * Rflare**2 * c) * 2.24
    fields = [
        'CMB', ['FIR', 70 * u.K, 0.5 * u.eV / u.cm**3],
        ['NIR', 5000 * u.K, 1 * u.eV / u.cm**3], ['SSC', Esy, phn_sy]
    ]
    IC = InverseCompton(ECPL,
                        seed_photon_fields=fields,
                        Eemin=LE_cutoff,
                        Eemax=Ee_syn_max)
    We = IC.compute_We(Eemin=1 * u.TeV)
    print('Estoy aqui: ', We)
    return SYN, IC, amp_cor, We, Ecut_flare
Exemple #14
0
def ssc_model_components(parameters, precision=20):
    log_amplitude = parameters[0]
    alpha = parameters[1]
    beta = parameters[2]
    log_e_max = parameters[3]
    log_e_min = parameters[4]
    B = parameters[5]

    d_meyer = dict(a=(10**log_amplitude) / u.erg,
                   alpha=alpha,
                   beta=beta,
                   e_max=10**log_e_max * u.eV,
                   e_min=10**log_e_min * u.eV)

    T = meyer_model(**d_meyer)
    SYN = Synchrotron(T,
                      B=B * u.uG,
                      Eemax=50 * u.PeV,
                      Eemin=0.01 * u.GeV,
                      nEed=precision)

    # Compute photon density spectrum from synchrotron emission assuming R=2.1 pc
    Rpwn = 2.1 * u.pc
    Esy = np.logspace(-10, 10, 50) * u.MeV
    Lsy = SYN.flux(Esy, distance=0 * u.cm)  # use distance 0 to get luminosity
    phn_sy = Lsy / (
        4 * np.pi * Rpwn**2 * constants.c
    ) * 2.25  # see section 1.6.2 in Ghiselini, Radiative Processes.

    IC = InverseCompton(
        T,
        seed_photon_fields=[
            "CMB",
            ["FIR", 70 * u.K, 0.5 * u.eV / u.cm**3],
            ["NIR", 5000 * u.K, 1 * u.eV / u.cm**3],
            ["SSC", Esy, phn_sy],
        ],
        Eemax=50 * u.PeV,
        Eemin=0.01 * u.GeV,
        nEed=precision,
    )
    return SYN, IC
Exemple #15
0
def do_fit(
    periods,   # [0, 1],
    ThetaIC,   # np.array([90, 90]),
    Pos3D,     # [[1, 1, 1], [1, 1, 1]],
    Dist,      # np.array([2, 2]),
    Alpha,     # np.array([2.58, 2.16])
    label='',
    do_abs=True,
    lgEdot_min=31,
    lgEdot_max=37.5,
    lgEdot_bins=10,
    lgSigma_min=-3,
    lgSigma_max=-1,
    lgSigma_bins=10,
    Tstar=pars.TSTAR,
    Rstar=pars.RSTAR,
    AlphaSigma=1,
    Mdot=1e-8,
    Vw=1500
):

    logging.info('Starting fitting')
    OutFit = open('fit_results/fit_results_' + label + '.txt', 'w')

    NEdot = (lgEdot_max - lgEdot_min) * lgEdot_bins
    NSigma = (lgSigma_max - lgSigma_min) * lgSigma_bins
    Edot_list = np.logspace(lgEdot_min, lgEdot_max, int(NEdot))
    Sigma_list = np.logspace(lgSigma_min, lgSigma_max, int(NSigma))

    logging.info('{} iterations'.format(NEdot * NSigma))

    print(Edot_list)
    print(Sigma_list)

    n_periods = len(periods)

    if len(ThetaIC) != n_periods:
        logging.error('Argument with wrong dimensions - aborting')
        return None

    # Absorption
    if not do_abs:
        logging.info('Skipping absorption')
    else:
        # Computing Taus
        logging.info('Computing absorption')
        start = time.time()
        Obs = np.array([0, 0, -1])
        Abs = abso.Absorption(Tstar=Tstar, Rstar=Rstar)

        data_en, data_fl, data_fl_er = list(), list(), list()
        Tau = list()
        DistTau = list()
        for iper in periods:
            en, fl, fl_er = data.get_data(iper, GT=True)
            data_en.append(en)
            data_fl.append(fl)
            data_fl_er.append(fl_er)
            DistTau.append(list())
            tt = dict()
            for i in range(len(en)):
                tt[i] = list()
            Tau.append(tt)

        DistFrac = np.linspace(0.01, 1, 50)

        for ff in DistFrac:
            for i_per in range(n_periods):
                dist = ff * norm(Pos3D[i_per])
                PosStar = Pos3D[i_per] * dist / norm(Pos3D[i_per])
                for i_en in range(len(data_en[i_per])):
                    tau = Abs.TauGG(en=data_en[i_per][i_en] * u.keV.to(u.TeV), obs=Obs, pos=PosStar)
                    Tau[i_per][i_en].append(tau)
                DistTau[i_per].append(dist)

        logging.info('Abs done, dt/s = {}'.format(time.time() - start))

        # # Ploting tau vs dist
        # plt.figure(figsize=(8, 6), tight_layout=True)
        # ax = plt.gca()
        # ax.set_yscale('log')
        # ax.set_ylabel(r'$\tau_{\gamma \gamma}$')
        # ax.set_xlabel(r'$D$ [AU]')

        # ax.plot(DistTau0, Tau0[92], marker='o', linestyle='-')
        # ax.plot(DistTau0, Tau0[95], marker='o', linestyle='-')
        # plt.show()

    for (Edot, Sigma) in itertools.product(Edot_list, Sigma_list):

        logging.debug('Starting Edot={}, Sigma={}'.format(Edot, Sigma))

        # Computed parameters
        DistPulsar = [psr.Rshock(Edot=Edot, Mdot=Mdot, Vw=Vw, D=d) for d in Dist]
        DistStar = Dist - DistPulsar
        DistRef = 4.
        # SigmaFac = [pow(Dist[0] / d, AlphaSigma) for d in Dist]
        SigmaFac = [pow(DistRef / d, AlphaSigma) for d in Dist]
        SigmaShock = [Sigma * f for f in SigmaFac]
        Bfield = [psr.B2_KC(Edot=Edot, Rs=dp, sigma=s) for (dp, s) in zip(DistPulsar, SigmaShock)]
        Density = [psr.PhotonDensity(Tstar=Tstar, Rstar=Rstar, d=d) for d in DistStar]

        if 0 in Bfield:
            logging.info('Bfield is 0 - skipping')
            continue

        # Normalization
        Norm0 = np.array([1e24 / b for b in Bfield])

        # Fitting
        fix_n = [True for p in range(pars.MAX_PERIOD)]
        fit_n = [Norm0[0] for p in range(pars.MAX_PERIOD)]

        for idx, iper in enumerate(periods):
            fix_n[iper] = False
            fit_n[iper] = Norm0[idx]

        logging.info('fix_n:')
        logging.info(fix_n)
        logging.info('fit_n:')
        logging.info(fit_n)

        npar = 5 - sum([int(f) for f in fix_n])

        ####################
        # Further parameters
        Eref = 1 * u.TeV
        Ecut = 50 * u.TeV
        Emax = 20 * u.PeV
        Emin = 10 * u.GeV
        SourceDist = pars.SRC_DIST * u.kpc
        EnergyToPlot = np.logspace(-2, 11, 500) * u.keV

        ######################
        # Loading data

        data_en, data_fl, data_fl_er = list(), list(), list()
        tau = list()
        model = list()
        for ii in range(pars.MAX_PERIOD):
            idx = periods.index(ii) if (ii in periods) else 0

            en, fl, fl_er = data.get_data(ii, GT=True)
            data_en.append(en)
            data_fl.append(fl)
            data_fl_er.append(fl_er)

            thisTau = list()
            if do_abs and (ii in periods):
                for ien in range(len(en)):
                    thisTau.append(np.interp(DistStar[idx], xp=DistTau[idx], fp=Tau[idx][ien]))
            else:
                thisTau = [0] * len(en)

            tau.append(thisTau)

            ECPL = ExponentialCutoffPowerLaw(
                amplitude=1e20 / u.eV,
                e_0=Eref,
                alpha=Alpha[idx],
                e_cutoff=Ecut
            )

            SYN = Synchrotron(
                particle_distribution=ECPL,
                B=Bfield[idx] * u.G,
                Eemax=Emax,
                Eemin=Emin
            )

            IC = InverseCompton(
                particle_distribution=ECPL,
                seed_photon_fields=[[
                    'STAR',
                    Tstar * u.K,
                    Density[idx] * u.erg / u.cm**3,
                    ThetaIC[idx] * u.deg
                ]],
                Eemax=Emax,
                Eemin=Emin
            )

            thisModel = (
                SYN.sed(photon_energy=[e * u.keV for e in en], distance=SourceDist) +
                IC.sed(photon_energy=[e * u.keV for e in en], distance=SourceDist)
            )

            if do_abs:
                thisModel = [math.exp(-t) * m for (m, t) in zip(thisModel, thisTau)]

            model.append(thisModel)
        # END for

        def least_square(n0, n1, n2, n3, n4):
            chisq = 0
            for ii, nn in enumerate([n0, n1, n2, n3, n4]):
                if fix_n[ii]:
                    continue
                chisq += sum(util.vecChiSq(
                    [(nn / 1e20) * m.value for m in model[ii]],
                    data_fl[ii],
                    data_fl_er[ii])
                )
            return chisq

        minuit = Minuit(
            least_square,
            n0=fit_n[0], fix_n0=fix_n[0],
            n1=fit_n[1], fix_n1=fix_n[1],
            n2=fit_n[2], fix_n2=fix_n[2],
            n3=fit_n[3], fix_n3=fix_n[3],
            n4=fit_n[4], fix_n4=fix_n[4],
            limit_n0=(fit_n[0] * 0.001, fit_n[0] * 1000),
            limit_n1=(fit_n[1] * 0.001, fit_n[1] * 1000),
            limit_n2=(fit_n[2] * 0.001, fit_n[2] * 1000),
            limit_n3=(fit_n[3] * 0.001, fit_n[3] * 1000),
            limit_n4=(fit_n[4] * 0.001, fit_n[4] * 1000)
        )

        fmin, param = minuit.migrad()

        logging.info(minuit.matrix(correlation=True))
        chisq_min = minuit.fval
        n_fit, n_err = list(), list()
        ndf = 0
        for ii in range(pars.MAX_PERIOD):
            n_fit.append(param[ii]['value'])
            n_err.append(param[ii]['error'])
            if not fix_n[ii]:
                ndf += len(data_en[ii])
        ndf -= npar
        # p_value = 1 - stats.chi2.cdf(chisq_min, ndf)

        logging.info('Fit')
        logging.info('ChiSq/ndf = {}'.format(chisq_min / ndf))
        logging.info('ChiSq - ndf = {}'.format(chisq_min - ndf))

        # # plot testing
        # for ii, nn in enumerate(n_fit):
        #     if fix_n[ii]:
        #         continue
        #     plt.figure(figsize=(8, 6), tight_layout=True)
        #     ax = plt.gca()
        #     ax.set_xscale('log')
        #     ax.set_yscale('log')
        #     ax.set_title(ii)

        #     ax.errorbar(
        #         data_en[ii],
        #         data_fl[ii],
        #         yerr=data_fl_er[ii],
        #         marker='o',
        #         linestyle='none'
        #     )

        #     ax.plot(
        #         data_en[ii],
        #         [(nn / 1e20) * m.value for m in model[ii]],
        #         marker='o',
        #         linestyle='none'
        #     )
        #     plt.show()

    #     print('p-value', p_value)

    #     if do_abs:
    #         TauPrint0 = [tau0[len(data_en0) - 4], tau0[len(data_en0) - 1]]
    #         TauPrint1 = [tau1[len(data_en1) - 3], tau1[len(data_en1) - 1]]
    #     else:
    #         TauPrint0 = [0, 0]
    #         TauPrint1 = [0, 0]

        if chisq_min - ndf < 1e3:
            OutFit.write(str(chisq_min) + ' ')
            OutFit.write(str(ndf) + ' ')
            for ii in range(pars.MAX_PERIOD):
                if not fix_n[ii]:
                    OutFit.write(str(math.log10(n_fit[ii])) + ' ')
            OutFit.write(str(math.log10(Edot)) + ' ')
            OutFit.write(str(math.log10(Sigma)) + ' ')
            for ii in range(pars.MAX_PERIOD):
                if not fix_n[ii]:
                    idx = periods.index(ii)
                    OutFit.write(str(Dist[idx]) + ' ')
                    OutFit.write(str(DistPulsar[idx]) + ' ')
                    OutFit.write(str(Bfield[idx]) + ' ')
    #         OutFit.write(str(TauPrint0[0]) + ' ')
    #         OutFit.write(str(TauPrint0[1]) + ' ')
    #         OutFit.write(str(TauPrint1[0]) + ' ')
    #         OutFit.write(str(TauPrint1[1]) + '\n')
            OutFit.write('\n')

    OutFit.close()
Exemple #16
0
# blob emission

SYN = Synchrotron(comoving, B=B, Eemax=Emax, Eemin=Emin)

# Compute photon density spectrum from synchrotron emission
Esy = np.logspace(
    np.log10(((Emin / u.TeV)**2 * (B / u.Gauss)).cgs.value) + 3,
    np.log10(
        ((e_cutoff / u.TeV)**2 * (B / u.Gauss)).cgs.value) + 5, 300) * u.eV
Lsy = SYN.flux(Esy, distance=0 * u.cm)  # use distance 0 to get luminosity
phn_sy = Lsy * 2.25 / (4 * np.pi * R**2 * c)

SSC = InverseCompton(
    comoving,
    seed_photon_fields=[
        ["SSC", Esy, phn_sy],
    ],
    Eemax=Emax,
    Eemin=Emin,
)

EIC = InverseCompton(
    lab,
    seed_photon_fields=[
        "CMB",
        ["BLR", T, w],
    ],
    Eemax=Emax * delta,
    Eemin=Emin * delta,
)

# Use matplotlib to plot the spectra
eopts = {"Eemax": 50 * u.PeV, "Eemin": 0.1 * u.GeV}

SYN = Synchrotron(ECBPL, B=125 * u.uG, Eemax=50 * u.PeV, Eemin=0.1 * u.GeV)

# Compute photon density spectrum from synchrotron emission assuming R=2.1 pc
Rpwn = 2.1 * u.pc
Esy = np.logspace(-7, 9, 100) * u.eV
Lsy = SYN.flux(Esy, distance=0 * u.cm)  # use distance 0 to get luminosity
phn_sy = Lsy / (4 * np.pi * Rpwn**2 * c) * 2.24

IC = InverseCompton(
    ECBPL,
    seed_photon_fields=[
        "CMB",
        ["FIR", 70 * u.K, 0.5 * u.eV / u.cm**3],
        ["NIR", 5000 * u.K, 1 * u.eV / u.cm**3],
        ["SSC", Esy, phn_sy],
    ],
    Eemax=50 * u.PeV,
    Eemin=0.1 * u.GeV,
)

# Use plot_data from naima to plot the observed spectra
data = ascii.read("CrabNebula_spectrum.ecsv")
figure = naima.plot_data(data, e_unit=u.eV)
ax = figure.axes[0]

# Plot the computed model emission
energy = np.logspace(-7, 15, 100) * u.eV
ax.loglog(
    energy,
Exemple #18
0
    def plot_sed(
        self,
        iperiod=0,
        period=0,
        best_solution=True,
        Edot=1e36,
        theta_ic=90,
        dist=2,
        pos=np.array([1, 1, 1]),
        ls='-',
        lw=1,
        label='None',
        Tstar=pars.TSTAR,
        Rstar=pars.RSTAR,
        emin=0.1,
        ecut=50,
        fast=False
    ):
        Alpha = pars.ELEC_SPEC_INDEX[period]

        Eref = 1 * u.TeV
        Ecut = ecut * u.TeV
        Emax = 20 * u.PeV
        Emin = emin * u.TeV
        SourceDist = pars.SRC_DIST * u.kpc
        n_en = 1 if fast else 2

        Obs = np.array([0, 0, -1])
        Abs = absorption.Absorption(Tstar=Tstar, Rstar=Rstar)

        if best_solution:
            b_sed = self.bMin[iperiod]
            norm_sed = self.normMin[iperiod]
            dist_sed = self.distPulsarMin[iperiod]
            dist_star = dist - dist_sed
            density_sed = psr.PhotonDensity(Tstar=Tstar, Rstar=Rstar, d=dist_star)
        else:
            idx = np.argmin(np.array([math.fabs(l - math.log10(Edot)) for l in self.lgEdotLine]))
            b_sed = self.bLine[iperiod][idx]
            norm_sed = 10**self.lgNormLine[iperiod][idx]
            dist_sed = self.distPulsarLine[iperiod][idx]
            dist_star = dist * (1 - dist_sed)
            density_sed = psr.PhotonDensity(Tstar=Tstar, Rstar=Rstar, d=dist_star)

        EnergyToPlot = np.logspace(-0.5, 9.6, n_en * 300) * u.keV

        ECPL = ExponentialCutoffPowerLaw(
            amplitude=norm_sed / u.eV,
            e_0=Eref,
            alpha=Alpha,
            e_cutoff=Ecut
        )

        SYN = Synchrotron(
            particle_distribution=ECPL,
            B=b_sed * u.G,
            Eemax=Emax,
            Eemin=Emin
        )
        IC = InverseCompton(
            particle_distribution=ECPL,
            seed_photon_fields=[[
                'STAR',
                Tstar * u.K,
                density_sed * u.erg / u.cm**3,
                theta_ic * u.deg
            ]],
            Eemax=Emax,
            Eemin=Emin
        )

        tau = list()
        for e in EnergyToPlot:
            if e.value * u.keV.to(u.TeV) < 1e-4:
                tau.append(0)
            else:
                tau.append(Abs.TauGG(
                    en=e.value * u.keV.to(u.TeV),
                    obs=Obs,
                    pos=pos * dist_star / norm(pos)
                ))

        model = (
            SYN.sed(photon_energy=EnergyToPlot, distance=SourceDist)
            + IC.sed(photon_energy=EnergyToPlot, distance=SourceDist)
        )
        model_abs = [math.exp(-t) * m.value for (m, t) in zip(model, tau)]

        EnergyToPlot, model_abs = util.fix_naima_bug(EnergyToPlot, model_abs)
        model_abs = util.smooth_break(EnergyToPlot, model_abs)

        ax = plt.gca()
        ax.plot(EnergyToPlot, model_abs, ls=ls, lw=lw, c=self.color, label=label)
Exemple #19
0
    print "dN/dE(", E, ") = ", electrons(E)

# In[46]:

#now, to get the total emission from those electrons.
#naima supports three emission modes: Synchrotron, Bremsstrahlung, Inverse Compton

synch = Synchrotron(electrons,
                    B=3 * u.uG,
                    Eemin=1 * u.GeV,
                    Eemax=510 * u.TeV,
                    nEed=100)

IC = InverseCompton(electrons,
                    seed_photon_fields=["CMB", "NIR", "FIR"],
                    Eemin=1 * u.GeV,
                    Eemax=510 * u.TeV,
                    nEed=300)

brems = Bremsstrahlung(electrons,
                       n0=1.0 / u.cm**3,
                       Eemin=1 * u.GeV,
                       Eemax=510 * u.TeV,
                       nEed=100)

#set normalization by fixing the total electron energy. For some reason, this is done
#via the emission spectrum.
synch.set_We(10**50 * u.erg)

#units check...
print "Flux dN/dE:", synch.flux([1] * u.keV, distance=2 * u.kpc)
Exemple #20
0
                                        beta=2.)

eopts = {'Eemax': 50 * u.PeV, 'Eemin': 0.1 * u.GeV}

SYN = Synchrotron(ECBPL, B=125 * u.uG, Eemax=50 * u.PeV, Eemin=0.1 * u.GeV)

# Compute photon density spectrum from synchrotron emission assuming R=2.1 pc
Rpwn = 2.1 * u.pc
Esy = np.logspace(-7, 9, 100) * u.eV
Lsy = SYN.flux(Esy, distance=0 * u.cm)  # use distance 0 to get luminosity
phn_sy = Lsy / (4 * np.pi * Rpwn**2 * c) * 2.24

IC = InverseCompton(ECBPL,
                    seed_photon_fields=[
                        'CMB', ['FIR', 70 * u.K, 0.5 * u.eV / u.cm**3],
                        ['NIR', 5000 * u.K, 1 * u.eV / u.cm**3],
                        ['SSC', Esy, phn_sy]
                    ],
                    Eemax=50 * u.PeV,
                    Eemin=0.1 * u.GeV)

# Use plot_data from naima to plot the observed spectra
data = ascii.read('CrabNebula_spectrum.ecsv')
figure = naima.plot_data(data, e_unit=u.eV)
ax = figure.axes[0]

# Plot the computed model emission
energy = np.logspace(-7, 15, 100) * u.eV
ax.loglog(energy,
          IC.sed(energy, 2 * u.kpc) + SYN.sed(energy, 2 * u.kpc),
          lw=3,
          c='k',
Exemple #21
0
ECPL = ExponentialCutoffPowerLaw(1e36 * u.Unit('1/eV'), 1 * u.TeV, 2.0,
                                 13 * u.TeV)
SYN = Synchrotron(ECPL, B=100 * u.uG)

# Define energy array for synchrotron seed photon field and compute
# Synchroton luminosity by setting distance to 0.
Esy = np.logspace(-6, 6, 100) * u.eV
Lsy = SYN.flux(Esy, distance=0 * u.cm)

# Define source radius and compute photon density
R = 2 * u.pc
phn_sy = Lsy / (4 * np.pi * R**2 * c) * 2.26

# Create IC instance with CMB and synchrotron seed photon fields:
IC = InverseCompton(
    ECPL, seed_photon_fields=['CMB', 'FIR', 'NIR', ['SSC', Esy, phn_sy]])

# Compute SEDs
spectrum_energy = np.logspace(-8, 14, 100) * u.eV
sed_IC = IC.sed(spectrum_energy, distance=1.5 * u.kpc)
sed_SYN = SYN.sed(spectrum_energy, distance=1.5 * u.kpc)

# Plot
plt.figure(figsize=(8, 5))
#plt.rc('font', family='sans')
#plt.rc('mathtext', fontset='custom')
ssc = IC.sed(spectrum_energy, seed='SSC', distance=1.5 * u.kpc)
plt.loglog(spectrum_energy,
           ssc,
           lw=1.5,
           ls='-',
#naima models are phyical and accept/return astropy quantities.
#Try: electrons( 2.0 ) without a unit...
for E in [ 1*u.GeV, 1000*u.GeV, 1*u.TeV]:
    print "dN/dE(", E, ") = ", electrons(E)



# In[46]:

#now, to get the total emission from those electrons.
#naima supports three emission modes: Synchrotron, Bremsstrahlung, Inverse Compton

synch = Synchrotron(electrons, B=3*u.uG,
                   Eemin = 1*u.GeV, Eemax = 510*u.TeV, nEed = 100)

IC = InverseCompton(electrons, seed_photon_fields=["CMB", "NIR", "FIR"],
                   Eemin = 1*u.GeV, Eemax = 510*u.TeV, nEed = 300)

brems = Bremsstrahlung(electrons, n0=1.0/u.cm**3,
                   Eemin = 1*u.GeV, Eemax = 510*u.TeV, nEed = 100)

#set normalization by fixing the total electron energy. For some reason, this is done 
#via the emission spectrum.
synch.set_We(10**50 * u.erg)

#units check...
print "Flux dN/dE:", synch.flux([1]*u.keV, distance=2*u.kpc)
print "SED E^2dN/dE:", synch.sed([1]*u.keV, distance=2*u.kpc)


# In[47]:
Exemple #23
0
                                        e_cutoff=1863 * u.TeV,
                                        beta=2.)

eopts = {'Eemax': 50 * u.PeV, 'Eemin': 0.1 * u.GeV}

SYN = Synchrotron(ECBPL, B=125 * u.uG, Eemax=50 * u.PeV, Eemin=0.1 * u.GeV)

# Compute photon density spectrum from synchrotron emission assuming R=2.1 pc
Rpwn = 2.1 * u.pc
Esy = np.logspace(-7, 9, 100) * u.eV
Lsy = SYN.flux(Esy, distance=0 * u.cm)  # use distance 0 to get luminosity
phn_sy = Lsy / (4 * np.pi * Rpwn**2 * c) * 2.24

IC = InverseCompton(ECBPL,
                    seed_photon_fields=['CMB',
                                        ['FIR', 70 * u.K, 0.5 * u.eV / u.cm**3],
                                        ['NIR', 5000 * u.K, 1 * u.eV / u.cm**3],
                                        ['SSC', Esy, phn_sy]],
                    Eemax=50 * u.PeV, Eemin=0.1 * u.GeV)

# Use plot_data from naima to plot the observed spectra
data = ascii.read('CrabNebula_spectrum.ecsv')
figure = naima.plot_data(data, e_unit=u.eV)
ax = figure.axes[0]

# Plot the computed model emission
energy = np.logspace(-7, 15, 100) * u.eV
ax.loglog(energy, IC.sed(energy, 2 * u.kpc) + SYN.sed(energy, 2 * u.kpc),
          lw=3, c='k', label='Total')
for i, seed, ls in zip(
        range(4), ['CMB', 'FIR', 'NIR', 'SSC'], ['--', '-.', ':', '-']):
    ax.loglog(energy, IC.sed(energy, 2 * u.kpc, seed=seed),
Exemple #24
0
def do_fit(
        ThetaIC,  # np.array([90, 90]),
        Pos3D,  # [[1, 1, 1], [1, 1, 1]],
        Dist,  # np.array([2, 2]),
        label='',
        do_abs=True,
        lgEdot_min=31,
        lgEdot_max=37.5,
        lgEdot_bins=10,
        lgSigma_min=-3,
        lgSigma_max=-1,
        lgSigma_bins=10,
        Tstar=pars.TSTAR_LS,
        Rstar=pars.RSTAR_LS,
        AlphaSigma=1,
        Mdot=pars.MDOT_LS,
        Vw=pars.VW_LS):

    logging.info('Starting fitting')
    OutFit = open('fit_results/fit_results_ls5039_' + label + '.txt', 'w')

    # Loading data
    phaseData, fluxSuzaku, fluxErrSuzaku, gammaSuzaku, gammaErrSuzaku = get_data_ls5039(
        'SUZAKU')
    phaseData, fluxHESS, fluxErrHESS, gammaHESS, gammaErrHESS = get_data_ls5039(
        'HESS')

    logging.debug('PhaseData')
    logging.debug(phaseData)

    # Loading energy
    energyXrays = np.logspace(0, 1, 5)
    energyGamma = np.logspace(math.log10(0.2e9), math.log10(5e9), 10)
    energyAll = np.concatenate((energyXrays, energyGamma))
    logging.debug('Energies')
    logging.debug(energyXrays)
    logging.debug(energyGamma)
    logging.debug(energyAll)

    # Loading grid
    NEdot = int((lgEdot_max - lgEdot_min) * lgEdot_bins)
    NSigma = int((lgSigma_max - lgSigma_min) * lgSigma_bins)
    Edot_list = np.logspace(lgEdot_min, lgEdot_max, int(NEdot))
    Sigma_list = np.logspace(lgSigma_min, lgSigma_max, int(NSigma))

    logging.info('{} iterations'.format(len(Edot_list) * len(Sigma_list)))

    if (len(ThetaIC) != len(phaseData) or len(Pos3D) != len(phaseData)
            or len(Dist) != len(phaseData)):
        logging.error('Argument with wrong dimensions - aborting')
        return None

    # Absorption
    if not do_abs:
        logging.info('Skipping absorption')
    else:
        if Path('abs_pars.json').exists():
            logging.debug('Reading abs pars')
            with open('abs_pars.json', 'r') as file:
                data = json.load(file)

            DistFrac = data['DistFrac']
            DistTau = data['DistTau']
            Tau = data['Tau']
        else:
            # Computing Taus
            logging.info('Computing absorption')
            start = time.time()
            Obs = np.array([0, 0, -1])
            Abs = abso.Absorption(Tstar=Tstar,
                                  Rstar=Rstar,
                                  name_table='absorption_table_ls5039.dat')

            Tau = list()
            DistTau = list()
            for iph in range(len(phaseData)):
                DistTau.append(list())
                tt = dict()
                for i in range(len(energyAll)):
                    tt[i] = list()
                Tau.append(tt)

            DistFrac = np.concatenate(
                (np.linspace(0.005, 0.2, 20), np.linspace(0.201, 1.0, 10)))

            for ff in DistFrac:
                for iph in range(len(phaseData)):
                    dist = ff * norm(Pos3D[iph])
                    PosStar = Pos3D[iph] * dist / norm(Pos3D[iph])
                    for ien in range(len(energyAll)):
                        tau = Abs.TauGG(en=energyAll[ien] * u.keV.to(u.TeV),
                                        obs=Obs,
                                        pos=PosStar)
                        Tau[iph][ien].append(tau)
                    DistTau[iph].append(dist)

            logging.info('Abs done, dt/s = {}'.format(time.time() - start))

            absToSave = dict()
            absToSave['DistFrac'] = list(DistFrac)
            absToSave['DistTau'] = list(DistTau)
            absToSave['Tau'] = list(Tau)

            logging.debug('Writing abs to json file')
            with open('abs_pars.json', 'w') as file:
                json.dump(absToSave, file)

        # # Ploting tau vs dist
        # plt.figure(figsize=(8, 6), tight_layout=True)
        # ax = plt.gca()
        # ax.set_yscale('log')
        # ax.set_ylabel(r'$\tau_{\gamma \gamma}$')
        # ax.set_xlabel(r'$D$ [AU]')

        # ax.plot(DistTau[7], Tau[7][str(5)], marker='o', linestyle='-')
        # ax.plot(DistTau[7], Tau[7][str(13)], marker='o', linestyle='-')
        # plt.show()

    chisqMin = 1e10
    minEdot = 0
    minSigma = 0

    for (Edot, Sigma) in itertools.product(Edot_list, Sigma_list):

        print('Starting Edot={}, Sigma={}'.format(Edot, Sigma))

        # Computed parameters
        DistPulsar = [
            psr.Rshock(Edot=Edot, Mdot=Mdot, Vw=Vw, D=d) for d in Dist
        ]
        DistStar = Dist - DistPulsar
        SigmaFac = [pow(0.1 / d, AlphaSigma) for d in DistPulsar]
        SigmaShock = [Sigma * f for f in SigmaFac]
        Bfield = [
            psr.B2_KC(Edot=Edot, Rs=dp, sigma=s)
            for (dp, s) in zip(DistPulsar, SigmaShock)
        ]
        Density = [
            psr.PhotonDensity(Tstar=Tstar, Rstar=Rstar, d=d) for d in DistStar
        ]

        # plt.figure(figsize=(8, 6), tight_layout=True)
        # ax = plt.gca()
        # ax.set_yscale('log')
        # ax.set_ylabel(r'$\tau_{\gamma \gamma}$')
        # ax.set_xlabel(r'$D$ [AU]')

        # ax.plot(DistPulsar, SigmaShock, marker='o', linestyle='-')
        # plt.show()

        # logging.debug('DistPulsar')
        # logging.debug(DistPulsar)
        # logging.debug('DistStar')
        # logging.debug(DistStar)
        # logging.debug('SigmaShock')
        # logging.debug(SigmaShock)
        # logging.debug('SigmaFac')
        # logging.debug(SigmaFac)
        logging.debug('Bfield')
        logging.debug(Bfield)
        logging.debug('MeanBfield')
        logging.debug(sum(Bfield) / len(Bfield))

        if 0 in Bfield:
            logging.info('Bfield is 0 - skipping')
            continue

        # Normalization
        NormStart = np.array([1e23 / b for b in Bfield])

        npar = len(phaseData)

        # Further parameters
        Ecut = [rad.Emax(b, 1) * u.TeV for b in Bfield]
        Eref = 1 * u.TeV
        Emax = 100 * u.PeV
        Emin = 10 * u.GeV
        SourceDist = pars.SRC_DIST_LS * u.kpc

        # Computing Alpha
        Alpha = [2 * g - 1 for g in gammaSuzaku]
        # print('Alpha')
        # print(Alpha)
        # print('gamma')
        # print(gammaSuzaku)

        # Computing Model
        tau = list()
        modelAll = list()
        for iph in range(len(phaseData)):

            thisTau = list()
            if do_abs:
                for ien in range(len(energyAll)):
                    thisTau.append(
                        np.interp(DistStar[iph],
                                  xp=DistTau[iph],
                                  fp=Tau[iph][str(ien)]))
            else:
                thisTau = [0] * len(energyAll)

            tau.append(thisTau)

            ECPL = ExponentialCutoffPowerLaw(amplitude=1e20 / u.eV,
                                             e_0=Eref,
                                             alpha=Alpha[iph],
                                             e_cutoff=Ecut[iph])

            SYN = Synchrotron(particle_distribution=ECPL,
                              B=Bfield[iph] * u.G,
                              Eemax=Emax,
                              Eemin=Emin)

            IC = InverseCompton(particle_distribution=ECPL,
                                seed_photon_fields=[[
                                    'STAR', Tstar * u.K,
                                    Density[iph] * u.erg / u.cm**3,
                                    ThetaIC[iph] * u.deg
                                ]],
                                Eemax=Emax,
                                Eemin=Emin)

            thisModel = (SYN.sed(photon_energy=[e * u.keV for e in energyAll],
                                 distance=SourceDist) +
                         IC.sed(photon_energy=[e * u.keV for e in energyAll],
                                distance=SourceDist))

            if do_abs:
                thisModel = [
                    math.exp(-t) * m for (m, t) in zip(thisModel, thisTau)
                ]

            # Ploting tau vs dist
            # plt.figure(figsize=(8, 6), tight_layout=True)
            # ax = plt.gca()
            # ax.set_yscale('log')
            # ax.set_xscale('log')
            # ax.set_ylabel(r'$\tau_{\gamma \gamma}$')
            # ax.set_xlabel(r'$E$ [keV]')

            # print(energyAll)
            # print(thisTau)

            # ax.plot(energyAll[5:], thisTau[5:], marker='o', linestyle='-')
            # ax.set_xlim(1e8, 1e10)
            # plt.show()

            modelAll.append(thisModel)
        # END for

        fluxModelSuzaku, fluxModelHESS, gammaModelHESS = list(), list(), list()
        for thisModel in modelAll:
            sedSuzaku = [f for (f, e) in zip(thisModel, energyAll) if e < 1e3]
            energySuzaku = [e for e in energyAll if e < 1e3]
            sedHESS = [f for (f, e) in zip(thisModel, energyAll) if e > 1e3]
            energyHESS = [e for e in energyAll if e > 1e3]
            fluxModelSuzaku.append(getSuzakuFlux(sedSuzaku, energySuzaku))
            n, g = getHESSFluxAndGamma(sedHESS, energyHESS)
            fluxModelHESS.append(n)
            gammaModelHESS.append(g)

        def computeModelPars(N, model, energy):
            thisModel = [(N / 1e20) * m for m in model]

            sedSuzaku = [f for (f, e) in zip(thisModel, energy) if e < 1e3]
            energySuzaku = [e for e in energyAll if e < 1e3]
            sedHESS = [f for (f, e) in zip(thisModel, energy) if e > 1e3]
            energyHESS = [e for e in energyAll if e > 1e3]

            thisFluxModelSuzaku = getSuzakuFlux(sedSuzaku, energySuzaku)
            thisFluxModelHESS, thisGammaModelHESS = getHESSFluxAndGamma(
                sedHESS, energyHESS)
            return thisFluxModelSuzaku, thisFluxModelHESS, thisGammaModelHESS

        chisqFit, nFit = list(), list()
        fluxFitSuzaku, fluxFitHESS, gammaFitHESS = list(), list(), list()

        for ii in range(len(phaseData)):

            def least_square(n):
                chisq = 0

                fitFluxModelSuzaku, fitFluxModelHESS, fitGammaModelHESS = computeModelPars(
                    n, modelAll[ii], energyAll)

                chisq += ((fitFluxModelSuzaku.value * 1e12 - fluxSuzaku[ii]) /
                          fluxErrSuzaku[ii])**2
                chisq += ((fitFluxModelHESS.value * 1e12 - fluxHESS[ii]) /
                          fluxErrHESS[ii])**2
                # chisq += ((fitGammaModelHESS - gammaHESS[ii]) / gammaErrHESS[ii])**2

                return chisq

            minuit = Minuit(least_square,
                            n=NormStart[ii],
                            fix_n=False,
                            limit_n=(NormStart[ii] * 0.0001,
                                     NormStart[ii] * 10000),
                            errordef=1.)

            fmin, param = minuit.migrad()

            chisqFit.append(minuit.fval)
            nFit.append(param[0]['value'])

            fitFS, fitFH, fitGH = computeModelPars(param[0]['value'],
                                                   modelAll[ii], energyAll)
            fluxFitSuzaku.append(fitFS)
            fluxFitHESS.append(fitFH)
            gammaFitHESS.append(fitGH)

        # print('N*B')
        # print([n * b for (n,b) in zip(nFit, Bfield)])
        # print([c / 2 for c in chisqFit])
        totalChiSq = sum(chisqFit) / 10.

        if totalChiSq < chisqMin:
            chisqMin = totalChiSq
            minEdot = Edot
            minSigma = Sigma

        print('ChiSq = {}'.format(totalChiSq))

        if totalChiSq < 1e20:
            plotResults(phaseData=phaseData,
                        nFit=nFit,
                        fluxFitSuzaku=fluxFitSuzaku,
                        fluxSuzaku=fluxSuzaku,
                        fluxErrSuzaku=fluxErrSuzaku,
                        fluxFitHESS=fluxFitHESS,
                        fluxHESS=fluxHESS,
                        fluxErrHESS=fluxErrHESS,
                        gammaFitHESS=gammaFitHESS,
                        gammaHESS=gammaHESS,
                        gammaErrHESS=gammaErrHESS,
                        modelAll=modelAll,
                        energyAll=energyAll)

        continue

        # logging.info('Fit')
        # logging.info('ChiSq/ndf = {}'.format(chisq_min / ndf))
        # logging.info('ChiSq - ndf = {}'.format(chisq_min - ndf))

        # # plot testing
        # for ii, nn in enumerate(n_fit):
        #     if fix_n[ii]:
        #         continue
        #     plt.figure(figsize=(8, 6), tight_layout=True)
        #     ax = plt.gca()
        #     ax.set_xscale('log')
        #     ax.set_yscale('log')
        #     ax.set_title(ii)

        #     ax.errorbar(
        #         data_en[ii],
        #         data_fl[ii],
        #         yerr=data_fl_er[ii],
        #         marker='o',
        #         linestyle='none'
        #     )

        #     ax.plot(
        #         data_en[ii],
        #         [(nn / 1e20) * m.value for m in model[ii]],
        #         marker='o',
        #         linestyle='none'
        #     )
        #     plt.show()

        #     print('p-value', p_value)

        #     if do_abs:
        #         TauPrint0 = [tau0[len(data_en0) - 4], tau0[len(data_en0) - 1]]
        #         TauPrint1 = [tau1[len(data_en1) - 3], tau1[len(data_en1) - 1]]
        #     else:
        #         TauPrint0 = [0, 0]
        #         TauPrint1 = [0, 0]

        if chisq_min - ndf < 1e3:
            OutFit.write(str(chisq_min) + ' ')
            OutFit.write(str(ndf) + ' ')
            for ii in range(pars.MAX_PERIOD):
                if not fix_n[ii]:
                    OutFit.write(str(math.log10(n_fit[ii])) + ' ')
            OutFit.write(str(math.log10(Edot)) + ' ')
            OutFit.write(str(math.log10(Sigma)) + ' ')
            for ii in range(pars.MAX_PERIOD):
                if not fix_n[ii]:
                    idx = periods.index(ii)
                    OutFit.write(str(Dist[idx]) + ' ')
                    OutFit.write(str(DistPulsar[idx]) + ' ')
                    OutFit.write(str(Bfield[idx]) + ' ')
    #         OutFit.write(str(TauPrint0[0]) + ' ')
    #         OutFit.write(str(TauPrint0[1]) + ' ')
    #         OutFit.write(str(TauPrint1[0]) + ' ')
    #         OutFit.write(str(TauPrint1[1]) + '\n')
            OutFit.write('\n')

    print('ChiSqMin {}'.format(chisqMin))
    print('lgEdot {}'.format(math.log10(minEdot)))
    print('Sigma {}'.format(minSigma))

    OutFit.close()
Exemple #25
0
class ElectronIC(SpectralModel):
    """This class inherits from SpectralModel in 3ML, and can be used
    to infer the population of electrons in a source.  The fit works 
    as follows:

    1. Choose a parametric form for the electron spectrum, e.g., a power
       law with an exponential cutoff.
    2. Use Inverse Compton scattering to calculate the gamma-ray flux.
    3. Fit the calculated gamma-ray flux to the data using one of the
       plugins available in 3ML.

    The free parameters of this model include the parameters of the
    electron spectrum and the distance to the source.
    
    Additional quantities which affect the calculation are the components
    of the interstellar radiation field (ISRF) which contribute to the IC
    flux.  These are not floated in the fit.  Users may wish to obtain an
    estimate of the ISRF in the vicinity of the source of interest using
    GALPROP.
    """
    def setup(self):
        self.functionName = "ElectronIC"
        self.formula = r"$f(E)=A(E/E_{\rm piv}}^\gamma}$"

        self.parameters = collections.OrderedDict()
        self.parameters["gamma"] = Parameter("gamma",
                                             -2.,
                                             -10.,
                                             10,
                                             0.1,
                                             fixed=False,
                                             nuisance=False,
                                             dataset=None)
        self.parameters["logA"] = Parameter("logA",
                                            -4.,
                                            -40.,
                                            30,
                                            0.1,
                                            fixed=False,
                                            nuisance=False,
                                            dataset=None)
        self.parameters["Epiv"] = Parameter("Epiv",
                                            1.,
                                            1e-10,
                                            1e10,
                                            1.,
                                            fixed=True,
                                            unit="keV")
        self.parameters["dist"] = Parameter("dist",
                                            1.,
                                            1e-10,
                                            1e10,
                                            1.,
                                            fixed=True)
        self.ncalls = 0

        self.pdist_unit = 1. / u.Unit(m_e * c**2)
        self.PL = PowerLaw(1 * self.pdist_unit, 1 * u.keV, -2.5)
        self.IC = InverseCompton(
            self.PL,
            seed_photon_fields=[
                'CMB', ['FIR', 26.5 * u.K, 0.415 * u.eV / u.cm**3]
            ],
            Eemin=1 * u.TeV)

    #        def integral(E1, E2):
    #            a  = self.parameters["gamma"].value
    #            Ep = self.parameters["Epiv"].value
    #            A  = 10.**self.parameters["logA"].value
    #
    #            if a == -1.:
    #                def f(energy):
    #                    return A * E0 * np.log(energy)
    #            else:
    #                def f(energy):
    #                    return A * energy * (energy/Ep)**a / (a + 1.)
    #            return f(E2) - f(E1)
    #
    #        self.integral = integral

    def __call__(self, energy):
        #        pdist_unit = 1. / u.Unit(m_e * c**2)

        self.ncalls += 1

        # Convert spectral index to naima sign convention
        a = -self.parameters["gamma"].value

        # Convert to naima base units: all energies in keV
        Ep = self.parameters["Epiv"].value * u.keV

        # Normalization is actually for electron differential spectrum
        A = 10.**self.parameters["logA"].value * self.pdist_unit

        # Initialize the electron particle distribution
        self.PL.amplitude = A
        self.PL.e_0 = Ep
        self.PL.alpha = a

        # Fix the distance of the source, in kpc
        dist = self.parameters["dist"].value * u.kpc

        if type(energy) is float or type(energy) is int:
            E = [energy] * u.keV
        else:
            E = energy * u.keV

        icFlux = self.IC.flux(E, distance=dist)
        return icFlux.to(1. / (u.keV * u.cm**2 * u.s)).value

    def electronFlux(self, energy):
        # Convert spectral index to naima sign convention
        a = -self.parameters["gamma"].value

        # Convert to naima base units: all energies in keV
        Ep = self.parameters["Epiv"].value * u.keV

        # Normalization is actually for electron differential spectrum
        A = 10.**self.parameters["logA"].value * self.pdist_unit

        # Initialize the electron particle distribution
        PL = PowerLaw(A, Ep, a)

        if type(energy) is float or type(energy) is int:
            E = [energy] * u.keV
        else:
            E = energy * u.keV

        return PL(E).to(1. / u.keV).value

    def photonFlux(self, E1, E2):
        return self.integral(E1, E2)

    def energyFlux(self, E1, E2):
        a = self.parameters["gamma"].value
        Ep = self.parameters["Epiv"].value
        A = 10.**self.parameters["logA"].value

        if a == 2:

            def eF(E):
                return np.maximum(A * np.log(E / Ep), 1e-100)
        else:

            def eF(E):
                return np.maximum(A * np.power(E / Ep, 2 - a) / (2 - a),
                                  1e-100)

        return (eF(E2) - eF(E1)) * self.keVtoErg