예제 #1
0
	def get_test_emission(self, frame):

		propagator = propagation.get_propagation_module('analytic')
		ice = medium.get_ice_model('ARAsim_southpole')

		# work up a simple example to test functionality
		ant = np.array([0,0,-100])
		vertex = np.array([-2543.18,2319.96,-1828.74])
		azi = 2.4658
		zen = 1.0863
		inelast = 0.55
		inttype = 'cc'
		flavor = 14
		energy = 9.20e+18
		n_index = ice.get_index_of_refraction(vertex)
		cherenkov_angle = np.arccos(1./n_index)
		shower_axis = -1 * hp.spherical_to_cartesian(zen, azi)

		r = propagator(vertex,
			ant,
			medium=ice,
			attenuation_model='SP1',
			n_frequencies_integration=25,
			n_reflections=0
			)
		r.find_solutions()
		num_solutions = r.get_number_of_solutions()
		viewing_angles = []
		distances = []
		launch_vectors = []
		receive_vectors = []
		# print('num solutions is {}'.format(num_solutions))
		for iS in range(num_solutions):
			launch_vectors.append(r.get_launch_vector(iS))
			receive_vectors.append(r.get_receive_vector(iS))
			# launch_vector = r.get_launch_vector(iS)
			viewing_angles.append(hp.get_angle(shower_axis, launch_vectors[iS]))
			distances.append(r.get_path_length(iS))
			# viewing_angle = hp.get_angle(shower_axis, launch_vector)

		#fem, fhad = helper._get_em_had_fraction(inelast, inttype, flavor)
		fem=0
		fhad=0.55

		signal = askaryan.get_time_trace(
			energy = energy * fhad,
			theta = viewing_angles[0],
			N = self._n_samples,
			dt = self._dt,
			shower_type='HAD',
			n_index = n_index,
			R=distances[0],
			model=self._askaryan_model,
			seed=self._seed
		)

		polarization_direction_onsky = util_geo.calculate_polarization_vector(launch_vectors[0], shower_axis)
		icetray.logging.log_debug("Polarization direction on sky {}".format(polarization_direction_onsky))

		this_eR, this_eTheta, this_ePhi = np.outer(polarization_direction_onsky, signal)

		# create traces for the eR, eTheta, and ePhi components inside
		eR = icetradio.I3Trace()
		eTheta = icetradio.I3Trace()
		ePhi = icetradio.I3Trace()

		eR.trace = this_eR
		eR.traceStartTime = 0
		eR.samplingRate = self._sampling_rate
		eTheta.trace = this_eTheta
		eTheta.traceStartTime = 0
		eTheta.samplingRate = self._sampling_rate
		ePhi.trace = this_ePhi
		ePhi.traceStartTime = 0
		eTheta.samplingRate = self._sampling_rate


		# put those traces inside an EField
		field = icetradio.I3EField()
		field.eR = eR
		field.eTheta = eTheta
		field.ePhi = ePhi

		frame.Put("DummyEField", field)
예제 #2
0
models = ['Alvarez2009', 'ARZ2020']
"""
The times are not returned by the signal generator module, so we have to construct
our own time array using the input time step. We have chosen the middle of the trace
to be at t = 0. When using the ARZ2019 or ARZ2020 modules, the t=0 in our times
array defined like this marks the moment when the signal from the vertex arrives
at the observer's location.
"""
times = np.arange(0, N * dt, dt)  # Array containing times
times = times + 0.5 * dt - times.mean()
"""
We are now ready to plot a trace from both models.
"""
for model in models:

    trace = get_time_trace(energy, theta, N, dt, shower_type, n_index, R,
                           model)
    plt.plot(times, trace / (units.microvolt / units.m), label=model)

