Beispiel #1
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)
Beispiel #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.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)
Beispiel #3
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)
Beispiel #4
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
Beispiel #5
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)
Beispiel #6
0
def log_likelihood(e_cutoff, data, amplitude, alpha, B, Eemin, Eemax):
    crab_distance = 2.2 * u.kpc
    ECPL = ExponentialCutoffPowerLaw(amplitude=amplitude / u.eV,
                                     e_0=1 * u.TeV,
                                     alpha=alpha,
                                     e_cutoff=abs(e_cutoff) * u.erg)
    SYN = Synchrotron(ECPL, B=B, Eemin=Eemin, Eemax=Eemax)
    model = SYN.sed(data['energy'].quantity, distance=crab_distance)
    sigma = (data['flux_error_lo'].quantity +
             data['flux_error_hi'].quantity) / 2
    sigma2 = np.where(sigma != 0, sigma, np.ones_like(sigma))
    loglik = np.sum(np.log((model.value - data['flux'].data)**2))
    return loglik - 2 * np.sum(np.log(sigma2))
Beispiel #7
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
Beispiel #8
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
Beispiel #9
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
Beispiel #10
0
def tryecut(ecut_arr, data, amplitude, alpha, B, Eemin, Eemax):
    liktrial = np.zeros(len(ecut_arr))
    for i in range(len(ecut_arr)):
        ECPL = ExponentialCutoffPowerLaw(amplitude=amplitude / u.eV,
                                         e_0=1 * u.TeV,
                                         alpha=alpha,
                                         e_cutoff=ecut_arr[i])
        SYN = Synchrotron(ECPL, B=B, Eemin=Eemin, Eemax=Eemax)
        amp_cor = fitfactor(data, SYN)
        liktrial[i] = trylik(ecut_arr[i], data, amplitude * amp_cor, alpha, B,
                             Eemin, Eemax)

    result = ecut_arr[np.where(liktrial == np.min(liktrial))]
    #print(liktrial)
    dof = len(np.asarray(data['flux'].data))
    if np.min(liktrial) > dof:
        print('Warning: Minimum Log-likelihood > degrees of freedom')
    return result
Beispiel #11
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()
    InverseCompton,
)

ECBPL = ExponentialCutoffBrokenPowerLaw(
    amplitude=3.699e36 / u.eV,
    e_0=1 * u.TeV,
    e_break=0.265 * u.TeV,
    alpha_1=1.5,
    alpha_2=3.233,
    e_cutoff=1863 * u.TeV,
    beta=2.0,
)

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],
    ],
Beispiel #13
0
import numpy as np
import matplotlib.pyplot as plt

import naima
from naima.models import (ExponentialCutoffPowerLaw, Synchrotron,
                          InverseCompton)
from astropy.constants import c
import astropy.units as u

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)
Beispiel #14
0
import astropy.units as u
import naima
from naima.models import (ExponentialCutoffBrokenPowerLaw, Synchrotron,
                          InverseCompton)

ECBPL = ExponentialCutoffBrokenPowerLaw(amplitude=3.699e36 / u.eV,
                                        e_0=1 * u.TeV,
                                        e_break=0.265 * u.TeV,
                                        alpha_1=1.5,
                                        alpha_2=3.233,
                                        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
Beispiel #15
0
    beta=beta,
)

lab = ExponentialCutoffBrokenPowerLaw(
    amplitude=amplitude * delta**3,
    e_0=e_0 * delta,
    e_break=e_break * delta,
    alpha_1=alpha_1,
    alpha_2=alpha_2,
    e_cutoff=e_cutoff * delta,
    beta=beta,
)

