Exemple #1
0
 def __init__(
         self,
         i,  # input energy bin
         nphot,  # number of photons
         geometry,
         verbose=False):
     self.verbose = verbose
     self.rad = numpy.zeros(nphot)
     self.phi = numpy.zeros(nphot)  # initial left-right angle for position
     self.theta = numpy.zeros(nphot)  # initial up-down angle for position
     self.alpha = rng.uniform(
         0, 2 * pi, size=nphot
     )  # initial left-right direction for direction -- value does not matter due to symmetry
     #mu = numpy.linspace(-1, 1, nphot) # uniform distribution
     mu = rng.uniform(-1, 1, size=nphot)
     self.beta = acos(mu)  # up-down angle for direction
     # self.beta = acos(numpy.linspace(-cone_in, cone_in, nphot)) # up-down angle for direction
     self.geometry = geometry
     energy_lo, energy_hi = bin2energy(i)
     e = (energy_lo + energy_hi) / 2.
     if self.verbose:
         print('PhotonBunch of size %d with energy %.2f keV' % (nphot, e))
     #self.energy = e * numpy.ones(nphot)
     self.energy = rng.uniform(low=energy_lo, high=energy_hi, size=nphot)
     #bin = energy2bin(self.energy)
     #assert (bin == i).all(), (bin.min(), bin.max(), self.energy.min(), self.energy.max(), energy_lo, energy_hi, self.energy[bin!=i])
     self.bin = i * numpy.ones(nphot, dtype=numpy.uint)
     self.stuck = self.rad != 0  # False
Exemple #2
0
def run(prefix, nphot, nmu, n_nh_bins, geometry, binmapfunction, verbose=False):
	rdata_transmit = numpy.zeros((nbins, nbins, nmu*n_nh_bins))
	rdata_reflect = numpy.zeros((nbins, nbins, nmu*n_nh_bins))
	#rdata = [0] * nbins
	energy_lo, energy_hi = bin2energy(list(range(nbins)))
	
	binrange = [list(range(nbins+1)), list(range(nmu*n_nh_bins+1))]
	for i in tqdm.trange(nbins-1, -1, -1):
		photons = PhotonBunch(i=i, nphot=nphot, verbose=verbose, geometry=geometry)
		for n_interactions in range(1000):
			emission, more = photons.pump()
			if emission is None and not more:
				break
			if emission is None:
				continue
			if len(emission['energy']) == 0:
				if not more:
					break
				continue
			if verbose: print(' received %d emitted photons (after %d interactions)' % (len(emission['energy']), n_interactions))
			beta = emission['beta']
			alpha = emission['alpha']
			assert (beta <= pi).all(), beta
			assert (beta >= 0).all(), beta
		
			# vertical bin, i.e. which viewing angle can see this photon?
			mbin = numpy.asarray(binmapfunction(beta=beta, alpha=alpha)).astype(numpy.uint)
			# highest bin exceeded due to rounding
			mbin[mbin == nmu] = nmu - 1
		
			# bin in NH
			nh = geometry.compute_los_nh(beta, alpha)
			nh[nh<1e-2] = 1e-2
			kbin = ((log10(nh) + 2) * n_nh_bins / (4 + 2)).astype(int)
			kbin[kbin == n_nh_bins] = n_nh_bins - 1
		
			mkbin = kbin * nmu + mbin
		
			bins = emission['bin']
			# produce unique array bins, mbin which contains counts
			counts, xedges, yedges = numpy.histogram2d(bins, mkbin, bins=binrange)
			# record into histogram if it landed within relevant range
			if n_interactions < 1:
				rdata_transmit[i] += counts
			else:
				rdata_reflect[i] += counts
			del counts, emission, bins
			if not more:
				break
		del photons

	return (rdata_transmit, rdata_reflect), nphot
Exemple #3
0
from __future__ import print_function, division
import numpy
from numpy import pi, exp
import h5py
import astropy.io.fits as pyfits
import sys
import progressbar
from binning import nbins, energy2bin, bin2energy