plt.legend()
plt.xlim((-5, 5))
plt.xlabel('Time [ns]')
plt.ylabel(r'Electric field [$\mu$V/m]')
plt.show()
"""
One important thing to keep in mind is that the Alvarez2009 model varies the
length of the electromagnetic shower randomly, and also the ARZ models chooses
a random shower from the library to account for random fluctuations. This means
that each time we call the functions, the showers are different and so the
electric fields are also different. This is not practical when we want to
calculate the field from a fixed shower at different locations. In order to
do so, we can use the argument same_shower=True.
n_samples = 256
ff = np.fft.rfftfreq(n_samples, dt)
tt = np.arange(0, n_samples * dt, dt)
R = 1 * units.km

models = ['Alvarez2009', 'ARZ2019', 'Alvarez2000', 'ARZ2020']
shower_types = ['EM', 'HAD']

Es = 10**np.linspace(15, 19, 5) * units.eV
domegas = np.linspace(-5, 5, 10) * units.deg
thetas = np.arccos(1. / n_index) + domegas

output = []
for model in models:
    for E in Es:
        for shower_type in shower_types:
            for theta in thetas:
                trace = get_time_trace(E,
                                       theta,
                                       n_samples,
                                       dt,
                                       shower_type,
                                       n_index,
                                       R,
                                       model,
                                       seed=1234)
                output.append(trace)

with open("reference_v1.pkl", "wb") as fout:
    pickle.dump(output, fout, protocol=4)
예제 #4
0
def generate_signal(deposited_energy,
                    shower_axis,
                    em_or_had,
                    launch_vector,
                    distance,
                    arrival_time,
                    n_index,
                    attenuation_values,
                    dt,
                    n_samples,
                    model,
                    seed,
                    keep_unattenuated_fields=False):
    """
	A function to generate askaryan fields at the antennas

	Get the askaryan signals/fields at the antenna. This means that the fields
	returned by this function will already include the polarization factors,
	the 1/R, and the attenuation due to the ice.

	Parameters
	----------
	deposited_energy: double or float
		energy deposited in the shower in eV
	
	shower_axis: I3Position
		the shower axis
	
	launch_vector: I3Position
		the launch vector of the ray that makes the signal

	distance: float
		the path length traveled by the signal in m (including ray bending!)

	arrival_time: float
		the time the field arrives at the antenna, in seconds (including ray bending!)

	n_index: float
		the index of refraction at the vertex

	atttenuation_values: complex np array
		the complex frequency-dependent attenuation factors

	dt: float
		the time between samples for the askaryan emission, in seconds

	n_samples: int
		the number of samples to have in the Askaryan emission

	model: string
		what Askaryan model should be used to generate the emission
		options are described in NuRadioMC.SignalGen.askaryan
		https://github.com/nu-radio/NuRadioMC/blob/master/NuRadioMC/SignalGen/askaryan.py

	seed: int
		what random number seed should be used in generating the askaryan emission

	keep_unattenuated_fields: bool
		whether or not to keep a copy of the E-fields that does not have attenuation factors applied
		default is False, to reduce file output sizes

	Returns
	-------
	signal: I3RadioSignal
		the radio signal container for this event
	"""

    local_launch_vector = util_dataclasses.i3pos_to_np(launch_vector)
    local_shower_axis = util_dataclasses.i3pos_to_np(shower_axis)

    viewing_angle = hp.get_angle(local_shower_axis, local_launch_vector)

    signal = askaryan.get_time_trace(energy=deposited_energy,
                                     theta=viewing_angle,
                                     N=n_samples,
                                     dt=dt,
                                     shower_type=em_or_had,
                                     n_index=n_index,
                                     R=distance,
                                     model=model,
                                     seed=seed)

    signal_spectrum = fft.time2freq(signal, 1. / dt)
    attenuated_signal_spectrum = signal_spectrum * attenuation_values
    attenuated_signal = fft.freq2time(attenuated_signal_spectrum, 1. / dt)

    # calculate the polarization
    polarization_direction_onsky = util_geo.calculate_polarization_vector(
        local_launch_vector, local_shower_axis)
    icetray.logging.log_debug("Polarization direction on sky {}".format(
        polarization_direction_onsky))

    # create the e-fields at the antenna
    this_eR_attenuated, this_eTheta_attenuated, this_ePhi_attenuated = np.outer(
        polarization_direction_onsky, attenuated_signal)

    # store the eR, eTheta, ePhi components in trace for attenuated field
    sampling_rate = 1. / dt
    eR_attenuated = util_dataclasses.fill_I3Trace(this_eR_attenuated,
                                                  arrival_time, sampling_rate)
    eTheta_attenuated = util_dataclasses.fill_I3Trace(this_eTheta_attenuated,
                                                      arrival_time,
                                                      sampling_rate)
    ePhi_attenuated = util_dataclasses.fill_I3Trace(this_ePhi_attenuated,
                                                    arrival_time,
                                                    sampling_rate)

    # put those traces into fields
    field_watt = util_dataclasses.fill_I3EField(eR_attenuated,
                                                eTheta_attenuated,
                                                ePhi_attenuated)

    # and finally, create and return a signal object
    signal = icetradio.I3RadioSignal()
    signal.view_angle = viewing_angle * icetray.I3Units.rad
    signal.polarization_vector = util_dataclasses.np_to_i3pos(
        polarization_direction_onsky, 'sph')
    signal.field_watt = field_watt

    if keep_unattenuated_fields:
        # make a copy of the fields that doesn't include the attenuation factor
        # we can generally *not* save this information as a space saving measure
        this_eR, this_eTheta, this_ePhi = np.outer(
            polarization_direction_onsky, signal)
        eR = util_dataclasses.fill_I3Trace(this_eR, arrival_time,
                                           sampling_rate)
        eTheta = util_dataclasses.fill_I3Trace(this_eTheta, arrival_time,
                                               sampling_rate)
        ePhi = util_dataclasses.fill_I3Trace(this_ePhi, arrival_time,
                                             sampling_rate)
        field_noatt = util_dataclasses.fill_I3EField(eR, eTheta, ePhi)
        signal.field_noatt = field_noatt

    return signal
예제 #5
0
E = 1e20 * units.eV
n_index = 1.78
theta = np.arccos(1. / n_index)

dt = 0.01 * units.ns
n_samples = 2048
ff = np.fft.rfftfreq(n_samples, dt)
tt = np.arange(0, n_samples * dt, dt)
R = 1 * units.km

model = 'Alvarez2000'
shower_type = 'EM'

domega = 0.1 * units.deg
trace_1 = get_time_trace(E, theta + domega, n_samples, dt, shower_type,
                         n_index, R, model)
domega = 0.3 * units.deg
trace_2 = get_time_trace(E, theta + domega, n_samples, dt, shower_type,
                         n_index, R, model)
spectrum_1 = fft.time2freq(trace_1)
spectrum_2 = fft.time2freq(trace_2)
spectrum_1 *= 1. / units.V * units.MHz * dt
spectrum_2 *= 1. / units.V * units.MHz * dt
freqs = np.fft.rfftfreq(n_samples, dt)

fig = plt.figure(figsize=(10, 5))
ax1 = fig.add_subplot(121)
ax1.plot(tt,
         trace_1,
         color='black',
         label='$\\theta_C+0.1\degree$',
예제 #6
0
n_index = 1.78
theta_C = np.arccos(1. / n_index)
N = 512 * 2
dt = 0.1 * units.ns
R = 1 * units.km
tt = np.arange(0, dt * N, dt)

thetas = theta_C + np.array([0, 1, 2, 3, 4, 5]) * units.deg
fig, ax = plt.subplots(2, 3, sharex=True)
ax = ax.flatten()
for iTheta, theta in enumerate(thetas):
    trace = ask.get_time_trace(E,
                               theta,
                               N,
                               dt,
                               shower_type,
                               n_index,
                               R,
                               "ARZ2019",
                               interp_factor=interp_factor)
    ax[iTheta].plot(tt,
                    trace[1],
                    '-C0'.format(iTheta),
                    label="$\Delta \Theta$ = {:.1f}".format(
                        (theta - theta_C) / units.deg))
    trace = ask.get_time_trace(E, theta, N, dt, shower_type, n_index, R,
                               "Alvarez2000")
    trace = np.roll(trace, int(-1 * units.ns / dt))
    ax[iTheta].plot(tt,
                    trace,
                    '--C1'.format(iTheta),