# 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,
Beispiel #16
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)
Beispiel #17
0
def tophat(E0, g0, energy, time, theta_obs, D_L):
    mu_obs = np.cos(theta_obs)
    z = z_at_value(Planck15.luminosity_distance, D_L)
    if isinstance(energy.to_value(u.eV), float):
        energy = np.array([energy.to_value(u.eV)]) * u.eV

    # calc: R_b, t_b, Gamma_sh
    u0, b0 = np.sqrt(g0**2 - 1), np.sqrt(1 - 1 / g0**2)
    if g0 == 1.0:
        return 0 * u.erg / u.cm**2 / u.s

    R_dec = ((3. * E0 / (4. * np.pi * n_amb * m_p * c**2 *
                         (g0**2 - 1)))**(1 / 3)).to(u.pc)
    xi_z = (c * time / (1 + z) / R_dec).cgs

    if np.isposinf(alpha_stf):
        u_xi = lambda xi: u0 if xi < 1e-1 else (u0 * xi**(
            -3 / 2) if xi > 1e1 else np.sqrt(
                ((g0 + 1) / 2 * xi**(-3) *
                 (np.sqrt(1 + 4 * g0 / (g0 + 1) * xi**3 + 4 /
                          (g0 + 1)**2 * xi**6) - 1))**2 - 1))
    else:
        ui = np.inf
        eiso_u = lambda u: (max(u0, min(ui, u))**(-alpha_stf) - ui**(
            -alpha_stf)) / (u0**(-alpha_stf) - ui**(-alpha_stf))
        I = lambda u: alpha_stf / (alpha_stf + 2) * u**(-alpha_stf - 2) * (
            1 + hyp2f1(-1 / 2, -1 - alpha_stf / 2, -alpha_stf / 2, -u**2))
        miso_u = lambda u: (I(max(u0, min(ui, u))) - I(ui)) / (u0**(
            -alpha_stf) - ui**(-alpha_stf))
        u_xi = lambda xi: fsolve(
            lambda _u: xi**3 *
            (_u[0] / u0)**2 - eiso_u(_u[0]) + miso_u(_u[0]) *
            (np.sqrt(_u[0]**2 + 1) - 1), u0)[0]

    eats = lambda xi: -mu_obs * xi + quad(
        lambda _xi: np.sqrt(u_xi(_xi)**2 + 1) / u_xi(_xi), 0, xi)[0]
    xi = fsolve(lambda _xi: eats(_xi[0]) - xi_z,
                b0 * xi_z / (1 - b0 * mu_obs))[0]

    R_b = xi * R_dec
    t_b = (R_dec / c).cgs * quad(
        lambda _xi: np.sqrt(u_xi(_xi)**2 + 1) / u_xi(_xi), 0, xi)[0]
    Gamma_sh = np.sqrt(u_xi(xi)**2 + 1)

    if Gamma_sh == 1.0:
        return 0 * u.erg / u.cm**2 / u.s

    # calc: electron distribution
    specific_heat_ratio = 4 / 3 + 1 / Gamma_sh
    compression_ratio = (specific_heat_ratio * Gamma_sh +
                         1) / (specific_heat_ratio - 1)

    B = (np.sqrt(8 * np.pi * eps_B * compression_ratio * n_amb * m_p * c**2 *
                 (Gamma_sh - 1))).to((u.erg * pcm)**(1 / 2))
    Ne = zeta_e * 4 / 3 * np.pi * R_b**3 * n_amb

    gm = (eps_e / zeta_e * (p_e - 2) / (p_e - 1) * m_p / m_e *
          (Gamma_sh - 1)).cgs

    _gc = 6 * np.pi * mec * Gamma_sh / (sigma_T * B**2 * t_b)
    Y = (-1 +
         np.sqrt(1 + 4 * min(1, (gm / _gc)**(p_e - 2)) * eps_e / eps_B)) / 2
    gc = _gc.cgs / (1 + Y)  # rough estimate from Sari & Esin (2001)

    e_syn_max = (min(np.sqrt(3 * e / (sigma_T * B * (1 + Y))), (e * B * R_b) /
                     (12 * 2 * np.pi * Gamma_sh * mec2)) * mec2).to(u.TeV)

    electrons = ExponentialCutoffBrokenPowerLaw(
        amplitude=(Ne * (p_e - 1) / (max(2., gm) * mec2) *
                   min(1., (gm / 2.)**(p_e - 1)) if gm < gc else Ne /
                   (max(2., gc) * mec2) * min(1., gc / 2.)).to(1 / u.eV),
        e_0=(max(2., min(gm, gc)) * mec2).to(u.TeV),
        e_break=(max(2., max(gm, gc)) * mec2).to(u.TeV),
        alpha_1=p_e if gm < gc else 2.,
        alpha_2=p_e + 1,
        e_cutoff=max(((max(2., min(gm, gc)) + 1) * mec2).to(u.TeV), e_syn_max),
        beta=2.0,
    )

    # calc: syn+ic flux
    SYN = Synchrotron(
        electrons,
        B=B.to_value((u.erg * pcm)**(1 / 2)) * u.G,
        Eemax=electrons.e_cutoff,
        Eemin=electrons.e_0,
        nEed=50,
    )
    '''E_ph = np.logspace(-7, 14, 22) * u.eV
    L_syn = self.SYN.flux(E_ph, distance=0 * u.cm)
    phn_syn = L_syn / (4 * np.pi * self.R ** 2 * c) * 2.24

    IC = InverseCompton(
        self.electrons,
        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", E_ph, phn_syn],
        ],
        Eemax=self.electrons.e_cutoff, 
        Eemin=self.electrons.e_0,
        nEed=50,
    )'''

    Doppler = 1 / (Gamma_sh * (1 - np.sqrt(1 - 1 / Gamma_sh**2) * mu_obs))
    flx = Doppler**4 * SYN.sed((1 + z) * energy / Doppler, D_L)[0]
    tran = EblAbsorptionModel(redshift=z).transmission(e=energy)[0]
    return (flx * tran).to(u.erg / u.cm**2 / u.s)
Beispiel #18
0
# In[8]:

#to illustrate the use of units and how to access the spectra.
#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)
Beispiel #19
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()
# In[8]:

#to illustrate the use of units and how to access the spectra.
#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)