energy_lo, energy_hi = bin2energy(numpy.arange(nbins))
energy = (energy_hi + energy_lo) / 2
deltae = energy_hi - energy_lo

table = []
PhoIndices = [
    1., 1.20000005, 1.39999998, 1.60000002, 1.79999995, 2., 2.20000005,
    2.4000001, 2.5999999, 2.79999995, 3.
]
Ecuts = [20., 30, 40, 60, 100, 140, 200, 400]

nh_bins = numpy.array([
    9.99999978e-03, 1.41000003e-02, 1.99999996e-02, 2.82000005e-02,
    3.97999994e-02, 5.62000014e-02, 7.94000030e-02, 1.12000003e-01,
    1.58000007e-01, 2.24000007e-01, 3.16000015e-01, 4.46999997e-01,
    6.30999982e-01, 8.90999973e-01, 1.25999999e+00, 1.77999997e+00,
    2.50999999e+00, 3.54999995e+00, 5.01000023e+00, 7.07999992e+00,
    1.00000000e+01, 1.41000004e+01, 2.00000000e+01, 2.82000008e+01,
    3.97999992e+01, 5.62000008e+01, 7.94000015e+01, 1.12000000e+02,
    1.58000000e+02, 2.24000000e+02, 3.16000000e+02, 4.47000000e+02,
    6.31000000e+02, 8.91000000e+02, 1.26000000e+03, 1.78000000e+03,
    2.51000000e+03, 3.55000000e+03, 5.01000000e+03, 7.08000000e+03,
Exemple #4
0
---------------

Loading and computation of neutral, solar-abundance cross-sections.
"""

import numpy
import scipy
from numpy import pi, arccos as acos, tan, round, exp, log, log10, sin, cos, logical_and, logical_or
import binning
import os

electmass = 511.  # electron rest mass in keV/c^2

xscatt = numpy.zeros(binning.nbins)

energy_lo, energy_hi = binning.bin2energy(numpy.arange(binning.nbins))
energy = (energy_hi + energy_lo) / 2.
deltae = energy_hi - energy_lo

xthom = 6.7e-4  # Thomson cross section
x = energy / electmass  # energy in units of electron rest mass

# compute scattering cross section
# Thomson regime
xscatt_thomson = xthom * (1. - (2. * x) + (26. * (x**2.) / 5.))
t1 = 1. + 2. * x
t2 = 1. + x
term1 = t2 / (x**3.)
term2 = (2. * x * t2) / t1
term3 = (1. / (2. * x)) * log(t1)
term4 = (1. + 3. * x) / (t1**2)
Exemple #5
0
def run(prefix,
        nphot,
        nmu,
        geometry,
        binmapfunction,
        plot_paths=False,
        plot_interactions=False,
        verbose=False):

    if plot_paths or plot_interactions:
        import matplotlib.pyplot as plt

    rdata_transmit = numpy.zeros((nbins, nbins, nmu))
    rdata_reflect = numpy.zeros((nbins, nbins, nmu))
    #rdata = [0] * nbins
    energy_lo, energy_hi = bin2energy(list(range(nbins)))
    energy = (energy_hi + energy_lo) / 2.
    deltae = energy_hi - energy_lo

    binrange = [list(range(nbins + 1)), list(range(nmu + 1))]
    for i in tqdm.trange(nbins - 1, -1, -1):
        photons = PhotonBunch(i=i,
                              nphot=nphot,
                              verbose=verbose,
                              geometry=geometry)
        remainder = [(photons.rad, photons.theta)]
        if plot_paths:
            plt.figure("paths", figsize=(4, 4))
        for n_interactions in range(1000):
            emission, more = photons.pump()
            if emission is None and not more:
                break
            if emission is None:
                continue
            if len(emission['energy']) == 0:
                if not more:
                    break
                continue
            if verbose:
                print(' received %d emitted photons (after %d interactions)' %
                      (len(emission['energy']), n_interactions))
            beta = emission['beta']
            alpha = emission['alpha']
            #beta = numpy.abs(beta)
            #beta[beta > pi] = pi - beta[beta > pi]
            #beta[beta > pi/2.] = pi/2. - beta[beta > pi/2.]
            assert (beta <= pi).all(), beta
            assert (beta >= 0).all(), beta
            #bins = energy2bin(energy)
            # vertical bin, i.e. which viewing angle can see this photon?
            mbin = numpy.asarray(binmapfunction(
                beta=beta, alpha=alpha)).astype(numpy.uint)
            # highest bin exceeded due to rounding
            mbin[mbin == nmu] = nmu - 1

            bins = emission['bin']
            # produce unique array bins, mbin which contains counts
            counts, xedges, yedges = numpy.histogram2d(bins,
                                                       mbin,
                                                       bins=binrange)
            # record into histogram if it landed within relevant range
            if n_interactions < 1:
                rdata_transmit[i] += counts
            else:
                rdata_reflect[i] += counts
            #if (emission['energy'] == 6.40).any():
            #	print ' %f: %d/%d are lines' % (energy[i], (emission['energy'] == 7.06).sum(), (emission['energy'] == 6.40).sum())
            #	linebin = set(bins[emission['energy'] == 6.40])
            #	print linebin, rdata[i][724,:], rdata[900][724,4] if i > 900 else ''

            # remove the emitted photons from the remainder
            if plot_paths:
                mask = emission['mask']
                path = [(prev_rad[mask], prev_theta[mask])
                        for prev_rad, prev_theta in remainder]

                remainder = [(prev_rad[~mask], prev_theta[~mask])
                             for prev_rad, prev_theta in remainder
                             ] + [(photons.rad, photons.theta)]

                rad_paths = numpy.transpose(
                    [path_rad for path_rad, path_theta in path] +
                    [2 * numpy.ones(mask.sum())])
                theta_paths = numpy.transpose(
                    [path_theta for path_rad, path_theta in path] + [beta])
                plt.figure("paths")
                plot_path(rad_paths[:100],
                          theta_paths[:100],
                          color=(['b', 'r', 'g', 'y', 'k', 'm', 'w'] *
                                 5)[n_interactions],
                          alpha=1 - 0.75 * numpy.exp(-n_interactions / 5.))

            if plot_interactions:
                print('plotting %d photons ...' % len(beta))
                plot_interaction(nphot=nphot,
                                 n_interactions=n_interactions,
                                 **emission)
                #plt.savefig(prefix + "rdata_%d_%d.pdf" % (i, n_interactions))
                plt.savefig(prefix + "rdata_%d_%d.png" % (i, n_interactions))
                plt.close()
                print('plotting ... done')
            if not more:
                break
        if plot_paths:
            plt.figure("paths")
            plt.xlim(-1, 1)
            plt.ylim(-1, 1)
            plt.title('Energy: %.2f, %d interactions' %
                      (energy[i], n_interactions))
            #plt.savefig(prefix + "paths_%d.pdf" % (i))
            plt.savefig(prefix + "paths_%d.png" % (i))
            plt.close()

    return (rdata_transmit, rdata_reflect), nphot
Exemple #6
0
def store(prefix, nphot, rdata, nmu, extra_fits_header={}, plot=False):

    energy_lo, energy_hi = bin2energy(list(range(nbins)))
    energy = (energy_hi + energy_lo) / 2.
    deltae = energy_hi - energy_lo
    import h5py
    try:
        print('Loading previous file "%s" if exists ...' %
              (prefix + "rdata.hdf5"))
        with h5py.File(prefix + "rdata.hdf5", 'r') as old_file:
            print('  reading values')
            rdata_old = old_file['rdata'][()]
            print('  reading header value')
            prev_nphot = old_file.attrs['NPHOT']
            print('Accumulating onto previous result ...')
            rdata = rdata + rdata_old
            del rdata_old
    except Exception as e:
        if "error message = 'no such file or directory'" not in str(e).lower():
            print('updating file failed; writing fresh. Error:', e)
        prev_nphot = 0
    nphot_total = nphot + prev_nphot
    print('  storing ...')
    import datetime, time
    now = datetime.datetime.fromtimestamp(time.time())
    nowstr = now.isoformat()
    nowstr = nowstr[:nowstr.rfind('.')]
    with h5py.File(prefix + "rdata.hdf5", 'w') as f:
        f.create_dataset('rdata', data=rdata, compression='gzip', shuffle=True)
        f.create_dataset('energy_lo',
                         data=energy_lo,
                         compression='gzip',
                         shuffle=True)
        f.create_dataset('energy_hi',
                         data=energy_hi,
                         compression='gzip',
                         shuffle=True)

        f.attrs[
            'CREATOR'] = """Johannes Buchner <*****@*****.**>"""
        f.attrs['DATE'] = nowstr
        f.attrs['METHOD'] = 'Monte-Carlo simulation code'
        f.attrs['NPHOT'] = nphot_total
        for k, v in extra_fits_header.items():
            f.attrs[k] = v

    print('  total of %d input / %d output photons across %d bins' %
          (nphot_total, rdata.sum(), nbins))

    if not plot:
        return nphot_total, rdata
    import matplotlib.pyplot as plt
    import sys
    PhoIndex = 2
    matrix = rdata
    total = nphot_total
    deltae0 = deltae[energy >= 1][0]
    NH = 1e24 / 1e22
    weights = (energy**-PhoIndex * deltae / deltae0).reshape(
        (-1, 1))  # * deltae.reshape((1, -1)) / deltae.reshape((-1, 1))
    yall = (weights * matrix.sum(axis=2)).sum(axis=0) / deltae * deltae0
    for mu in range(nmu):
        y = (weights * matrix[:, :, mu]).sum(axis=0) / deltae * deltae0
        sys.stdout.write('plotting %d/%d ...\r' % (mu + 1, nmu))
        sys.stdout.flush()

        plt.figure(figsize=(10, 10))
        plt.plot(energy,
                 exp(-xphot * NH) * energy**-PhoIndex,
                 '-',
                 color='red',
                 linewidth=1)
        plt.plot(energy,
                 exp(-xscatt * NH) * energy**-PhoIndex,
                 '-',
                 color='pink')
        plt.plot(energy,
                 exp(-xlines_cumulative[:, 0] * NH) * energy**-PhoIndex,
                 '-',
                 color='orange')
        plt.plot(energy, energy**-PhoIndex, '--', color='gray')
        plt.plot(energy, y / total * nmu, '-',
                 color='k')  #, drawstyle='steps')
        plt.plot(energy,
                 yall / total,
                 '-',
                 color='gray',
                 alpha=0.3,
                 linewidth=3)  #, drawstyle='steps')
        #plt.plot(energy, exp(-xboth) * energy**-PhoIndex, '-', color='yellow')
        plt.gca().set_xscale('log')
        plt.gca().set_yscale('log')
        #plt.xlim(0.1, 10 * (1 + 10))
        plt.xlim(1, 40)
        lo, hi = 1e-8, 1
        plt.vlines(6.40, lo, hi, linestyles=[':'], color='grey', alpha=0.5)
        plt.vlines(7.06, lo, hi, linestyles=[':'], color='grey', alpha=0.5)
        #plt.vlines(8.33, lo, hi, linestyles=[':'], color='grey', alpha=0.5)
        #plt.vlines(9.4, lo, hi, linestyles=[':'], color='grey', alpha=0.5)
        #plt.vlines(10.4, lo, hi, linestyles=[':'], color='grey', alpha=0.5)
        plt.ylim(lo, hi)
        #plt.ylim(1e-5, 1e-3)
        #plt.xlim(6, 15)
        #plt.show()
        #plt.savefig(prefix + "_%d.pdf" % mu)
        plt.savefig(prefix + "_%d.png" % mu)
        #numpy.savetxt(prefix + "_%d.txt" % mu, numpy.vstack([energy, y]).transpose())
        plt.close()
    print()
    return nphot_total, rdata