From c04a09d7023faac2c5bb0daaf74d04371b187aa5 Mon Sep 17 00:00:00 2001 From: Brian Clark Date: Wed, 7 Jul 2021 08:17:41 -0500 Subject: [PATCH 001/418] Adjust initial conditions for cpp raysolver The ability of the root finder to locate a minimum when the source is very near (100-200m) seems to depend somewhat delicately on the initial conditions. This new set seems more robust. --- .../SignalProp/CPPAnalyticRayTracing/analytic_raytracing.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NuRadioMC/SignalProp/CPPAnalyticRayTracing/analytic_raytracing.cpp b/NuRadioMC/SignalProp/CPPAnalyticRayTracing/analytic_raytracing.cpp index 3de057b44..b4b638c8d 100644 --- a/NuRadioMC/SignalProp/CPPAnalyticRayTracing/analytic_raytracing.cpp +++ b/NuRadioMC/SignalProp/CPPAnalyticRayTracing/analytic_raytracing.cpp @@ -617,7 +617,7 @@ vector > find_solutions(double x1[2], double x2[2], double n_ic // revealed this case where only checking -1 didn't get us close enough // for the method (which is admittedly a *polishing* algorithm) to find the root. - for (double x_guess_start = -1; x_guess_start>-3; x_guess_start-=1){ + for (double x_guess_start = 0; x_guess_start>-3; x_guess_start-=0.5){ if(found_root_1) break; double x_guess = x_guess_start; sfdf = gsl_root_fdfsolver_alloc(Tfdf); From 3d1852d9f68e9e77d3c883897345c62a0406a505 Mon Sep 17 00:00:00 2001 From: Brian Clark Date: Mon, 12 Jul 2021 11:50:58 -0500 Subject: [PATCH 002/418] Adjust the initial condition of first root solver to make things more robust --- .../SignalProp/CPPAnalyticRayTracing/analytic_raytracing.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NuRadioMC/SignalProp/CPPAnalyticRayTracing/analytic_raytracing.cpp b/NuRadioMC/SignalProp/CPPAnalyticRayTracing/analytic_raytracing.cpp index b4b638c8d..8009b616c 100644 --- a/NuRadioMC/SignalProp/CPPAnalyticRayTracing/analytic_raytracing.cpp +++ b/NuRadioMC/SignalProp/CPPAnalyticRayTracing/analytic_raytracing.cpp @@ -617,7 +617,7 @@ vector > find_solutions(double x1[2], double x2[2], double n_ic // revealed this case where only checking -1 didn't get us close enough // for the method (which is admittedly a *polishing* algorithm) to find the root. - for (double x_guess_start = 0; x_guess_start>-3; x_guess_start-=0.5){ + for (double x_guess_start = 2; x_guess_start>-3; x_guess_start-=0.2){ if(found_root_1) break; double x_guess = x_guess_start; sfdf = gsl_root_fdfsolver_alloc(Tfdf); From af4125123e21a107e6a2c7d49d3761fa3e60b5bb Mon Sep 17 00:00:00 2001 From: Brian Clark Date: Fri, 6 Aug 2021 15:52:00 -0400 Subject: [PATCH 003/418] Try and make the first root solving more robust in the cpp ray tracer --- .../analytic_raytracing.cpp | 88 ++++++++++++------- 1 file changed, 58 insertions(+), 30 deletions(-) diff --git a/NuRadioMC/SignalProp/CPPAnalyticRayTracing/analytic_raytracing.cpp b/NuRadioMC/SignalProp/CPPAnalyticRayTracing/analytic_raytracing.cpp index 8009b616c..6f4863052 100644 --- a/NuRadioMC/SignalProp/CPPAnalyticRayTracing/analytic_raytracing.cpp +++ b/NuRadioMC/SignalProp/CPPAnalyticRayTracing/analytic_raytracing.cpp @@ -572,7 +572,7 @@ double obj_delta_y(double logC0, void *p){ vector > find_solutions(double x1[2], double x2[2], double n_ice, double delta_n, double z_0, int reflection=0, int reflection_case=1, double ice_reflection=0.){ //function finds all ray tracing solutions - //we assume that x2 is above and to the right of x2_mirrored + //we assume that x2 (stop) is above and to the right of x1 (start) //this is perfectly general, as a coordinate transform can put any system in this configuration // printf("finding solution from %f %f to %f %f with %f %f %f", x1[0], x1[1], x2[0], x2[1], n_ice, delta_n, z_0); @@ -612,40 +612,68 @@ vector > find_solutions(double x1[2], double x2[2], double n_ic // We have to guess at the location of the first root (if it it exists at all). // Because we might not guess correctly, or guess close enough, // it's in our favor (for numerical stability reasons) to try several times. - // So, we start at 0, and walk back wards. // This issue on GitHub (https://github.com/nu-radio/NuRadioMC/issues/286) // revealed this case where only checking -1 didn't get us close enough // for the method (which is admittedly a *polishing* algorithm) to find the root. + // It also turns out that the most difficult region of parameter space + // are (1) vertices that are mostly sideways from the receiver + // and (2) within ~100m of the receiver + + double x_guess_start_ic = 3; + double x_guess_stop_ic = -2; + double step_size = 1; + + double start_depth = x1[1]; + double horz_distance = abs(x2[0] - x1[0]); + double vert_dist = abs(x2[1] - x1[1]); + double total_dist = sqrt(pow(x1[0] - x2[0], 2.) + pow(x1[1] - x2[1], 2.) ); + + // first trouble region: vertices mostly horizontal from the receiver + if( abs(vert_dist) < abs(start_depth)/100. + && + abs(horz_distance) < abs(start_depth)/5 ) + { + x_guess_start_ic = 10.; + step_size = 0.25; + } + // second trouble region: vertices very close to the receiver + if( total_dist < 100){ + x_guess_start_ic = 10.; + step_size = 0.25; + } - for (double x_guess_start = 2; x_guess_start>-3; x_guess_start-=0.2){ - if(found_root_1) break; - double x_guess = x_guess_start; - sfdf = gsl_root_fdfsolver_alloc(Tfdf); - gsl_root_fdfsolver_set(sfdf,&FDF,x_guess); - do{ - iter++; - // cout<<"Got to iter "< x_guess_stop_ic; + x_guess_start-=step_size){ + + if(found_root_1) break; + double x_guess = x_guess_start; + sfdf = gsl_root_fdfsolver_alloc(Tfdf); + gsl_root_fdfsolver_set(sfdf,&FDF,x_guess); + do{ + iter++; + // cout<<"Got to iter "< Date: Tue, 2 Nov 2021 15:15:03 +0000 Subject: [PATCH 004/418] adjust test order --- NuRadioMC/test/SingleEvents/T04validate_allmost_equal.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/NuRadioMC/test/SingleEvents/T04validate_allmost_equal.py b/NuRadioMC/test/SingleEvents/T04validate_allmost_equal.py index 96dfc64c8..04bc46443 100755 --- a/NuRadioMC/test/SingleEvents/T04validate_allmost_equal.py +++ b/NuRadioMC/test/SingleEvents/T04validate_allmost_equal.py @@ -174,14 +174,14 @@ def test_almost_equal_keys(keys, fin1=fin1, fin2=fin2, error=error): error = test_almost_equal_keys(keys, fin1=fin1, fin2=fin2, error=error) keys = [ - u'max_amp_shower_and_ray', - u'polarization', u'ray_tracing_C0', + u'ray_tracing_C1', u'launch_vectors', u'receive_vectors', u'travel_times', u'travel_distances', - u'ray_tracing_C1', + u'polarization', + u'max_amp_shower_and_ray', ] error = test_almost_equal_station_keys(keys, fin1=fin1, fin2=fin2, error=error) From d091a1c6f737356c7c8d07eb61770be5df0552e5 Mon Sep 17 00:00:00 2001 From: Christoph Date: Wed, 3 Nov 2021 13:39:44 +0100 Subject: [PATCH 005/418] Prevent error when printing error message --- NuRadioMC/test/SingleEvents/T04validate_allmost_equal.py | 2 +- NuRadioMC/test/SingleEvents/validate_ARZ.sh | 4 ++-- NuRadioMC/test/SingleEvents/validate_MB.sh | 9 ++++----- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/NuRadioMC/test/SingleEvents/T04validate_allmost_equal.py b/NuRadioMC/test/SingleEvents/T04validate_allmost_equal.py index 04bc46443..4486c2c42 100755 --- a/NuRadioMC/test/SingleEvents/T04validate_allmost_equal.py +++ b/NuRadioMC/test/SingleEvents/T04validate_allmost_equal.py @@ -69,7 +69,7 @@ def test_almost_equal_attributes(keys, fin1=fin1, fin2=fin2, error=error): def test_almost_equal_station_keys(keys, fin1=fin1, fin2=fin2, error=error, accuracy=accuracy): - gids = np.array(fin1["station_101"]['event_group_ids']) + gids = np.array(fin1['event_group_ids']) for key in keys: arr1 = np.array(fin1['station_101'][key]) arr2 = np.array(fin2['station_101'][key]) diff --git a/NuRadioMC/test/SingleEvents/validate_ARZ.sh b/NuRadioMC/test/SingleEvents/validate_ARZ.sh index 81d84bc13..649550183 100755 --- a/NuRadioMC/test/SingleEvents/validate_ARZ.sh +++ b/NuRadioMC/test/SingleEvents/validate_ARZ.sh @@ -1,4 +1,4 @@ #!/bin/bash set -e -NuRadioMC/test/SingleEvents/T02RunSimulation.py NuRadioMC/test/SingleEvents/1e18_output_ARZ_reference.hdf5 NuRadioMC/test/SingleEvents/surface_station_1GHz.json NuRadioMC/test/SingleEvents/config_ARZ.yaml NuRadioMC/test/SingleEvents/1e18_output_ARZ.hdf5 -NuRadioMC/test/SingleEvents/T04validate_allmost_equal.py NuRadioMC/test/SingleEvents/1e18_output_ARZ.hdf5 NuRadioMC/test/SingleEvents/1e18_output_ARZ_reference.hdf5 \ No newline at end of file +python3 NuRadioMC/test/SingleEvents/T02RunSimulation.py NuRadioMC/test/SingleEvents/1e18_output_ARZ_reference.hdf5 NuRadioMC/test/SingleEvents/surface_station_1GHz.json NuRadioMC/test/SingleEvents/config_ARZ.yaml NuRadioMC/test/SingleEvents/1e18_output_ARZ.hdf5 +python3 NuRadioMC/test/SingleEvents/T04validate_allmost_equal.py NuRadioMC/test/SingleEvents/1e18_output_ARZ.hdf5 NuRadioMC/test/SingleEvents/1e18_output_ARZ_reference.hdf5 \ No newline at end of file diff --git a/NuRadioMC/test/SingleEvents/validate_MB.sh b/NuRadioMC/test/SingleEvents/validate_MB.sh index b5da1c0f1..3dc5f19af 100755 --- a/NuRadioMC/test/SingleEvents/validate_MB.sh +++ b/NuRadioMC/test/SingleEvents/validate_MB.sh @@ -1,6 +1,5 @@ -#!/bin/bash -set -e +# #!/bin/bash +# set -e -NuRadioMC/test/SingleEvents/T02RunSimulation.py NuRadioMC/test/SingleEvents/MB_1e18_reference.hdf5 NuRadioMC/test/SingleEvents/surface_station_1GHz.json NuRadioMC/test/SingleEvents/config_MB.yaml NuRadioMC/test/SingleEvents/MB_1e18_output.hdf5 - -NuRadioMC/test/SingleEvents/T04validate_allmost_equal.py NuRadioMC/test/SingleEvents/MB_1e18_output.hdf5 NuRadioMC/test/SingleEvents/MB_1e18_reference.hdf5 \ No newline at end of file +python3 NuRadioMC/test/SingleEvents/T02RunSimulation.py NuRadioMC/test/SingleEvents/MB_1e18_reference.hdf5 NuRadioMC/test/SingleEvents/surface_station_1GHz.json NuRadioMC/test/SingleEvents/config_MB.yaml NuRadioMC/test/SingleEvents/MB_1e18_output.hdf5 +python3 NuRadioMC/test/SingleEvents/T04validate_allmost_equal.py NuRadioMC/test/SingleEvents/MB_1e18_output.hdf5 NuRadioMC/test/SingleEvents/MB_1e18_reference.hdf5 \ No newline at end of file From c5fb755b976fbbf74558ae09f9f44230edc59b92 Mon Sep 17 00:00:00 2001 From: Ilse Plaisier Date: Tue, 9 Nov 2021 13:18:43 +0100 Subject: [PATCH 006/418] add option to correct for cable delays in channelAddCableDelay --- NuRadioReco/modules/channelAddCableDelay.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/NuRadioReco/modules/channelAddCableDelay.py b/NuRadioReco/modules/channelAddCableDelay.py index c036c258e..7ffa236f9 100644 --- a/NuRadioReco/modules/channelAddCableDelay.py +++ b/NuRadioReco/modules/channelAddCableDelay.py @@ -12,11 +12,14 @@ def __init__(self): self.logger = logging.getLogger("NuRadioReco.channelApplyCableDelay") @register_run() - def run(self, evt, station, det): + def run(self, evt, station, det, mode = 'add'): """ Adds cable delays to channels + mode: str + options: 'add' or 'subtract'. """ for channel in station.iter_channels(): cable_delay = det.get_cable_delay(station.get_id(), channel.get_id()) self.logger.debug("cable delay of channel {} is {}ns".format(channel.get_id(), cable_delay / units.ns)) - channel.add_trace_start_time(cable_delay) + if mode == 'add': channel.add_trace_start_time(cable_delay) + if mode == 'subtract': channel.add_trace_start_time(-1*cable_delay) From ecd37b72b1a65edd8704d6dbd421e76d3fab3198 Mon Sep 17 00:00:00 2001 From: Ilse Plaisier Date: Tue, 9 Nov 2021 13:19:55 +0100 Subject: [PATCH 007/418] add relative_position option for devices --- NuRadioReco/detector/detector.py | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/NuRadioReco/detector/detector.py b/NuRadioReco/detector/detector.py index 28bc57c9c..40389c04f 100644 --- a/NuRadioReco/detector/detector.py +++ b/NuRadioReco/detector/detector.py @@ -522,7 +522,7 @@ def get_absolute_position_site(self, site): altitude = res['pos_altitude'] * units.m return np.array([easting, northing, altitude]) - def get_relative_position(self, station_id, channel_id): + def get_relative_position(self, station_id, channel_id, mode = 'channel'): """ get the relative position of a specific channels/antennas with respect to the station center @@ -532,12 +532,18 @@ def get_relative_position(self, station_id, channel_id): the station id channel_id: int the channel id + mode_id: str + specify if relative position of a channel or a device is asked for Returns --------------- 3-dim array of relative station position """ - res = self.__get_channel(station_id, channel_id) + if mode == 'channel': res = self.__get_channel(station_id, channel_id) + elif mode == 'device': res = self.__get_device(station_id, channel_id) + else: + logger.error("Mode {} does not exist. Use 'channel' or 'device'".format(mode)) + raise NameError return np.array([res['ant_position_x'], res['ant_position_y'], res['ant_position_z']]) def get_site(self, station_id): @@ -690,7 +696,13 @@ def get_cable_delay(self, station_id, channel_id): Returns float (delay time) """ res = self.__get_channel(station_id, channel_id) - return res['cab_time_delay'] + if 'cab_time_delay' not in res.keys(): + logger.warning( + 'Cable delay not set for channel {} in station {}, assuming cable delay is zero'.format( + channel_id, station_id)) + return 0 + else: + return res['cab_time_delay'] def get_cable_type_and_length(self, station_id, channel_id): """ From b7d765457de3dc6036435729809792e2ddf9a7fd Mon Sep 17 00:00:00 2001 From: Ilse Plaisier Date: Tue, 9 Nov 2021 13:22:02 +0100 Subject: [PATCH 008/418] get relative position for devices --- NuRadioReco/detector/detector.py | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/NuRadioReco/detector/detector.py b/NuRadioReco/detector/detector.py index 28bc57c9c..40389c04f 100644 --- a/NuRadioReco/detector/detector.py +++ b/NuRadioReco/detector/detector.py @@ -522,7 +522,7 @@ def get_absolute_position_site(self, site): altitude = res['pos_altitude'] * units.m return np.array([easting, northing, altitude]) - def get_relative_position(self, station_id, channel_id): + def get_relative_position(self, station_id, channel_id, mode = 'channel'): """ get the relative position of a specific channels/antennas with respect to the station center @@ -532,12 +532,18 @@ def get_relative_position(self, station_id, channel_id): the station id channel_id: int the channel id + mode_id: str + specify if relative position of a channel or a device is asked for Returns --------------- 3-dim array of relative station position """ - res = self.__get_channel(station_id, channel_id) + if mode == 'channel': res = self.__get_channel(station_id, channel_id) + elif mode == 'device': res = self.__get_device(station_id, channel_id) + else: + logger.error("Mode {} does not exist. Use 'channel' or 'device'".format(mode)) + raise NameError return np.array([res['ant_position_x'], res['ant_position_y'], res['ant_position_z']]) def get_site(self, station_id): @@ -690,7 +696,13 @@ def get_cable_delay(self, station_id, channel_id): Returns float (delay time) """ res = self.__get_channel(station_id, channel_id) - return res['cab_time_delay'] + if 'cab_time_delay' not in res.keys(): + logger.warning( + 'Cable delay not set for channel {} in station {}, assuming cable delay is zero'.format( + channel_id, station_id)) + return 0 + else: + return res['cab_time_delay'] def get_cable_type_and_length(self, station_id, channel_id): """ From a4922d512324bf1ecfb179c4297b65d1b708d4d3 Mon Sep 17 00:00:00 2001 From: Ilse Plaisier Date: Wed, 10 Nov 2021 13:21:40 +0100 Subject: [PATCH 009/418] add sphericalwavefitter for pulser position --- NuRadioReco/modules/sphericalWaveFitter.py | 173 +++++++++++++++++++++ 1 file changed, 173 insertions(+) create mode 100644 NuRadioReco/modules/sphericalWaveFitter.py diff --git a/NuRadioReco/modules/sphericalWaveFitter.py b/NuRadioReco/modules/sphericalWaveFitter.py new file mode 100644 index 000000000..751070164 --- /dev/null +++ b/NuRadioReco/modules/sphericalWaveFitter.py @@ -0,0 +1,173 @@ +from NuRadioReco.utilities import geometryUtilities as geo_utl +import scipy.optimize as opt +import numpy as np +from radiotools import helper as hp +from NuRadioReco.framework.parameters import stationParameters as stnp +from NuRadioReco.framework.parameters import showerParameters as shp +import matplotlib.pyplot as plt +from NuRadioReco.utilities import units +import scipy.signal +from scipy import constants +from mpl_toolkits.axes_grid1 import make_axes_locatable + + +class sphericalWaveFitter: + " Fits position x,y, z of a source using spherical fit to channels " + + def __init__(self): + pass + + + def begin(self, channel_ids = [0, 3, 9, 10]): + self.__channel_ids = channel_ids + pass + + + def run(self, evt, station, det, start_pulser_position, n_index = None, debug = True): + + print("channels used for this reconstruction:", self.__channel_ids) + + + def get_distance(x, y): + return np.sqrt((x[0] - y[0])**2+ (x[1] - y[1])**2 + (x[2] - y[2])**2) + + + def get_time_delay_spherical_wave(position, ch_pair, n=n_index): + T0 = get_distance(position, det.get_relative_position(station_id, ch_pair[0]))/(constants.c/n_index)*units.s + T1 = get_distance(position , det.get_relative_position(station_id, ch_pair[1]))/(constants.c/n_index)*units.s + return T1 - T0 + + + self.__channel_pairs = [] + self.__relative_positions = [] + station_id = station.get_id() + for i in range(len(self.__channel_ids) - 1): + for j in range(i + 1, len(self.__channel_ids)): + relative_positions = det.get_relative_position(station_id, self.__channel_ids[i]) - det.get_relative_position(station_id, self.__channel_ids[j]) + self.__relative_positions.append(relative_positions) + + self.__channel_pairs.append([self.__channel_ids[i], self.__channel_ids[j]]) + + + self.__sampling_rate = station.get_channel(0).get_sampling_rate() + if debug: + fig, ax = plt.subplots( len(self.__channel_pairs), 2) + + + def likelihood(pulser_position, x = None, y = None, debug_corr = False): + if len(pulser_position) == 1: + pulser_position = [x, y, pulser_position[0]] + corr = 0 + if debug_corr: + fig = plt.figure(figsize= (5, 1*len(self.__channel_pairs))) + for ich, ch_pair in enumerate(self.__channel_pairs): + positions = self.__relative_positions[ich] + times = [] + tmp = -1*get_time_delay_spherical_wave(pulser_position, ch_pair, n=n_index) + n_samples = -1*tmp * self.__sampling_rate + pos = int(len(self.__correlation[ich]) / 2 - n_samples) + corr += self.__correlation[ich, pos] + if debug_corr: + ax = fig.add_subplot(len(self.__channel_pairs), 1, ich+1) + ax.plot(self.__correlation[ich]) + ax.set_ylim((0, max(self.__correlation[ich]))) + ax.axvline(pos, label = 'reconstruction', lw = 1, color = 'orange') + ax.axvline(self._pos_starting[ich], label = 'starting pos', lw = 1, color = 'green') + ax.set_title("channel pair {}".format( ch_pair), fontsize = 5) + ax.legend(fontsize = 5) + + if debug_corr: + fig.tight_layout() + fig.savefig("debug.pdf") + + return -1*corr + + + + trace = np.copy(station.get_channel(self.__channel_pairs[0][0]).get_trace()) + self.__correlation = np.zeros((len(self.__channel_pairs), len(np.abs(scipy.signal.correlate(trace, trace))) )) + + for ich, ch_pair in enumerate(self.__channel_pairs): + trace1 = np.copy(station.get_channel(self.__channel_pairs[ich][0]).get_trace()) + trace2 =np.copy(station.get_channel(self.__channel_pairs[ich][1]).get_trace()) + + t_max1 = station.get_channel(self.__channel_pairs[ich][0]).get_times()[np.argmax(np.abs(trace1))] + t_max2 = station.get_channel(self.__channel_pairs[ich][1]).get_times()[np.argmax(np.abs(trace2))] + corr_range = 50 * units.ns + snr1 = np.max(np.abs(station.get_channel(self.__channel_pairs[ich][0]).get_trace())) + snr2 = np.max(np.abs(station.get_channel(self.__channel_pairs[ich][1]).get_trace())) + if snr1 > snr2: + trace1[np.abs(station.get_channel(self.__channel_pairs[ich][0]).get_times() - t_max1) > corr_range] = 0 + else: + trace2[np.abs(station.get_channel(self.__channel_pairs[ich][1]).get_times() - t_max2) > corr_range] = 0 + self.__correlation[ich] = np.abs(scipy.signal.correlate(trace1, trace2)) + + + + #### set positions for starting position #### + self._pos_starting = np.zeros(len(self.__channel_pairs)) + for ich, ch_pair in enumerate(self.__channel_pairs): + positions = self.__relative_positions[ich] + times = [] + + tmp = get_time_delay_spherical_wave(start_pulser_position, ch_pair, n=n_index) + n_samples = tmp * self.__sampling_rate + self._pos_starting[ich] = int(len(self.__correlation[ich]) / 2 - n_samples) + + + method = 'Nelder-Mead' + x_start, y_start, z_start = start_pulser_position + dx, dy, dz = [.1, .1, .1] + #ll = opt.minimize(likelihood, x0 = (start_pulser_position[0]-10, start_pulser_position[1], start_pulser_position[2]),method = method)# + ll = opt.brute(likelihood, ranges=(slice(x_start - 2, x_start + 2, dx), slice(y_start - 2, y_start + 2, dy), slice(z_start - 2, z_start + 2,dz)), finish = opt.fmin) + print("start position: {}".format(start_pulser_position)) + print("reconstructed position: {}".format([ll[0], ll[1], ll[2]])) + + if debug: + + method = 'Nelder-Mead' + x = np.arange(x_start -4, x_start +1, dx) + y = np.arange(y_start - 2, y_start +4, dy) + z = np.arange(z_start - 2, z_start + 2, dz) + xx, yy = np.meshgrid(x, y) + zz = np.zeros((len(x), len(y))) + zz_values = np.zeros((len(x), len(y))) + for ix, x_i in enumerate(x): + for iy, y_i in enumerate(y): + c = opt.minimize(likelihood, x0 = (start_pulser_position[2]), args = (x_i, y_i, False), method = method) + zz[ix, iy] = c.fun + zz_values[ix, iy] = c.x[0] + + fig = plt.figure(figsize = (10, 5)) + ax1 = fig.add_subplot(121) + pax1 = ax1.pcolor(xx, yy, zz.T) + ymin = np.matrix(zz).argmin() + z_min = opt.minimize(likelihood, x0 = (start_pulser_position[2]), args = (xx.T[np.unravel_index(ymin, (len(x), len(y)))], yy.T[np.unravel_index(ymin, (len(x), len(y)))], False), method = method) + likelihood([xx.T[np.unravel_index(ymin, (len(x), len(y)))], yy.T[np.unravel_index(ymin, (len(x), len(y)))], z_min.x[0]], debug_corr = True)# debug plot + print("z position for minimum grid: {}".format(z_min.x[0])) + ax1.axhline(start_pulser_position[1], color = 'orange', label = 'starting position') + ax1.axvline(start_pulser_position[0], color = 'orange') + ax1.axhline(yy.T[np.unravel_index(ymin, (len(x), len(y)))], color = 'grey', label = 'minimum grid') + ax1.axvline(xx.T[np.unravel_index(ymin, (len(x), len(y)))], color = 'grey') + ax1.set_title("z starting position {}, z at minimum: {}".format(start_pulser_position[2], np.round(z_min.x[0],2))) + ax1.set_xlabel("x position [m]") + ax1.set_ylabel("y position [m]") + ax1.legend() + ax2 = fig.add_subplot(122) + ax2.set_xlabel("x position [m]") + pax2 = ax2.pcolor(xx, yy, zz_values.T) + divider = make_axes_locatable(ax1) + cax = divider.append_axes("right", size="5%", pad=0.05) + cbar = plt.colorbar(pax1, cax=cax) + cbar.set_label("minimization value", rotation=270, labelpad = 15) + divider = make_axes_locatable(ax2) + cax = divider.append_axes("right", size="5%", pad=0.05) + cbar = plt.colorbar(pax2, cax = cax) + cbar.set_label("best fitting depth [m]", rotation = 270, labelpad = 15) + fig.tight_layout() + fig.savefig("minimization_map.pdf") + + + def end(self): + pass + From 3a769fc6cbb443f11b3fb1cccd9a02cf9a9ef0ec Mon Sep 17 00:00:00 2001 From: Ilse Plaisier Date: Wed, 10 Nov 2021 13:27:39 +0100 Subject: [PATCH 010/418] add steering file for rnog reconstruction and corresponding data --- .../examples/RNO_data/pulser_data_21.root | Bin 0 -> 258567 bytes .../examples/RNO_data/run_reconstruction.py | 71 ++++++++++++++++++ 2 files changed, 71 insertions(+) create mode 100644 NuRadioReco/examples/RNO_data/pulser_data_21.root create mode 100644 NuRadioReco/examples/RNO_data/run_reconstruction.py diff --git a/NuRadioReco/examples/RNO_data/pulser_data_21.root b/NuRadioReco/examples/RNO_data/pulser_data_21.root new file mode 100644 index 0000000000000000000000000000000000000000..8771f4285425c9b43a89442481f055252e693eb1 GIT binary patch literal 258567 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 z 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 (F&2~7vIwgYn}OwHHoLqTd+`&*0x6w~dN=~I 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�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 literal 0 HcmV?d00001 diff --git a/NuRadioReco/examples/RNO_data/run_reconstruction.py b/NuRadioReco/examples/RNO_data/run_reconstruction.py new file mode 100644 index 000000000..9dde74415 --- /dev/null +++ b/NuRadioReco/examples/RNO_data/run_reconstruction.py @@ -0,0 +1,71 @@ +import NuRadioReco +import matplotlib.pyplot as plt +from NuRadioReco.modules.io.rno_g.readRNOGData import readRNOGData +import pandas as pd +import numpy as np +from NuRadioReco.utilities import units +from NuRadioReco.modules import channelBandPassFilter +from NuRadioReco.detector import detector +import datetime +from NuRadioReco.modules import sphericalWaveFitter +from NuRadioReco.modules import channelAddCableDelay + +""" An example to show how to read RNO-G data and how to perform simple reconstructions. The data used is pulser data and a simple (brute force, not optimized) spherical wave reconstruction is performed to obtain the pulser position """"" + +""" Initiazize modules needed""" + +channelBandPassFilter = NuRadioReco.modules.channelBandPassFilter.channelBandPassFilter() +sphericalWaveFitter = NuRadioReco.modules.sphericalWaveFitter.sphericalWaveFitter() +channelAddCableDelay = NuRadioReco.modules.channelAddCableDelay.channelAddCableDelay() + + +use_channels = [10, 0, 23] +sphericalWaveFitter.begin(channel_ids = use_channels) + +""" Specify the detector. """ + +det = detector.Detector(json_filename = "detector_description.json") +det.update(datetime.datetime(2022, 10, 1)) + +""" Get positions for the pulsers from the detector file as starting positions for the fit """ + +station_id = 21 +pulser_id = 3 #Helper string C +pulser_position = det.get_relative_position(station_id, pulser_id, mode = 'device') +rel_pulser_position = [pulser_position[0], pulser_position[1], pulser_position[2]] + + +plots = True +""" read in data """ +list_of_root_files = ['pulser_data_21.root'] + + +readRNOGData = NuRadioReco.modules.io.rno_g.readRNOGData.readRNOGData() +readRNOGData.begin(list_of_root_files) + +for i_event, event in enumerate(readRNOGData.run()): + print("reconstruction for event", i_event) + station_id = event.get_station_ids()[0] + station = event.get_station(station_id) + channelAddCableDelay.run(event, station, det, mode = 'subtract') + channelBandPassFilter.run(event, station, det, passband = [5*units.MHz, 450*units.MHz]) + sphericalWaveFitter.run(event, station, det, start_pulser_position = rel_pulser_position, n_index = 1.78, debug =True) + + if plots: + fig = plt.figure() + i = 1 + for channel in station.iter_channels(): + if channel.get_id() in use_channels: + ax = fig.add_subplot(3, 2, i) + ax.plot(channel.get_trace()) + ax.title.set_text("channel id {}".format(channel.get_id())) + ax.grid() + i+= 1 + + fig.tight_layout() + fig.savefig("trace_{}.pdf".format(i_event)) + + + + + From 9698f87e2bfc6db2d741c3687f98b17f29fc261c Mon Sep 17 00:00:00 2001 From: Ilse Plaisier Date: Wed, 10 Nov 2021 13:39:12 +0100 Subject: [PATCH 011/418] add rnog example --- .../coax_delays/plots_coax_delays.py | 94 ++ .../fiber_delays/plots_fiber_delays.py | 107 ++ .../gps_positions/gps_positions.py | 29 + .../RNO_data/detector_description.json | 1449 +++++++++++++++++ .../read_data_example/pulser_data_21.root | Bin 0 -> 258567 bytes .../read_data_example/run_reconstruction.py | 71 + 6 files changed, 1750 insertions(+) create mode 100644 NuRadioReco/examples/RNO_data/calculate_cable_delays/coax_delays/plots_coax_delays.py create mode 100644 NuRadioReco/examples/RNO_data/calculate_cable_delays/fiber_delays/plots_fiber_delays.py create mode 100644 NuRadioReco/examples/RNO_data/calculate_cable_delays/gps_positions/gps_positions.py create mode 100644 NuRadioReco/examples/RNO_data/detector_description.json create mode 100644 NuRadioReco/examples/RNO_data/read_data_example/pulser_data_21.root create mode 100644 NuRadioReco/examples/RNO_data/read_data_example/run_reconstruction.py diff --git a/NuRadioReco/examples/RNO_data/calculate_cable_delays/coax_delays/plots_coax_delays.py b/NuRadioReco/examples/RNO_data/calculate_cable_delays/coax_delays/plots_coax_delays.py new file mode 100644 index 000000000..f7673c4ad --- /dev/null +++ b/NuRadioReco/examples/RNO_data/calculate_cable_delays/coax_delays/plots_coax_delays.py @@ -0,0 +1,94 @@ +import numpy as np +import matplotlib.pyplot as plt +from NuRadioReco.utilities import units +import argparse +import os + + + +parser = argparse.ArgumentParser() +parser.add_argument('--hardware_number', type=int, default = 7)# default is for station 21 +args = parser.parse_args() +hardware_number = args.hardware_number + + +coax_names = [] +# station 21: hardware number 7, station 22: hardware number 6, station 11: hardware number 5 +# if you need the surface s21 data, ask Dan or Zack. +for file in os.listdir("data/station_{}".format(hardware_number)): + if file.endswith("LOG.csv"): + file = file.replace("S21_SRX{}_".format(hardware_number), '') + coax_names.append(file.replace("_LOG.csv", '')) + + +## dict ({hardwarenumber: {cable number: number of jumper cables}}) with number of jumper cables (taken from: https://radio.uchicago.edu/wiki/index.php/File:ChannelMapping_v1.xlsx) + +jumper_cables = {'5': {'1':0,'2': 0, '3': 0 , '4': 0 , '5': 0 , '6': 0 , '7': 0 , '8': 0 , '9':0 }, +'6': {'1': 1, '2': 0, '3':2 , '4': 2 , '5': 0 , '6':2 , '7': 1 , '8': 0 , '9': 1 }, +'7': {'1': 1, '2': 0, '3': 1 , '4':1 , '5':0 , '6':1 , '7':1 , '8':0 , '9':1 } +} + +jumper_cable_delay = 3.97*0.89 #3.97 ns/m #cables of 35 inch/0.89 m, https://www.timesmicrowave.com/DataSheets/CableProducts/LMR-240.pdf + +fig1 = plt.figure(figsize=(9, 30)) +fig2 = plt.figure(figsize=(9, 30)) +for i_coax, coax_name in enumerate(coax_names): + log_mag_data = np.genfromtxt( + 'data/station_{}/S21_SRX{}_{}_LOG.csv'.format(hardware_number, hardware_number, coax_name), + delimiter=',', + skip_header=17, + skip_footer=1 + ) + mag_freqs = log_mag_data[:, 0] * units.Hz + log_magnitude = log_mag_data[:, 1] + ax1_1 = fig1.add_subplot(len(coax_names), 1, i_coax + 1) + ax1_1.grid() + ax1_1.plot( + mag_freqs / units.MHz, + np.power(10., -log_magnitude) + ) + phase_data = np.genfromtxt( + 'data/station_{}/S21_SRX{}_{}_PHASE.csv'.format(hardware_number, hardware_number, coax_name), + delimiter=',', + skip_header=17, + skip_footer=1 + ) + phase_freqs = phase_data[:, 0] * units.Hz + phase = np.unwrap(phase_data[:, 1] * units.deg) + group_delay = -.5 * np.diff(phase) / np.diff(phase_freqs) / np.pi + # phase = (phase_data[:, 1] * units.deg) + freq_mask = phase_freqs > 25 * units.MHz + ax2_1 = fig2.add_subplot(len(coax_names), 2, 2 * i_coax + 1) + ax2_1.grid() + ax2_1.plot( + phase_freqs[freq_mask] / units.MHz, + phase[freq_mask] + ) + line_fit = np.polyfit( + phase_freqs[freq_mask] * 2. * np.pi, + - phase[freq_mask], + 1 + ) + ax2_1.set_xlabel('f [MHz]') + ax2_1.set_ylabel('phase [rad]') + ax2_2 = fig2.add_subplot(len(coax_names), 2, 2 * i_coax + 2) + ax2_2.grid() + ax2_2.plot( + phase_freqs[freq_mask][:-1] / units.MHz, + group_delay[freq_mask[:-1]] / units.ns + ) + ax2_2.set_title(coax_name) + print('Coax {}: {:.2f}ns + {} * {} = {}'.format(coax_name, line_fit[0], jumper_cables[str(hardware_number)][str(coax_name)], jumper_cable_delay, line_fit[0] + jumper_cables[str(hardware_number)][str(coax_name)]*jumper_cable_delay)) + ax2_2.axhline( + line_fit[0], + color='r', + linestyle=':' + ) + ax2_2.set_xlabel('f [MHz]') + ax2_2.set_ylabel(r'$\Delta t$ [ns]') + +fig1.tight_layout() +fig1.savefig('coax_magnitudes.png') + +fig2.tight_layout() +fig2.savefig('coax_phases.png') diff --git a/NuRadioReco/examples/RNO_data/calculate_cable_delays/fiber_delays/plots_fiber_delays.py b/NuRadioReco/examples/RNO_data/calculate_cable_delays/fiber_delays/plots_fiber_delays.py new file mode 100644 index 000000000..00815f486 --- /dev/null +++ b/NuRadioReco/examples/RNO_data/calculate_cable_delays/fiber_delays/plots_fiber_delays.py @@ -0,0 +1,107 @@ +import numpy as np +import matplotlib.pyplot as plt +from NuRadioReco.utilities import units +import argparse +import os + + + +parser = argparse.ArgumentParser() +parser.add_argument('--hardware_number', type=int, default = 7)# default is for station 21 +args = parser.parse_args() +hardware_number = args.hardware_number + +fiber_names = [] +# if you want the data, ask Dan or Zack! +# station 21: hardware number 7, station 22: hardware number 6, station 11: hardware number 5 +for file in os.listdir("data"): + if file.startswith("{}".format(hardware_number)) and file.endswith("FULL_LM.csv"): + fiber_names.append(file.replace("_FULL_LM.csv", '')) + + + +#fiber_names = [ +# '7A1', +# '7A2', +# '7A3', +# '7A4', +# '7A5', +# '7A6', +# '7ABLUE', +# '7ABROWN', +# '7AGREEN', +# '7AORANGE', +# '7B1', +# '7B2', +# '7B3', +# '7B4', +# '7C1', +# '7C2', +# '7C3', +# '7C4' +#] + + + +fig1 = plt.figure(figsize=(8, 30)) +fig2 = plt.figure(figsize=(8, 30)) +for i_fiber, fiber_name in enumerate(fiber_names): + log_mag_data = np.genfromtxt( + 'data/{}_FULL_LM.csv'.format(fiber_name), ## data can be downloaded from https://drive.google.com/drive/folders/1mASLMMJhxWzbNFcEOQBc8KWy2cAb99GB + delimiter=',', + skip_header=17, + skip_footer=1 + ) + mag_freqs = log_mag_data[:, 0] * units.Hz + log_magnitude = log_mag_data[:, 1] + ax1_1 = fig1.add_subplot(len(fiber_names), 1, i_fiber + 1) + ax1_1.grid() + ax1_1.plot( + mag_freqs / units.MHz, + np.power(10., -log_magnitude) + ) + phase_data = np.genfromtxt( + 'data/{}_FULL_P.csv'.format(fiber_name), + delimiter=',', + skip_header=17, + skip_footer=1 + ) + phase_freqs = phase_data[:, 0] * units.Hz + phase = np.unwrap(phase_data[:, 1] * units.deg) + group_delay = -.5 * np.diff(phase) / np.diff(phase_freqs) / np.pi + # phase = (phase_data[:, 1] * units.deg) + freq_mask = phase_freqs > 25 * units.MHz + ax2_1 = fig2.add_subplot(len(fiber_names), 2, 2 * i_fiber + 1) + ax2_1.grid() + ax2_1.plot( + phase_freqs[freq_mask] / units.MHz, + phase[freq_mask] + ) + line_fit = np.polyfit( + phase_freqs[freq_mask] * 2. * np.pi, + - phase[freq_mask], + 1 + ) + ax2_1.set_xlabel('f [MHz]') + ax2_1.set_ylabel('phase [rad]') + ax2_2 = fig2.add_subplot(len(fiber_names), 2, 2 * i_fiber + 2) + ax2_2.grid() + ax2_2.plot( + phase_freqs[freq_mask][:-1] / units.MHz, + group_delay[freq_mask[:-1]] / units.ns + ) + ax2_2.set_title(fiber_name) + print('Fiber {}: {:.2f}ns'.format(fiber_name, line_fit[0])) + ax2_2.axhline( + line_fit[0], + color='r', + linestyle=':' + ) + ax2_2.set_xlabel('f [MHz]') + ax2_2.set_ylabel(r'$\Delta t$ [ns]') + +fig1.tight_layout() +fig1.savefig('fiber_magnitudes.png') + +fig2.tight_layout() +fig2.savefig('fiber_phases.png') diff --git a/NuRadioReco/examples/RNO_data/calculate_cable_delays/gps_positions/gps_positions.py b/NuRadioReco/examples/RNO_data/calculate_cable_delays/gps_positions/gps_positions.py new file mode 100644 index 000000000..4aa0d7efc --- /dev/null +++ b/NuRadioReco/examples/RNO_data/calculate_cable_delays/gps_positions/gps_positions.py @@ -0,0 +1,29 @@ +import numpy as np + +site = 2 +## site 1: station 21, site 2: station 11, site 3: station 22 +## csv file with data can be found here: https://radio.uchicago.edu/wiki/index.php/Deployment +## Station positions are with respect the GPS base station on the MSF roof +data = np.genfromtxt( + 'data/survey_results.csv', + delimiter=',', + skip_header=5, + dtype=("|S20", float, float, float, float, float, "|S10") + ) + +data_site = [] +for i_row, row in enumerate(data): + if 'site {} power'.format(site) in row[0].decode('UTF-8'): + power_easting = row[1] + power_northing = row[2] + print("Determine relative positions for strings and surface antennas for site {}:".format(site)) + print("position of power string easting: {}, northing: {}".format(power_easting, power_northing)) + print("altitude of power string:", row[3]) + print("_______________________________________________________") +for i_row, row in enumerate(data): + if 'site {}'.format(site) in row[0].decode('UTF-8'): + easting = row[1] + northing = row[2] + print("{}| \n rel position easting: {}, rel position northing: {} \n distance to power string: {}".format(row[0].decode('UTF-8'), easting - power_easting, northing - power_northing, np.sqrt((easting - power_easting)**2 + (northing - power_northing)**2))) + + diff --git a/NuRadioReco/examples/RNO_data/detector_description.json b/NuRadioReco/examples/RNO_data/detector_description.json new file mode 100644 index 000000000..7381a9159 --- /dev/null +++ b/NuRadioReco/examples/RNO_data/detector_description.json @@ -0,0 +1,1449 @@ +{ + "_default": {}, + "channels": { + "0": { + "amp_type": "iglu", + "ant_comment": "Phased Array Vpol", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -80.975, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_type": "RNOG_vpol_4inch_center_1.73", + "cab_time_delay": 714.49, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "channel_id": 0, + "station_id": 11 + }, + + + + "1": { + "amp_type": "iglu", + "ant_comment": "Phased Array Vpol", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -79.93, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_type": "RNOG_vpol_4inch_center_1.73", + "cab_time_delay": 709.99, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "channel_id": 1, + "station_id": 11 + }, + + "2": { + "amp_type": "iglu", + "ant_comment": "Phased Array Vpol", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -78.68, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_type": "RNOG_vpol_4inch_center_1.73", + "cab_time_delay": 704.73, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "channel_id": 2, + "station_id": 11 + + }, + + "3": { + "amp_type": "iglu", + "ant_comment": "Phased Array Vpol", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -77.89, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_type": "RNOG_vpol_4inch_center_1.73", + "cab_time_delay": 700.43, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "channel_id": 3, + "station_id": 11 + }, + + + "4": { + "amp_type": "iglu", + "ant_comment": "Power String Hpol", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -76.9, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_type": "RNOG_quadslot_v3_air_rescaled_to_n1.74", + "cab_time_delay": 695.01, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "channel_id": 8, + "station_id": 11 + }, + + "5": { + "amp_type": "iglu", + "ant_comment": "Power String Hpol", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -75.97, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_type": "RNOG_quadslot_v3_air_rescaled_to_n1.74", + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "cab_time_delay": 690.62, + "channel_id": 4, + "station_id": 11 + }, + + "6": { + "amp_type": "iglu", + "ant_comment": "Power String Vpol", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -63.88, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_type": "RNOG_vpol_4inch_center_1.73", + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "cab_time_delay": 583.35, + "channel_id": 5, + "station_id": 22 + }, + + "7": { + "amp_type": "iglu", + "ant_comment": "Power String Vpol", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -63.88, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_type": "RNOG_vpol_4inch_center_1.73", + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "cab_time_delay": 484.26, + "channel_id": 6, + "station_id": 22 + }, + + + "8": { + "amp_type": "iglu", + "ant_comment": "Power String Vpol", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -63.88, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_type": "RNOG_vpol_4inch_center_1.73", + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "cab_time_delay": 387.12, + "channel_id": 7, + "station_id": 22 + }, + + + + "9": { + "amp_type": "iglu", + "ant_comment": "Helper String B Vpol", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 17.65, + "ant_position_y": -26.72, + "ant_position_z": -87.57, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_type": "RNOG_vpol_4inch_center_1.73", + "cab_time_delay": 704.73, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "channel_id": 9, + "station_id": 11 + }, + + "10": { + "amp_type": "iglu", + "ant_comment": "Helper String B Vpol", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 17.65, + "ant_position_y": -26.72, + "ant_position_z": -86, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_type": "RNOG_vpol_4inch_center_1.73", + "cab_time_delay": 700.31, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "channel_id": 10, + "station_id": 11 + }, + + + + "11": { + "amp_type": "iglu", + "ant_comment": "Helper String B Hpol", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 17.65, + "ant_position_y": -26.72, + "ant_position_z": -84.72, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_type": "RNOG_quadslot_v3_air_rescaled_to_n1.74", + "cab_time_delay": 695.13, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "channel_id": 11, + "station_id": 11 + }, + "12": { + "amp_type": "rno_surface", + "ant_comment": "rno_surface, Helper C", + "ant_orientation_phi": 300.0, + "ant_orientation_theta": 120.0, + "ant_position_x": 25.41, + "ant_position_y": -9.14, + "ant_position_z": -1.5, + "ant_rotation_phi": 30.0, + "ant_rotation_theta": 90.0, + "ant_type": "createLPDA_100MHz_InfFirn_n1.4", + "cab_time_delay": 45.95, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "channel_id": 12, + "station_id": 11 + }, + "13": { + "amp_type": "rno_surface", + "ant_comment": "rno_surface, Helper C", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 24.36, + "ant_position_y": -6.74, + "ant_position_z": -1.5, + "ant_rotation_phi": 30.0, + "ant_rotation_theta": 90.0, + "ant_type": "createLPDA_100MHz_InfFirn_n1.4", + "cab_time_delay": 45.88, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "channel_id": 13, + "station_id": 11 + }, + "14": { + "amp_type": "rno_surface", + "ant_comment": "rno_surface, Helper C", + "ant_orientation_phi": 120.0, + "ant_orientation_theta": 120.0, + "ant_position_x": 22.99, + "ant_position_y": -4.18, + "ant_position_z": -1.5, + "ant_rotation_phi": 30.0, + "ant_rotation_theta": 90.0, + "ant_type": "createLPDA_100MHz_InfFirn_n1.4", + "cab_time_delay": 45.6, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "channel_id": 14, + "station_id": 11 + }, + "15": { + "amp_type": "rno_surface", + "ant_comment": "rno_surface, Power String", + "ant_orientation_phi": 60.0, + "ant_orientation_theta": 120.0, + "ant_position_x": 13.09, + "ant_position_y": -1.349, + "ant_position_z": -1.5, + "ant_rotation_phi": 150.0, + "ant_rotation_theta": 90.0, + "ant_type": "createLPDA_100MHz_InfFirn_n1.4", + "cab_time_delay": 45.38, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "channel_id": 15, + "station_id": 11 + }, + "16": { + "amp_type": "rno_surface", + "ant_comment": "rno_surface, Power String", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 11.93, + "ant_position_y": -3.68, + "ant_position_z": -1.5, + "ant_rotation_phi": 150.0, + "ant_rotation_theta": 90.0, + "ant_type": "createLPDA_100MHz_InfFirn_n1.4", + "cab_time_delay": 45.4, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "channel_id": 16, + "station_id": 11 + }, + "17": { + "amp_type": "rno_surface", + "ant_comment": "rno_surface, Power String", + "ant_orientation_phi": 240.0, + "ant_orientation_theta": 120.0, + "ant_position_x": 11.294, + "ant_position_y": -8.875, + "ant_position_z": -1.5, + "ant_rotation_phi": 150.0, + "ant_rotation_theta": 90.0, + "ant_type": "createLPDA_100MHz_InfFirn_n1.4", + "cab_time_delay": 45.31, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "channel_id": 17, + "station_id": 11 + }, + "18": { + "amp_type": "rno_surface", + "ant_comment": "rno_surface, Helper B", + "ant_orientation_phi": 180.0, + "ant_orientation_theta": 120.0, + "ant_position_x": 15.66, + "ant_position_y": -17.09, + "ant_position_z": -1.5, + "ant_rotation_phi": 270.0, + "ant_rotation_theta": 90.0, + "ant_type": "createLPDA_100MHz_InfFirn_n1.4", + "cab_time_delay": 45.31, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "channel_id": 18, + "station_id": 11 + }, + "19": { + "amp_type": "rno_surface", + "ant_comment": "rno_surface, Helper B", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 18.37, + "ant_position_y": -16.26, + "ant_position_z": -1.5, + "ant_rotation_phi": 270.0, + "ant_rotation_theta": 90.0, + "ant_type": "createLPDA_100MHz_InfFirn_n1.4", + "cab_time_delay": 45.43, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "channel_id": 19, + "station_id": 11 + + + }, + "20": { + "amp_type": "rno_surface", + "ant_comment": "rno_surface, Helper B", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 120.0, + "ant_position_x": 21.33, + "ant_position_y": -17.22, + "ant_position_z": -1.5, + "ant_rotation_phi": 270.0, + "ant_rotation_theta": 90.0, + "ant_type": "createLPDA_100MHz_InfFirn_n1.4", + "cab_time_delay": 45.73, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "channel_id": 20, + "station_id": 11 + }, + "21": { + "amp_type": "iglu", + "ant_comment": "Helper String C Vpol", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 34.17, + "ant_position_y": 3.18, + "ant_position_z": -96.67, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_type": "RNOG_vpol_4inch_center_1.73", + "cab_time_delay": 704.73, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "channel_id": 21, + "station_id": 11 + }, + "21": { + "amp_type": "iglu", + "ant_comment": "Helper String C Vpol", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 34.17, + "ant_position_y": 3.18, + "ant_position_z": -95.66, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_type": "RNOG_vpol_4inch_center_1.73", + "cab_time_delay": 700.47, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "channel_id": 22, + "station_id": 11 + }, + "22": { + "amp_type": "iglu", + "ant_comment": "Helper String C Hpol", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 34.17, + "ant_position_y": 3.18, + "ant_position_z": -94.66, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_type": "RNOG_quadslot_v3_air_rescaled_to_n1.74", + "cab_time_delay": 695.03, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "channel_id": 23, + "station_id": 11 + }, + "23": { + "amp_type": "iglu", + "ant_comment": "Phased Array Vpol", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -95.37, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_type": "RNOG_vpol_4inch_center_1.73", + "cab_time_delay": 714.47, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "channel_id": 0, + "station_id": 21 + }, + "24": { + "amp_type": "iglu", + "ant_comment": "Phased Array Vpol", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -94.37, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_type": "RNOG_vpol_4inch_center_1.73", + "cab_time_delay": 709.91, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "channel_id": 1, + "station_id": 21 + }, + "25": { + "amp_type": "iglu", + "ant_comment": "Phased Array Vpol", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -93.36, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_type": "RNOG_vpol_4inch_center_1.73", + "cab_time_delay": 704.54, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "channel_id": 2, + "station_id": 21 + }, + "26": { + "amp_type": "iglu", + "ant_comment": "Phased Array Vpol", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -92.36, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_type": "RNOG_vpol_4inch_center_1.73", + "cab_time_delay": 700.35, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "channel_id": 3, + "station_id": 21 + }, + "27": { + "amp_type": "iglu", + "ant_comment": "Power String Hpol", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -91.37, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_type": "RNOG_quadslot_v3_air_rescaled_to_n1.74", + "cab_time_delay": 695.03, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "channel_id": 8, + "station_id": 21 + }, + "28": { + "amp_type": "iglu", + "ant_comment": "Power String Hpol", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -90.39, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_type": "RNOG_quadslot_v3_air_rescaled_to_n1.74", + "cab_time_delay": 689.92, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "channel_id": 4, + "station_id": 21 + }, + + "29": { + "amp_type": "iglu", + "ant_comment": "Power String Vpol", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -78.42, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_type": "RNOG_vpol_4inch_center_1.73", + "cab_time_delay": 583.87, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "channel_id": 5, + "station_id": 21 + }, + "30": { + "amp_type": "iglu", + "ant_comment": "Power String Vpol", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -57.98, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_type": "RNOG_vpol_4inch_center_1.73", + "cab_time_delay": 484.74, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "channel_id": 6, + "station_id": 21 + }, + "31": { + "amp_type": "iglu", + "ant_comment": "Power String Vpol", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -38.33, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_type": "RNOG_vpol_4inch_center_1.73", + "cab_time_delay": 387.61, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "channel_id": 7, + "station_id": 21 + }, + "32": { + "amp_type": "iglu", + "ant_comment": "Helper String B Vpol", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": -17.2, + "ant_position_y": 29.097, + "ant_position_z": -94.7, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_type": "RNOG_vpol_4inch_center_1.73", + "cab_time_delay": 706.05, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "channel_id": 9, + "station_id": 21 + }, + "33": { + "amp_type": "iglu", + "ant_comment": "Helper String B Vpol", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": -17.2, + "ant_position_y": 29.097, + "ant_position_z": -93.71, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_type": "RNOG_vpol_4inch_center_1.73", + "cab_time_delay": 701.72, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "channel_id": 10, + "station_id": 21 + }, + "34": { + "amp_type": "iglu", + "ant_comment": "Helper String B Hpol", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": -17.2, + "ant_position_y": 29.097, + "ant_position_z": -92.7, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_type": "RNOG_quadslot_v3_air_rescaled_to_n1.74", + "cab_time_delay": 696.54, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "channel_id": 11, + "station_id": 21 + }, + "35": { + "amp_type": "rno_surface", + "ant_comment": "rno_surface, Helper C", + "ant_orientation_phi": 300.0, + "ant_orientation_theta": 120.0, + "ant_position_x": -22.46, + "ant_position_y": 3.208, + "ant_position_z": -1.5, + "ant_rotation_phi": 210, + "ant_rotation_theta": 90.0, + "ant_type": "createLPDA_100MHz_InfFirn_n1.4", + "cab_time_delay": 49.30, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "channel_id": 12, + "station_id": 21 + }, + "36": { + "amp_type": "rno_surface", + "ant_comment": "rno_surface, Helper C", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": -23.817, + "ant_position_y": 5.259, + "ant_position_z": -1.5, + "ant_rotation_phi": 210, + "ant_rotation_theta": 90.0, + "ant_type": "createLPDA_100MHz_InfFirn_n1.4", + "cab_time_delay": 45.43, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "channel_id": 13, + "station_id": 21 + }, + "37": { + "amp_type": "rno_surface", + "ant_comment": "rno_surface, Helper C", + "ant_orientation_phi": 120.0, + "ant_orientation_theta": 120.0, + "ant_position_x": -25.07, + "ant_position_y": 7.49, + "ant_position_z": -1.5, + "ant_rotation_phi": 210, + "ant_rotation_theta": 90.0, + "ant_type": "createLPDA_100MHz_InfFirn_n1.4", + "cab_time_delay": 49.36, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "channel_id": 14, + "station_id": 21 + }, + "38": { + "amp_type": "rno_surface", + "ant_comment": "rno_surface, Helper B", + "ant_orientation_phi": 180.0, + "ant_orientation_theta": 120.0, + "ant_position_x": -20.61, + "ant_position_y": 16.93, + "ant_position_z": -1.5, + "ant_rotation_phi": 90, + "ant_rotation_theta": 90.0, + "ant_type": "createLPDA_100MHz_InfFirn_n1.4", + "cab_time_delay": 49.19, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "channel_id": 15, + "station_id": 21 + }, + + "39": { + "amp_type": "rno_surface", + "ant_comment": "rno_surface, Helper B", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": -18.2, + "ant_position_y": 17.16, + "ant_position_z": -1.5, + "ant_rotation_phi": 90, + "ant_rotation_theta": 90.0, + "ant_type": "createLPDA_100MHz_InfFirn_n1.4", + "cab_time_delay": 45.82, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "channel_id": 16, + "station_id": 21 + }, + "40": { + "amp_type": "rno_surface", + "ant_comment": "rno_surface, Helper B", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 120.0, + "ant_position_x": -15.62, + "ant_position_y": 17.54, + "ant_position_z": -1.5, + "ant_rotation_phi": 90, + "ant_rotation_theta": 90.0, + "ant_type": "createLPDA_100MHz_InfFirn_n1.4", + "cab_time_delay": 48.89, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "channel_id": 17, + "station_id": 21 + }, + "41": { + "amp_type": "rno_surface", + "ant_comment": "rno_surface, Power String", + "ant_orientation_phi": 60.0, + "ant_orientation_theta": 120.0, + "ant_position_x": -8.52, + "ant_position_y": 8.05, + "ant_position_z": -1.5, + "ant_rotation_phi": 330, + "ant_rotation_theta": 90.0, + "ant_type": "createLPDA_100MHz_InfFirn_n1.4", + "cab_time_delay": 49.42, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "channel_id": 18, + "station_id": 21 + }, + "42": { + "amp_type": "rno_surface", + "ant_comment": "rno_surface, Power String", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": -9.89, + "ant_position_y": 5.59, + "ant_position_z": -1.5, + "ant_rotation_phi": 330, + "ant_rotation_theta": 90.0, + "ant_type": "createLPDA_100MHz_InfFirn_n1.4", + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "cab_time_delay": 45.75, + "channel_id": 19, + "station_id": 21 + }, + "43": { + "amp_type": "rno_surface", + "ant_comment": "rno_surface, Power String", + "ant_orientation_phi": 240.0, + "ant_orientation_theta": 120.0, + "ant_position_x": -11.29, + "ant_position_y": 3.22, + "ant_position_z": -1.5, + "ant_rotation_phi": 330.0, + "ant_rotation_theta": 90.0, + "ant_type": "createLPDA_100MHz_InfFirn_n1.4", + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "cab_time_delay": 48.93, + "channel_id": 20, + "station_id": 21 + }, + "44": { + "amp_type": "iglu", + "ant_comment": "Helper String C Vpol", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": -33.64, + "ant_position_y": -0.8, + "ant_position_z": -95.37, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_type": "RNOG_vpol_4inch_center_1.73", + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "cab_time_delay": 705.24, + "channel_id": 21, + "station_id": 21 + }, + "45": { + "amp_type": "iglu", + "ant_comment": "Helper String C Vpol", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": -33.64, + "ant_position_y": -0.8, + "ant_position_z": -94.34, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_type": "RNOG_vpol_4inch_center_1.73", + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "cab_time_delay": 701.09, + "channel_id": 22, + "station_id": 21 + }, + "46": { + "amp_type": "iglu", + "ant_comment": "Helper String C Hpol", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": -33.64, + "ant_position_y": -0.8, + "ant_position_z": -93.37, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_type": "RNOG_quadslot_v3_air_rescaled_to_n1.74", + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "cab_time_delay": 695.83, + "channel_id": 23, + "station_id": 21 + }, + "47": { + "amp_type": "iglu", + "ant_comment": "Phased Array Vpol", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -95.67, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_type": "RNOG_vpol_4inch_center_1.73", + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "cab_time_delay": 714.76, + "channel_id": 0, + "station_id": 22 + }, + "48": { + "amp_type": "iglu", + "ant_comment": "Phased Array Vpol", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -94.66, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_type": "RNOG_vpol_4inch_center_1.73", + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "cab_time_delay": 710.17, + "channel_id": 1, + "station_id": 22 + }, + "49": { + "amp_type": "iglu", + "ant_comment": "Phased Array Vpol", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -93.66, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_type": "RNOG_vpol_4inch_center_1.73", + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "cab_time_delay": 704.9, + "channel_id": 2, + "station_id": 22 + }, + "50": { + "amp_type": "iglu", + "ant_comment": "Phased Array Vpol", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -92.66, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_type": "RNOG_vpol_4inch_center_1.73", + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "cab_time_delay": 700.45, + "channel_id": 3, + "station_id": 22 + }, + "51": { + "amp_type": "iglu", + "ant_comment": "Power String Hpol", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -91.67, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_type": "RNOG_quadslot_v3_air_rescaled_to_n1.74", + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "cab_time_delay": 695.16, + "channel_id": 8, + "station_id": 22 + }, + "52": { + "amp_type": "iglu", + "ant_comment": "Power String Hpol", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -90.72, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_type": "RNOG_quadslot_v3_air_rescaled_to_n1.74", + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "cab_time_delay": 690.6, + "channel_id": 4, + "station_id": 22 + }, + "53": { + "amp_type": "iglu", + "ant_comment": "Power String Vpol", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -78.7, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_type": "RNOG_vpol_4inch_center_1.73", + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "cab_time_delay": 583.41, + "channel_id": 5, + "station_id": 22 + }, + "54": { + "amp_type": "iglu", + "ant_comment": "Power String Vpol", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -58.62, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_type": "RNOG_vpol_4inch_center_1.73", + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "cab_time_delay": 484.86, + "channel_id": 6, + "station_id": 22 + }, + + "55": { + "amp_type": "iglu", + "ant_comment": "Power String Vpol", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -38.53, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_type": "RNOG_vpol_4inch_center_1.73", + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "cab_time_delay": 387.55, + "channel_id": 7, + "station_id": 22 + }, + "56": { + "amp_type": "iglu", + "ant_comment": "Helper String B Vpol", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": -17.51, + "ant_position_y": 33.13, + "ant_position_z": -96.8, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_type": "RNOG_vpol_4inch_center_1.73", + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "cab_time_delay": 704.91, + "channel_id": 9, + "station_id": 22 + }, + "57": { + "amp_type": "iglu", + "ant_comment": "Helper String B Vpol", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": -17.51, + "ant_position_y": 33.13, + "ant_position_z": -95.8, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_type": "RNOG_vpol_4inch_center_1.73", + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "cab_time_delay": 700.52, + "channel_id": 10, + "station_id": 22 + }, + "58": { + "amp_type": "iglu", + "ant_comment": "Helper String B Hpol", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": -17.51, + "ant_position_y": 33.13, + "ant_position_z": -94.8, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_type": "RNOG_quadslot_v3_air_rescaled_to_n1.74", + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "cab_time_delay": 695.17, + "channel_id": 11, + "station_id": 22 + }, + + "59": { + "amp_type": "rno_surface", + "ant_comment": "rno_surface, Helper C, pointing side-downwards", + "ant_orientation_phi": 300.0, + "ant_orientation_theta": 120.0, + "ant_position_x": 9.12, + "ant_position_y": 17.6, + "ant_position_z": -1.5, + "ant_rotation_phi": 30.0, + "ant_rotation_theta": 90.0, + "ant_type": "createLPDA_100MHz_InfFirn_n1.4", + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "cab_time_delay": 49.01, + "channel_id": 12, + "station_id": 22 + }, + "60": { + "amp_type": "rno_surface", + "ant_comment": "rno_surface, Helper C, pointing upwards", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 7.1, + "ant_position_y": 23.12, + "ant_position_z": -1.5, + "ant_rotation_phi": 30.0, + "ant_rotation_theta": 90.0, + "ant_type": "createLPDA_100MHz_InfFirn_n1.4", + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "cab_time_delay": 45.99, + "channel_id": 13, + "station_id": 22 + }, + "61": { + "amp_type": "rno_surface", + "ant_comment": "rno_surface, Helper C, pointing side-downwards", + "ant_orientation_phi": 120.0, + "ant_orientation_theta": 120.0, + "ant_position_x": 5.36, + "ant_position_y": 25.5, + "ant_position_z": -1.5, + "ant_rotation_phi": 30.0, + "ant_rotation_theta": 90.0, + "ant_type": "createLPDA_100MHz_InfFirn_n1.4", + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "cab_time_delay": 45.46, + "channel_id": 14, + "station_id": 22 + }, + "62": { + "amp_type": "rno_surface", + "ant_comment": "rno_surface, Helper B, pointing side-downwards", + "ant_orientation_phi": 60.0, + "ant_orientation_theta": 120.0, + "ant_position_x": -6.48, + "ant_position_y": 25.95, + "ant_position_z": -1.5, + "ant_rotation_phi": 150.0, + "ant_rotation_theta": 90.0, + "ant_type": "createLPDA_100MHz_InfFirn_n1.4", + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "cab_time_delay": 52.85, + "channel_id": 15, + "station_id": 22 + }, + "63": { + "amp_type": "rno_surface", + "ant_comment": "rno_surface, Helper B, pointing upwards", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": -7.49, + "ant_position_y": 23.84, + "ant_position_z": -1.5, + "ant_rotation_phi": 150.0, + "ant_rotation_theta": 90.0, + "ant_type": "createLPDA_100MHz_InfFirn_n1.4", + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "cab_time_delay": 45.60, + "channel_id": 16, + "station_id": 22 + }, + "64": { + "amp_type": "rno_surface", + "ant_comment": "rno_surface, Helper B, pointing side-downwards", + "ant_orientation_phi": 240.0, + "ant_orientation_theta": 120.0, + "ant_position_x": -8.6, + "ant_position_y": 21.44, + "ant_position_z": -1.5, + "ant_rotation_phi": 150.0, + "ant_rotation_theta": 90.0, + "ant_type": "createLPDA_100MHz_InfFirn_n1.4", + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "cab_time_delay": 52.58, + "channel_id": 17, + "station_id": 22 + }, + "65": { + "amp_type": "rno_surface", + "ant_comment": "rno_surface, Power String, pointing side-downwards", + "ant_orientation_phi": 180.0, + "ant_orientation_theta": 120.0, + "ant_position_x": -2.5, + "ant_position_y": 11.19, + "ant_position_z": -1.5, + "ant_rotation_phi": 270.0, + "ant_rotation_theta": 90.0, + "ant_type": "createLPDA_100MHz_InfFirn_n1.4", + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "cab_time_delay": 52.82, + "channel_id": 18, + "station_id": 22 + }, + "66": { + "amp_type": "rno_surface", + "ant_comment": "rno_surface, Power String, pointing upwards", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": -0.22, + "ant_position_y": 11.48, + "ant_position_z": -1.5, + "ant_rotation_phi": 270.0, + "ant_rotation_theta": 90.0, + "ant_type": "createLPDA_100MHz_InfFirn_n1.4", + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "cab_time_delay": 45.78, + "channel_id": 19, + "station_id": 22 + }, + "67": { + "amp_type": "rno_surface", + "ant_comment": "rno_surface, Power String, pointing side-downwards", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 120.0, + "ant_position_x": 2.45, + "ant_position_y": 11.07, + "ant_position_z": -1.5, + "ant_rotation_phi": 270.0, + "ant_rotation_theta": 90.0, + "ant_type": "createLPDA_100MHz_InfFirn_n1.4", + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "cab_time_delay": 49.44, + "channel_id": 20, + "station_id": 22 + }, + "68": { + "amp_type": "iglu", + "ant_comment": "Helper String C Vpol", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 17.29, + "ant_position_y": 26.16, + "ant_position_z": -96.62, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_type": "RNOG_vpol_4inch_center_1.73", + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "cab_time_delay": 704.79, + "channel_id": 21, + "station_id": 22 + }, + + "69": { + "amp_type": "iglu", + "ant_comment": "Helper String C Vpol", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 17.29, + "ant_position_y": 26.16, + "ant_position_z": -95.61, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_type": "RNOG_vpol_4inch_center_1.73", + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "cab_time_delay": 700.51, + "channel_id": 22, + "station_id": 22 + }, + "70": { + "amp_type": "iglu", + "ant_comment": "Helper String C Hpol", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 17.29, + "ant_position_y": 26.16, + "ant_position_z": -94.61, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_type": "RNOG_quadslot_v3_air_rescaled_to_n1.74", + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "cab_time_delay": 695.09, + "channel_id": 23, + "station_id": 22 + } + + + }, + + "devices":{ + + "1": { + "amp_type": "iglu", + "ant_comment": "Helper String B CAL Vpol", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 17.65, + "ant_position_y": -26.72, + "ant_position_z": -86.54, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "device_id": 0, + "station_id": 11 + }, + + + "2": { + "amp_type": "iglu", + "ant_comment": "Helper String C CAL Vpol", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 34.17, + "ant_position_y": 3.18, + "ant_position_z": -95.69, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "device_id": 1, + "station_id": 11 + }, + + + + "3": { + "amp_type": "iglu", + "ant_comment": "Helper String B CAL Vpol", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": -17.2, + "ant_position_y": 29.097, + "ant_position_z": -93.72, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "device_id": 2, + "station_id": 21 + }, + + "4": { + "amp_type": "iglu", + "ant_comment": "Helper String C CAL Vpol", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": -33.64, + "ant_position_y": -0.8, + "ant_position_z": -94.37, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "device_id": 3, + "station_id": 21 + }, + + + + "5": { + "amp_type": "iglu", + "ant_comment": "Helper String B CAL Hpol", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": -17.51, + "ant_position_y": 33.13, + "ant_position_z": -93.8, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "device_id": 4, + "station_id": 22 + }, + + + "6": { + "amp_type": "iglu", + "ant_comment": "Helper String C CAL Vpol", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 17.29, + "ant_position_y": 26.16, + "ant_position_z": -94.62, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "device_id": 5, + "station_id": 22 + + }, + + "7": { + "amp_type": "iglu", + "ant_comment": "Surface CAL VPOL", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 18.52, + "ant_position_y": -1.01, + "ant_position_z": -1.5, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "device_id": 6, + "station_id": 11 + }, + + "8": { + "amp_type": "iglu", + "ant_comment": "Surface CAL Vpol", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": -51.46, + "ant_position_y": -29.4, + "ant_position_z": -5.6, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "device_id": 7, + "station_id": 21 + }, + + "9": { + "amp_type": "iglu", + "ant_comment": "Surface CAL Vpol", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": -0.16, + "ant_position_y": -33.23, + "ant_position_z": -0.5, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "device_id": 8, + "station_id": 22 + } + + + + + }, + "positions": {}, + "stations": { + "01": { + "pos_altitude": 3247.834, + "pos_easting": -1669.182, + "pos_northing": 1196.214, + "pos_site": "summit", + "station_id": 11, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "station_type": "Nanoq" + }, + "02": { + "pos_altitude": 3249.67, + "pos_easting": -405.361, + "pos_northing": 962.845, + "pos_site": "summit", + "station_id": 21, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "station_type": "Amaroq" + }, + "03": { + "pos_altitude": 3250.055, + "pos_easting": -235.135, + "pos_northing": 2174.534, + "pos_site": "summit", + "station_id": 22, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "station_type": "Avinngaq" + } + } +} diff --git a/NuRadioReco/examples/RNO_data/read_data_example/pulser_data_21.root b/NuRadioReco/examples/RNO_data/read_data_example/pulser_data_21.root new file mode 100644 index 0000000000000000000000000000000000000000..8771f4285425c9b43a89442481f055252e693eb1 GIT binary patch literal 258567 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 z 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 (F&2~7vIwgYn}OwHHoLqTd+`&*0x6w~dN=~I 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�=hv4K36L;x$o?5YDnTodbFzAs32}xKy_*G-qyT95-RvU8jYkqzdSU< z8>+hC*-yuR=OcZt_Nm>?dwv_+gvT&-)+ri9SuzvW^35GDd8(A!tiCu#=D^PQYm@8cd%d0Y415x z1%h;5J-jEPfGo!L_g=cx=UYcL5of%c$h7v?28t^mZp3{>$aIHD|dG_Zq~wTnOv#bN)@25)UxlK;rpBpO78GP&4QJoIrkGT zi6>@c&$7oC-qF2K@Xi;+Y~*BGK6ZBolcmsLwDKWINY9G(yT)1|+|Sd}IjCW68GFla z%1YTu$S=2#s^0l_c@k}rG^=L2uEz(5|IL7aRL{sag`#Sf$(* zHr#_`wX8QQLZr+Ij^ZFSz*dmeM_B6;pIBKH%g;K*=+=J!jyRStM<2AJlAZlkbp#8e zpZw{GrmW95GPVE@Sq6R{<&)vLAa}L$iCr1C& zZx8LaqeYDDoO7}PgF*!2qdj+fGpy@7yQOwXi`Yhlf>-8h;}0>DSr#dyS2kI0a6Rs7 zIAkHCck&@5(R(79S+5vM)-Q@Y^TQouQ`CxfH-+sdiE`D!} z@kG{B+#wSXLhbL$yNvwS7_2X>cA+~(X(}YtD9BB+GiPyheQd-)I$TAkp$Xo4=Zg(t zf8 zTU#UhMyITlKy9eiA~fGzL=AnmI_3%pOT?yE-pI*!YEf9KjZvOi6xe*2k&V4c6wJx@ z`dm!8`BhmrQo0#r`CbTL?VAWj)If(wtLO>VTpigRReWyJJR_wc_l&Oqntn8mobMpL*ciU_n`LkvA)b8)sNM=|GK~T^cf@mH(=h-d(xg_4J+JFRt(M zUiLYOT#aPbpqfEDN3H$SZ(MbbQ997OygAy~1GtCR^j(~gznR?H2~~sSq?s9-U==HL zQx8p7dS4}w{Hi;~n)F(Y&)OFnjshMOE#`-2unsakD3kAau6ALui?ye21dJkV%tG@Jcd->X$SdU(#UZQTRMupqL-tVlV=;fH)Ak4bJtD(J#L^023d z&v#~Zuc&|4eCrwQJThEr^zwJ;CC_$VS-m}dqmVUq7MC|7sk=r21&2}VPo(YJLU}{^ zDV*3`NZ*@LUpx^{&f5>#tv|EMI`a!_vsg0LdePvb#gzi6mfgL(nPv6eIaaLy8}-Zg zTK%{8hL<8ikfb(O!kiznQLWV`eC2yYma?p*dRJX=87D=4=3N}S=MF5ghb69tJaGyZ z$yfAWep>X)+7JJy4_+i~?OnR9Vn&~IgKVAQz^;H{t(eOsiw zE626_^;j!)nedg&9Ry@m3Toho+0v=W>~$Wz*Sr)CvS4iI$|iJdulnXOPT$IrbsJiF zfTEBn-|sPuEA?0PUNo+K5DSu*@uI^K^SaTsSvF%bhGZG?LJ6dXe>+3n-77v~&u10o z$mh^5mSBCSEF>F1_Qc10ow?gcN_^?)DT(*WgICVSV_<_AT|O7E&7XS+o2S*`knnHD9>H>lc%bsngta$$Xv zJ&G4>^o>zY+@?Fm&92Bh%J<1bu_)^Sj8zU0pJ?=E2dxQi zH7MQY8A+uWWlyW+E8IsP*j3g?rb16DPn;QlJKe$`{@lqIJZ$6bxtbA(XzP>)HP@aT z5KJlxCm(CGN#MmW4Vt*a>eUBX ze=^1t`=|SKZYXI`L@NK50w>8_+?dCTA9+x^UfGV?KC8<9sWTX*8WH>Kg4RR zZStM)SL-XU+~+hE(isaqyvkDyk5(!d`>=(owMBN&GW!IXZ0?1P!(;1#drHmVh+g&G zH?_>)vy4`KSP;^win%=zQI>z`N*>o*nUyFRAQAMg()msl`|D+oS!Z%?<%lha^V70C z1n%1L%LjmUpwWy4H4&Jp1un_~J&_;)!dm zG#GO;5gpmJM!EGKp~K+`KO2InCsJg^oQ)rBL>i*S3Jp9g%40irWs<&HNrS96Hki!# z%ods9SHo-dkr%9GcALzyGw6f<(PwYM%um#xd_B)7pG!*kQof82S)T`+@KC4k#1zF_ zrPuc6B*S$xV*VOtQD3m9YvY4TDSLn6SwCtFpkJ6?j))iZjScjE5fIF7_rSGe|z6VI&$GoTqkZ%zC+5KT(k=itx4?%Ct%5R9wcoP;`e5;-b`jcze{SSON z+=RpS!pbJ+E90Vdiu#UPaSZ|&Xm0F9%wwLSGsC%j zo*<0D9`y%P;^eH%BrU4O&rnCX9>(Ou3OV&QTTGQAWGOXq2yb6SgV0nVYVig$0rY@l@*bZR`I*<;t0PjyS2DL ztOj$lFm#?L5-E~gvj zSIk{jy~I!xcl54)?YdyYae-B0ZQ)8Q9^T2ub=Ah{JiHi#-w=<$utrXXRdk9|Ha8;! z!dJ1a<_=HAEpyI5?XoW9oAokhBzQ8bL+$QczrT6>csyE~wZgCM4hp&^d%;(T2Dc8D zAA>{bEKEqo?dWGc&dw%{S5~b^EpN>($h?h5=nnA%{oSew_mg~HC%bKIweJT4Vx{dT zu~(AR$aKx8@fUU>u`~h}TW`XKvjlcPl4jMjT0*HGC_=m0hx*-EX=8p73_3&*=wLHs z<=0YuXkt;eV55YI_@hByd?d3r$<9^|!rknF+D-PFeICrSJ6&wGFkh9J0ZrStd#*VyoqsYb3j$ z8Lu@q=)w zHrFgJfYQbW$7#`kSrMD6-Lw|LDnJA7Nv5W+9V1mDI8VD}SttE9TpDlYH1n zgeh+%=Vuh83)Ux7yGqacL&0;Q*cA9_ z@&>gmn%Q=@5`+!1d)TaPT!+h^%M7r#Y__a7TS^iks9jrQcg=;ijf6JglZPBIdFEZ^ z;3wj1JhVtuFY=M?9DSVeTjgCVv-NyrloLy#HczJ$8jx9;*uWHXlI5HBfh}JjDzu6Uh_1H)lYPLcqBkYtT-{C`7H=oU7 z@&o)3+ar27%R8or!KC8yShsND# z)j%%C`6gN@n|oRnBNHqYIXX!ln=L{kLB=FQV#e3XZJdLna%6NHI%UyCfn_@C(_E|b zk-vd6d=sCODQJ(AXq{{T6|0Knxn|`fis>$l;=Cx|$@Am$ZX#rHs+taVO0+QbQ}sFa zc4$XEPVNrpijsjuSf5r9HMn1h6>vI zYZ-nrr@l#-&6mSrdp8bHGrXraWzDBg2xKDsnIX1;6_Vp*VOCSDsmq{3HH-Yo4~eB= z<`Y#co0Y@iUo@ImEt5)F3He?+!OzKm;gQeTJP|(xtP%lQl_`P&*lHPARXA`If57|U zF#WVLMM7B>D4R#+|74~3ba+^0UezD<3N89(7`s?E3&mS5;+Z(HR#;h;t*;GLP9Epo z;B_lh{Dcw71*$@2AFYF!1K*;es^7|qZ2Iga?ppe((vhbicen^6uXp1e=?iN_-|&YY zmk~1pyd|A#uy9YN{+UL!d!S+G5d9_EL?9HK3dXlBo4^F;5i!%e_T5$y_z^oI8-&!%|=~6a4-sZZ}@>H;6OT?#n(YJy_WUZ-8@?lVLWmi zv`Y?Irc;|BR+7iFr^5HB?-`>qD zLszO`pIETx=8*j}2H)T$vLyZZOD4#gSb=?>`nBP;wGr~bhO&c;^i|z%^*HS!nX+5x zF>Cw^o}x*-$4aAn$4T}`5XzxI(JO6dq4TK!?ipb1d?P0G2xYKi?E515&7ASc zw33GNx0^X)5&5f)>FJ|b0bboXBfWgUh3;Y(*kY)0>~YtoS6!i6Lf(p9-1Seq#^sG7 z_xp0>SJ+m4%Lp0`GzNQ^6;Uq4U{#NVupoA>vE3^F=6eV0gLUK6WLy>%m_u2t znzt%?qMs+N`9qu)=( z9V8eInK*s!qaRk>NJi)n4Lzelvg*!O;c>-u8wo=~6F1Dv+NHws-&sG9>DG<0!p^P| zb2@wW$yv7z(W0&UHnS`Dt;(6Vqq8!qejshM>^RwpJ=fLj!;kzvWJ!8Oxp8c0W7q7e zSTEHGYRe3XkSD`i&!T4cqY%gWIv#Xo7}r@hk&9J&D=6X*^MV62v$Y`Fa-AN;&E{%j zX7df1FLvi=7EMDT>$~{i^^!_ZciGgFT3ExK7e1d)}x2e^GY=<=a)23H;XZ2$(>|m%Pj&B!q+^ z49Xw~EQVGF3F_)*H6pU4RYcHMX>GwJx*T9R;sR;J#BwKdN&6BfbVAA@|)Pfbr8D!vyf{!47;_BnO?CMkhx4$EBELVR3h^#N8LEQ zYfNHbU&y&x65fa}k~iinX^;71`AH4-5z>l0WSpW{euqv)m(nL1#mh{dA#-mo+CR0E z-e7%KdUpTJ)o?+%PK2UevKpU}pVf1aOtu_47YSPp&lOwny#CEf=85(&ojmfwukh&b z2*e!e)tk8kUs!E#-T;Tg0*octUm^Fi>_u5(#QH?}b{Qm^z$cMGh>8Z)(v|IU8d*;V zp?T(@SeQ=ap8S7$o_l@5Vz9sXD09HF^Vwn_aU(qB?bNk&kO!~DZt-X`q-_Tdw^rI{ z{R4k#zmFM)e4*M{{EUm&Q0;Ah09>hO{D~NhcGF1+%AGO@MZ9D#bDw8o!e!^P_bzRf z$5%~mPiRkLv=e8t6uBPWBtLhCm$2(R_8`xTo~2!0p1*FT73pV@Ji#bQ@fo?6yr_1< zuB5Lc5i(IQMpiIaOg&qkpd!Jk4LB|NlgXK7#i3fB5!z)7*~XF2Y3<;RtC8besg)wv zVQ@OCi9&uR8sN&?1C%o!=bNGwQuX|e&^G*{-$s9i_FXj z%ce~vnX$43gAMZ&MBE6bTm)}jZmYIWm5%HECdVVo1G|c%%o9}P-&pbV!A{!SGRv?D z8LeHJ`mT(W?$bA4tazgW`pFmIf5jnPS>CL3#=8Yom!oM>O&m6dWJEU7Q})!{LNM&CzZ<>!4*mlgwG-d@Lb8(d z@`P}vEd0cj^PDoUtO03LA!elyq6#(ktQ>xe59Ke7+_U8hoU2#Nfqm6p zf%$4P&Kt7|6YFK|X?Ja9Ei8Xbi|n&9ANK2cgRe93TKCV(vtdCNBxp3Xv0=P%?k-zT z7DxwdJ|~uDWt?=cMp(~_@##&*J5r2=p9-9;CO^d6$W*AAme-W~RsX(bmM+T-o|q@p z9~w)>l#zNTg8eRODPs^p*j3v#jE3&d4LewGip9Zzs2qbK;~CP2`fO;^iWfB&*RZ=V z4y(+ngpOe*KvoVV&rWf5sj|<=(XjG-M=)jzrH3&F3BI6?~EJbq} zIK@`nVyQ*B%~tmmk5eNBuvb}1c!BrfmCYKqwJZm8hI`?+#CGGq(pLVSD^+f@0SK~ zI~8*U%-_s!Yjrxd<|hVMTf0bx5yD7TK@L*>|CanLN^w$zSo=U?XT|e;rvcap?QHR$ z9gmM-QFu*gpIk)qra#(u761)3@8Uq#_aG<58p1Rrlkboz?b%yq5xXe{CZVzuswRBF ztdk#@QShhMnzykk^%F%jqs=raPlN+lIJp+=Q{PY?xlgMwM9)|iBeDgte$yI%7o0bD zn`_*py``c683O$x=d2R6MxN_mLj4u%wfWMATqiD&adX-orpud(%nD0TY|7eoXCh=k1FBuH zNPgRw57B|%%J8sx(Yf5mr^{)TT{n-ag8N1XR$(7+W!9?q=f?gUfy@;=19h>zV~yr& zCq%0qV&O$taxcjd<$0AcS!sTIVtjIB74vPED*cqzfo|ZQV7pw&7S^k=T`-V%QP2zZF z9QzJ!i<>`_K3XBqZPhAC%L-)_!TuSowIeSg4pE$VV0?FaZ+9AQoaRowTV|E!7BfOO z5dScAGgCYnUzz@=HSf%^3wutK&QJR3Y*g6P31&_%fo=7&Cn}LU($BuqTak1;jXut- zz>$*;9!WK~(3tFT_w}5e*0kPe6cgFZVr)vT#WK_)jMYz%$qweE$Q-(4!Eep}H8V+5 zDs?z#K8-~n>D`IUZs1<0CM2!#7Gxje(ecoXMySQ$qOIy_*=(M}wa`ZQ20%#hFnJ2Z z8ZAhB^8e5oTvImEeO7GtP-jNirCMlnIqX$hbOL~#)9`Fs%irO)R_Z|ejZVa(tTtIN zA~6OVY88x`g)#4JkvS1RSR1h~_Caj}G~jd<=a2NQ3XlY>!JqlUpBXd%?F1QGJQ#G^ zpS4LFxOx_2bTI8>8|t0lV6mDrz7HyL%qc%0N@un19p5!o`ss1BKcBh+;*zC+9_a-= zXQv@J9yDK_>D(_8k1WpT%}^R+@%~mM^TP2nJm={dFE6adh4m2IX1&rFooA2dz0COx zcLBw)Q4<~IsgSr>3P!O%Ph`nXI15V6yIKI*6}r#0zFI9$hou>7}~m=ugI0#G}5M58kWPVKreH z`+#J0a82Zu2KTK?B0@9U9G^4XZj4>XSK7uBU}3f296Rl{ho_ZLYz@D|XAFAD(_+cy z*>JfzHZt14FS(A7;5{%U=16QbxulE)TdgkQ^J#x}faN~kPToOJFr}HR{5NuzCyy^3 zX=Am>kdr;cYkG!_mo3B+Gpdh!f!;5aQ~^ z!N|#dI(- zKBIj7c5OhAI-f76S}R%HaWGB6YG?SxHxbxDgFF>|Qrvv%nh z|0UaxrD{f*ePZ>+ht`W87qJ^Rzd=jjg2~n8=L0q?ZSK#8mYO4q49w5n#YNNUI%Li7 zcb`5>Z!Jff^7m#y>IbyKBFa0#mLq%l-8{lB;UVWUmYuh4tqe)SPuf?k>QuERo1!*S zwSluSy!|MWn;8hApBb{3Fy1Rq!c?dRRUPM=@ymG*%WHL1XR_wK+F7n#!(_c5}w3bfPF90ga+R6!wrIQNU@;aHpCby;TON&^V`#{k z-{mvMQsf>81^;1XA$M$YtJY$@a)$^*m7O@9Up8L;0ygK9%|HKznIvN*AA<03 zKQo_CRU_~tR*9Fl3lH|unz*MsT%A3H>D?SZAu6!CG?@=2C9>Z9kMrry*M3?QN%2`Q zs7SBtITc#DpSDa?oom?NTGk>O?Ag3!IM>led2gEF#EA4LKbaj`a=`k~PUz9o;0{RB ztnpH$qF&Lvh*d%5u3V)DBD-ph885nLGhh^cT^>dM2DL_(ikaG)Q@ZcYbuukIyIAg~ z9P~s!nJ-c;>Lm?$q^X9<+%%KPvegTSz?|?cTS?Bz0~s;~wgitfqeu^0>)BY{EbCRh z38tRa)LW|v>DhN{Hv>;35*qF^*FnL&InP03hZQs5u}=I1i)DVNeky&qAdyb0X!8@B z+j+xIz<$XWWj1luI5%DdUt?ZLlHNNl4}!$f`1C*{F+TCNxe~(hM83?}u@hpg(X#xl zSyJf^p)fl9`T(4DYBr-G_ zeo2q$SL+z8CwmKji!&4ON4o~0|UO`C2?tFU;S6U z@|my9d!Akk&R&Qx$}wRn##`lc>!NjBFImJkvZ%C#^<+)pMwWj#t$YTd8sotpso{Te zS5X0cXWiIsh*my@7ir|>^q0OtRjf4`KRusy;>(=dPRq!7PPWfz*u1{A{LZv`F#oj+ z_|aNWnK5U3%7;c;(p#7@cqq?5h}uZM6>&bAI39~xImAql)f_FVEp|28V7Z69Ld{rD|o!Q|3RbHYc{ zG`dNq#o}AB2sh;@y*TgGNsCER3psPNsQC3rJ_IzM@fKu*J)S(p}bw}{=DGWbpioYiM7 z>AV)i2&CTMJl%IQ3uYeD5P$L1{=?D6Pv;um2ggH#uuqVO5o;Z5Qta#J+G9M0^RMjf zRP|76JvE$ZjdmO1$VpmhM4Y;=^wE1rM*i}Au`Wi828vAdoK3G^wZ~OlUv1Mv7ONO@ zUrXj$D%SLv|00FBJ7-Pzj8@)*COPFy4I_L2wEQzTxACHcX*GD zknQGU+|Q=Nn%I>ua1Uuw&I;!3lVtG4PPgWMtDQ=S+=ubU^H>oU!`VpAy@KR0;^HBk z6kOpM`Ygi$Q$iSHOUz@w;8f3&rzyI`rbC3}pH+ndv_Oj3cs(h`F-kVV{i8AYdoy)m zg61!-hv%CW$fNQz$*n#b`Jl$E+d*DWO}2`HgZ#NYO-`bGz?}WTrsB9@7vr2&&olkq z`!BX4RjNN|f_P6WW{B60bj)~LL&z(B!6&9q~Etg^)V+-@U8T2lx zbJGeL*I)cE&Y|9r1~r~zcMc?;m&8&oQIwmnB8N|AGLR@#SwcmZ?9v#C_zRqzgE zW2|oeg%eoeGO7BMda?ADwZd|cgX)%f3IA_qqL`m` z(Kg&lOC~#?pY2YvQmTsVb}l~S+3a~^yXgaIG@nIo)`AxJD|<)}V3B6NoHuiJ)`3;* z?o5(`(HOg&Ygx7;#zCB!5pxt-n6-yq^iTE}OHaR?nA0~uw5EbzCB>vv^p_s$Q(C11 z{?G5V#+8Kmgf8~v&2S72jA{pu&JiFnNHM2GX2##fC-+2KUN`OMBIoFfYXO{h9> za@e8tu(>aun1^OT=rwkQrpW{pOTj;)d*g#*^OY+G!{%R4=sUBav1aG^b`fx+3|_~6 zR+7QDu+8?DeL6ook7+Z$OMO_pOP-?=lAj!jn{|bw*fG5R!QM>r#z*?UlPW~-lhqu# zwnr$Zdgng1wDEHJDJKkM-XVmnSg!6{rm!{9`}~y@v(#px|C(|0(VbUc)HGgUc(U{g z&xIrCNed(fQlYgy{&EeznEF6m+*r_ngZ!`(tHF0)+=lSJFprwO+ZM}VL ziKnL@t=jOW64snHm8F6Lj;0S*B#g#bi-}>=J_grW`p%ed9R%JD!YtQykTEI#R;gd4 z$&T~9w3^k&wBbn10;x3bq!~-XM?{bGJNFj{vub(>>9BL+buE%9-n6U+>rK9z8Lf@h z8ta1DRi&1>%TLY2b^kmMMiy8fUY@q#2t;f=AOuY3`9e>1O_?+{du&1OF4E)o@m94W zW*mON;$bIQa}31b^I2n`%VC%SQj}`)^pM48S1N^K$wq&yO*M*Ku*_kXXiBc+Gp(wO zu+u}~MA=BJBJNPsry_{`;CXA6&5^1xEonvd0omH}?>4{NC@-hz6 z(9FFt8Vk?o)C{}A!!P9d&TmRxX2$Py^1Cwc-q+>scOYJp`#_Hjyysd@gv54evBD?&n9=K6L)+0TU z119&*eD)4iZ)cN=4`A)o+wa1vbKS-bCq)%i3 zQ_B(*U-OLWCHWxd2i=l4;(Tn*H#s$HZd{}TD&W!iI4qC$yQ`B`7qc`L|oQMj4KjKN(Kr|r*|x6I02(MHyqz1IR%B!0pFvkgW`3I@C98kK;m zYDhO*hsWg0vfjA^;;y}sd%Ix9%#UEMVIH%SFKd`*LSi(2{-59B4mQ55Z^oTZ%N&VO z*{yi6{9pE4-|!@CUp)(ZGu6~11+~e3htc`a?zwQ@x3^2nsgMtWRUDTGvGOn*qd?=H%D>2Bkx?)-AG>Hp!R2_k9EGI%y*xb`M>b z3N&ccY_|&Cx{8fRh*dO)cD$9z(W~;n2V4g^gd(B7t&9u?l{vznv2>BAJYCiDFdoqX zF%RoQ3Y}8}f5A|F8aak&)xe0zL@o9+*v-I`+6T)Mv#)ewO-rdW%5{SS@~N}cKbybU zj}M8+n@kl=uI(JQ5}eNyXNcL^3X%W#%JhX?W1`BfiBijIsj3lEumr5HS?FDCg!!h& z?r*#|CpV-Obw_8U&m>djP`%#l)XuY6q|c>cK#>3W1yvS}_XWB~|=%w0pzPx*O=%pu-mhKK^>%K$&$48}g?H;jn){;Bkam3`-{co|Q1?_eC)WDeLg7)n&gH#=P?@1vd3vj9+|Ctz*J51!%lNRWu7`QLIO z2WMY+zr?(`CC|57V(ERvlBbc_T66KOx+*;_!vn?PPDEDu&fMbu+4RA!xsz_NX{@bl z`84~YoSa7En$zO9*e6zKs-@E7qHJ-(oKTbNop%FKxStmncQz7|t2Ik(nP{PYSp3=( z?W(70Ce^1|E0s3-P+X}Bk;fm+&nVO<@x-Je=se@=E2Svu-Pgrj&mJmJUuDT-MaIs;mg{<5#_Ce?q)P(u70NL$-}`KB#e!|cls*VrvJFh zG6nfLy`q=&oo|i~&Wg+a)GNU!-e$w2!YgIBXuZfQ{v`h&#FkHG0(T>UG9B8anOF%@ zO*_X9=U==MTyb)=+ew|OYwk$jhEJc-iB$1?BEMt_^0PUyssK3nVa5%qVLxQX)xKhz;Xuer-3W%0<-)h9_R;4VSFYftpeY(e_xujcU}dUB_#|Vg zmWY$!Bz`Sl)603UOMZeyco6ajIhk>}eeaxW1zYof(WG20FAr1V7vLfDfUD6{b09*D z4NaR6mN9vkr4?$=)VB^0ujW=O%EIAL&e$hf%Q1Uq_G0$Tei-765`~Yh!)~CbR z8LUk_amFXE?B7M_WE!)`o7JY1b*lkwG#7_qQ6aURwO4D@h%IwIeQyND7QuKlhP7oO zk4zhIFqQ^mZig1Bn$tis5)qMj`d*n)Y$AE&XV`H0BI7i(jg0M6({~orPAhMn6ql6O zF2~h6>ER9X9M|KG#aZchM#}ok`wucpeM11>%B~-rEJ`<^Q}bPqeoCrE4(Ez!K|W(^ zMGsJ>_yB^X`80|)lv#-X$?Q2x?;g1lcJTJdB5)|xdXa!I4!O7adU2rYIQ0|deP{rL z)x5}L1=6#TgLLY1C8{e^a*JVa<^sU+M$$dR7EaN5bxlc^Z z=jU0uzuq^qnNhI-^4)wVJl*VxXNb&c9$d>0nMHPk9Uf+BRvi9rKAu&9H--Vv6;MxO zFx;m*%dbxED4)X%Y;AWOU_@Yjx*=veDLQ#Z+89rpJ~&eko4^{YeYYxK&ccL0&&6TS0%nmtTy~g()mQJdE+2eZn&?onHdXfP|mg%pFb}9-1CNO=hE+W*CDm%{dEc-)>sy(mu3$ zdiAvS*Oj$}7_k#&Dp^Rf0i(Buc+P|vJ*qB>-(X;?!f&u@>Wuj`dfm~`IX+m7QXkJ^ zyVqX8+jEb(7df33*${1*x3N(E9SJD^W0b*$`AogFHx2cTsVs@u*vyM2nlBa&@uEDc zs$po84X>QTy3mxhA<^cLX3=?9&~6-a5jYDi&J`<|XVDrh)B-Mv=d%CHnS~^iEU-Ip z6)V9zxr2}5k45)=AP~%WPuu=;T34^*no_N9r4Z!cEDfwN|H0?cln(Uj#JuA8FeP^2E+H>sZVk z2F+Z^I5l^`&#~G3@M)wg%jb0Md!~h)O_$$J9ae!=6FMR9IjUJB!vefW4qQwrW57miu^NnUAu6vOxGe z>sodc$}6+XOPb-SHp!gejrB&GI3frhqN*>cwcsCE4gOoJ*2njJntMdLs&td-jeOud zk|oOM&HYqqYJ27i&VtrpL;fZC{zy_|B(`uEoQ%T0N@yRCf+^8M*g||uM%g;~FT6P( z3Cd}n8iRr1V3&$GtPvj86~?QAZ1{tjRp>~Rs;a87rKe>z^LO$H|Fe;Bo_URJ$$fAx zj>e3Uszx(Kn~nUxzzU|FiFWf$_F}4cb5Co5jEM~(TV_El1+9qTNDnXAcn*3Y1yl2% zyI4yo5LZpRMZso-?a)i!Po(0Thrqo;b$n!6%pI&6lt^Dl9BJY+oZvc`FTa!7(T_ZX zM>6we8lf685$m3Q;uFrw-8^-p4v1cbG1ek;m3Gwrzzjvw5Lj(24u$oD5X`u>6^B|e zT7wl=T?HvcXY*GPxNOI8C$3IgCq~E48$44@EF(10srAgLjcpi{{OrqY+OsI5Deu9$ z8LKOelf0Akv7Py=JxA4IYZj}Td2^!haQvAA5raCL$!w){b_0XaJ%$H(q+C*PVm`6n z__p#*ys!1eD#<^PY)H#4fAxp(tf-8a(ZA;3abx;mga=HYRfSI7!-8nlevL?Jz9F5= z@yyvN;^o}OE6G%-guh|%;kAlnPR+CLnWy$lBk?fwNqgA4vRk}vrOVhnLlu&U zkN$iyk|C8-ACOO-(W!#6*;SKA;&!A*tT3@c8ovm=Tj@# zbr5B!T&Uk51^A2Zb~&(y*3D_;x1|E}W6`FpRaQ)tW)4pahLD-!d*F6hV1G4c71@;9 z6Bg=V*2xL|tlbio$Q|4eO@$MJiSpf?3TFc!Oy3BMWE1&SL&Ha#=@kBGqvTZEB8JKo+mv1(G*z)w0MJexEedfJcKPQIb^La~q zjUh>U1oWs`PBwRbZT6$J2FnnV^!v^4q^LX$WC71(7ifx^j0B|} zF@0=c+GGvz6JLVI$j_t|Dsk4F6SvuYn79^C<&J%q=cgs>!J4z`2hkk=c_0Ij=RI?U z)_INY=$I%Wy|nJG%}izNdMQd~u`uiGILlX@%BG2UdNwTEMn}kMbSl>w2MuJS^0bWC zoXcj|hrp9G?iju~W5@52O?|0M7kz7s&%Ptr<+}J}l@o{ad*jeN<_q(HCx=~pE`3`%5i&_LdXmPX8Xvw6*ValZ3`lHjo_hZve*3JQK_@1#3mcb(y^EF08uNeZ zJZS*dN)1cu81rNZVk`aaDXQg)APjzP7~+u-{TIEn24Z`7UG5WCY-KThEGEx|pA+jh zTj(VE&t(R&p<7uu`}W9DBM>s-newOJ`e~)Cx>Xa~nF&4a%ELJM%3s(|K7st>JLUL9 zq>%UNw_c2c{O&l@Mh5ldQTQAwoJW9?ld zMU6|WoiXCH4n_L3;AvCZ5Wv8x7uc_v~PoQH{XwEgFvU}X`hzj>gWa^IbJ(I zvuxU;cg3}4n~XqpwY*qz*rL3Vm4x<1e0plG^0v*i(O3_5!?Qy^7}h!YCHH2`Gh=X! zaTzmNvzsF)Rv1^F%%Agy^)jxKN5H+(1oqG#!sewhzvhl-V2_3|tuY$6J0%Tyy__`((DUkszYXb{QfNSpd9@q2#HcWtX|dt*1cfI}Mp zkP(&BmuX||dgZT}NIUEut{ydO*9(>$~DxXQX=Q&OtVr?|LaaPjJ{)fCSOC*=aFP z=8I)J<+{4U7;q;%$dP%X^%WKCZP9dd9_*d0(HHl%s@pn}HK0q4QTOA{%p%?nMqrho zBm4L5?889QZ|oSB1e*W@+BKoFTO?Y`Wi8Igdl|4SB0HmU$tOnJJOQt-0i$TcE7lXmD3B>k3{zT3!Wa9WXZLn|M0l#Gf^cE3U%R( zIP^-$rt;OVlo`<&A*jT$O|H3lgH9!WWz_~x%hL>Z@lZgtVmp1#@x_ee56>1_v&vv zEi8=V#FkA=KeOqtB1742@dRmL`RGTjaqTRO<3Bb7+AI4aQt{p=R#?OdGoLUL!yAfu ztc;2TNCdAtEK{CLPGN7_hG&Ks)h>30Srpy`vjE}HLEmF*G7o$uTp(`F&l&rm%B&6_ z=~?xcI8(749}YLLnUnj>_~yEiRWzvnR5h==jLzE%&P#lMe*CMM?e2ltc3ha zyjoUY$v-KahKX~ZATd!Jf-?{MkcOL)Kofqz2v3J_~ zh&%ZAOymRy3_bkuadd~L096GZ7rtKfte&*)eH-2XQuH8$Izv9@jW5G->M z&e?g=&ck+Ix%+^<2dqz8p1ARxtt;>P%cEx;ea80JY~6G7d$%69^;=uFZQi=Mxg1@8 zXzwYzU%PY3v3K2l>)pS1_tnR?kNw8+7w$ZH_sYF5TOYMNdGo5R|8VH55B*sd;IEFp z|Ii8BKe_#yt)JNZ<&AeQf3v=J?&-zp(Kw8;@P?T>gA{-SX_{!f&qMvL4>MdhbnpKd|?*z3<-pp}n8pd-L9( z?ESyJTi5f~r>{S<{@<+YW0!AOzJK|-?U$=hK`i%9l>l4<;tPjcRK5~8b`l9s*)}LSh`}#ZUyHcNe^77#2Y0K9y zFI#>*ZT^?#SC*g2_YW^`Nb7H0esFn0umOL7o!MFcb^Vj|*VostuU-E~{(W2id-M8R z>pL) z(#nU{tJi;A-?zSdeQ#R5Hlw&9e}8YDd~L2c78$=HEnXfz;J$gn6PCv;4~-O`A6s&9 zbjE%Sai$3Sv&oEnX#L>&(e;|#`|)r~Y}tqN40{NmQ(i!&-q~s40n3*zkI46f()OeC zeP#YClBgf`9!7i%49Ux0lkX3uWhY!s?3}hl5#FiT@2N%@yT&`HB)?BuJSP$SWqHB{ z`F5I$u|tUVA$=yjx*dI-ifD+#ZHJFYF2h@Y)igMQrE@Z79HPCcY?PDA#X#Q3=`@j#WSu{h^>OBy zXkBy%QLx%h5k8!GJ1^hxiIKV2dlp~@`9Uj;s}^_giXsuMu;8_uCuYnSWQ0?_k(R@v zWInuk!^%RYm?P5CeFCk5gqzRGeHYHvYA)F8lhcQrN5-y88}R3+vTpHN6Z^?ZI`_DB zT$g72GFGZg#Xy*QGu*fLsVc#u@1;M7BM;&doTU2W=0h7N@>m$0yxTMFz(~Ax@3aS+ zJb34hh?xAS&r>;#PwIKIw`V@F^c|O6VLc11iES4z%bnl`jX>m9WL~U`!>Lrlo>0%7 z!|2dW_)WAi)dLx&Q&R2Dg%L&R7%iE9*&Nvq*v&4R`2F04NrnyFPh0SsWj_+&#%F@8Hg+^IR1h&lD!JP*=Ts;?SigkOsDHNO@87L&AJGEPUah!Cc#T)9P4r?c-(SGt@0kUO)HY{UAJ2E|&mzWk*ir$Q6kI(yH_M zU@msg-1fvqv7LN`UU{bwj1kL`>!Gq%Du}C$C0xk-9j28>Xp||Ji5rv^usZA*yP>KG z{tm;D&#e5T#ER6<--N=(js9DCk?!UD<^9AcS-z;vrII9AyixYB)jt4Fil#b2gZ$^URF?g51TLVjRRUH^i4D^O0Vw zjZrlSMd!VMBQLEzYL%b}xUmI1D6-M-gFKC#TjGTLg>CFf@$SIy*foAi`olWiJD&1z z)>F3W)0vwxG-aUqJj~Wa4{2WvF)K7{{`vIk=7~SV&iZPF)m9t1b;3WG84_KtA2)@K z5ZPN>@c~XjwuiUC$M)SwVr(az-!ESBlKlUQc;@6<(k=-jL9Ge>L@e|*@s$6X7CxLY z$VYAOC6UV$GOkMFZ5fAi{NK0!L;8`K8MzWgkq`2$`h(?Vz4(c~HEp<- zTx*xMs%>Wiij=UxqM7>h?n`T4HM`6*AFzcv@jiqbb2s+7KH_Nl96KE85pA`ub27*2 z2X-cLTh>{8Ra*&zw31VXMzjP!l)bS&u~lKwsYyR((-t%a@^qtXx zPo&-E3Tqw2ZYp46e=>4xlvy^5vW&8bpN@p6D|Y=Y`Ppf3;$Lh5X6p2;>tvrZV*3_y zLT`Su`}>P;$`H|$J2XQ+_`b`a`E2tc5m5x+j82*BR2l$#%b&K?OnY- zH!c6k^2y~dm)9slMte34%UB7PqzV&AlqyNQvZDixY%U6X#c-8WY z%kM64O(*ac|8#wiGa8~9*G1c}iS4u3L{;8}@kU><{M+>D zMaws)rLSI|v%D}*`u4CEPhTF%pGU?&l^FML!cY8JTKt3j_iOq7uleuS!zR2nW4JLA z#lwl2FG*jY5q{(w($-U#tCoMaJU9P7GU(vq$W)^K^z+(`>Vx47wE6x-&;Pu>Gk)uR z`RT*yB@PjTT*mNlko|d)e5~bz!lry(`unIz{yEWs^D^5!ls$&!^MWYS6LlCgP!^PB zzdGaphxMPv&S6%A>T@UV??^1-W$D$$!5-H0$R$y|vL zn(u~FldtWpr3Fann#lMqx%t4;s6M$UD|J~$jORV5IKxKy z#+-j7y-!3x^U#w#U~q`WKBbGYPT9AZ`I1e7YKjLi6y7>@ZSKE5@&UE+?mavGf~?Nj zS+gV2p$BH%d9P|_Qg-sTT>lS|=G)R6{n_Uz%tm^ABv|~Cj8=uzeP)eifAL4nOn6JY zH>7?v{r0X?I93+u9(kTzgV{Pavh~2}H^d<3X|?+&GSebIRhuw!&IZb?o*zcfZc;e{ z5vP9VJ#Cpy-rp$Y=|pU0$T4t1*O_GzS;m~X=IIV(Qso(J0rmF$Ra_ukBhprhg>w^; zLQ^u3`291Z1?-e~x2MU8emc{vz}3+Q^>=!u=C9Qx*2hjVQ5bw5oH*Khcdou65`AO- zKUH=k)iD08X@l(v(n~*~f%e>~ZaltxA^W8c!|4Yf&&chgfoZZ|HQrrKG-N<8FfrI3 z`DZZ@eb5&Y44uHB-hhE=bH6<~W!cOSZH6X9PB=UHjpkBtT_4M+Spn6F;!csZx*_`j zy$KxeQ_ib((awvRGhedeMfq}r-9HKqwpU_)Z8U3vQ>TmPTy4Q z?ejNAcdrR&eodqVFM5!vzc6<^d?fLHnP*x4uCu5@EKj!ZYBxs@Z^)AyvEc;GtyoVT z!x`y2yecnmw#EbGDXazwhR4O!&Bp6>IX#iR$^onZZ|d}B`Q3UC5<+*IBUPDr%gl7& zBz%5kL-fZUOr@r*Wmfg0@kAfUNIyB~G=0j%P&4yptxfgaH$kTpzCan%pOv@FsV@ zL`?yiXQyPFv5+ExBe9gHM%vkl+wwGW$j87ha=@6qgMD;ZIkm;-WX!b4u1@PHuEz10 zFHv%H$f9M@gD2M$;)+BAr)8FC0Dr&>@n}7*jn~H$RqI9bB2#&8CyB>nN1jUin(e@@!f@jyw4eK@ zN<-Ue(VY;cnPnOA+eRU7pL&7$9Mdv2Px*~+ZPnn+X|C@);|0uy{;3V({m8BvX|1n& z&17bEo?9QQm6_4$*UWDI;&1%wRPJZ?_B~+6VGVgvy){>6MO|I`J$)=|uZ9B0;ky|Z z(m4Jv*GJ-VC%h2Oc)wRrM40D1OI0tP!mOBaeZr%f8I}n1d17>g9hP}fBXv^z)cs>g zPl*;@6FYl-?6Y&)RPx>UiFW#D zSFXRbzB~Q6YI)Og^Ts6`U$OD1jr%VjPnP>DJb{@4a{LC-%N|@9BF_+{Qa!;qP@MnJN7=i zp159+i2vz{&0n*=C1cqPT7AayP0K5mAI%M+I;Cz8KvdDi^*#LUtI zmWyJm3U@W_Y8fAO5sGdSY2}c$w6+JmO;j%iL%qsBwRlW@VvpFZ+E960{)|oU6?)Qmfewq))g-~pywKDqWi+)fxo+kc zk6tF!$RV>>+|f%`q!kBdc6Pf>Uk|j71+YR>v6LR@N7~FaW-JynKk;2G6RQGimSr_2 zz4yh|@vOz+`9rR(t;0^wv!)lRGMcN40gO89KHscp>}&eWS7JcLDptx4TA0L~vDf^L zeb)STBq!}=1xecUbm}rA8|;`>?_8TLy)`f9-m-$oqT6BMy!Qd zr?e1hFxu&_9J{&n`^|l`jnv<*n?CEER?OE(nO^5_gK}~`U1rtXO&pzFDworn{H9-?GBT7F zMy7LXpQ}d3Gx&e?!bXqPw<<*tU6Z1U{i@cqN(M=x9@04@@HO_yz4^Hj8e43|I>T1K zf$!M($>HSalk&FJ!_R8JRhP)5#t`*4mUoAoCHxX9LLbK}q}@vJ!Bh78 zGJmhG4Gzsy^^KH`oim5?d@@3pv@)4sZg`fFB$jJTJjG4qvL zf6GkoKdE@bbG1$yJIn617L_7nUy?b?*Z&7j6K>xC0J(|->;M6P3~JKV+5lYu1ONa4 z0008!JOBUy00000WCv72VRLI`bQW@9WNBe;bYEm)bYWXEG+kRVFf=$_2xD(;Vrgz= zWB>yI0f1cq000UA000310f1cqT1*Hexd04+0eAsK-3id`)qyA>C=7o z*@uCML|F}Jr4lQlVyKWrgJmk9kwp#BBxn>PA;xIMAc@9U#8?OzV+tXb5KXD20SqA| z5Fi*}7+{8(Is4k(XX&%{qCp^>#nc^Z)3VZ}rsKUccGBuk?4d zcFy<2y@$IF=MHDOdhT$cclY$!&Bu4T=W2h)K0SN9alBRw@AUkI?!M)4)8V$BJ=?Wg zy7%4se{)84d*eFOn9g*^nd7lm-svPTgd~?3g->r?PtBvW{81!~~&)wSV zo4WVV-0pW*S8qLBJUo0j*PYk;eWw;L%-nCAC$)Ij;r8ZmJ<8qOGxvA(o@wn&<9fGG zZ|$D*^`K9byuI-o+ntB=U4QBL;_;1MKXAA-&)r@d=ey_7H6uCO`}-Qh?al4A>EZI> z!D#)~%<5dv)N=RU=-RFQ-P{u>em+XwGwXcI^m}gRb7Ls=Zu2w(<9V>(3%y!u>FthI z|3I(*x~CS<_pK;{$L{EET=7n=UuaHoLG8TTGp<+O2KZ)j_HWBIfd>xuLAb4NXz*E`dfwJ;-66D|7u^`4G* zdfLoy>i)YMhglhUT#c`-|NMWLk?FgZPR12o8rzN+N>kMfG%Bzs7cVvuhQm@90&#H@e?Coa^c9 zwSIf|&<5_jsq3%TLUPqe?u}FKni=CY>u3%u<8fYeINMYBAAjFIyg}={9Tnf`_eO2p z+}~~WNT%ZHuD;WF?(CB@C>foWyNs7)(Fb=lj@O#|l}2%AQgXk$Yv-1((gsOltDzkn zL(0zfDT$*4rcdioZzKzquJ!(G?Obd|dN#uw-GTZz{+3>y>E6{8x5ej|yZewPdTIK( zJ*vEvG@h9@NEwMgL>ruLL}o&k=qhtT{kyu0Jm?=iY2n+V&YSgp>j?)LKN(IQ`j-|W zUvJDk_w?@E@QK+h-``pL_y8Y9=bky&QzQ+an7v+UvbUn&)wo4lbO-rZS?jSyFJekt7e@k(Bf)9>6Qt zhnE{|pItdVcYM8PFGT0F_43N``6zw8@#Ei_Sy$1R)_ZGahWmz(Yw61InO5W7M$*dl zJbq&b4)M;zhsSCc1$X?k|NZHlcN_mZwQ=!qcVl}Em)9N+A^BGR?io8NCf&65sjZ^j zZjG+#$!24%UyBzG>8TIIoo8pR_$WT;mo%q$8r2KOUp_u_c=Yg%hrf9E`s0t>_~?!A zK0bE5dicbdKYr$qp83MV*B$@D@o?kEZhY$aCC9&V{B*qerH4O!_^XGXJ^cFN2fF(5 z@%y{uyN*A2{Gncb-|_!E{?zf=M)i4z-+uUp!?z#)_V9)4fHzvuAfhsUG)EsfDAuSd&YI{w1(ll69` z=U!?Z?uv>JG~4t2|7gFgGd^Pt;JQag$<~H!z0;E{JUnuL)VY7O)Ls35zE)b5_>^XTx7plP z>o?6O@60G@%GY|bb*-h>YPEd5cZJ?x{&~H7)A!wfy|uekO9%X3tMOy4;z;v= zWwfz8*GE0IPm(Jf3sV_AdqxkC6tZ)rKR@sE|C`MmH^Ve!7RTMvIJ1nN=uDTFB&#VI;H)fg@pX(z$(p@MG?cC7{Jkam$ zgY0f}SNNvZPb_4ukxR6P@SrF<;nectBb;$+8E9{IlyqKhOeBVWh5%_>t+NqU4}v&B z7-%yqLbt( zQ`(AsKQtyh;Qq^phtf^U1KHc|eKyHB;D&v8) zVNbr*RUFTf!>+hsFu>5}-qV)Qs4-|OZ8h3?QB4@N_ixo=QdxU%)c^Sz^Z6(N*`NW7 zcJpx0>T0M6RnR+RGb4jl*c;lPHph4P-3-D8jr94r^_50)cb{vW2FD|Jbd|qAs$i>l z*VX!kN$@Z^#tC?f+(xr{qYtA)pM_`p{LP-m!Rr&i#%KEcxlr-jjceAb@o1Glf}YkL z773x(_F66W>S|BDJZLB$>GRhb)#bx`X}8ApZcjps_&;1w@AzSP#LBbA>;gozI2KA} zhnJ_%H9O;dy??D8DWTPxU+z+h>s)`cyq)q2Mh?pgHYF5C-e zE$X*^kkP%_khjT3_uk*tWUN;>dHaBqaWyXhRy^0;*P|yNSmg0`^u6A*Y|>B8GZvg0s-2czZC2~QE$%wjDow4G#bsCP3pSv;QDxB$ zZf&I-_2Nmi51)0N7D!vxyS8|4^fIiY#YKb56ZE6;<5E3Bm?5a{w8o9EmO|~ldc867 zP*^yh^8D^?J`uR-Pll<V|%CP)}FEf#?0TqyD$lk7K1uFT%6w= z9q`5aKH0WL5W?4OchZB_%nyyRuV{_@jh@NZuSK(9ab8KX-mP``^sThy+x18XkwqMx zH_*RpU&iy9S?c#&Kk`vfi_`__ur`c}POIiY+OVW^FQM(YV& z3Q<@YdhpfZy7m9k=R?DlcD%5j$thi}fyho=JS{*7Ua`~byKnnGT}gmu&1JO#I^Y-j zPX8>>xuHeKz4!WIeQ@G>s3dr;J}W3{$m-IKiv+DByToqc61-(p^x^8+S?}(~ukIG{ z@fqvN!wkXHw>HEzU#t(>W$^|1fXdP9Y%O@_HJO`t^|O%;`ee+jA zARRl~II#Qtpy0Vi%_D|_qCofFF)O;h=1q+YYN4CRF3G14@fwWc9f?9goQ3O~>2M6G z6{mp)w{7bPZ_)0gW)a$rX3f%?i5bK@Mq2Av@(rO{^EOL1pt?@)5gh8(;RsBQgePF zzJRce$6C{3>p2Z3>3%c4HM;V>tPi~OT;BYBhu?qrZw`O9Pd@*~U%m13$8S4){h5c) z{6}a0z~RU8AwF>9CvN=o@$&IIkIx;x;P5qvZ$A8|hrfLI{==UyD)6Cn>)$#4kH^1p z{DJ=dyFC2wKmN$^sapK9!yl@}@9f@hI{dD~M_Q3j9{=v~Z_n=!7Y+Eok3W6<^(gg5 zW4!>u8j827ZLcG<3B7S@XNejZXM?DZg@aAuRr${>1$bwfbWI0&U4FAIw=FR?ppd z`)qyO7k;Db##gIt=n)FLC;o+=XoK}Uq3~9Ye!dnZ|Ur_ShPFh)!FqypasH zb7Qpn;BmjvlP9@@xyF|!^~v3|eKjfM%a9&6uMFiDFN{>w-hGGn#?g1x+AA|>ng^Ca8Ma)6W-<3lcX~#P-GhoW4v&c? zLob;ip8WV!K5MqtkNlA&zOX0G^f`YGwkhJ)Dw!94!vpK*Pn@6@psI<`)q=>x>RkHJ z4C}dnX;m$+Uqw&(gx(uV)kw6RHtv78YAw3Y;Og-J`d9oVd)pZ3=EWeWf3-RDNbZc1 zFCCwZ-ezMh-Al`8=f37HlC;10idMwkJPEyu-}u~0!+N~MH)@G>J=>L+qRHF!OsAsS zVod0j9mh9Ap+y#* z*J?tZ6H{qq8-L(Y(HIw#5BzR6Yr8^&-OYwy?-SaV|80fbBj$DQNbe#FcP_3o)Ab?I z{M}xQ(b134@aj-wY$iiLu|zz-u}RpArfDACy%-CQnt8<|ry5`6$PZ5O44GsT$w+I~ zr-Rs<`SjIHaNC{D6Lv>a*j6u#*HMFHuSc=o9=gPp-6=ko*6BI~C@wGS{AN9}ysXVD zJ;{3!hrX6Pz|F>}-H9&G_;3i0BxN-7`bw-E+1T6?es&KWM`~J+#wlC#X7}^DCI>s5 zAR2a4eaTK=?H*DDv6|z`6W#qh(0g({~cuk@(H?%tBjBB zSWXuegF$IL^uReNdbwXTXB%XUUg@srYm75)PqT9KbgO-#5nKt|yx4g7JUE}7;^B)h zkg}UXUX31aM{TG~OcS@cXE<-}$4Ayp-1Yw2Nr%*5k&)U>6ZX4)#nt1};vX|V zc>tQ8_M)TUH(upE>0O>GTH_rfpGZ*G%t-ygu{$meUB`wF2bd9EPewdVr;_Z|cjbT@ zuX*BEtG$slF+F}{9MyBQHfiF|#CLrna&}9r<~3PiZN?I7O)vfOdPGP?wn_iJ;g@^2 zx4NfwX?0`M-bqBS*CIzKC7*q3^U8)dXOa7>QRe=x)3|qpJTLXUk&6yI+kFs>Sl89D zfZ|(Zjh}?Std;1{>ZXl0WcgZM7HX+Vav?hwdr;oYg@*6)*z zax?aHCriJv71~t)xYp-*@epMnXdH5z0_Cx{T@XwRSPuG{JXU87V#XQ%fE`gD=Q`K0Ks zDDrevLRXoB{HN|@Gw3RQ%K13!eZ#BI9-nUp_capvZ5}q{LBq0Ze#BjQBzz{A2)-Li z_XKUXQZu%sak2pC8X@n!wdonWO`n}wvUEnRmRYQavZ%9qi!ST8EA;29-EC!|?KEs{ zuq6;I%@O~1T|}OS+}O8KSvl)uR5!YQd(S_ezxmu~QTNM4-P4L+&Cg*+2CdEgZ#Spq zF5In0m{b2S0Bk{q#E9uOYa@!k{vT~~ZKM-!(mB1R3$Hd8Ex%D) z{CFB(Yziim552p-H*PV~JN&6017GkkwJyVbw$ETMbyw%=_ha(mz5CL9`>#7Zbo}1q zhmVgQ|5A4FALQGgJN&Jp(f{r7HUUl2M=F#_=EZE-<42za=mK3l0y)RX>+M|Nk6+qCEVk zTL-A-)YH7F@qEtVpXuJ;P!At$q`Xlx{N&snFE{c}W&y9oCwJBUd%H6n+M1ABk|k$I zw%?4hFVuEEZ$EGL>iPKeY&5&nOjZBT&3DK557ffDQ9)jOSMG(z&cetH-8t9f<2FY2Djc7A1yi^d)rfL1=R+uJ|ca|N>9Df=&rOf;&~4>nj(?iMKgxm zyK8OWYM$}s8wX7|a#5?{=31dEp#Y=BPm7)4A9_Vp#}oWimX$pgi}Tr5Kgw^y*SrV% z4tLQiM##6r!8{q#%Hp5KV`VTuS#*uh4jF50HKexj`W>y_9ews(@6wlXW_GQXj12aZ z$1aN3?<-M)*EspY=22X`QHbC0Jmcs-Tl63%xfpjPn!UGX`9VX;jVeNB{FbFT3&DEb zUkv9$^D|BvMv)l!n@$jkSzr4E`!`OQmuGfovkrwv0oG)#gcz~B`+B)=)RS1Is2?p( z@3o4v(u@49Da2is z-(F1?o*wJTqVfpnKdXMV)w$Yx{shf7{#hdxDXiXZ+94HJdktH^5WkQXEf@1^T|_cz zM6+fIah{c3?hQ*!tI!!Quh>>IdVZ`Dn}KK6#y;O2%bW78q{y0%S6r(qt+W6M@TW;2 zJ0QNot~}U?Z)ucIM7PN?bl-SOQGpM_LJ!`X6&IiKbLxlVsaNZ(O3t2RiTPgE?yjDN zh*XTRG$e%m!Zpz6*4!9PnxRkE)8OsGkosZARNAS~xzH!{0UE_O{eLAc6ipu17QYe3qoK|RH`+%p~9`9k9(TO^IbO8wVD z<~Q{;p9dOHA06Usj*C}F;CKh-(JR@&T?aG6o9IlMPx07BmL~erIK?}x?x_v&icRp0 zb=vrUYuMOmKkcE23c`0hhd!ywe&^n7_QNv1#OUYS_h^cHdBN-Ht7aDD2e*DM~ zNv-0cKC4Yqypd~h!mZg-wM*k(iAIqBXs6nSFkma*26@{&6rR98EHO0yVy{(n!R)V1 zB_FK|0pjhRwI)N=(P~|B-}BW4q9}W~J}--h&)~<+vOr#9+#@kJeL?3JhJcj=Um)43rCd7`T zSa6b#!;IBjjNKTF(hU9UcjFH{Lpn+eIF7w(ZFJc?I9v>3r2C{V+~iYH5;Pk*?;RAQ zHL{1(=^?U-AFYBr2G!4)PPlt|!HKI$tn$`5F4`pvXtmF}i`2tq;_{@3o?5SJGZgML zqpkPY(UAqe>4g456}5R9we#$16z%#Q3UoKAW1o0SD;2J7bWBFUOmUSva2gq>KcN

kZA>4mrO~XMkvg6ZyycZq)92eO8QB(xUNeeWxgBY(jK|hk75o>{ap*~ zlG?RLtMO1~W;b`?R1)GTE4|bc-xWzBBYIwrTurg}k-eU21bM&R=Wb&m88hmhjF%fa z^tTz{q4D&pCp-pQnH`RWwAn~9hF7ib#`d+cSB+rp%F=x$T(65D#O6@a$f9$v@zms< z;%@U+%di>+O>v()N88RA=qG(lFVm{k91fb<4TX%iv63Jdb^muC8&2l*KpWw+l|TQI zUNy2faWs7N(I5SU0>!U-t!JYi?b`olf$vy4`qdq)c~+lqoT1K|Cyh$~j(liu@J?fB zireeT0WFVrM&oqNj*ZuPzmXU8@@v*)b*QAxUeVp-Lv>YKTIsXl1d(Zx#Smlf-L=|J z;ES>bCer@{Oz|Je4qN8}!oale&YPm!%xBXUok`)@z|liBv~IQ}cg zKY9G6D&_y$;ivQQ|3LHkOUJK2{_Dp-oiG1%nE69h&;JXDuRnat;oqu~{!&){7mt6x zI{Tl^hyUp^?LV9M@kaN3@bFs?Uv>D({{4;R*zayO@b0gbkN;$T#kK7Eua=V+SyD4D z>Tszj<>Pr|?=7D6;5@N$lWRTqY`6t3P+P?xK?}bAR)pRc61-R&n_Jyj3%!8GaI^>* zp1~91oZ^3~LoT$&&?RKMa(XJ2WPdr%Q+RYGLd;9NMx=mz;eA?wmKCc*`N^X6)QNnw zs`MUxw3k}O94!lqEllv3RPe!85wvn$eBjBsj<>Om-zet3v1X(9}Y{2NK85b_* z)sO)CUVHAr>2%e+Gpbr${YNtWLatI zWAw!RD}_Fl)uun#f0}Q4bSG*Ih3UY>>Gj;x+ZMXft2B+d4`sWiozb`5IlO}kwVM3* z9_OTiyS6rV`kA#`^s}w6$AyZt9PD=*JHTh3U2oi{_Jb{L)>=JTjnzzOYkg>xT_c_& zj%h`^JN{{0vXbKT`~+OP>u`#9Xkz*4@|$R2gU`gfcc`Pj8YuX zYj$&WC(W+Mu`aWw>xC_c_}3bq=rxqpS1tM5)tZ&`Nuy?US?}f4jaZ55%Apjents^s zl`)h;e^hhNV3ryE*uNS1Rxhv)YavhUPj|si#xZ)j|6xPAcq~BA`d^FlGb104o6lYK zXC*dzLff!S&>v1fU;i%O)8=Sk{pb!fM*-5vM_Y@mw_eS&`X1gIs^G-MH~RemO+d20 zjO0Zv^I03BHB#j%5=4Tn>uM68;1PLJ2w3k%$0x&Yqkn243dB2h5x{C}t@W~sW;7g8 z`}7%pv=Zhrl3i>3>$qaBv0$ie zZaDrF52G&xfv#}VdJ#R@)5BdpudPM7xN9T`m3q!hU_?Ee!->T9slHE;P*+62PbF;E zot&o2W^Ijjy`gPmlJyXMNejk3*Fl_Qb`w`aNB(1{?+$5 zX5_5QCr?~^Y!F?| zYcq$nmUzh+);2;&Yi%0ejKsCY(8D*=9{HgaaI&$PFBTWgO@ zqB*Ul70*tDt=3T1de&xG3EondoM{Y|`yjz)$%SM#;b^Q3Dy%a3S*2u6i`6Vx7#~R1l19l3A-1bBR@GmWFh1ve;vC-o#be-7kP!oSI>ZXxa z7qi%82Bqm=+T49xrL@v+o&DjswJ)w(vDJ{~zWN)rjJGzrbA6Q2{WBU@*V7Q0;(MIX zGv28NtUg?YLvRA=fIHVS#_KSP8L~~*Y>-;7ta!ZC{WJc#Q#&JHdL98=32^6nYa);; z_BRSo3eA=+S$?3w=@a~G4)J$aPg}D#;?#qndUoXcq$hR)^Y!=?ahyB~r z=80x>IUbnLyH{KNG%A*n4qGo~Tj>eUPXAhlj+Ucg6w%DZTPuaEvxp6@G*)qa+%ouc z=&&)+p(Oft59vjJCBoyS?%q*<2@rFSy5@8sd=wQ_KnpZgY9RL5nYY`u-fF=Yt1Zq z&or2bTO86DtQVauo`z?ZOVCCw(ApighWBa(eLC@&TEb`Ro0}C$Wer%CvBjf%S=G@y zM$r8v2H%r{ny1w90VHJ&jYN-Uw+4)#Ch);J1`onvZtEr`|Yww;aH}Q1+SAky}S(EOv-(GbXjje`8#zYQ6g+wDo zcTYExXKMWuB&qvlF3@#3Sv9wvcGW+0*K3XBa=DlLq9iT3Q84@AF87>OQeE}y@cZ^O7rBx4BlPPjkpWe;d!i70 zY44aCTl-4Y9I^81yl@ykL`T?(*AZ^5-PdMj>Rs>eGqskaj@D;6RDM2PHtC%*NL5=k ze>=k-n<`OfT&YM>QU79;-TfoYX?|&f2g)i+O!7>0Cy9j3SXW%YdfwDH`Cit%%DzT=OYh&)n%otQ zp6TyKBYEH9y=BDJM4ysYN$_Y+!E|>~QBX)9^ew_(6wXL<59dC|y58XB6b21OE zQ&%6>>@$+pZ>xAmHHDA#Ni~-}*)IR?#ZT93x3k1rvyYXzdu3Juz2pr%tuFD!IO$x{ zh5n?ZnxQ_g0iE%i(YzVuenXYL54E0RRp-0sw6>rAFt%5B z&OOWjo|Ag|^toDiwVt-RaQ0PqO_X)DHK}QKBO#M>87ke|7*!}O%BPh@Q+K~DE_QOl zRPZ+rHF{3_R1f-Ds~JYC_iTDCI}eOTI#;H$v$$rpA8Y+?nK4^myi!)P`+xTMGrj(X zc07OE@dt1G%#FWxeB}5e?P~t$nfIUhsub@xAOF|mqc?u>#t+{3|BhdL{GLYgO@|*o zynW{E;myO}IQ+g=^oNfB?(yr6|K9O09{-EuA3uI;|NiZ${>4>L|Cz&gw3qt34}anC zZ$!;At=Y$pKYsk1)mr~RXQuu2;}2I;{d9D9_TYP?_6MuC{%zG?|IWjg40nC7^}Ric z{_OGpJ^sDUKzll^^sB873e#YZw3qtx(g@Bi`%qQbUtEUP8CXz^b+8xgO1+Y>-91FI zWk_+t`w#y_zxPDZc2l>?>K@^l#Y1BeNpW{?&Xh-m%dOBf~rpnWvA z7uSxAOSNz30S)Pts&mo)6OF$!6I-YC%j~4GhidEE?;8y+hs?UC#o`7Cjy+;4afci} z&sS_5Cc^>hgYg+%zfp47gY8?6SGP+8^V!XnW*9rz?X;PF40@5FV&h+nZgzO!^Ow!7 z`_%fff1=K7|6fl}KUodk*?7zuV65=fkzo7(@=O|;+&IcF7P9A`#`ip5OP}-@E5shW zRKHt6NvH4Li;2&5$JRT~KH#p&#Gh|gi@fP(NJQq{KDj+*RXy;t_VaYVGwf76vRjY> z4NkkW=IZI4C3&{FW?#{FK6e_)&Pk2W<{$^}H)4BkXfFH1CYKlGU^+kSqaF9or4-NN ztKn6aR)ygGwYz=;-KKK+9(KAXo{W0-+peV305oTHYD3L;y2GkmOiJvcphtM8>Y-I% zi%XIEMK-rKC#T77zq_4DX=l{=u4_vzw90?69@KlbcWA{EQLzsP^2_+$;!Nx(dAS~+ z!6f9^4jt8R@5ICk4Tr~DZ6u7sM+t+}< z>{r~nYwPbcR#LyGpOEo*GWycvW^-%Qan{A|?{K;??2BjZGoerHQlo|VBB;;*4Iy-& z^P`>DU{~6`&Fhuvh3$4u>7_<$2jjC@zope_{LPBp+xkSYX6dBCTjQ#yXZ?x=G`8I{ z{$`XWD|{|!!91lNw_i*RIttTBYIpWT=*5hqgL>kFNv|C*aJdtRXe3;$Hc8x4 zgwJ|9LDU|IduIgj9vOoyo`*qtEgwQlk$rm*SiC!G^O@!d4LU8rNN5Or_fR`LE=0K} zyROz9ZhR@e5^I95#K2U7YwPXW-Yknsk=Z$1|4tQRVer{q^$Yzz+wAS|ft5u5CJtUN z;`et)%?q=(FV#ohPR}e-+S=tCJ!L(f=~L(zAG}*HcA_|6C>pl<>x<(sc7YCgG`j^G zf2`+u@uH`!zlsSvS!ln}i`_5IbGqAQYh%V==_w2X!)(47`xFB%_4-ZT8j zFrB?9Z+8tf<638@*dJOw92b9txcc<@MyPt-N{InO)3{BPUrynb=KhJ+n%p}dv(x+P zcM&;k_Q`BL6x%7gwTu#^neT0f1$(pDyGpCxu^)Cezu2GMFQNl1{noY8UvO!Fc9!LxwUHg|zGj-{n;dX6c0z=m!gtjAr+WHad}MYn#KBJeQ*AX`w6>wI zrRhc^#X#5()i7-9TEg?KpFO}d9g7O1v8T^=*ZU72j8u~g_a>LP0LFZ~)}D^5$%Kd-P3nwK*hq99vTMgxqdNWNSJ`uSxx080;u2OTyV4wZ z{&r!Jez70>ELYjoX$TNjQtOahG zD8;M~>GTY?rePhlxHrlBqRu*d zFwU~;tVnNnf2xuGd>qO?TL-yJamYuTVduWLrmC$k_U_?Ugm>|3Be<{Y_r*7Sd04Kf zYtNlpLcR?tWS7KNFJ@UE>KSpOV>I|gIGrZf-ueTl68B&+hliTk`j5_5c`@FH4CwIP zl|V~ufN9`;kfX>JFn7YoX6ZqmGo=wZ`Uk)?d%i zYj7~V1a*)dbZ~+j@BGcy=BdsvxUK#kX^-QT^x3Z^ha2lvW@FW6&*I!kM@);|vlvuA z`z<^azU-FZZt%#3}5gI37(t z^*z1c__mqscOTgCy}D3_3k{5Cd1kUXGbg>!K+ux?jv>nKny6q;iG%Y^oOH%tacYLE z=rZfj8qrW6XzedI4;G0m()iE{3yp%1xGWf{64me>Ik*~vexx3veC@*CB-r_pd7M_m zd>ivdHJs$PSzCM$G44FbW;nxq>S?2_bbzt?q>+SbmTgwWNjcK_nq-Gg$|SShw?afMwQPYj=vRT-c9XvBjY z<7#Mpc~;c=YR~!ZlADIVp%#{iKd|3jp+ZE=l~*9wBf~`hO_giylPTZi06n73)BttA z*rQ!0YYRPL=cyn_-guMjUwxc_y~sr`FO6I+x@5bVnzJv~m#qeWPW>8)U?t?L$gMY^s9H?j!}_ntHmF&E&7qWvn~A0xjaiN3vZ|7;Ftm^3Fo-wZ>{k)wqOaCr8dO zgbi>KiLJ#(4&6dv{D1bIKT3nik<(giiTs7^g)@=tRu|>C(&#>r96VM_JYXlN7{7f* zo&AX8d)_y3IJIx1Gw*3mqM>4{JOuhiE`nEW9hXXb2B6&fo_iycBqxFo#aMj4I&e;y z7+&O?*a?KQ#dXAKpqq)_#7XQfq$PgA&d8_Yc9^8>N>q3}i5AOuZU;XKy`2RhmIOc9 zU2fbE*63BM-)Aq?3r|&sjWp1!?NN`Low4&uw&Y{+{5!Sk8@4tphQd6tL37$`{^Dm) zC@tvw7o6j8^@NHWYnV0Yx=hE|!)V6CdafD3XS~=vn_6*B#KX;LxodY_lakMzEnB;^ ziI{-TMcq_c(BNW>V&k%r>|N2a+J>KLz%2Jr4sK35n=dq=a$v^a9jx5uQurks6XXZc zpseDeRVY*xkX3+Zop(awAxC~J3H6Od?5*gkJfYa*wc@Bwd%?H7z19}YV`(u`;walMI`)`s)ctmt#|%ZtQQ)^_8&G$sj_zoeu3h(zeVx45lg7liSu3DNd>3^Z#m2{9YOYN+TnidG}tf*shVW`CZ)@)8<~-nA1Fp zOe&=P>y2XK`cVc(WFtgSpdeO){*gD;Hy>qR<1X?qA~i9o<|C8yQunbt@xlBnwnew| z`ko)TcJ2$zKubcsBw|mnf)<@J;ghqqMx)^>G{j@PTt3ukl^1=n_-DBVN-_3FYfql~ zlY`5{fZfN^Ztjr9hXGh~wDAienfqx3*Z6tT%Wt?%Bxa*@EW~1Sh>GWr7o4FdLQQjR zHd95Ws2(psW{1UR|JSlQd5+c=?RO4_2n8J@6R}lsvevgIHSeztkx4r9CA`(B(A_$- z+>gfXY!TZG!yV$Hr;WoLYjGo7qV8fjIDaL<_k6)e4@a@{(O@b?`yU^#ZCq5gkq^F! z*uPu}uNg1kQhJ0)@DQ82B%Q6{*tEL5YC>pSHV(S^s7Ly>UtGt^&g zt9C~p&<`5XidlnZ?ubSpr!pG37U+$79i4bdt9A1Ci3EFe2|==0FreBum^yodGN} zwKOxM)~zd_O3Oag=Z}^DeXKi%Qhokx-ubWf_wlqehKsXXs~li8KyC)x-6 z3tfMjZGzp41_GtCz~nh`nBH4?Wi&K9gY8V{_U6Ke}AaV z_T#PT&^#JHRqH=~{9Elu{>jNy<1XJ#!2kY0qj6T)Z)rqdRA0WmPd$d*+0ALRU(G-M zc$^QJv+Vpq8A9=%2YXhY5?|6Q{7*5t#e=ZgVMv-u>05Czl>?+<``}SKN8BeOG|nLsW5l(x++x?{8YY7J#C&*8EDPU>Owaj- z^-3amZE~411AC6k#o9mzdFlOr0J7o)S)9UZ%Qrb+kS3%xH{U4}P11~Z&zAFTKji>= zzgBg0Ve}&DkmXbH&6~ac+|d@_~q4u)8GsicB7k~I&Tb?w1Ho#cs@gMnBMRo~=B z4hr%Y-z0I)w3DNQ=VYZhAJQM|DwegU0l`I=k~ZgivV!6m zyfqVs;|xEbV5@^eXnuqKE{t=zIW`Ag5jmf52I9BCzO)5|EinD!3UJ!Oe?}YPb>a zIsTt z%$pkZ6WzNpH8v(aPz(5z-^0Ted+a2R+J@8R;5RljoZKgy=e81f(g}^Hk+kuLyJNE_ zu+ml*h{o|%wibijMYZmNMra>#Mf?mUk`7cUPZG^x12Ixo=?V9D2Q8)UW@)2-bN$xU zS1K`@cYX78%#BCloi=C3^t5Mm^ad|ome+Tw*riVM(2V!C_FKh4-+r>*uhuh7&srJx z#v!zmZfNcJ2r3+JZme6iv6)#`myYJ8;P)q!x$>gjZ?14mQPn6(my1mAnSm@I&AstN z6wvGX#47m0hh3-D)S8ortV<(#Bo4XUy!b7&!P0X*F7+I;s5~?gR443<#)*u>!t5wi z1+9`dHCSs^=+C95xT<{xS-Cz@bH)yC?FbZU&N4t^pkk3L%Y0`imP1oK4IV8Y`|Z}A zCR|&*-hoxBuUg8puN9}n83pd$oaL@)BORWSdEiUY^2RRWu;0Z6Cy3&2wwCYjJ}1|T zUa2Rbd2y7O-Bfe8n(&p1Sk;4eCGsalw(tacEgsy;ZE@I$4C0#U{BRvJg9X7@YLJnWPBdjCcj5jfck zwLWT{@XOwXzGQ^{p;vLS{?`w=XI4-yuJ01+36VB+R5*@KRWF0DaW*d6I6sSt4*H~r z)H*B%VQ-UXcaH4&4gj7Cx(q4tyg~gsp!TeHV=q-xAwhba!7m zS+-LIj}FNu%~PzKSi1QdGhDCwN|f*MECFrS8LGpXFebW9rl2R-?j)>sWWuZ;JG!+N z8@1TyqG@-tJY+hJxhppJ~ zb?G_uV3Wo1#84qEx*;pjr=%Cv)NbR#@lj`-M(gQ4^$ET6)n~S_touYRM9A14G=WVZ zC2JZssBTRgDCcnaplEm@JzX;p64%%SfC~RthUJ-Z*&Z1S&c-aEzaL; z6AdIn$O5TyFdtZM5j+iPm0(a*rZ3njGQQeLgcJf@FV+m#6aUPP=9wja8|%?**i3eS zW>v8$E{USzk?4cA%Mr$$j;IAZC7X4!%6)ER`l4$f#myhEBkY(JgML*~&iZyQDTO>x ziS>ZFCX&-Tej(b41z2M^lU~s>ju3AVU5K;#jMb&lX760rjh1!XDl~WiC3%JXgQY5* zp?zp=5wrdm&5(c6H`=n?y~b8c>Wf#i8z1?mjmV0uu-JsQR=Q9H*Xj{{#O3$^ zX00F5!}T{|=*eJqReX}B5fvN`noo=r{v3_c_|yeon-*9wlDD5sCT@C#RZje%#>C%% zE*7)RJ~mWuOwqOR;j;L$zeW81C-pdDb@rf!q3=ctSN3|UIjzU%ylT=4GjEo`ghj&ETuKllLUzOpaKgUU!8Iu<7f|@DO>9t5-+}S(KTj5%4|aO^cx(>|_>r zg4ea0jb`R2x{h1tJfS|pqbK}oRl0**`1UL7$nUX+yV`6Ys*SE4N)Ol6R;W{-Q4?i1 zil*9XEi{|4V`D+=0hq{KugpR=1V=AFh$(Cpc^IWTSO%BOz9>@NT9Up+-=~@#rD3@TYENEsJ=#HEjYiGabM>&4Yx1hWye6z9M zaFMaAjUXdiKfHC@xc0QKl^)Ul%}(JQxv_~xM45C@KlpI}6~E+=sy@HeZQ|L~Uj3wyx#(h1ZHJ?r#ZB~fBYxQP6wcN9Mg#ziQ^+)|rrlB~9 zdbtrsP=hu2q_*ktEWP@~dA&O_u-Z7)XFd-MVMq2z$BS-qrz-acjP71p~w^l9R*jge*L5uplQ zzB;j$>lv%D@x6^T!L+=&@Mn$D!h8&)HlBx))I-uN?`{ov_w+XlqFTc4!r4_*yUPQ# z%pjUtQmeRL1#1DF?H(gh3$h{ZP6Oj9*KtA|-XF`W8eLDatbS^_PspY_a7YqZza(Jo zFD`S?cXybkM>y91F@<+AgQFLJL`e;Z9c$UjE|nt-bP*MX9xl!JM{%spqU3u zV9&{Ldau+K_^zu(*c)HmwbIXK^}2u7jKu7nXu(gJ7;-Cjvi^M*=l0a%j6nd+pFZ7K zHQO`s4LWJ4f->We8}SLPtdh)!{qU=C&Chc%tGiY+w_+!&WlrKJWRi~8s#RYJr(yi? z=fx^~FGaD8uF^kax2I)XXT|LZpsUm|;Ns0b!oh3nrgl7@9PYOk!?lZz)|cUJv1r=I zG105L$)y?xz5^R%-dnFM*SG%U>VKR-&-q=AL(h7iU$+@jT1p&FeTFyydeT8+h-5ll zGQDpVF$vlDG8=q)Us|x|27P}4+?7PspZp0Pp7o03pkTfYJ-}pS)7Y-sTSdkck6qK6Bmm71apzt=c1r*h9uuK4$ijbFpMk(q$eJ{ zo-}=lO@1mBcTbnDb6r8kjF`UttaRf{xC0C>|R7!EN*!R+IY3Ke5p~= zx+;J~t?evuH{6C7*yJ?mj1`)qCsYsEx8j?*U~tw#^m8?x`1-}@@L+$%C>!5eIvUj+ z=*u@-HPKf(9S#*W^zBZM)b=8b-2nrQvgGhJtp~kKjntqZ?fEk+GV8tv;-*W(w;S!S z_lfS>lO3LmbLHbzG2)fQuB^r855k0fc7Ln(SZnZ968U`hvwN@PYub-Q??PL?^-T28 z6?=Ua9pYSCW;3Te9~>>}^h}(Ew|LB|z|AaWWqBX6sq8t$vapkPV(1#roRsx3(A3F5GHBqQ6>>{f;&fC^Al$kfNoj zS}QfRd=E0dnB7{k_M}zZ8|Sis_eXaTt7NVp_o_3o7LTN3Kj-k?boLX+|Emg{7Y<*0 z_^HEjT{E@y#;Ex^uOy3*$KeXTG8;}3;@sIQ!fFCbf{|%j2@l%JF z5C8b^V~0Q0X%x4$ljnPmf2!Z_?E44)^W(So?_Y19&C6+zf37nw{?Osy?wN0F=g%K( zKhFDGCBD=vt@zI!f2?PJq2FI>N6sf&lXAGt@Q&v2MSXMOmsEA52FT0@IVMF@udO~qywtvzn1 zzhu(v1?S(q*bMEP-Me@KypfPiuXuzLxvrPfctHHv6_#A>0N;|f47v2&=Kn>YUzpep z9e|E}9zNmJwTztbAo#iyhbBrRCnqXn717XlT8oT`7~pMMjMuvRb&bi{IchI__s*sG))`79 zSbT04i74F%h&8qlHP>>h%!Wj?uTZ#&03T52kth zws+6e9#85dqTl;Pzjk}6Yhhchp86!7BAaHGqUwtajMX|v8LQvBjnV8%;b!(xzxZ)H zqSk(P7t{u?M4VU@1+U^P=iu?QQFt&eQ}J9fm;j-no2@7-xW7hljA8=EGh z=5S|RCI7zp2OPh?Drpqsb&@fZW5lc|pI0TwoJjK-9z-D=$l_RKk(${Zb3$(;h0EC> zs6b3yJG>|;oduw=*?`WFMbg%BjOCkyo&LX6(mRf(GJ~}zEVKl{PsqVu!%jeJ1;&t)jl^V${75*2XLrz$wHHh76vfq>O~Sh>xb(8$i4q0{t7 zXFHF}`A4dsHm*Y}T?{Vet5orkJ? zuJhTZM@C-JV30*v&O)g;$S*cn|imzNcQu^x7X0Ddz_~-M?(>#x)`OMhYma)C!AGEnVp!kDGIyoND#pl{s(8bq2>r^D4gP@U5Lm`F)2UI{Z() z`sz+0dc7S%-(QsAPZtUJbNTvzv-2jOj5cRmzYpc9|FfM(`Mdi4=i4dNNdb-crpEd! zon+D3nfdlkVo)ngCv2|mLj8PRr%`@k&o2^yRo2>x3-WTF4vFlyfZ;n;gHFKw2*0I1 zaKBS+)Kp|^d-h5+`FOqBHzRVyzqq5j`p)a9iQ*4+Qpfx2(OI;7SheD0v0Xj=vZQp> zS~kebE6C>VKDQg*H?2EKie1433bB@}dD(RqkdB1D!XVv0wW8g#qk<4ltad%a zHc<3(i!)^4cd~+(W>0H6<6`z7HcFdeV1%di=!`6Sr24&tsRdWb5ER>r4-+^y%kh6}KXIGdU}lkhQ#^ z_1}78nv<^HYyrK!T9);N^7wlC_PP2<=uVx|XxizYzIi4}*(0Zp%1%^uK; zBYZ%IXRGH9*%mg6_r4J?@mY94?6>N6^KS$^cRFe6ZF+X)5?@#!yVLo?OR4oRNu`(( zUBolo3I+5--Kn*0G{(Qk#XdigKC%a?c$Uw^;)@EbXJPiD&7{JPK^kQ$wT5!|VY2nL z%qw-0j`$J^n>Sgc*Ko7lVIp3erRGbBtF_dIm9n3!FsIJdp7=Slo02} zYtTn#OCFZ@qwZ(@W|6?f2u|j*mw*(o_j3Zr@G=bSv^x8eR?_W4b2?IS*hZf`&I-t& ziw|Z;c7~VER;`{FZ-spMlC%R2y?oE+ zu}H&zLuZ;e+tF*XK?;@%VZ77pePZ`ME*qKd^TpIo-L|{t-p1X@xvi|IEz7G))$SY7 z6`A*F(dZThI*Y`Pc6yHe+4{@zXuCUU?@1@a$k65+S);~F2Ro61cP_dmzWttJ?hnsO zle!`i^_`406K5(ovs&J7xT>dl6c6S<;k=E(?Y?)jl00Mr)@!>>g_rl+m-w;_bUj!aVF$;Vs+WN-|`-MH-&&R~}V0 z5=7&K3m&StJg-ki_hPRux5|57xCk_TfL~Nmtp7`r@E1C3#c4qHnBq)zwPM5eN~^|K z5o7&*kG6~@eI$b2nd$LKF_^BC2sIQN6dzLcPEYhbk zkH^G2q!Hl^x-Zl*w6fbD?Nnws{|K&9$8fICWqPw!Jqh*FC@*v`pNfq`Ss8RYjO>?T zH+GFTlK~lvq(TnQG-7DU&ccT~{m*xZhz32L7hjg8YoZ*_96!;z+kJPfXXTR3+xn4G zUO20?nqFppxs1(&3Ls||Mvqoh#Do227vvP(buka+F*ND5Oaqx-gkuHA7PT&F%c}@Tc04 z-P1*OM5)l0Pv$IcXSP6GkcK)s*(y4iwr1Z+CL2InjuB~G`)*yfCW^;K68yiF z80zCu{nvXAMq8hPmogFW`q}f69*iTzm*v9MxYS#%@@$|j{*pYuYz;Jsrsisms?&+u zBlFE$6&HUk4Nz||I{u}}trad{<$Z=GDz4Vw96zyn(*f364Elk1!I{Y->@q%fct6wq zowyi(qX|!PW6HQ^Pp`updv490U!USG4jJmB1sjG3q$qk*6;WR z2ihKw@j&HLWww6d_;-(grw9UyWYfF;Sl+dBDE3^u$MUp4H_n$I5JMM_6eD}8Ij{_( zjcgPBqVDFy(Of*4Mclo4JPEN&r=Xl>+hC`2`QV?|6P-xiGmn&~7UOZ6jWvE|`r7wm zc=tC3r+SI3iVVu9tA4Y#P{7u#;!zZk?eh%<&kmPBrR<0O39{B=)Od>j>r4<-TExPO zk=N4>J05b3BjO&v(RXbr{pds|QG~lmXDy2`!vT1f4O(A8B;Kqb^jD(CrRH!)@8i1e zfsRlKH<<+tisNM<`#zh|dNhRSFdXx#sg97-l*Lxb!uF#wOZ?zijQbnK;J9XGU+kWb z?2HrV_&Z^RZZQ{n115B~r}*T4f6k!Zt~z1$nbxbBOy9T(7UVOC;PYL`Eorxxy68#w z`sSO5<19LYjOMrZ4BWwb?LO7baHB6&ZL}ok)A7_+K88c1!~2TP*nM(O{P>ZgLyxEB z#k|>j*a0_LA9e=+p)-uLXFpdf)M)N$W_Co8Zr?DnXLsT$m=G3YCGfr2p%^xl#$&@} zsulKJ0vyF2Lr}jX#sK&7}@(9qZHU>Qp zhwve-JshV$*;U^1dLDG4m@Zw$8-)Z^FY!8jmzDe}TH?&KP9vCDNG)uhZT(8SLs3^w z0+&PZIMmK!b#Lj~o`ibj`(BSSRc4q?cZhN0AW?13g1bUU-Ha;Zin>&bqDnJ{?B3s@{<(=nq~IU(&D0 z3Qt262Zl4Ee)``kg!-FfRP27S_fG0>Uh5~aSMmeUCGEoIn4>rVzh%7YT7Ic9Y~*dD zBQi#!^*oBr_^G<%_rR2F1FuB{2VNzE{2cYEp7=~8#{20*_JUr&992n%C=*>t$K0Ik zemo8EWSjzDOqFWWV>6u*SO$7VE&HTm-}#E-YMrH78(R;zk&fxPQC+APoGzn_!`A++ z{^LKe9AeU20fRGNYxdWB?)^Peo^UvuyoWKn7Ye11A;IzEW~B5Xe#2Yr(^ejAHdQ@@ ztfCbf-mgV>Lq}Q^7uh@bdZHWTTtq^Z8Y!$U2DuLGh3`ao;Xt(xgqX%MKEQm_8k*%Tn)7i?GJkwgz z$D4N+EvrTCMNjrm26;95;yC+3MJ(K>D*NP=wqBFkjiM~CtI;ubwQp)VoY5kp)1MZ`mk`- z)H%mdQ(w^igZrB+&dIWOFWwbfP~*dYTAR$b+qtU_TTQA)Kx}Hin@a5lp9X>zBa~$n zYjHL|>#+6j;slF)RBjikZJk+ud?N?2`d5^MPUjbrU}#)^2P&j9M!Q8JTHpGqTV=_` zzWJW~81*GZv1Yw|w~k(RM`t#;`)QH2%ij2|p|YFN{;B9`J$XK`3;CKnd-IrRYVR(@ z`PtZ7fa^rFH+IXDp^;UzK}cJZ&SSx2YP9h_k4&`_&(t}_u30y>t@zT+Yivj3TpvvT z3Z9A>3Ex`#YNMcBdTedHtmVd_llECb`h4Rt)<)i2EwYFw4QU-k zacDPn`=YfQKa~HQJVzrCZ(nb8z53O*#)IP8WPhA%AuCM3ZANZa2Y1SG((+{)qsn@$ zB+$8>Ms8=UJvr+BRhfwdi+`XtyX5HDpux&OBu(ZR|(a*Ap^lloe&On(&C6 znyB>bE9rkcFNc7eMwVwwP zzMUIu+aTS|u}u7K#&4c@YW>VbLNqjg7FH$iVihnx-eiAZCi;xMJ5#5!GU72lGcTxr z_X+Y_a1d_Yb*CX=Er}P7$66BTTku*Be_@n6Z$O zbVaQ-$LWWqxAHihCUdtH#`o@G548>bwAMW%r&`pt&&0+zQYacn7x6AcUU4&D7#GkJ z*_;_a+v2{>3Hn9>Csl>gqJU@$T*F4fQ!?I8&EfacZ*+wSs`2gG9lPc`5$q4#nW^h# zJr)PEA^d1@A-L0;4gFiEJgD00$LRV`4s$D8iqtmlr7+#X^Mc-SFCAYwP40*$y4u>RAG2p3iW$D{Nqy)Omn?NyMz#hmpm|t)=SVa2k*$eyg-NN1 zboy;5F%~B}z&!jSbF)_nRu#ugyL6SUpzBZ!4&Ta)Mf$5xtd0nedM*ACjqWayA?IQ( zf13^Nq@ToGWF16Teea4m+-9sr-&ki6&-KfAGVUA6>RH%$G8ny zHgZ^6fSLR0J#Wq(vO-2@{nj%;6&akthV#@`4v;D5u)#s@r8A~#vlWH`<$>r@zMN;R z8}G|AYvFswv*W=z=Ug0*RfCDiD=%{6(Bi^nGMYEN!oOc1iH}9c+uKZ^drxQbJlBfR z0%E~*hrASz(6t?ryzY3r(N$d2?%WTw5_}C<7WUY^-y7?kr1a0CgJ(A`kosCF#p&Nq7CortKsJHPU!@yGNI>9BQjlqe~>tBQiu<14cz6Jv$CPVUJ5${*ch zz11t&HEECALx=aqDNgx(p?<2)Z{)Zd#?=x87G;LwqBW#g27zUn{N``~T!Po>J~i&V zU_9d+X5k?@Zrnd8YPc+0Rcm6)^j)(z{-FaLY?jL_G%M83tCtVp;fN#f#<$|0gsgVK z&x0|WqX;&gfJ^)hht`(8vsZfOyBbcor552+{6+_p4;4ywSE>4;HMYV-rG_=4clp;W zg*L=)WZmEv(kX_t`+eo!cAqz?Cdn+goxaX2c2b5q7THC!5nsY_Y^f1hH5vn6fFH8{;?Cdf;2IFuXRT#H%O?u3Z>O7uU(rWTL|B0VA?X2thiPt@)dyX(+) zv-SBWQDt{$JJG>fk_%j4oNs6|y;y-hWdkv+?P=Cl1PbTK=x%%h>XJX2@2H7B zYRh0HC*GZU=VC4DdmoNJc{li()=JydFQ36E@u;Y`8Vg!RrMaslk4}UIJj*M9P@Ptr!~( z4s%=W!Ap&SS1~n%^#VDZTGm#vnJoHc;p{sLKh`S_<{g_UoNLYY2eO%}rmp0p^~VOX zBkQb&XFnY<9+Wg{SvIt%xequDk}m7%eR(09V16XpDobFr3b2uO%c; zo1w9)6BCSE)mY#w(GI)V;#e8ol%=bSdEKUMdqw0+R*Df339~8c4DsjSXPpC z+xWl8B~4?M>1j525egl*zB?2KrIV12qCwVO>nT_d*EH500D%$kLrj7XHT=9gPrb)mQdt`=D(0elnQ;?y?uJe$9M{Ekb^Pu)C< zYl&BMYJYLI-x)(s;ydzU&&8Z@(->*xs4+dVm}F&7*C#1-GaWtDu3gz9UMI{Ojk=e; zL0J}c^A1K1%es!%)|@X-1~v|X*TtvUr{x<_o1W+{+5viCpJ*!xpH85eXeiu3k85)^ z0DC(~ZLTlgUClyE@wMrvs9tMU3$NL0#-k!r^op`wWfY@3pa$ zx9U2?06B;Z_`U?YE$m8}Oh&E9REi+8S0s@QWW&~u@foa-s63h771!*#PZXMl6jzv2qJ}RZf^FR%vus-L@ST$(*#a~0or5aP^o6D} zpr_SVtHHAPt&Z!k;YNUQ^H_^Ub}GeiRyu7~k|fcTaKx?|1gsjM?>F>WcgbPn^|gfX znVlJn!_jfHTpS|ih$BU_XcVZ3tn7YuSz;rGMy;-zpL?Q-8k*G@ITuD=$+{m2Mu(IO2s_b+isg;F&qSSJMBFN} zh!^qnesdPzadod(e3P%@ty|Nh) zCM#_pqxvHfgP-WeJ$Z4@VsOXq)updQ8Ak@|S;hj#7y+y4b9siX_1!a@pbXJR-zPu| ziJsBk%W)#?c8);0;=QwHt&y{<8~tzfYhO%S-}ntOSWexHH;FJy^l{csryKPNTO-Oa z=YB^OPsm}ZZrjWq96+9og^r`MAyoN6^Odh!-+A#b4QQlLw+N5;zHcB`qrqno(}&`D z8B^oior`(d5P4#DZDBsOi!0$$+G z|D~zff{zw6sRnZ{j(iamyb&BVUF--;LBEnSv|nGD_wLlQt&HA^viUyydPaqw$?Vw|f2ZD94lTUN(Rq=2Wtzd8h$d;|P*LTd9)J zhF{dMJ}0eB3)V%jd#o?mnY_OVNZNmRs-$3`V7iNfZ zCzdzrvu!kwY={Ww?kf;qqrXY~?lRxCF(SB#&VU=thDR2^4Nd75l8N%@!K&~wCdbx@ z#v|`N-sMNIJ64c}u-|}&jSlrfOS|Swg#GS`Q;MyJBC4_VgL z^&ciS-TdWH`BWSKp|kfi%lKlbfgYm7Yyu6V>Q=78nt3mhMq|PqTeD)ntVpue?Fw9ua@K3$maIonJASvAICHtze_DqnuCDXZ1O| zziWYAgwYno>JQFB%AVpK~F=g^{TI!)>6&EdnSc-pBX_UMQ`ij=OT zvw?f2omIqz8?jOIBkmwxK35udR-xzC|3pz%M2s9Fq!UmahFomM&anIBr#6OrCKoYl z?>iS&FY@Aihc55y&a&*)V73mVg~q@Y?7j83;(lnQwb^td4I4cgwOV*pY1U=el|MK^E5>b{6#jM!Ik4Sehwx}LUx)lp8JsAw>M3T8G&_lX_sZ&KN( zr+Zy_j;vEZeWq?;PXvP%ARluTK|ZZMS^wWBGAmHYdQ#|5tDVFXTIcn#H)=zoNh!~8 z5$)D$k=j!v35TFGjV)S!wz;+|sZWgKdgHRwjCYVv*qw{H=r>lxT*akkg=#~c{pKu4 ziq(V}Lb|=it@flXR^K!5@VBTB>|*9l0T{2c&*(QgLqvC@ArSxM=;jKaBOTdD7Uj^) zkPxp`j498p@ohw#-8aYevt$~!R$euho?*?&OV%SlfxcL@&c?}Z?7kbmBW%K-*eI;X zswnGv(zs{mj6SHN?oxCOzJw)dR3qMf9wbmLrY!B|rTK`96-4XU>MVVu^Id@O6dle> zrc>6(Nownd=2Yd848#SmbpLbpN8_#>(B5pmJTPe_JN8BR#yPd!w4F8}X}nB^S=+$_ zGkcLq-v&runAu`eoT>kQ`;_h=wPa%bbozTNPyed7$BR)GZ!`;b+^XUgd;nuY?6}w` z#w1dsHafna(U~i+jXfBP*6Y=iqNSu6UKNjEGe-Y4Dx7bvtRtO)kD-4WZ6$OuqTSkJ z*Y=61c@E?Djs<}!_-v;(xG`(LF&ZhWrj}Axbx-nxhoCrmmF0f4%7uHIBP8Fvdy*aZ zG^-`Q#k*o>tv@|TO2rBm$KXe_g1I1cD|Mpp>;Dwn!Ln?c=kYWY!}ApJq^o@HUR>uK z6h6c95-VW5CsJFlG@?~J9f`FPsaIECrPHjoQ(I^UI*@+gAK(Y4QOXd%*;_V<*HDZ+S)2rDJoLAETR@f0liwGw1Nw24NAbU1qdMZwFQ-5G#GVjH1QmKbv1 z?|pjCPwI`io;+gagx15BMdC26dJJ(1p?7b>(~LBv$v<;Fq4G zY6i96Czl-}zxTvfkdW#V?gj_JGZ)p`d8#&S-&&^)EyxedsTt`Ny{?@ac}cG~8r-}i ztLKc#>_Ceg*(K?uC>~UV#wLi*W({+t@2Q~3`0G!w6vgi}g4L_NQ-3P<6UiC7ohvtw zj?(t#9ITFPBRhqugLFh+a3KkSkVuPpP&@y?{>sY!iwX0Ut4N)v>KB}hUGVmR$h3JG zNp1CfeL}97J0K$wlYC6%H`kGFwu~1eV`jA)t^cXk%6BdN=TBaRcJKg@2d_3@h-3DbI7ptEqQ zxSCz?MITu;^N`<-CgqM9TX``NN9z_Qr|G_o#1k4_un*Dh(eGBQI=6w9pOb@ftw@x9 zk_h&yOlYz@`Hi0Nq~;FxPiwi;tW9Poy`s6Ubh;kKr9QXT%KjfL1*19%QlE$>+JQz$L#dj0;kJaOmMP95@(G{KC zNCSp0GL?D58Cttqe<;K1TL&^FuN{;+lE%N#waP^IF{!WcHE1yXXSp_fU73zm+L&En zY195W{#8YpbHU6ZCJ84ngB-6Yr6821ibcY{W6G z(PjVX4}@WD*=oE^eIVXyIQU#a2H60S7<@`*GH3Z8Z|1Dk6VuPU!#HiQpwXjT!Fmk# z%k!H5@EdKh+KqQk4Nq}l`iH?t9G&@sCa0bwEkH4%RMOUHe%Qm@3w^LdnDDNK_@wWW zNDniI)hN%UJ6JF|Z`tok2F8O&9&ev9id@yj&=~vDhmA}hAYZ>RAF70S4mPpzIE!H( zx})2C%C~qTyJD5aM=*)Cpl>vj#FIA+FT?_mx3)uGR!*l(2zJGeZfFbsi`U4{BnLY2 z1ifTYvWoe`Lt6n+D@$FuXtaV?S8LlfP@|?|!?pTW%*boOg5(IN1L0zXSVDSFT39fe z+qLmiYwY1x5d^L~l0I`iwHo<3QjmGA$KzeIc3CZTQucn-7l=hfX| zqj)PbQ9R8GlP5U}c8cX939VPCePtsyQ7-&Pa@=o@#Ek4a4xn6ndXqL{*)qrcQPC(Y zBeqQ6b2U!gIyi^fX&-aCSX$=qXgR&!`2X?7^AsE+>mYJrabynQrDR=ZzF-7(39TmN zxnk|}G;5`5sXE7db=N{G`em`82drN62IfF~%HoUYoLRxA*=@#7lfTArqsf_JpNZYA zvK7T1uxrkD>WGZZI;-R`cf$|mC+LQbYC~wuTk9LJ%p>>33y{;OcX-k}OCwWh!b?+n6WR)AGN=_@rmF zVLVfQst@A*;VgU<#=$!A-DVeuLW*F@@owpVq%ohVLm{t;8q=z1d*)7?V?T_eT7X&A zp5O2+BC+O3=nZQm3l75sJEbkVRb+##uQztXaO9V~yP7=qPdrTeqq>1j!3Sd{up`d5 zOZ=P`njMfI5TDN;-24QImzhd@lBX1d_(>$s)>uv&rc z3v|v7RRVEo`eDD@8JSmBLr4NwxTmRjI$BtMFg*k)&6yifykCwo1Ix z;N5&mhxnmN$oPV^MKkM}*rwLhK*7*3K7h=LJbx&{DA*;hCXXa);n^|M^dJ>ZiQ+YcUdAPbfM=q#{qimo#8U4xg@e)vy z&&4SlRLHB$DU#_|bB(MW{9`S=)lIzH%t@t_2C@vbsj6*o-cCG&WXelGCFZG_oPDI! zUgXK;c=bnhn-~g;Zk?`pl$5a~Y#naHTJl) zYZ185T-7}c^(VLzItaI8Rd`SQw%yo+ebPG?#?x6wcB_oAoUIcKye-8^bg%@bl1!^2 zw6C-EDQc5lhfBpoIIVJ!*UTjpIdN^q$#>P-lIKWsJ_~=IC&LartejHM3sV2@d1W`n zl##gfR)05nFu6D~g8eQFsP{M%V}!BU$3#~7$@=&NL!b>;s4n4OA*sm*jE6`Q+m!CqJvudMR8IO{3TG_cNk!YevI<(985%jC zmgVx~Vw~tD`|J!gKe^B8GrUB4G16Of3@5>i&>&lSBr^a5LhJZsD{Ky(g~z)(qsiI+ z-le3H$(mu_;53zD>N_VoON-9-apD&aB6^Y5<TU7C!EwJQ3Q_HxhX z;xSo4ED?*!uKU}0qp>_`(XNr8+5BWb5-e#Yt*Ba#dQd%J`5V#jn)v16E7Ot)V#CPL z^PDJ=nTP%GLoltgysVq?ihx)pjLuXnOuytctbpjIT%0$#R9e`s#08zH`Mc6Kwkc!n zog@zaWcAcH&@z^o9_S&zt$iqCgVS&ntg3NYhp|EWWBM{mas0W_$ITf6sgBFlPK1$X z#5~sS4ttR?!+cPvwWOE;j}@G0p7DOYc1mDz7dO?50ZG*~+K%$F->Uiu`_tU5ENt6mrF z@b)rMv-!2A&Ny~{2(*)@=3hS7=?U`H@ZIn)=>ZG_-{PUzYP%{rW`4z*veP&NJ|Rp- z+7NNLMhvM}ta9cye`Em58S*_vpmsx@ohqA$WwiDW`@APLsE&1BqJ5UInCNqGa(W4o zV5iT>*)nI26kxsO9M!DA^{fPYEMh5NT6UDJ5;=)o)sKn(WZxiy!E3o!OwIR_0TqFy z58e=;4g#L_qXD$@`1HUDs@}S|L5#7VbFCSZQ=bgz#6o)Rx$G0qsjBdfNFV>vtO{&w z=GYMUPh?6z%8kiJ?BsdgV?n<+kuv{gmOsb2)nASx z@SKd7`j+$v>VenqoqUDUq9IqdABGSiXWk;&Y|%s@({~jH@*pA#tP%XqdloaP_`>yB z|3*sc{GoXM1G@l49UtybJvZ-1$LNKalD_hvjnMPlJim;Xsx&7mH*YgqmR8EoWA>eQ z4E2{~yDO{pVAffcZ1woAXp4QuI24=*f7}XYXp_A14MsuU$q>{`-f=8s#TaO0{A=z# zCvvTxt94A?=P(RkKI>@@jgX3p+pdU!tXT~VA}gv&8E5ZA3@h(5{$#2~qdT)#DZeW_ z$MX3@%IO>b#a4<=?8%2S*?&?K%#wEN3F%9GZtlviv$Q6{rA1bRw`{$DmEliV)pFZb zR8B8{XLPY+xpKcoC2i*^`%?9pncMp__owAzFzenq43tKT(?+A7zv&S@cE>0RZ$?@vmbnblTVyGrf_ z6Tr%uZ+05?8xAR-V3VfCV(dN1?K`~A&$`nzHkPcHMb}#KeXTqV#|nytTLl#FmQK~i ziL2n0)>l9f`dCcDvx%`F-R8rr%j^$G@7U|{?P*nO@B$6uKV%=_I)C#%J{2wKQP$OW ze#fgDs}*MB(n|iFNH0Ho>M#oVoHd4td34v{A9cksxOsPxI1%67TeU(r1BaBt);zB%o(Jy0YJ51~vZBt4VQ zSKn*bo%$7CTiv8Q9}hqaNVdA{$pq$8y@v@{WN4(4w$C%B4eQ^N_gEdX|98<3QMnk9 zRpd2zHcTZLd!x>pc*(9>T>d;S!&#YRN#sxl?7lDH81hH$-iS%Mr z*$duI86I@ z#7)ku^_ymO`3)6JWyZ!btZHUtzNU+{0kAscC|ko<%O~L=M1wpb3nQb$pFww` zUbbmIOJiBH+|fvu#?g6e=gDk{zv=W~pph3cqXj1?o)I5TyUM+aMaU+!Ga0k}`ymdi zQqGN6b+$Xq${=l#^UvT|s+>otsQg?~k6}JeCA95)~z1m(dq1t51d$M2E2d z@P7H(y0UKaP0sD&#pPa_87D=s3(r;VRIgyp#t$rtd>CvDXR;jdj%?>xlH9G9VsK~H zXne)|OX{loaGw*IJu@C9EznuWwr^iliGWe&U#za@y9XA=31J(ZGdFqkzs6pT(g(3hR$O(JSSaP~D852{p&JY#OQ>0oA7Y+Lj9242! z@15FC@&eo7>0~Nvp)d}oMB1|3m;k38HraK2IVStKNU{nlQ84QYhpU}sQ)sd%%}UCQ zvYg~eKH6#C`T}2wl6)R6E?2kK0p4WKoe?%%OInlplXGBc^Td3sj%Y;`8N;HJM77ZP zH%}!4yu6dPaYXgwbgVLN_1O>+OGcJHd3XFHGP;}M6%)Ut7kqDYC13d2$%kd+Bv{1C z3hE)9n%FMwkubg?bCQ4Q8RYZXTrD~1(F)uYxFbs z(EZerZV%3%M*1C#6Ps2R8RCUPZI4wl8*pGyrW2*b&hYjix$2X7o^^#}*hziCvpECBEZezN?`$;K zo6N+_xHF&*rx%bRi862XA4Zg~T*snldCo%4r)6A3d*r3r2RPI^K@?`YYsO2HVLD9X z$QJADR3I4C4({r_eY|q=Dm&DIotzbL3h}Z09-fS!%$hlGP0a)}*r=G4jdjY1^+<#u zAI?j-lg7{&jFK3L<#cW$1moPq#;*`t^ZppK?s(7=Nz7SQ`K(o~@&bGUzS+MHUTeD>>(rh?QzER#GTTwfVv&7iZ!Vi|9K!aG1HbRDz78bM&@ zsrI2cM0K{f4z*}3tX;UR#md={xyQ4nW+N@cPNuIknv@ON&u8O*^Q^WGMe+wSBYa|O z{T`W?oLGP}A}9E-=IG(?vl7KX@N|fW6a7FI`pqiHBcGbn>CVjmNk^{C7@+&{ed+bX z^Es4jmd1zX$|9Q$IxdUllsz_8`*>oqQTCEvSqX@$9v-t@@5lnG3hNvD=v(7oOgOBZ zj8sNi>_vy=QN&`Iv9v!~yJ;J8gDXjf@s0hRHRRi!N9tq=ZxT_*(`aU*{CtAJ88&R% zQ@7O23=QYW_!(`J*GO9aZzfcWIs=s5fwSOzmA$M{CD`7+L2;RB^@JH&bs_z7rabm%WeIto<7~5w?oFuD8ycrCv@U-q3TphU zZT+F0{2%-%g9H&ntNenDo|E5sYV6V3$(bG(3#)Fxn-RP<+TMts55Y6?h&+68Uo#+j zTI49AD85rmfs=H)q`k@Ww%FXy+QKQaKR1l^lo_?k@;BmEwL>b=*g%>pn!{bI?Ukt^ zdvI~HXyhs~nJ0-R*?Fx%AN4D+3ja6N9Mcwggs((1c5%(yj%UWbdtEjEXj59G9ac`1 zQ(tUvi&#Z|lwZM*KzC#_BhNjgfjx5$f$VYcVP;3n=PD<^$w~EHe%4A&Q0!Iil*{t| zXLVRJPq||%!_p%X5KYTx=2aG9uuEDT>oZcy`|h9Jll!$WQAh639zVjCLX75=#P&?i zo_CAa4N^~E%&<4Es48F+$E#!v>~(mZ`5nx{;~Kl{ADd*>XaU5d{aA(E#a?(z0hBm- zg?t7zU|1l-Rp#k&nH8r#7X{Hc7JTXhA{TO8JYMigR)K!;Wn~U>Wk$`0x{EibdE{i3 zeyK%=n_wxq;IaCd3-6BfCJ=n3iiC_fy`)F>p%xn6XzhnWXw#wBRJjV(0Epc8=Rr-{f=1Yp{E+7s=GOnIqN+Hp8}beE$|yGt4b*uF_nIH!&nE*)L@EfgB)4& zc(~kiD1BE=M807+J1(7=EbG)=*yfj&;Xg6?MIyC^#bTJ;zO%0Jkz7Qp-kN_gu1!s? zOe~M$WEnV6&+d&qyeCgj-ZwpiURZ+N$e*3QA^=SM1_6z(rH|dO3Y+8H^sDIFt}jTK z?%x+)BJY{Ytb20|58P@IKCCj;dO^0=`vLF>d?|ZUoMScjD)&ZuS)Aa6{0k*v0rAJ>RY(O{#&gD(41S=evi^{VR`^e68CgGBlvsnYbVdW4;xwRh*$Wn#Z)lDdr|k`#;&e5f>=2#= zwh&kIi2S#x1F!6)hck0M?*(yq-;%0P-h3m?vAg+ya7Nk?x3%i1@v<2@IW4gNW9{+` zb=Jkm|SUEW}zCV6iH09I4i+(SPPh0PvBfAnw|HIM9BFc*`^=(De~GK&u~gDUoObF zlOxTHM)NZ=9$8ijTTS+iVLV`F$l6ZDMOx&mSh2DwqC7I+Ixu@PaBDIotdRQOsa{We zn~1s^3}ccPR!GdbIXeO>RwL6kc#?S=ZAM^CSP!0@To?faDkrHz2_M@EB~}B|j_YyW zL{LHcOE+T^tlEsNGGG?1rWtT0P2qp(Ftln%zqOE4FCzdgkRkjIY$pQ6)HSn(am8%a z_77|9skxVJ;sMG$J5zjk-+6`^#1@o+lQF^j>V>+Do=;5LNAfcRwLav4ud5|w*Vr!X z9l6DeR)_s*ELoZufIaS#!FHOQ6wmjUwmTUwv$56T@!CdEk-O=|fpx`URQp*S+Ve za_H8=oDO@DXJA6v<$46{GHaN5$(X!tIqXb6Gy39PGp$wGJ*(OpAghmAwK1Y%813i( z>9euW7+#0$@}Y?x((lHBBJ?6SF@vkI&Ay!SpzegPC&400u?N|Lld&oKqb*X>+>i(c zt38a&T+N2-T{Fn?Z{pX+ZMClKK0YQ_V~LXJJOkXfneYg(js0`yWtv`zwd+P?chFV0GyMtcHb568#IFPQCSAr z4$4T|uz@-p^DnAN4PQRzX~+#}gUtFiNHR}WWu(o(#0L74wtd3BV=_q>$>@{4qp&A@ zv*-RaKjRHXqR!-Da;GSQj+fJdb;%^lB5Ie?9V+5wfzw%coTuqRL6UsZt)NqAmb;gWF@lWZy+F zW`V_v1m`NgqAOjjC~g*e&?R<$|Ft;TVrr$D6 z3Wv(`AT)gN$&dthBM%$KO*VQpxQPw8y4D4t4=jKqu; z1?nM`uR5ktq*byjB0R^eB+E>j{Vhg*DRMZH$r~0%a!2Gl_y__`dsCDf6hzy-{Y1a8`els>Ny%p7FCbQn+ zSD71Fq0+8r{eSs+qlQ-MS8+0~@RhhaZ8S22g6(|86hrAn$&kyiotX*k=!4i3ZmPXv z^VB-oeVutRo372s%vmG3@|)(CEm3c4N1@sWdd*91@}L`Bl|>|Jk(J7Uc!AE-ca~p7 zTI@!G-39g2O`et=C&#n8`5y}dolnjqqZ2t}-*^L=Z2Ji|S%&Cp?uHTvpUi!9j6{+Q zzFYN1>ooL=Jf9ogSG&zCZ)^|$v(KK*EUSN!Su+28DXpSOM&Gkc8hcw=$i6Y2b%k|} zSuK`UWG=HoaG8^~n4d z;$g*PCa1z>G!jZylWSf`QBOy4J{%lR*OFCAdwFK=Re9D3o_$f<4Pmj`(4zUl8>(Ka z#ZtXQqs_^jM4T(fH>7{0o<@k2T0Lrp?G<}?R{Y#xP=4Q;;o7C!JT}a4T*Vjrb28Y) zs#|^8vG%IbU@g9!7(SA`nl18?H5y zoy@7qah2uaL5yRr)f2Hi3q{5v3waKv19E47`0I{jve3D5vPl^`-#l^s%#R*fReY}u zzqrqiB#1=>-b!ds#(j;1MzU&^cxQ3n!~yA@{?Kq)S1ZDYo)hVCmW=p^bh1DAIkDR5 z=~I0QR1`T#d;B9F6*?h}Q@7V=%xL*KD6-LGcLS-!x3B17~|A~<$c~j$* zcB4UQwXA}EkZ;wqJd&K9eh;q5Q+Qi(02IWEV{4C0^uprFK{=;9H3-ulR$J|1-_By6 zG_S3eM^r;+YU4+?(iT5xoyAfx1}!tSz4grO4<<7R zAwNy!VD5BErZWOXD{PGjGrbylCTaWwG-Wr*?b9ZS;FTZ*wjsNmXXdpJZ`z+x9@eVy zI##3ST` zyy9)ASC*Hy*IG4gckr`+WXwB6Pt09bhK)93)`MI?9}uj{54zwJCrNJJG+K6JDcxO?EvBQgzqVL5{_&dEI)8?!aG*LxHtXEJQ zj}IkV33j8tgDs)e_3*qgmd)va<-^1QD$4L(t#aev%8Ahr{o`u}7vyK?7P4%vtz0df z4gcV)aza)5;f#_8bFG*F#(@Y)y7eTl_rc8b`{ug%^?2&^lU&mD<8zHw3cjBi6N$pQ z*uSi6`Y0n#;=`1sMaVw-l|SMuy~O5;xn&3O1o)an#d#`J!^g1F#SFs+rGK@&Y&B0X zxFYw$R%VlixyMLoFzcb(qD~P8e@?emXOTQ{aRk$uE^Q!h|k;^51+qXY0q+N;m5}1etv=E-yQAyY@U2Lb4t?T zXZ9qcPMaIP3x6nnz@N}2EWP~2MBM4$?dhRCwPY6NgICO=_zd?lz9(&3ZFs_yU=LA% zS!`^r7M1tLZFXdy>CHE{rB7x9A0(d%Ra=9Kd1Fx{4>;YU1C5m`xG`k0#vU+f$*_JU)l$YN-zlJRJj8e=$6v5ZxFGN?Q z;ArMlmdUJF%bNRSJV z>m@=Nl%3u|{ASx5PyTk+13H8z;x+Sc)+ys*gJccGopju);zz`B9UmJYYQyrwuU6Od zWFN;Xr={*Wr$v3!PkNrg#p>l+??V-HIoC1c)x&8Wzf-Hh?sxApdr#`vi{xi>U656J z6iv=gH)b5F)yzDrQ+Etk%_5Rg-rp%W#$sn4-@zg$y3fer3kVHUpi+rMVsvl`_5|IV-;3m}l6NjfNbj4nO}+w3VL2?Q{r=^F-Gqi!f^qUFR#$rPmjw;~|&y8d8GheOEgk$iHxqnuEJ?pSm+KEQzr@RNu9HA*2usp&HAWr0F?|yEiNZu&dhHzyr{)=V#Ll(8-S}kD+=)FQ zTX3A33f_aQ!lLw)e74nDbjHQHIoq*&MfZ_&p2Uw~7Cn`;sp@5y_*?oD%bhFyZX)cA ziA^Ri%`=PR%>JB+m)88-UB;{}d+LNZQruJTMKV_1X+>J0JySI_GF&{R4xxy|8ky6n z4WH48L$oL73iE`s%y`A(!EkAtpDcrHerh$vn~jd(%WCxC>)g+ZvcVmtNXLray#84H zOSQjQW1d+rP7l-d*x>|JfU4~f*UR?9Yqv!5TPH+ESsxlb*^68YyuAfjR9hQ1JTMXh z0)j}lNVkNfh_rx8cXxM#beGbNq;!gOH-dC`4Bego0OIj@&UxSSUH|)ii|cXkVfL*1 zUe9`Jtv$F&5e(wk<5EW~raJ<8Hd!eWaB1bF-3+0aPL-A*mIl&0v?he7`|28bJ#&}! zwW0he*xKwh9W$sSsZ<{2)tulf51a)K)*oFshoFy>3^hP~ysDqF!>Uy6LVxx6z>jl~H{e`Xq8<3Y;5xV5z>iR_B z(Q_Gp%)PkSDCWH!$Grss#)#s6L~?F6sZ4=Sr0N;|drm96%L94b&UP>53#OME7TZr! zgm?BAg*q7{bwFFh+d7r#T>D+|`3g?EGpLBll^1(!^ETG_6&uNulPdBmH3thDAmhZUgUgLAF4OVk zNL;p}i_<}PYvr1~z{=JwXVopv?6TY|Q@ev*;_Trq<% z`w`EF4i`H`v$L)9$4*u?9N0599JjhTE78}LD;%0P6^@*B4~o}RoHfs=6>6)`7r+lc`0S9ee%@V}Z@VmxXFtq~&vgjZnm1{; zv1uSZT~wog;+l&;aybj!`c|xLw=9PgXS&SjeJMA_x>MI*mRNjX(HWedSbpkOow3Q~ z1mfQ0Fa|BeQ`$J2f>^AlsvTB0^EWS220so3%T5akEtvE=C(T*&0q>Rt>S4Cm*| z*E(JluU%DKZX7TbYU@y|R8^_kt?U+e8bp-Q)Rt8_*){I^cdqRoVMpLA*N_*P@uUjm zSahDwuN~z~mtRh=O)FgSY&!3q9u2#MT~*s$xD4aJ!Np@IeD{eYtC7aflGFL*!=hd% z<1WZ|<*2u90j(2#A({^g19q3@sr1{~fgtQ*e5I?=Q{EL$y#16lZm~0$7?=NF6Fy8)ED^MZChUtjMPQE&S7$MCeTe})SM?Y`Zsa1$3UD5VB z{wr)m&$;Z-<6(togg{EaFX(H!>k?~RW+*vV@zG|WaNf!&E=-asq^B}^S}p{!9a)__ zgYyNTbCSfIFVGCeOpm&#;c`t-B30vMoox9Bd>N1MkV(HaMFzUOnFr`002wbI9~$7n z7`*jro66sVf%kDCBx99&Mr7gpVA({{U;SAu({7WrnU%o4S$P?#Mw@(|kshu4TjO_GmI?LRS=wTx5 zTi-qE_IG=4tk+k<5x!^i1-E2X6`=VzYp*jP+m00o>&?f>2JZD!2+@&FGTIVwB4@O7 zvTikv^%Bz)KT@8~`y^Ne*{Uu~+AX*>V|2V&)Ac&{Jz133j0}M{(c|HHd=o{NC(QdM z{pRy1anP0Zo%llV<}=vckR~%uvD@kvmtx|O!jnY@ z0sW{)?f{#b$J5`Hb}kPiX_Dk@yN7*M#y2(-5J?PBX@pG!0rR%u&r zIw|K*ox^1~W;J8!)QM<(zM!%b8bcmRSw(>^g(os($9l{GFKo;iPX@4lQcd)&pK%MB z{laQB-v`2kFT*>#Eq?ZD??`qhfVcJ=lN~3!#We1iv@grS5G|;4JL_;(6;Idk?AxUS zW0q}!Rhq3f7GKQ*k|x8b<>gvQ+dwqq)DokqW^OJW_Xy#6${zB!#D^Vy-wi7z+FwwDLTk8if=$SG<8d%MRN? z!+AGOHs-wZL)%yuEw(`n^8%$THDmH=oz*`*~=Lbv=Z&PpVbwHW4*whQc$_FIWd18 zrR%~~ro*aeoF}EQTVUHO-b0nK*cGjV(do(|XUrC=W}hg_T+Et*rb}|+M$=@?u)AO0 z#q*4kJC=5>NuHUsWq3x5K5hX9CSLA!@aUU}{9a<}>9|NWn}<1Bmr+RSgR&A-gdR@% zO9o;BqW;=3ksr}N;y0nO%hky@0;@s?XXTVuINQ6kRJA%gWvN5yRC>>oLNitMm4;=b z_LE5;w9Pl1OsQB&F9jN5L38AaCy-SzQW+&ceVhKE6G~ZI>V<(G?zU(XGhFIIf?3e@ z_96PE*tB4h{^-*Ax)F$&o+wJ4gJfe*EF_lSfrDoelFCPIyH)Pto2-a-1aX+!gb;^j zK$iDHV=l(H0Ncp3i7>g)VO87#;2wQy1Pei;>?;FKN98;U2AtT0t6uD}>7Ln6)zKWt zPO>FJatxQ7VAChLRnPP6-d!ikQLrnSM(3$g8(8u^5oz{$R zHhI(02Fj%eC!H`u(-k)Ts~!i7owSD4`fIHbkvV0JREpK-GrRRo*|k-UD)v{N*^Lf8 z(@v^eozf~*myw+cWn2z3`|c-P+lgPUdWOa$J{~!{9Ov*1*Q zonOFgIWG$#RiBK&+c+B^$sFa$;mdbV+qWO)FD6Q@!0v)#2$iBF^XO0||3=XAgxd2XYNri0#t<~4yl z{4dVOr>O^eYsIM9E>i0Ii7K^v7u+Z+(;-r)yNhR$iHP323Y}N-&Ng;Oy9tX??7o~nlb{NmbQyj=2h+St^yJLmSU~(g~Xc7 z1D)-b^E1XZ6~(KTQ>C?|)`kw}kMByAB0Z>Wmv+w=6Vp||TpG{!Cl=Qt^Ob5W?SvB! z7hbKaM3J4n^|hA?jfzDXyplS0FVjiAGP+njsO?N-$(xSny0kJiw`Sqz?)D2WC!)XP z7Brw$u3=1Z;u-PKd7@s+vFr3KrpbFcUinhANHwwTsI>e{ynoYb4Jq%6;c5y;F3qmq zqPO~^dCz=*BxPSPJj%{xb%Cl%v~waJIrsBKPKuPrqmInPY%v)iPVj>a6RB%WRfaYz zWMeDUhmE_7joZjnC6=Rjn+zzDXbf6Xe)zq&3+idUZPLm6N>mdUj_RFmB6?THFNWJ14f-6+ zM+KVep2vIxwi0>bIdKo!c&SW|eG~kFIf;sEvm>tl7Ds$`HLFljk<>Me7mg;j(MRb$ zi5-S648;zURkKrYaglFTqC>ezEIM9}^Nz%qiJ4T;_Y{6STRLBen~YO@9NUboCb(eS zMaz*aj99@MbH*qk_dGO8LTki^YwgR#)lSJ175wp-sqB4jT25L8d;OMKDnYcIL!mu0 zqI`ut!{q@k7F}P^7mYKsmA!sqcmaW!pmZh-zpEWYMVrYmZm|b+&}iCKa9wT?<%Uri z{<~d`t@b-c>_FGo;Nz=;`yZ1CR zjladYuu0>k_oq*W1ctp@r{cEbBF*VX?L+Yr(+r$^t7IV|O>zEGT2_g8x~nG506T`#ywy7nr`_2)=fUSMkpO=+FJr%F ziir+!=yo!j468$YiX1r4eBE{k93E;EC~rzRSZI_i6Q_J0ewC2J${EThy2?@okfn_y5Q_p+1j@%H)zHwAMOF*o2dYq}g~d_f5?f zqjmJswvhOQ7<$ha_rcWYtP%A36sdOlw(qAnMvLH)CBdN;-xMLsdiJgbZB)C|BimP` z>(jBLr*G_QSu7m7bKoXU?DXdQ7PM)46nQA9!j?suWx}F9rtakm3%7KQ=V&$}E|Q}! zen!v8x4oxR`PwjSY6?T#)TzZ@#Blv=FJs+TT1&n;T8!D*@!8Do{%PL?lHSUF%{?2& z?zR4LgE`TuVrP}H)w2jh9m8#6qvrnElZN>q<>H8sxIy=pC@If<+nTIas$pdeld||G zv)J27#V~Bfzn&*d^rAAvEf~kgBNGr&vp9 zKpqkCN~i>fQZ9us7g@%*XmG&T^Y7a^Xx7Hw>se7@8!}b|8dTO{*xWW$-SZ3@6qALM zL-#?uJ8gS`Cy`L)gtdCwC}SKroVJ!Fv-ByQphXr-b~B+(PrAHs)rnp4iEXu0(7hF< z61!BH&;sp93gdgbUHsLnMs0)C(Mpa77klefxSUSSpL!vB-Kx)z-;&DBBvTw&v}h*K zkm_4j2@yw%CZH$~a0fE7a_0Klm~~$U&$@TS!v`n6)4Ct;{kaWyN#YrKCxl*N1W03e z&`pl}8H_EJ`^Ao*eI+5FaP+HDRZmgTtSB9Ih^x5@0mt88^NtM5_BYo()16l0Ot zWhUW|*(azSZSyWh%uVg?}Z0Wf;zpkbt!o3p-a2rD*4{2-7o#5CA`7f zK%Mnq?d0C!Fey#v>u-ACKljUSY^GX${Inu!l&SVyf)Q9%`}Lkls`i*g6MhxCrN_r& z{Cuk{H41Z1Cr&1FH;pCiD%UJIz#vFF8a)hKW?YbTvqLFE;6oeQy1Nqr?i_6|o;E+t zoYw^P8c&gI+@*9Xvtnyk#8GzV;Mhl6TKN8bM<|A5=>E3B2W`S-360}EwycL4b_6;^ zO^G@~1<T$!C~roNlgqzi^|DJ zUDz$}r%tgogkajJF?}{-Mq4!GaUBB=XBFFgE-hPO@gDS(XSjyr1-ADzdYvlOT5vD9 zhJD6v6tah`A?IvEHM9MSn!~$KnHVCp=QWrbt^T&!xVDo}gRg^X+5J>5Gz)J>SC%J~ zbyK=4Paf96+x`2ew+}KRNLTGfAyABDvdyvut({U%zX)b{^K_x=eQ@+2I`8zd^>QE; z>t^KOY01v<#=(t+y!gU}qM_?iQ(E^jti1>w6>@AFmLGDqA2{F3vT=06pC&qtk;tWv zv2URNV((++v3$gf?4>lyO?zi9DKZNr1(nNJ{zloO=xf6_ClD&N39)Be8f?Hvdz1*Y$E^~ zq~qX>*^X+8P>EjNU0?1@%y%)m0IubO>qMgUErl!1EG*+r&~#~)(dfAS#E``onsK%d zx<{lD79XmemsTSN!5dVi75WDs1`T9}b7%#-&Rv^C^JTfpt(JzQd`DgE*U-z9zZ|&b z_M_UlDA@1#9js(?D^{x?h-QOw5~@!@*)q9#qUVUMDDa#TP zK#CPs6Xx@~>D#!$L1|9B_Ew9h%lf4i+@JRB%Gdk~plFq@gg<4SF#^TAU~7mmj}nzH zdCkvi<8-e;AH!YDh?etVPpjzIPG7WKM9$uGW;Z)GNv~$fQAylV>4BY&M>zL(e9ohH|MSSy_9w%Af!46!%}Z^?2!uD^T`VTsXvZZM=d zHoJT=CX5?*84>+O_!7VSxw7Q>bViV8BIb12*U~;r!mV7qb{lQdHIvd7h8_!f-)@~J z0*fC@6f3(JFtwz$6C}N2Yt2i!hK|B7aGjl`zw53GdBRU%I+uMup zGkz-&RIRPc@Lp3)Lw55_Y!RP#yGWm;m7|=XkFwyo4U*cFcCl`SdMl1&Zpw!c?P>%q zxW>u6D5fa3S2*c%?7CPe=8{#}_csi6<}{*$s~t)-ta4iH)0axuJ};MmKX{ek^L+S& zoyU@Pns&mv9x-D*da>~Nv(dEPi|EZFs8spjqaC5t@@&5O8CWB1t?%VhJ)i<~ayJ3L zBu#ApROU>CxexJ?MsJjia6aKh7wGPH)f|L*A}6-Tt45T38Y>^Yk3n4uVJFs$)hXkI z9{r+k?4XRBNbkh7D@3P^`im}d9BI$R_n_$!)V_>%CbmfF)FrMHYwxiv?gr&N)0?vB|o4EApZ2D$^lPi^z{?=!F2tCYvu!Ty{frLQreMgm}lvJ1-a5tsovb>}F1JJ$6g}qNJiBcPs zQ3g+}^Ttz_N41~Yq@lfg!IdQ4>v>?AAH_qdZj7ewJTC2DN^&|YZCu50H35) z9zA=zc4J5OG8)r@_uUu_T8;efGv;CO?q^I`l+^Gwqtpc1x=xcq#e$`n11=L`2;uhk z?KKsvF0~^XxfVKBA9K3GWIfdG=N#l0&*ze|;cNzJ8;9r&4dLv|DUEiQNc9`o=s*)u z<|uB6SFb?(H!P(VoM|S@F@XFNwdLf@<>{wbuKNAtZOl-Fz8rGRJDtC3Y3IzA!_=x> zM(vTlNcKc^(CPMbHaPN!(DfRnxk|#%4UVhaEtdT%-zn|y+oXLKVY*2vul8Aw$HpB? z#tHoYdFS=$cOM7#WeQNXs(+2(Q=M%8qO6IxR9^MsE#em2&Und72?Nj|-b!+)J z{WQwTCs$$lS1_d7HroIIKohtQ{`Zl7-{2VF4fyQ30TWwpPXL-Qk}uUP474ooYfBmH znOSKGy@J&+F;dqv*3tw30RX4#>+XRC3M`t}FaEAs-C)q&V7&fu0WgW;$JtK|DD9Ve zmKJ~MAHorQ;dTG20QuLj1ONaX0ALHDp{}Z``m*r_4L0%_zzl%w4KTZh+zOxv0?^?g zO2Joa{W7q(;Mdm;n3Q;X^2fm7%&m-7jIE5+waov5{BvYl;7>tJ{8a!tzko>m=o*-O zt&r>Xb7Tlw)>_7v{}o2(`a>{afd>mRSZKh)0v44U7`Ph+N`YTrH(;{C?a3c7h!&P= zmU<@tJRV5!C$2TA0sx@>`~d)zf9YQGN2kE#j^Dd~pl+qDt!1uasAa5Usry%L-Sw^v zfc^Oc?&EJQ>=W7Vz5nkm>{Gz+82=9}ECu3s(Eke-mZJST$p2pp)BDAce_B||x8Gq9 zEzR|Gbig+7-#kX|$0z@C_*+v>W&R7$|I(CG!+-Do-<$HE2B7haqsaYu2bj9|d+#Ww z=2~}(vQRTJHPrfRR0G_3i^iW201h`0WH+wEeNGn4BxXNc<{U5p&@FOnyO9_|ZQw{qlFDN53NdcQ_LOdrWPRggG~~8FxbO z6QogXxsoy}aHoH378ypr!y(+6-M=#n0Q9X{0AOy-;`ViA-R-dk0DuMq+!{U9jYTT| z00d?%{|=3Q2d!tUZ9-$Nt@7jbUv+yOA+L?|56joSQRXd#+8sou$nOwXe}d39G1t)g z?U4!pfz;WjE%JnRgA#p@LwnCF7mnl zRNikV`PT#>5N@2v>c@M)Z0g?$(EKw2a6&YGP3!> z=;HHrtx?POi#-5uL z4CVsN4gH-F_MavV?5{WWeaqx81_iha);a*F>jv)ZHpkw=X#MCMn0x#?4Bp?ufa?a8 zn_2j0Bz*wHbp!YJx6vW*ZfHLz{m;?iZa~(irbZ^3e^VRXjY#(=&fl(3^8T{^`QNWl z@~;_ZzRdEhc{!Dfub4n16si`n8x;`H?C9Ize|urTcAB`KV6wrh333 zt-Prow9757kCl_k_pXmMG^H6}Am?8w{H(|d!0vU^evTXIPZSI-{~6u+799<_^A_DU z_Xb@DA?6mn;D%KVEzBesA@CX<;`}CTDE+_$7Nq_-`-%SeXLi&z*Rs$xG1R0C0XCUNzdt7#L~qzry*LxaL3uNVXuaV}jSs#Dv|bM)j5g09aW2T3v^y5J6jV&L%=Jt(|H9zshK=cu4*qhu%_D|4qyAX~7M1>vhw(=lqhk4oP5h@p z=U)#Ryr%_Dm)E&WHAMBjst^J7gQhuMM|zYK!xslTFXE7z4qi+kHSM`ZK>!l{?wNpb zBX2Zt%jlju*K~YLz}dFj z=E$6+NQDf7G^0j7g4|Ig02j+2G{wso!Z~f@#qU+N=C9jhp)A zp8`B2_`^2|1niPOe*l228wK3f8h6Dyute~8B>cZa0^5Pgb!DdTpJpZqoCX2D5GjB~ z069Ptq5zx#i~)8K{oowq3a|(JbT9bm1mOhO0%Jmh<(h>tSggU~3>Gi2TsMOornfp# zyZsdaShD-$?5E3M{l@fm+WsNy-6;jUnFj>#2|$81bX`nl|DqI~JE+n-`}he(@V8L^ zN-Mzt015my^foLV#9Np!=waAuD64yi&vrqHw_3T@+;szfxlR_>?I+c{`O{Ie)YAMvvKO#3|7tG*tz_C0HE6;sKTbuv|B@U##ZmRF;w5zWIlK?xyn3eE*g0nB6G|@}^uX{6#@` z6*90a`gg#mf2*Kdz<;G7@U9v(1UsMs@ExojPCy=D9*_jS2~Z7~g|LJ`1w;VK04WeC zfCRuQ82Va6*JQ32KTcrr1WO=TuAAX68oI0QfM11g-~2;E*w=*V=>89*&7Fz-=q=>zS9q{Xy-?0e)9_wG}CFDBt;{UO#fuwUAEP!Z7AfN%v!4Vh(<`A#rEFL|iDj3!1 zm$Bcii-G0*zw^QQ3!i^w8F$nFqq|SP4E}D17Fb^VI~dVFfc>k{hhC2!e2eDQbsofR zr$+=3AiR9*v8;p(Zq=o=5gaey3B4ueS5mc<*1Z}qQB_x)pLvP&Bo@*K%;R<^=(b{g z`-2y-Lh5&haA1bU8g?3gyR&*7dai?(-8B;g008W2H>*oT@bAcOJmhw#^EPD3{^%Q6 zQTgNSX9#%+M)^^2XqZ?TTmIcGqPzI54!Ea#&*+}{y^wp?o+f{z>Dxup9eZFUxF))3 zKN0@x9h4>=Jx6$~eMG{DO1fUF56DQT|t$7%+Hi+vy8{I;*qu|Mp_!pY{b(LOahjZ4TE=iZ!rGvR@{0@lXc2RXK zak0%|vTgHRN(E(=u8Gy8>hM+$HgxR~3K^$D+HxVGQ0<%8egX8*ZJsL;sBv?Ry7Z9Y zW9KJQ+&AaA$}n$fCEk~sH$pu-oaVHmi|+_caS5EQ<@)+?`M6dmuGpU#J^vlx`05fM zz~#JJZ(DIxtm{_@i%OTI6{fRtAZgy1Wo==o+Q~++2>@DT{FIaNcrpK_NKBUAXM_g1WlYKYe1SwIY=4utm8$`$P z%6FfHk0$_N5R@31tDGvVR`eaxIbuF=IH7NUO)O%GoTGo^AZ*Hn`|Q3u+{_yp39&{G zau!#U=T9e^JQREN5#_jM)Cnef-0pEZu;n5;JJ7{=d~0?Yf@UMF2r^q+Oiz)7lN1{O z`Fw{lh!wURCkTIJlLf_Gb2w}^N^E}L2Oq;oOq8iC-s#Y)FMQ@QrN)L~oI)M(11cMZ zpx8)r327^XfQeZr?v&oqflt%-tl7^(7oQ!^srY#M1kp}To{_t%$)j!egQf)X5JVKK z;IW41b~yO8p`O?pOL^z4+L8;;eZK#wShhKdftt@R$Qa5hd3QvJuT)ytpNFqYHZCFu zZZo8I%|EK-(UzShzlol><_09;bn!0z_Nk4_1&z-~LR{%ItHv7Z&=muaxr&4L*_hc% z&6gxj&LI|N&ar9z46*S1;ZWT|#_wyVq6aiy)Tq<%ppGnA2iAsSm4`d4Hw^{f_%T76 z)@@_C-cL0il9G5Gm;E@t@CB=&gCOFtsc$fszH4A>&10ocR2q1(jsZ|Y2E(eP4?uVVw7W8W4`BdIp%!lplfPN&33-y^8+8bSuNEhm)M zz0yyhdNXh~_a3GC8sbbOsN%i7q5-vf<@2ST_Ey=XCie0dN*eFwd0&uNls^y`2A1lY zXFX@)pqXkfmt^7{)R9j`f`UmN!*g4;2M*eM>7zX%YsLZsf)2Y$w3E*AVufLoq`tjG zW0XLi1S9y!w!g)e9e<@h+{(d!f&u@y6v@-`G>Q9R8s!7oNCw#o3mS2Et2bBs-``|U zvh-n%bCi-er0KWle|&3<3Wuo9gx3H!?8z~y*eRQAMAjSwsjJ{h9u?>9SM>r%^3(Ij zu-#zA&6k{!-AX!IqV{Eus{XxLb_8VH~!}n|tYImkx=1%Y(cIl^AZ0p~);Fvu$ zmr1kg*J1$i*TpI0o}K0&v+4-jcr7egImVxNK97FKhi*5rOaGYr?RG(lAXLGq5x4Xs z)S(y!^r^<}b+cqsJ#q=8jjz2!u)_QE^9wA^9NxLZqV9SW^;iT`vAEjPkEpb+1+~+kK}z`JMiO6<#YpEx zy5snEW99yr+1{>i3SEJd4&!A;J~pnKLk<;2$4!Zn>d9mlg7UJxl9zQ5Z>kE@#(e(>-M=WZgAodZb#JmRtZ+JW*1B5_ zl{>)g!vD$ZWp!`5>}m~!AyIuD(%_P+Kwe?XR>)a`4Wj20&>_dmDUU}+_R4xmIvCgx zo<}|=mphgbShaENj|TXU<2#D8#3yp31cWVHdJ}^Bh|(&Rohwhw=hJ93Y17zKCsUfW zgnIFEvqlBl(>KnvDx(zzal}5^%{s+WBONR>dJakpSst6wP>aneP6jSBsiz|KMva;^o)AwA>_U(1)6)4{cCaQV)PbM094KpvITR5^?NXf2WLOvAxP5 zxZRHhRmiW#{~;3uPlcVYOZps2_*W7}F3v#~CXO-rsG2uS8m0XsUs0i83RmZ{&r3Ejc?*;)==Ve~P7Ao3 zGowrt`LzL%2^J!07@hUd&eFm|k{)GqEey7jRb-Fqu`&ryJX0)bhMc7{ z7&)g?)M6SkH!o5!8q@S=}Je%WdhsG5K0f+aY4XLjKE;K+HyDBv5dGMGkxX+jo*Xust z%x~>A9!LwCjhNF=>t8b-=*XBX%9+=*Iej@85b;_?$6zde$Vu%KGS+jmqziug5inPL zDf{T6hz(8*;D3ut&Gu58l6@%v9Zp}gcmPQ6Z-I08HbZ?6VW8m`}tby zrnpGnn&x7B@1;wEbKHo}vs*7IXp){cI2#={et&O1#}0tZK>R3}PmsB@HRXYbhSz~jZkj<+9vMp%i2Q{@k?@Y%o}e?GBw1E@ctgkeUDF6Za;|Mhv&a1O9iC=o zu4XWe$MjwgUEb)bac}^MHkH>>Q3gUJO=n5Rd^IwQEoyT z(8g8UeZF@vj-b{Nl;k=RUAABZ3Kzm(o4#F($tLWu9DOrP5^eWOA){CIo<(!&TB-9G#l?2m`TG2C(~p2; ztUl^W{%8jLZ5)OT9PdkFe1LCq>aTqfaQWog7x4{iSmBd$zA6GJ?VHnSioP-cYICDC$*?7IZhoze01{s5ss$4iH{zR)^XXQ4P!q$ArCn)z6J0el?XdU zoib?w?O1%ADx!Z!7OmLF9?>EK`XMFen%i0QM?P?+gxN^_1vge2qKs9A(X_VC)I{^^ zjvf2t_k|>Gl$t~trLG#x@+pi+kwJe34wC>o02IvI%RS@{8>}!JhK`hwq%Z@vbYKlt z=EOd0<=e+bnVOu8%~TTf+g$ITi?~mywu2u<&;8g}310^xf1RINB>Vlg^Kji6L*sbP zv&t8?tz^3T)l{mm4+Ye$> zHpoa^>_#Qy9cx%RFuM zGPXqC#_T2wd-=y^GOsnuBrg}pp&gGoysY_R)T3`gD+DV{BqIbRyXK%!6}iJ3vMk{|o= z>=N>uGZEWiM$Bj@VQ#=w3(oZ~IdR~V2}v`#mxmwF*b(fzB1e^B(UD?wISanwG@$aM zDNKKY3AM138pX=d%uI!hSnLI&Z2%{a==%xk5&j@v=pF}*o<7?ACXFc$dU`glk&aDe zHn3Md(_-IaDH2^9d8bP@#pRziA%Zm>sfrrrl0soEB((K*Gx5pLB2(=oElMR<_dO9g z;pf<;vj^TTYI9%2zDFzv@Z1-BxdEA?;_~v$ZNL$f#`F%LbiP2mw@dqI4MTwTaZ040 z8cD518AR7!&H(hl%mAWgSW?mv--fV5BB9I}dpofc(ig%qqN_Bo`X%dAt;_udhG_=7e#H2zoZoU>PoGwmM&)XldRVW4gK>5yNWkPv0gYLq9inmu6uWkBb5) zz-c0oV_tcE{m=Wbt%+{=y_t8%AxC_ zgrj?;*4;;^kW_6duQynTxho4^Vd+*VEb(-5q2;-hr1d4?658CG?$MH6!{!W3cm$u3 zX`k$F^E!6I)6M<+xAXRG-s-1b-*}B+Uwrckc{#5#VN+@Y?vg;AL_?`@4c>(uY}HF< zovpHf=Jy)?2cI(b9^~t!L99>UimFV%%I4(YS`L=t+Rl8b*X`Hoc|T?S9vq_E5vEP0 zA7vv7?^0#HC>>1x5U*R}(6bkzkjfrqaT-3T>NljyGq z$9BKp;XTy_vf5@zhr)YR&$GV?o6KVP-GISfhS%-gWkG*7fY1H`g1k404~J-?Y7uu! zQ(*bl%AVA;9VR$CFUWxhcbe%$M%52<;k!TEh;`0(n)`a1p~nx>q+2uFY0p;0tGe;L zH%oiB#$@1v2oCXsje}2B1fdD>$1+54oYju0;^mOOM+L;UD&g`^+4PSpeg@n1fqtIi zNl^#5La(wF3V-Qow-*4O8>=E`t4syk_;ll0wok^h9O;{>-GMxbWw0h)dew=mjKv(F zcXnj{C-M{p#--4dvLR;;-WLdmVU?ody<26n^=#QC-2$3cOFD-K5)8AC5=nA`l3ox~ z94cK_uJiXmEeXOzhU7jq%BEPRO@u#)r0-Yp`dX`q1TLSRLcSOYF@<|ftbuZ#(Q|x{ z`*BuOyPNEjv?>8TY9Y&5zPXfOdDZ!57eAV}5%dS=^@CNfYf?G6IA?=B%LTaH#3?df zbtw3;!l^l0Mp};t7mU~Vs5RAo$?E)Wq0oA&+O(pNfAMBLJsi8UFFeDar|Hp4OY5yV z<&OpEP%yYB7ld>s^r}IOQKEuxI?`}0AY8_kG>xNkWfR!!BHrj<;GuyZrr-tDK>;7u5^W%%ch&S{(q)LP+_W6YS#ji8BtX_0e_kToi&f0D>{jh5$ zB;}8XhP%X^a>)D$XQ9Y{7{Zg9oUSkGBh-hyImPr5&DVSQsnt(PnF(B;f(`n#cdu2R zz$#l!A#F{7Ad&8cbF^z!n9|eBUYQ4oLa?;A#=%PMA^N z$og$#{TU1a4|${w0<@)(Cv>E|KgzCgF*vmvO9V86ODl!2nkxG1+KM~)QdWe#6x9>& z@)>^C4D;Dm?Kqd7Ui98_K=eB(^iueoW6vvyOl+%zy*{=%^|^dY7L{XYTI#WhZyO?V zg|W0u1182|rO;Zgvw@Ncn~K8>^8&{C;aV;8Euv1olaeO3+L687r6VDuVq}v#Xl2P0 zy?(^Y9_0|8XCIKtm&~;?;WnLj#8b!DQ=tj#S=mFO*h3#gOK8*hB~|Qa5f`HNBF$u{k=vkolx{aCcbY+8pmWo zY+Bo1OBM*cg_W)T5}n(FhJ~WrSdx*u21Va&K0C_ydY#i&&2*!K6tE8RFor(nJG-*}3lU7EVCCS;F z=ioxIcBUrHaec>ZGz@8sCW3}GYRM4-yeGCX2ReNy%_kq^w=`*Z&cKhrba;wX%)b?R ze(;T8sOK~HP+z49=0}6o^CQ9&jI#&rkW}I{bxJMk1CuVZPpqyyNq1PS;40*v`dU*W zrsEZ;dtL-RK~LsTs>oaHl$n_2kDx`uC`(geSv?D^%(l^AF_+|t>A^B&;oSdTIG4%x zQj0Di6B1^y*<=F#H8}$+Q%7)Gs?LNgg*12`qNq*wSGDRXvY#Gb1aS}96Mt@2%HuFf zatv$jW15H_%3$wjxSAAxkh1tZETht@__f`TtOYk5Vo;Kb=^5d)0+s8f`|#jLjtv7I zH!}mar@+gh>X8L=hqwIB6RE2X1zEe^?>Aeo^N*lY+I9YMehPLh$!o`YKqHRFoI2H+ zdg{ELP-*lzn#~110uNP8h=c+^QL=jZU9W2p)}X*!(~usTsUZ#x-asLHb?TO0sW^DF z$^g4d@P@=dMFera64kYLJ=|}Vr?bjlj3jn=5G76*B~t|7%$<`yn|#t{=6V*soBU8N z45^PMf^eGQ+c7v_ygU_b^PK~>ufNI|^)>domzJ}J@j%<6uYa~_8P@-;@Kj(6Eq6lQ zE||HlQ{fGB8Zh%Ar_Nx-vn6!w6O77pR^(2JNSg@!cE0q=M3G6SZuW`E;I)w8Nhb*F zqe53);BiKwL`KK3lMo*v9bL=51Rg>j_GEI3njo6x^z54>C6fvhTAS%&@G4*k78Vn{ z(VI8rfZnVpTrSxB+R%$mM-RF1Lobu!ZInDP_#_gh)ur(uwU09kX9{M>ri2@Y(8iXl_$pi&EP%o_mT@4@bGDi}2a)}AkGGpT5r*MCq zoYtr9P|k|ksR%u27>-PtAy6LYRbI27FEw@bTa@7er(28{EMbFFHhyb>6bn*Uv`GU&|U8qg=XT zRqX*Qyhg7WgD+GG|eNoKRb|DG}usCbbN7*?Oc&V&BC!VO?{LR8&~2DsP0GA}qE z8V2we2JJWizSP3gF(I1njRV-BOziw`O*c2!UR>W?8ydL1 zx%OJm!V*Ek68tSSBQ0|w@HgC1UYS^_8`=>V>KPkoX@UI8@NFt=$S2X$c#EyBsZp3x zk^3*PEPX~NqsuL7Eqb0GO<44lMx8d9#%bexj{5k6SVE4i{|i&MB-&PTb0M`{qE zi;HFVc$4E`ZjbC>cCY18fDiNHo9xKovQL^JWjZ?A=GJ_hGqYTA(etRojy7d>DJIhk z6Fd`uz(+dod%KgW+P-g*!Y8)gJEeYVS=+NQk@bB&X(oKW4yh`{=c$>pZ}CQro=Jx8|xg5#JmS?h|cw zLEpMauw(4CgSd)~(eF?ZmY51_aQg}^E4*q(^D36#`~Z3*^QvUhlMHdv(U3N2e*EMU zHs8~Y_O1D=bD2aD=RKRgbY-6mP%%^58m&ld9>ch1!-u?kid%9GlsQ`&Se^r&rR=Z# z$+n?uXx(t(^gHmrYC>##Ebocx5yQ%pSc7&M0)mxxHf-AmAUP77MnCU-UhXayjNn~> z8&N1$wWyy@P|AyVTop1~^-0Dp&Hwuu!XofVvHqmlRrqR`ml)n4R${7 zbu6U0SEIh2a^VA+fl|5HVL)rUxewl>_t~QFzfI}2%{mh7V$FHH$gD3lhJ=0ko|@!! z5JVAX8FiddaNz)lfJk`AgMBwIyC^Ef#Z;2vC~8cl%+nh5ZuIJ1^{Q8_%+7L>inGHmA^F?_B6Q%VRvhPIr8y~Lg*I#PenlB18o!v_K3`N zwH|8KZI#PW7Mmn5y#KGYv+9Zi*ureEV4<-9K?4N0#tH83?(Xg$G$hbya18{v#@*dL zI0Scxrg7=v-n-@(%)Hh^ty3>mwd$+APxvE@%vsd<3D&4;JoKrzr9|s($2Jx&lYIW5 zYqG9Rx!qSp8Pij&XAnkH8t6Uta-Ly`qSNFc3{G;W8(R8NW<7-0_O50?6eL(y`E*#N zfvh+8?>E7Dr*gA>=D)Q@96!|WUz+OGpcW46BE|tZKmAnxtgn_;i7_PG2~<&kA>~-* zr2t-k5^=p32h8-fLUe0gxR{d{NsU7L+G=rXer{UdQ94Wd1>AloLe6WTGd5UP*{fjM z%T&a6P)(ld14bUqL}TRE<3O81wQCZ*z!I&0qX09In4`$FeLC-Ow8A6Jm_S=WqQ%yA zE`DV4CXztVz!ggt`|hP=`Oe?|&VwY!8QhJ|i$x2W!zX@1oJ#qJaEjbLM%pPpSmYxc z3-kqGG|)VK*D~m8ih`8(%vI4F7yqN&(sqzv9ntKdH)oOASDqz|0(}Yd!)B6Xqy11C zsHU9Te|X`?W@y+R7;RFEsabBz5hnn;Xl~z$siCf6B7^ zt1{x=6?SCI$#n@smFuJ;E6oyLg_31!HICj6U7qVAD?KP~TUgJskq)l&!*G0ylg!s* zPN{Z|Y7IHTN@vPkhn*UNlr^*71gCD}zh^6!zn6J?Iwj~d8h9>fXZ?&7LspUtuj17VY+L>DA*A-pLv&2Bo;=g+1V>5 zO-1SjE0w^LU^hK?&z&8to(n9IS=T9mt4SBgQ&yi`pqZ&BW0H`yT6|$EBcrsmL{+c^ zp127R0v)}w?gIHS&#?v*`Ix<2OQ|o$!8;sJ3QmjwTfl|a)I2LoCC7GWKA&~pW#OI; zPYSb6pzb`(|1l^5kEZ!CW3N>zqi+cO-oJo;QncnJ2YPhVV6aQ$SDq7KDX?CKBRuEz zEQ|j|EQRrPh9sWs;-t5_D#nObYMnpfS>1@2bY@i{?g?~FLfwBmo;c@qeR(&Ki}4Oi z<6Z81R8f}EVBY{afwWmE1m%DmT7jF3o-yxj%Y}Ty7{7k7U6T znE#UYK>gMmlT}}RE9_}l%p4H$XyFe%N>0WZ=aji{p+nYwpIwDIg`90fJLhHs>ET6< zP;=fe?utETZudb1hHfB)6F*GMsO{fTqP2%yL}6js&j;1LGN|DkIhY!)>h<;*Mo%?L z2P|9$G6$3B0%i~>gTW`i;phhqtO;)XTVJJz-6CS;U%Xb3RTdj9qGg79=G3x!%^O9) zbg(wg-pa0&TpEHesIL)BvcmCZP+K72t+!FXvXHNCOUoqtFw^bsGd`1{3 z|9vKKEq=2m#thu(qu5cMOgVRkQYHt7xAGiG(A&_1uv<5YoppK_g_oMIDc`DDJls3q zM_Ixov(}LAoPziE^owMv%Oxq^mNH-19oc^AvG*;WY@VzSUKdbY|9F{>aRYZ0+ZQ)w z&x;MnCUQLZd%B%dRX-iaq~7&PN#S*AFNc(@e!{JOwL&w zu5bq1UvAOo2NU&_V^Pm;w8KPJ7Zgt z_<~g43c(Suh|f=r&jmbKO?CstU|M=CR{rbLhETU!R|xCO0uATTn6m8zJ8tg{6aF!g zDh-7v5BGEefHKw0YqFRg>!I<)o)Y4?7%_ZOs@ClIlIG|`_Txv;H#EnU^XY}0JXVSJ zo1qxW{an-r>`=IE53m}rQg8ek`uDpbuYy~=s01fs4a#Z*ueR3o3H&K)XX`+U0N)Vh z?anxf-%vXA<5{p5MqIAM>#lb5NmD|S4@R)B}pO`ev@fa1$=Y)k? zjy98gfugk}Zwg8@dY}vgSz9^kk%|hF(*Y(iHvS!nOV@q4A+X_l9|{GAKGs(}zOe$* z@D|g%wyjzMCr#r6k+!1=;A;t~Ub!mw4*!Qo^+q*?t<{DztI6CwyMtXRC9) zyBxEnp~{D^P}5o$Ppvmo|Hv?fur}zfLR9K*6M37HA)uS09;tJzREdDZ2xZMJ5Oonf zD{~iY4-(8oA!I*JD2lVs$i~gc#?N4fOQL{nnMm6B`CD_g2%W+neton}NclmfEYmt` zF&iNq4t5ZYXf0#GYa-I74E&Qe&rDnWEZRPd7ZRXh!ZG$)>P39OuD&2-BME8!tlXNo zPpG11EVN@Tx?@E694Siv>T4#0zh>Z_S@6+YctJI3|WHN5UpW<1*YWV#h;d>jqMvkOej>@XbpD2JgNAvu{WJi$+CBx=A*9Ab%YI{d5(j zI9^QXF5U2eQnPy9+iC|%_T{zVo$HL&4Xk4!mbn%hPxDuVr`%nvXRy8z6tG~K=e)`) zA0-3VErW;lrx`wyK}-V)L8a%K4d8lE@2!+qE@!cV@< z#y)@`@O`1(2y1S3?TUhNHo;AB%mewjc9fG%bva{{(X0T!c#8N(v?+Ezfs9{Nt&o&k zi4fK4eSzq&8EbeLKpUcQ&XFYgCT4}c8uI9Jr})Kba^ead+_6u%SG7cBrb&ZKW9xEE zYb%VJy$w#KJsCtbdB!wj6n>gt)!0i3A-eYt-Emi#+)F5)b*lQ1QLo2orGf^c_pZ^j zE;(L{IZ9OG+1kyraWN*wxfw%lQ!Ed67>ZXHr~}40k>ZKlrXhHq0co;YMV;|BzU$d` zH}~)fFJPLd#jsNjv0Kr^Qwo?#m<0{fQpHVnh6~>D{!uaaUr$#{HV=6(HagP~v!)Nv zN;EI@@~m;>uju?em5_3=95*KR`}XfApJC;oUY*0`nFVHR}xMIBK?ras*3{L}G@ zKi6bgC#}Zfpr;0O>Lwl?*1daviH*vc3E0mIVRG~wAUg0s(a1^3X7AO#8Z>G3+B@ju z6i8pF;|q&|(~>iEIX0e$3s*+J0ixavDI7~bm!^x8rDXI<|KsN}e|l`v^X%2q{aIhz zq-U`D8_L5KOCF{Fb7bL_rY`F{8;QD|zr$YPl>hDSaT)+;gpgE~-faQk?r1uAMh3aF zotF2ZU>p-}f!po)dgb+G9-(bMM&$gFUq4^JY4gdo_L30&J8Ovcgh`NTqVQP{K$7P( ziWu0jK|ASDYMgx6EOb^Bu2H?Nheb}eeSs9OYc&)}N|=on2{WS~<1umI-HxV*b1#av zVbpXx2j~E^3Z;;>MI$hHNkiSm=J7GWQY7WWg;-0%0-ZbcwNqlz#H&Wj=5OA8{Bk3Y zBa)OwxKCM-$)!tdS4#Z(B7mJ0q1!8#~11|o`Y}F3N}o?q%Fb; z(%SpFz0{!$*~jGXKS+Gkguo3c`e`cG84%~Tjq3d+Ek3IZ19%bo$-jC~Ea7{cY*tD3*B|LJ2n+@J)Z`7;XnVXw zUza~In6>r#xyr@OT46EchLYX#3Vkm;NOsYoQ*lTi z9TAkbfFA2AK-VviW}Y1672ET#tFfp#NRs&6{Ts;R^6irFO1jq*@F@D_uEntAm%u~- z$7(X6_0NDx_2#ZZvW{aTL{fMV%7;HJd))$lMMXZ)g3A&zou9pg@oaxZf#}ZTTNn#7 zcie9DGc%$42`znxQnTa^gC9e89D9o=_zo8Y6ZrrxhGDS4#_w+IQ!WX-3n$a!xPD7YvoNA%vkpE%X4kAP*$`VR;@Gx7i&C|aaNK&mn#|#~ zB%co*y~kqnhvOu;wA?@bV#5fJ_jidHS7iC2Z+0uokB%kEF`9MlS1>mZb=gT&dUrcT z5G*0pIJ-Qhkw&nVt?34|RPrdIVIDH3N{mc~}E4VEufeEV`{0n6$Zyr=YcTO70c-1gxP!nEI< zS^xDXV~K{lC{CqNeFg_5rZwG=?lJ53jbyXK8*Eo*z*UZquBs*`@p}{1my|$%_B2xdOT*Tw9=x>Y0Gys+=$9KFymf(f7@sBwIMB#B7%Z`%yXwWkorvvQ{5uUvYKQ@`{nT8+CG znimy?cc%%iL%H>>5GcV5?y1)4G|GZkVoJt5E;DA$Y!Cv}tM8g0zT{2>PrSOiEU8a) z>QTBz0A1`vSM5mYjzjSd#)F)+z$#nyZMWLuWH8TnD)~y?q&*+f#I-J0sgHw~KksLa zLLe6H<%bW~e2_~{U4Wa~gxBPU>@}PBQ%jp=zjVn4vx~bTg=YryEjkzQ+(!&(KGcqA z)8~wN>?23oa*{b-co_5nvV}81s)0IC3pX9K zzPfB(BUJ3U1lPi!$)yVymHKEE=;4-HnVsJtz4xxl9M`6pM6Yh&%+H{7FW#*mNqvNb zw(;d2wi6JLpD@*!aGYeRKKpI@e!FWsrP?j~h|S27;b-72YNF7LxSr**W(oO%D!KZ; zIc3mS>`N{6^uAH$_&ra_P}dL z{_DNm>^ePH8Z9DDcPrt0Q!MM%e9Uw@rPt^Td}h}~uKwU4BHNQ=P^cie#Wsf(CCN0&~2(r%9LcQTv=iuZG%E7x@ul>7+C zPWEkc%KYB3+k{iMgR9OR!msUTKVc)P8zetM+}#1XOL1bbS6+Y$l|kP%AR(DO!p-u$4^RpOBS zpsci{ZIXQ+EupzIVS#koe-g=sz27BaC&L|r5^EB@h^i_NSf0R3?bn!6a#glBa5vO1 zGN%HZVXWjzYV+(kJZ^BfHe;{|d*1@${rxy0Q*UQNAmsvNO3|G2P+79B-RQ_3*FV+0 zP8zee5Ifm06y&Oz@`~^OFue=?C)x(TA6~Ar=QUf=_n81U}(_PG*AHCky0u z_S*myCg_!SN>M%4pg2Y;^f^?uRt@dn02)RkV!J8dl)Oiz{pfSea$0CoNglb9B$3VVm2XX>aDFQf*2?&daLyFBYfTNDx=eRNP5w z1REsP`Z~w+id+T#Dj_^X%xVgq9pq#FXhK9_PrytZ+#HR#GTy8}aq z3_uBMN%EBCsz$+DM04qhHgb8Lrxqm|av60^wC$4mS^!#C+)SQ!+EQrIKPAM!!JaHN zH1tmDC z&ZQ!zQMU|}m5|d%%Jq*F+0$q2O=pY9R7uNWlHZ=++B-d?DEY<%^+<1+zdakn>6`@` zsM{?z?_tc>uM0lF^w$$$A&)^GWBOCNY(GhQ%#b2#Zge~bd*@NAzGPlmm)j|q>|wpc zC;f!`8;I%j;#IaG0Y#hIy`}sc6Qr+Kx(z!Yb_?#}AruNIz22iZ9B+dFnXSL+Km-K{JM`#*KuChl&<2^!yy!n-5w1Cm*_m{x2VrvURW&1Daa7 z18uErSS&1oo^N~}&>iS*W9s1GXzB!X_cU|2^mrTipQ4YQ4frM=|k@iN2{eLU+ZQ&4PZ?2?w{|E0VHN5}; literal 0 HcmV?d00001 diff --git a/NuRadioReco/examples/RNO_data/read_data_example/run_reconstruction.py b/NuRadioReco/examples/RNO_data/read_data_example/run_reconstruction.py new file mode 100644 index 000000000..47b40e611 --- /dev/null +++ b/NuRadioReco/examples/RNO_data/read_data_example/run_reconstruction.py @@ -0,0 +1,71 @@ +import NuRadioReco +import matplotlib.pyplot as plt +from NuRadioReco.modules.io.rno_g.readRNOGData import readRNOGData +import pandas as pd +import numpy as np +from NuRadioReco.utilities import units +from NuRadioReco.modules import channelBandPassFilter +from NuRadioReco.detector import detector +import datetime +from NuRadioReco.modules import sphericalWaveFitter +from NuRadioReco.modules import channelAddCableDelay + +""" An example to show how to read RNO-G data and how to perform simple reconstructions. The data used is pulser data and a simple (brute force, not optimized) spherical wave reconstruction is performed to obtain the pulser position """"" + +""" Initiazize modules needed""" + +channelBandPassFilter = NuRadioReco.modules.channelBandPassFilter.channelBandPassFilter() +sphericalWaveFitter = NuRadioReco.modules.sphericalWaveFitter.sphericalWaveFitter() +channelAddCableDelay = NuRadioReco.modules.channelAddCableDelay.channelAddCableDelay() + + +use_channels = [10, 0, 23] +sphericalWaveFitter.begin(channel_ids = use_channels) + +""" Specify the detector. """ + +det = detector.Detector(json_filename = "../detector_description.json") +det.update(datetime.datetime(2022, 10, 1)) + +""" Get positions for the pulsers from the detector file as starting positions for the fit """ + +station_id = 21 +pulser_id = 3 #Helper string C +pulser_position = det.get_relative_position(station_id, pulser_id, mode = 'device') +rel_pulser_position = [pulser_position[0], pulser_position[1], pulser_position[2]] + + +plots = True +""" read in data """ +list_of_root_files = ['pulser_data_21.root'] + + +readRNOGData = NuRadioReco.modules.io.rno_g.readRNOGData.readRNOGData() +readRNOGData.begin(list_of_root_files) + +for i_event, event in enumerate(readRNOGData.run()): + print("reconstruction for event", i_event) + station_id = event.get_station_ids()[0] + station = event.get_station(station_id) + channelAddCableDelay.run(event, station, det, mode = 'subtract') + channelBandPassFilter.run(event, station, det, passband = [5*units.MHz, 450*units.MHz]) + sphericalWaveFitter.run(event, station, det, start_pulser_position = rel_pulser_position, n_index = 1.78, debug =True) + + if plots: + fig = plt.figure() + i = 1 + for channel in station.iter_channels(): + if channel.get_id() in use_channels: + ax = fig.add_subplot(3, 2, i) + ax.plot(channel.get_trace()) + ax.title.set_text("channel id {}".format(channel.get_id())) + ax.grid() + i+= 1 + + fig.tight_layout() + fig.savefig("trace_{}.pdf".format(i_event)) + + + + + From 3dd7ea347b4409eea04eaee7159bc8d094807ce3 Mon Sep 17 00:00:00 2001 From: Ilse Plaisier Date: Wed, 10 Nov 2021 14:10:08 +0100 Subject: [PATCH 012/418] adapt range spherical wave fitter --- NuRadioReco/modules/sphericalWaveFitter.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/NuRadioReco/modules/sphericalWaveFitter.py b/NuRadioReco/modules/sphericalWaveFitter.py index 751070164..c7a055998 100644 --- a/NuRadioReco/modules/sphericalWaveFitter.py +++ b/NuRadioReco/modules/sphericalWaveFitter.py @@ -126,8 +126,8 @@ def likelihood(pulser_position, x = None, y = None, debug_corr = False): if debug: method = 'Nelder-Mead' - x = np.arange(x_start -4, x_start +1, dx) - y = np.arange(y_start - 2, y_start +4, dy) + x = np.arange(x_start -3, x_start +3, dx) + y = np.arange(y_start - 3, y_start +3, dy) z = np.arange(z_start - 2, z_start + 2, dz) xx, yy = np.meshgrid(x, y) zz = np.zeros((len(x), len(y))) From 5d50f4d8fe3afdb813835d7f65ece3bbc35ba10c Mon Sep 17 00:00:00 2001 From: Ilse Plaisier Date: Wed, 10 Nov 2021 14:11:04 +0100 Subject: [PATCH 013/418] change channels used for reco in example --- .../examples/RNO_data/read_data_example/run_reconstruction.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NuRadioReco/examples/RNO_data/read_data_example/run_reconstruction.py b/NuRadioReco/examples/RNO_data/read_data_example/run_reconstruction.py index 47b40e611..67dc3111b 100644 --- a/NuRadioReco/examples/RNO_data/read_data_example/run_reconstruction.py +++ b/NuRadioReco/examples/RNO_data/read_data_example/run_reconstruction.py @@ -19,7 +19,7 @@ channelAddCableDelay = NuRadioReco.modules.channelAddCableDelay.channelAddCableDelay() -use_channels = [10, 0, 23] +use_channels = [10,9, 0,3, 21, 22] sphericalWaveFitter.begin(channel_ids = use_channels) """ Specify the detector. """ From dfd128893cc9cd6499ef5bff4fff2987511c13da Mon Sep 17 00:00:00 2001 From: sjoerd-bouma Date: Tue, 16 Nov 2021 15:37:48 +0100 Subject: [PATCH 014/418] optimizing single event readout --- .../modules/io/rno_g/rnogDataReader.py | 22 +++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/NuRadioReco/modules/io/rno_g/rnogDataReader.py b/NuRadioReco/modules/io/rno_g/rnogDataReader.py index 61674d72a..cf7913dad 100644 --- a/NuRadioReco/modules/io/rno_g/rnogDataReader.py +++ b/NuRadioReco/modules/io/rno_g/rnogDataReader.py @@ -6,11 +6,20 @@ from NuRadioReco.utilities import units import astropy.time import glob +import logging +import time +from functools import lru_cache +import six +import NuRadioReco.utilities.metaclasses +logger = logging.getLogger("RNO-G_IO") +# logger.setLevel(logging.DEBUG) +# @six.add_metaclass(NuRadioReco.utilities.metaclasses.Singleton) # maybe? class RNOGDataReader: def __init__(self, filenames, *args, **kwargs): + logger.debug("Initializing RNOGDataReader") self.__filenames = filenames self.__event_ids = None self.__sampling_rate = 3.2 * units.GHz #TODO: 3.2 at the beginning of deployment. Will change to 2.4 GHz after firmware update eventually, but info not yet contained in the .root files. Read out once available. @@ -39,6 +48,7 @@ def get_event_ids(self): return self.__event_ids def __parse_event_ids(self): + logger.debug('Parsing event ids') event_ids = np.array([], dtype=int) run_numbers = np.array([], dtype=int) for filename in self.__filenames: @@ -48,6 +58,7 @@ def __parse_event_ids(self): self.__event_ids = np.array([run_numbers, event_ids]).T def __open_file(self, filename): + logger.debug("Opening file {}".format(filename)) file = uproot.open(filename) if 'combined' in file: file = file['combined'] @@ -56,26 +67,28 @@ def __open_file(self, filename): def get_n_events(self): return self.get_event_ids().shape[0] + # @lru_cache(maxsize=1) # probably not actually relevant outside the data viewer? def get_event_i(self, i_event): + read_time = time.time() event = NuRadioReco.framework.event.Event(*self.get_event_ids()[i_event]) for i_file, filename in enumerate(self.__filenames): if self.__i_events_per_file[i_file, 0] <= i_event < self.__i_events_per_file[i_file, 1]: i_event_in_file = i_event - self.__i_events_per_file[i_file, 0] file = self.__open_file(self.__filenames[i_file]) - station = NuRadioReco.framework.station.Station((file['waveforms']['station_number'].array(library='np')[i_event_in_file])) + station = NuRadioReco.framework.station.Station((file['waveforms']['station_number'].array(library='np', entry_start=i_event_in_file, entry_stop=(i_event_in_file+1))[0])) # station not set properly in first runs, try from header if station.get_id() == 0 and 'header' in file: - station = NuRadioReco.framework.station.Station((file['header']['station_number'].array(library='np')[i_event_in_file])) + station = NuRadioReco.framework.station.Station((file['header']['station_number'].array(library='np', entry_start=i_event_in_file, entry_stop=(i_event_in_file+1))[0])) station.set_is_neutrino() if 'header' in file: - unix_time = file['header']['trigger_time'].array(library='np')[i_event_in_file] + unix_time = file['header']['trigger_time'].array(library='np', entry_start=i_event_in_file, entry_stop=(i_event_in_file+1))[0] event_time = astropy.time.Time(unix_time, format='unix') station.set_station_time(event_time) ### read in basic trigger data for trigger_key in self._root_trigger_keys: try: - has_triggered = bool(file['header'][trigger_key].array(library='np')[i_event_in_file]) + has_triggered = bool(file['header'][trigger_key].array(library='np', entry_start=i_event_in_file, entry_stop=(i_event_in_file+1))[0]) trigger = NuRadioReco.framework.trigger.Trigger(trigger_key.split('.')[-1]) trigger.set_triggered(has_triggered) # trigger.set_trigger_time(file['header']['trigger_time']) @@ -89,6 +102,7 @@ def get_event_i(self, i_event): channel.set_trace(waveforms[0, i_channel]*units.mV, self.__sampling_rate) station.add_channel(channel) event.set_station(station) + logger.debug("Spent {:.0f} ms reading event {}".format((time.time()-read_time) * 1e3, i_event)) return event return None From 71452eb6dea7bd99fb8d20cc14d0bb90327b3215 Mon Sep 17 00:00:00 2001 From: Ilse Plaisier Date: Tue, 16 Nov 2021 16:32:13 +0100 Subject: [PATCH 015/418] pull from develop --- .../coax_delays/plots_coax_delays.py | 94 -- .../RNO_noise_data/detector_description.json | 1449 ----------------- .../RNO_noise_data/fiber_delays/.gitignore | 2 - .../fiber_delays/plots_fiber_delays.py | 107 -- .../gps_positions/gps_positions.py | 29 - 5 files changed, 1681 deletions(-) delete mode 100644 NuRadioReco/examples/RNO_noise_data/coax_delays/plots_coax_delays.py delete mode 100644 NuRadioReco/examples/RNO_noise_data/detector_description.json delete mode 100644 NuRadioReco/examples/RNO_noise_data/fiber_delays/.gitignore delete mode 100644 NuRadioReco/examples/RNO_noise_data/fiber_delays/plots_fiber_delays.py delete mode 100644 NuRadioReco/examples/RNO_noise_data/gps_positions/gps_positions.py diff --git a/NuRadioReco/examples/RNO_noise_data/coax_delays/plots_coax_delays.py b/NuRadioReco/examples/RNO_noise_data/coax_delays/plots_coax_delays.py deleted file mode 100644 index f7673c4ad..000000000 --- a/NuRadioReco/examples/RNO_noise_data/coax_delays/plots_coax_delays.py +++ /dev/null @@ -1,94 +0,0 @@ -import numpy as np -import matplotlib.pyplot as plt -from NuRadioReco.utilities import units -import argparse -import os - - - -parser = argparse.ArgumentParser() -parser.add_argument('--hardware_number', type=int, default = 7)# default is for station 21 -args = parser.parse_args() -hardware_number = args.hardware_number - - -coax_names = [] -# station 21: hardware number 7, station 22: hardware number 6, station 11: hardware number 5 -# if you need the surface s21 data, ask Dan or Zack. -for file in os.listdir("data/station_{}".format(hardware_number)): - if file.endswith("LOG.csv"): - file = file.replace("S21_SRX{}_".format(hardware_number), '') - coax_names.append(file.replace("_LOG.csv", '')) - - -## dict ({hardwarenumber: {cable number: number of jumper cables}}) with number of jumper cables (taken from: https://radio.uchicago.edu/wiki/index.php/File:ChannelMapping_v1.xlsx) - -jumper_cables = {'5': {'1':0,'2': 0, '3': 0 , '4': 0 , '5': 0 , '6': 0 , '7': 0 , '8': 0 , '9':0 }, -'6': {'1': 1, '2': 0, '3':2 , '4': 2 , '5': 0 , '6':2 , '7': 1 , '8': 0 , '9': 1 }, -'7': {'1': 1, '2': 0, '3': 1 , '4':1 , '5':0 , '6':1 , '7':1 , '8':0 , '9':1 } -} - -jumper_cable_delay = 3.97*0.89 #3.97 ns/m #cables of 35 inch/0.89 m, https://www.timesmicrowave.com/DataSheets/CableProducts/LMR-240.pdf - -fig1 = plt.figure(figsize=(9, 30)) -fig2 = plt.figure(figsize=(9, 30)) -for i_coax, coax_name in enumerate(coax_names): - log_mag_data = np.genfromtxt( - 'data/station_{}/S21_SRX{}_{}_LOG.csv'.format(hardware_number, hardware_number, coax_name), - delimiter=',', - skip_header=17, - skip_footer=1 - ) - mag_freqs = log_mag_data[:, 0] * units.Hz - log_magnitude = log_mag_data[:, 1] - ax1_1 = fig1.add_subplot(len(coax_names), 1, i_coax + 1) - ax1_1.grid() - ax1_1.plot( - mag_freqs / units.MHz, - np.power(10., -log_magnitude) - ) - phase_data = np.genfromtxt( - 'data/station_{}/S21_SRX{}_{}_PHASE.csv'.format(hardware_number, hardware_number, coax_name), - delimiter=',', - skip_header=17, - skip_footer=1 - ) - phase_freqs = phase_data[:, 0] * units.Hz - phase = np.unwrap(phase_data[:, 1] * units.deg) - group_delay = -.5 * np.diff(phase) / np.diff(phase_freqs) / np.pi - # phase = (phase_data[:, 1] * units.deg) - freq_mask = phase_freqs > 25 * units.MHz - ax2_1 = fig2.add_subplot(len(coax_names), 2, 2 * i_coax + 1) - ax2_1.grid() - ax2_1.plot( - phase_freqs[freq_mask] / units.MHz, - phase[freq_mask] - ) - line_fit = np.polyfit( - phase_freqs[freq_mask] * 2. * np.pi, - - phase[freq_mask], - 1 - ) - ax2_1.set_xlabel('f [MHz]') - ax2_1.set_ylabel('phase [rad]') - ax2_2 = fig2.add_subplot(len(coax_names), 2, 2 * i_coax + 2) - ax2_2.grid() - ax2_2.plot( - phase_freqs[freq_mask][:-1] / units.MHz, - group_delay[freq_mask[:-1]] / units.ns - ) - ax2_2.set_title(coax_name) - print('Coax {}: {:.2f}ns + {} * {} = {}'.format(coax_name, line_fit[0], jumper_cables[str(hardware_number)][str(coax_name)], jumper_cable_delay, line_fit[0] + jumper_cables[str(hardware_number)][str(coax_name)]*jumper_cable_delay)) - ax2_2.axhline( - line_fit[0], - color='r', - linestyle=':' - ) - ax2_2.set_xlabel('f [MHz]') - ax2_2.set_ylabel(r'$\Delta t$ [ns]') - -fig1.tight_layout() -fig1.savefig('coax_magnitudes.png') - -fig2.tight_layout() -fig2.savefig('coax_phases.png') diff --git a/NuRadioReco/examples/RNO_noise_data/detector_description.json b/NuRadioReco/examples/RNO_noise_data/detector_description.json deleted file mode 100644 index d39dfd51d..000000000 --- a/NuRadioReco/examples/RNO_noise_data/detector_description.json +++ /dev/null @@ -1,1449 +0,0 @@ -{ - "_default": {}, - "channels": { - "0": { - "amp_type": "iglu", - "ant_comment": "Phased Array Vpol", - "ant_orientation_phi": 0.0, - "ant_orientation_theta": 0.0, - "ant_position_x": 0.0, - "ant_position_y": 0.0, - "ant_position_z": -80.975, - "ant_rotation_phi": 90.0, - "ant_rotation_theta": 90.0, - "ant_type": "RNOG_vpol_4inch_center_1.73", - "cab_time_delay": 714.49, - "commission_time": "{TinyDate}:2021-07-01T00:00:00", - "decommission_time": "{TinyDate}:2035-11-01T00:00:00", - "channel_id": 0, - "station_id": 11 - }, - - - - "1": { - "amp_type": "iglu", - "ant_comment": "Phased Array Vpol", - "ant_orientation_phi": 0.0, - "ant_orientation_theta": 0.0, - "ant_position_x": 0.0, - "ant_position_y": 0.0, - "ant_position_z": -79.93, - "ant_rotation_phi": 90.0, - "ant_rotation_theta": 90.0, - "ant_type": "RNOG_vpol_4inch_center_1.73", - "cab_time_delay": 709.99, - "commission_time": "{TinyDate}:2021-07-01T00:00:00", - "decommission_time": "{TinyDate}:2035-11-01T00:00:00", - "channel_id": 1, - "station_id": 11 - }, - - "2": { - "amp_type": "iglu", - "ant_comment": "Phased Array Vpol", - "ant_orientation_phi": 0.0, - "ant_orientation_theta": 0.0, - "ant_position_x": 0.0, - "ant_position_y": 0.0, - "ant_position_z": -78.68, - "ant_rotation_phi": 90.0, - "ant_rotation_theta": 90.0, - "ant_type": "RNOG_vpol_4inch_center_1.73", - "cab_time_delay": 704.73, - "commission_time": "{TinyDate}:2021-07-01T00:00:00", - "decommission_time": "{TinyDate}:2035-11-01T00:00:00", - "channel_id": 2, - "station_id": 11 - - }, - - "3": { - "amp_type": "iglu", - "ant_comment": "Phased Array Vpol", - "ant_orientation_phi": 0.0, - "ant_orientation_theta": 0.0, - "ant_position_x": 0.0, - "ant_position_y": 0.0, - "ant_position_z": -77.89, - "ant_rotation_phi": 90.0, - "ant_rotation_theta": 90.0, - "ant_type": "RNOG_vpol_4inch_center_1.73", - "cab_time_delay": 700.43, - "commission_time": "{TinyDate}:2021-07-01T00:00:00", - "decommission_time": "{TinyDate}:2035-11-01T00:00:00", - "channel_id": 3, - "station_id": 11 - }, - - - "4": { - "amp_type": "iglu", - "ant_comment": "Power String Hpol", - "ant_orientation_phi": 0.0, - "ant_orientation_theta": 0.0, - "ant_position_x": 0.0, - "ant_position_y": 0.0, - "ant_position_z": -76.9, - "ant_rotation_phi": 90.0, - "ant_rotation_theta": 90.0, - "ant_type": "RNOG_quadslot_v3_air_rescaled_to_n1.74", - "cab_time_delay": 695.01, - "commission_time": "{TinyDate}:2021-07-01T00:00:00", - "decommission_time": "{TinyDate}:2035-11-01T00:00:00", - "channel_id": 8, - "station_id": 11 - }, - - "5": { - "amp_type": "iglu", - "ant_comment": "Power String Hpol", - "ant_orientation_phi": 0.0, - "ant_orientation_theta": 0.0, - "ant_position_x": 0.0, - "ant_position_y": 0.0, - "ant_position_z": -75.97, - "ant_rotation_phi": 90.0, - "ant_rotation_theta": 90.0, - "ant_type": "RNOG_quadslot_v3_air_rescaled_to_n1.74", - "commission_time": "{TinyDate}:2021-07-01T00:00:00", - "decommission_time": "{TinyDate}:2035-11-01T00:00:00", - "cab_time_delay": 690.62, - "channel_id": 4, - "station_id": 11 - }, - - "6": { - "amp_type": "iglu", - "ant_comment": "Power String Vpol", - "ant_orientation_phi": 0.0, - "ant_orientation_theta": 0.0, - "ant_position_x": 0.0, - "ant_position_y": 0.0, - "ant_position_z": -63.88, - "ant_rotation_phi": 90.0, - "ant_rotation_theta": 90.0, - "ant_type": "RNOG_vpol_4inch_center_1.73", - "commission_time": "{TinyDate}:2021-07-01T00:00:00", - "decommission_time": "{TinyDate}:2035-11-01T00:00:00", - "cab_time_delay": 583.35, - "channel_id": 5, - "station_id": 11 - }, - - "7": { - "amp_type": "iglu", - "ant_comment": "Power String Vpol", - "ant_orientation_phi": 0.0, - "ant_orientation_theta": 0.0, - "ant_position_x": 0.0, - "ant_position_y": 0.0, - "ant_position_z": -63.88, - "ant_rotation_phi": 90.0, - "ant_rotation_theta": 90.0, - "ant_type": "RNOG_vpol_4inch_center_1.73", - "commission_time": "{TinyDate}:2021-07-01T00:00:00", - "decommission_time": "{TinyDate}:2035-11-01T00:00:00", - "cab_time_delay": 484.26, - "channel_id": 6, - "station_id": 11 - }, - - - "8": { - "amp_type": "iglu", - "ant_comment": "Power String Vpol", - "ant_orientation_phi": 0.0, - "ant_orientation_theta": 0.0, - "ant_position_x": 0.0, - "ant_position_y": 0.0, - "ant_position_z": -63.88, - "ant_rotation_phi": 90.0, - "ant_rotation_theta": 90.0, - "ant_type": "RNOG_vpol_4inch_center_1.73", - "commission_time": "{TinyDate}:2021-07-01T00:00:00", - "decommission_time": "{TinyDate}:2035-11-01T00:00:00", - "cab_time_delay": 387.12, - "channel_id": 7, - "station_id": 11 - }, - - - - "9": { - "amp_type": "iglu", - "ant_comment": "Helper String B Vpol", - "ant_orientation_phi": 0.0, - "ant_orientation_theta": 0.0, - "ant_position_x": 17.65, - "ant_position_y": -26.72, - "ant_position_z": -87.57, - "ant_rotation_phi": 90.0, - "ant_rotation_theta": 90.0, - "ant_type": "RNOG_vpol_4inch_center_1.73", - "cab_time_delay": 704.73, - "commission_time": "{TinyDate}:2021-07-01T00:00:00", - "decommission_time": "{TinyDate}:2035-11-01T00:00:00", - "channel_id": 9, - "station_id": 11 - }, - - "10": { - "amp_type": "iglu", - "ant_comment": "Helper String B Vpol", - "ant_orientation_phi": 0.0, - "ant_orientation_theta": 0.0, - "ant_position_x": 17.65, - "ant_position_y": -26.72, - "ant_position_z": -86, - "ant_rotation_phi": 90.0, - "ant_rotation_theta": 90.0, - "ant_type": "RNOG_vpol_4inch_center_1.73", - "cab_time_delay": 700.31, - "commission_time": "{TinyDate}:2021-07-01T00:00:00", - "decommission_time": "{TinyDate}:2035-11-01T00:00:00", - "channel_id": 10, - "station_id": 11 - }, - - - - "11": { - "amp_type": "iglu", - "ant_comment": "Helper String B Hpol", - "ant_orientation_phi": 0.0, - "ant_orientation_theta": 0.0, - "ant_position_x": 17.65, - "ant_position_y": -26.72, - "ant_position_z": -84.72, - "ant_rotation_phi": 90.0, - "ant_rotation_theta": 90.0, - "ant_type": "RNOG_quadslot_v3_air_rescaled_to_n1.74", - "cab_time_delay": 695.13, - "commission_time": "{TinyDate}:2021-07-01T00:00:00", - "decommission_time": "{TinyDate}:2035-11-01T00:00:00", - "channel_id": 11, - "station_id": 11 - }, - "12": { - "amp_type": "rno_surface", - "ant_comment": "rno_surface, Helper C", - "ant_orientation_phi": 300.0, - "ant_orientation_theta": 120.0, - "ant_position_x": 25.41, - "ant_position_y": -9.14, - "ant_position_z": -1.5, - "ant_rotation_phi": 30.0, - "ant_rotation_theta": 90.0, - "ant_type": "createLPDA_100MHz_InfFirn_n1.4", - "cab_time_delay": 45.95, - "commission_time": "{TinyDate}:2021-07-01T00:00:00", - "decommission_time": "{TinyDate}:2035-11-01T00:00:00", - "channel_id": 12, - "station_id": 11 - }, - "13": { - "amp_type": "rno_surface", - "ant_comment": "rno_surface, Helper C", - "ant_orientation_phi": 0.0, - "ant_orientation_theta": 0.0, - "ant_position_x": 24.36, - "ant_position_y": -6.74, - "ant_position_z": -1.5, - "ant_rotation_phi": 30.0, - "ant_rotation_theta": 90.0, - "ant_type": "createLPDA_100MHz_InfFirn_n1.4", - "cab_time_delay": 45.88, - "commission_time": "{TinyDate}:2021-07-01T00:00:00", - "decommission_time": "{TinyDate}:2035-11-01T00:00:00", - "channel_id": 13, - "station_id": 11 - }, - "14": { - "amp_type": "rno_surface", - "ant_comment": "rno_surface, Helper C", - "ant_orientation_phi": 120.0, - "ant_orientation_theta": 120.0, - "ant_position_x": 22.99, - "ant_position_y": -4.18, - "ant_position_z": -1.5, - "ant_rotation_phi": 30.0, - "ant_rotation_theta": 90.0, - "ant_type": "createLPDA_100MHz_InfFirn_n1.4", - "cab_time_delay": 45.6, - "commission_time": "{TinyDate}:2021-07-01T00:00:00", - "decommission_time": "{TinyDate}:2035-11-01T00:00:00", - "channel_id": 14, - "station_id": 11 - }, - "15": { - "amp_type": "rno_surface", - "ant_comment": "rno_surface, Power String", - "ant_orientation_phi": 60.0, - "ant_orientation_theta": 120.0, - "ant_position_x": 13.09, - "ant_position_y": -1.349, - "ant_position_z": -1.5, - "ant_rotation_phi": 150.0, - "ant_rotation_theta": 90.0, - "ant_type": "createLPDA_100MHz_InfFirn_n1.4", - "cab_time_delay": 45.38, - "commission_time": "{TinyDate}:2021-07-01T00:00:00", - "decommission_time": "{TinyDate}:2035-11-01T00:00:00", - "channel_id": 15, - "station_id": 11 - }, - "16": { - "amp_type": "rno_surface", - "ant_comment": "rno_surface, Power String", - "ant_orientation_phi": 0.0, - "ant_orientation_theta": 0.0, - "ant_position_x": 11.93, - "ant_position_y": -3.68, - "ant_position_z": -1.5, - "ant_rotation_phi": 150.0, - "ant_rotation_theta": 90.0, - "ant_type": "createLPDA_100MHz_InfFirn_n1.4", - "cab_time_delay": 45.4, - "commission_time": "{TinyDate}:2021-07-01T00:00:00", - "decommission_time": "{TinyDate}:2035-11-01T00:00:00", - "channel_id": 16, - "station_id": 11 - }, - "17": { - "amp_type": "rno_surface", - "ant_comment": "rno_surface, Power String", - "ant_orientation_phi": 240.0, - "ant_orientation_theta": 120.0, - "ant_position_x": 11.294, - "ant_position_y": -8.875, - "ant_position_z": -1.5, - "ant_rotation_phi": 150.0, - "ant_rotation_theta": 90.0, - "ant_type": "createLPDA_100MHz_InfFirn_n1.4", - "cab_time_delay": 45.31, - "commission_time": "{TinyDate}:2021-07-01T00:00:00", - "decommission_time": "{TinyDate}:2035-11-01T00:00:00", - "channel_id": 17, - "station_id": 11 - }, - "18": { - "amp_type": "rno_surface", - "ant_comment": "rno_surface, Helper B", - "ant_orientation_phi": 180.0, - "ant_orientation_theta": 120.0, - "ant_position_x": 15.66, - "ant_position_y": -17.09, - "ant_position_z": -1.5, - "ant_rotation_phi": 270.0, - "ant_rotation_theta": 90.0, - "ant_type": "createLPDA_100MHz_InfFirn_n1.4", - "cab_time_delay": 45.31, - "commission_time": "{TinyDate}:2021-07-01T00:00:00", - "decommission_time": "{TinyDate}:2035-11-01T00:00:00", - "channel_id": 18, - "station_id": 11 - }, - "19": { - "amp_type": "rno_surface", - "ant_comment": "rno_surface, Helper B", - "ant_orientation_phi": 0.0, - "ant_orientation_theta": 0.0, - "ant_position_x": 18.37, - "ant_position_y": -16.26, - "ant_position_z": -1.5, - "ant_rotation_phi": 270.0, - "ant_rotation_theta": 90.0, - "ant_type": "createLPDA_100MHz_InfFirn_n1.4", - "cab_time_delay": 45.43, - "commission_time": "{TinyDate}:2021-07-01T00:00:00", - "decommission_time": "{TinyDate}:2035-11-01T00:00:00", - "channel_id": 19, - "station_id": 11 - - - }, - "20": { - "amp_type": "rno_surface", - "ant_comment": "rno_surface, Helper B", - "ant_orientation_phi": 0.0, - "ant_orientation_theta": 120.0, - "ant_position_x": 21.33, - "ant_position_y": -17.22, - "ant_position_z": -1.5, - "ant_rotation_phi": 270.0, - "ant_rotation_theta": 90.0, - "ant_type": "createLPDA_100MHz_InfFirn_n1.4", - "cab_time_delay": 45.73, - "commission_time": "{TinyDate}:2021-07-01T00:00:00", - "decommission_time": "{TinyDate}:2035-11-01T00:00:00", - "channel_id": 20, - "station_id": 11 - }, - "21": { - "amp_type": "iglu", - "ant_comment": "Helper String C Vpol", - "ant_orientation_phi": 0.0, - "ant_orientation_theta": 0.0, - "ant_position_x": 34.17, - "ant_position_y": 3.18, - "ant_position_z": -96.67, - "ant_rotation_phi": 90.0, - "ant_rotation_theta": 90.0, - "ant_type": "RNOG_vpol_4inch_center_1.73", - "cab_time_delay": 704.73, - "commission_time": "{TinyDate}:2021-07-01T00:00:00", - "decommission_time": "{TinyDate}:2035-11-01T00:00:00", - "channel_id": 23, - "station_id": 11 - }, - "22": { - "amp_type": "iglu", - "ant_comment": "Helper String C Vpol", - "ant_orientation_phi": 0.0, - "ant_orientation_theta": 0.0, - "ant_position_x": 34.17, - "ant_position_y": 3.18, - "ant_position_z": -95.66, - "ant_rotation_phi": 90.0, - "ant_rotation_theta": 90.0, - "ant_type": "RNOG_vpol_4inch_center_1.73", - "cab_time_delay": 700.47, - "commission_time": "{TinyDate}:2021-07-01T00:00:00", - "decommission_time": "{TinyDate}:2035-11-01T00:00:00", - "channel_id": 22, - "station_id": 11 - }, - "23": { - "amp_type": "iglu", - "ant_comment": "Helper String C Hpol", - "ant_orientation_phi": 0.0, - "ant_orientation_theta": 0.0, - "ant_position_x": 34.17, - "ant_position_y": 3.18, - "ant_position_z": -94.66, - "ant_rotation_phi": 90.0, - "ant_rotation_theta": 90.0, - "ant_type": "RNOG_quadslot_v3_air_rescaled_to_n1.74", - "cab_time_delay": 695.03, - "commission_time": "{TinyDate}:2021-07-01T00:00:00", - "decommission_time": "{TinyDate}:2035-11-01T00:00:00", - "channel_id": 21, - "station_id": 11 - }, - "24": { - "amp_type": "iglu", - "ant_comment": "Phased Array Vpol", - "ant_orientation_phi": 0.0, - "ant_orientation_theta": 0.0, - "ant_position_x": 0.0, - "ant_position_y": 0.0, - "ant_position_z": -95.37, - "ant_rotation_phi": 90.0, - "ant_rotation_theta": 90.0, - "ant_type": "RNOG_vpol_4inch_center_1.73", - "cab_time_delay": 714.47, - "commission_time": "{TinyDate}:2021-07-01T00:00:00", - "decommission_time": "{TinyDate}:2035-11-01T00:00:00", - "channel_id": 0, - "station_id": 21 - }, - "25": { - "amp_type": "iglu", - "ant_comment": "Phased Array Vpol", - "ant_orientation_phi": 0.0, - "ant_orientation_theta": 0.0, - "ant_position_x": 0.0, - "ant_position_y": 0.0, - "ant_position_z": -94.37, - "ant_rotation_phi": 90.0, - "ant_rotation_theta": 90.0, - "ant_type": "RNOG_vpol_4inch_center_1.73", - "cab_time_delay": 709.91, - "commission_time": "{TinyDate}:2021-07-01T00:00:00", - "decommission_time": "{TinyDate}:2035-11-01T00:00:00", - "channel_id": 1, - "station_id": 21 - }, - "26": { - "amp_type": "iglu", - "ant_comment": "Phased Array Vpol", - "ant_orientation_phi": 0.0, - "ant_orientation_theta": 0.0, - "ant_position_x": 0.0, - "ant_position_y": 0.0, - "ant_position_z": -93.36, - "ant_rotation_phi": 90.0, - "ant_rotation_theta": 90.0, - "ant_type": "RNOG_vpol_4inch_center_1.73", - "cab_time_delay": 704.54, - "commission_time": "{TinyDate}:2021-07-01T00:00:00", - "decommission_time": "{TinyDate}:2035-11-01T00:00:00", - "channel_id": 2, - "station_id": 21 - }, - "27": { - "amp_type": "iglu", - "ant_comment": "Phased Array Vpol", - "ant_orientation_phi": 0.0, - "ant_orientation_theta": 0.0, - "ant_position_x": 0.0, - "ant_position_y": 0.0, - "ant_position_z": -92.36, - "ant_rotation_phi": 90.0, - "ant_rotation_theta": 90.0, - "ant_type": "RNOG_vpol_4inch_center_1.73", - "cab_time_delay": 700.35, - "commission_time": "{TinyDate}:2021-07-01T00:00:00", - "decommission_time": "{TinyDate}:2035-11-01T00:00:00", - "channel_id": 3, - "station_id": 21 - }, - "28": { - "amp_type": "iglu", - "ant_comment": "Power String Hpol", - "ant_orientation_phi": 0.0, - "ant_orientation_theta": 0.0, - "ant_position_x": 0.0, - "ant_position_y": 0.0, - "ant_position_z": -91.37, - "ant_rotation_phi": 90.0, - "ant_rotation_theta": 90.0, - "ant_type": "RNOG_quadslot_v3_air_rescaled_to_n1.74", - "cab_time_delay": 695.03, - "commission_time": "{TinyDate}:2021-07-01T00:00:00", - "decommission_time": "{TinyDate}:2035-11-01T00:00:00", - "channel_id": 8, - "station_id": 21 - }, - "29": { - "amp_type": "iglu", - "ant_comment": "Power String Hpol", - "ant_orientation_phi": 0.0, - "ant_orientation_theta": 0.0, - "ant_position_x": 0.0, - "ant_position_y": 0.0, - "ant_position_z": -90.39, - "ant_rotation_phi": 90.0, - "ant_rotation_theta": 90.0, - "ant_type": "RNOG_quadslot_v3_air_rescaled_to_n1.74", - "cab_time_delay": 689.92, - "commission_time": "{TinyDate}:2021-07-01T00:00:00", - "decommission_time": "{TinyDate}:2035-11-01T00:00:00", - "channel_id": 4, - "station_id": 21 - }, - - "30": { - "amp_type": "iglu", - "ant_comment": "Power String Vpol", - "ant_orientation_phi": 0.0, - "ant_orientation_theta": 0.0, - "ant_position_x": 0.0, - "ant_position_y": 0.0, - "ant_position_z": -78.42, - "ant_rotation_phi": 90.0, - "ant_rotation_theta": 90.0, - "ant_type": "RNOG_vpol_4inch_center_1.73", - "cab_time_delay": 583.87, - "commission_time": "{TinyDate}:2021-07-01T00:00:00", - "decommission_time": "{TinyDate}:2035-11-01T00:00:00", - "channel_id": 5, - "station_id": 21 - }, - "31": { - "amp_type": "iglu", - "ant_comment": "Power String Vpol", - "ant_orientation_phi": 0.0, - "ant_orientation_theta": 0.0, - "ant_position_x": 0.0, - "ant_position_y": 0.0, - "ant_position_z": -57.98, - "ant_rotation_phi": 90.0, - "ant_rotation_theta": 90.0, - "ant_type": "RNOG_vpol_4inch_center_1.73", - "cab_time_delay": 484.74, - "commission_time": "{TinyDate}:2021-07-01T00:00:00", - "decommission_time": "{TinyDate}:2035-11-01T00:00:00", - "channel_id": 6, - "station_id": 21 - }, - "32": { - "amp_type": "iglu", - "ant_comment": "Power String Vpol", - "ant_orientation_phi": 0.0, - "ant_orientation_theta": 0.0, - "ant_position_x": 0.0, - "ant_position_y": 0.0, - "ant_position_z": -38.33, - "ant_rotation_phi": 90.0, - "ant_rotation_theta": 90.0, - "ant_type": "RNOG_vpol_4inch_center_1.73", - "cab_time_delay": 387.61, - "commission_time": "{TinyDate}:2021-07-01T00:00:00", - "decommission_time": "{TinyDate}:2035-11-01T00:00:00", - "channel_id": 7, - "station_id": 21 - }, - "33": { - "amp_type": "iglu", - "ant_comment": "Helper String B Vpol", - "ant_orientation_phi": 0.0, - "ant_orientation_theta": 0.0, - "ant_position_x": -17.2, - "ant_position_y": 29.097, - "ant_position_z": -94.7, - "ant_rotation_phi": 90.0, - "ant_rotation_theta": 90.0, - "ant_type": "RNOG_vpol_4inch_center_1.73", - "cab_time_delay": 706.05, - "commission_time": "{TinyDate}:2021-07-01T00:00:00", - "decommission_time": "{TinyDate}:2035-11-01T00:00:00", - "channel_id": 9, - "station_id": 21 - }, - "34": { - "amp_type": "iglu", - "ant_comment": "Helper String B Vpol", - "ant_orientation_phi": 0.0, - "ant_orientation_theta": 0.0, - "ant_position_x": -17.2, - "ant_position_y": 29.097, - "ant_position_z": -93.71, - "ant_rotation_phi": 90.0, - "ant_rotation_theta": 90.0, - "ant_type": "RNOG_vpol_4inch_center_1.73", - "cab_time_delay": 701.72, - "commission_time": "{TinyDate}:2021-07-01T00:00:00", - "decommission_time": "{TinyDate}:2035-11-01T00:00:00", - "channel_id": 10, - "station_id": 21 - }, - "35": { - "amp_type": "iglu", - "ant_comment": "Helper String B Hpol", - "ant_orientation_phi": 0.0, - "ant_orientation_theta": 0.0, - "ant_position_x": -17.2, - "ant_position_y": 29.097, - "ant_position_z": -92.7, - "ant_rotation_phi": 90.0, - "ant_rotation_theta": 90.0, - "ant_type": "RNOG_quadslot_v3_air_rescaled_to_n1.74", - "cab_time_delay": 696.54, - "commission_time": "{TinyDate}:2021-07-01T00:00:00", - "decommission_time": "{TinyDate}:2035-11-01T00:00:00", - "channel_id": 11, - "station_id": 21 - }, - "36": { - "amp_type": "rno_surface", - "ant_comment": "rno_surface, Helper C", - "ant_orientation_phi": 300.0, - "ant_orientation_theta": 120.0, - "ant_position_x": -22.46, - "ant_position_y": 3.208, - "ant_position_z": -1.5, - "ant_rotation_phi": 210, - "ant_rotation_theta": 90.0, - "ant_type": "createLPDA_100MHz_InfFirn_n1.4", - "cab_time_delay": 49.30, - "commission_time": "{TinyDate}:2021-07-01T00:00:00", - "decommission_time": "{TinyDate}:2035-11-01T00:00:00", - "channel_id": 12, - "station_id": 21 - }, - "37": { - "amp_type": "rno_surface", - "ant_comment": "rno_surface, Helper C", - "ant_orientation_phi": 0.0, - "ant_orientation_theta": 0.0, - "ant_position_x": -23.817, - "ant_position_y": 5.259, - "ant_position_z": -1.5, - "ant_rotation_phi": 210, - "ant_rotation_theta": 90.0, - "ant_type": "createLPDA_100MHz_InfFirn_n1.4", - "cab_time_delay": 45.43, - "commission_time": "{TinyDate}:2021-07-01T00:00:00", - "decommission_time": "{TinyDate}:2035-11-01T00:00:00", - "channel_id": 13, - "station_id": 21 - }, - "38": { - "amp_type": "rno_surface", - "ant_comment": "rno_surface, Helper C", - "ant_orientation_phi": 120.0, - "ant_orientation_theta": 120.0, - "ant_position_x": -25.07, - "ant_position_y": 7.49, - "ant_position_z": -1.5, - "ant_rotation_phi": 210, - "ant_rotation_theta": 90.0, - "ant_type": "createLPDA_100MHz_InfFirn_n1.4", - "cab_time_delay": 49.36, - "commission_time": "{TinyDate}:2021-07-01T00:00:00", - "decommission_time": "{TinyDate}:2035-11-01T00:00:00", - "channel_id": 14, - "station_id": 21 - }, - "39": { - "amp_type": "rno_surface", - "ant_comment": "rno_surface, Helper B", - "ant_orientation_phi": 180.0, - "ant_orientation_theta": 120.0, - "ant_position_x": -20.61, - "ant_position_y": 16.93, - "ant_position_z": -1.5, - "ant_rotation_phi": 90, - "ant_rotation_theta": 90.0, - "ant_type": "createLPDA_100MHz_InfFirn_n1.4", - "cab_time_delay": 49.19, - "commission_time": "{TinyDate}:2021-07-01T00:00:00", - "decommission_time": "{TinyDate}:2035-11-01T00:00:00", - "channel_id": 15, - "station_id": 21 - }, - - "40": { - "amp_type": "rno_surface", - "ant_comment": "rno_surface, Helper B", - "ant_orientation_phi": 0.0, - "ant_orientation_theta": 0.0, - "ant_position_x": -18.2, - "ant_position_y": 17.16, - "ant_position_z": -1.5, - "ant_rotation_phi": 90, - "ant_rotation_theta": 90.0, - "ant_type": "createLPDA_100MHz_InfFirn_n1.4", - "cab_time_delay": 45.82, - "commission_time": "{TinyDate}:2021-07-01T00:00:00", - "decommission_time": "{TinyDate}:2035-11-01T00:00:00", - "channel_id": 16, - "station_id": 21 - }, - "41": { - "amp_type": "rno_surface", - "ant_comment": "rno_surface, Helper B", - "ant_orientation_phi": 0.0, - "ant_orientation_theta": 120.0, - "ant_position_x": -15.62, - "ant_position_y": 17.54, - "ant_position_z": -1.5, - "ant_rotation_phi": 90, - "ant_rotation_theta": 90.0, - "ant_type": "createLPDA_100MHz_InfFirn_n1.4", - "cab_time_delay": 48.89, - "commission_time": "{TinyDate}:2021-07-01T00:00:00", - "decommission_time": "{TinyDate}:2035-11-01T00:00:00", - "channel_id": 17, - "station_id": 21 - }, - "42": { - "amp_type": "rno_surface", - "ant_comment": "rno_surface, Power String", - "ant_orientation_phi": 60.0, - "ant_orientation_theta": 120.0, - "ant_position_x": -8.52, - "ant_position_y": 8.05, - "ant_position_z": -1.5, - "ant_rotation_phi": 330, - "ant_rotation_theta": 90.0, - "ant_type": "createLPDA_100MHz_InfFirn_n1.4", - "cab_time_delay": 49.42, - "commission_time": "{TinyDate}:2021-07-01T00:00:00", - "decommission_time": "{TinyDate}:2035-11-01T00:00:00", - "channel_id": 18, - "station_id": 21 - }, - "43": { - "amp_type": "rno_surface", - "ant_comment": "rno_surface, Power String", - "ant_orientation_phi": 0.0, - "ant_orientation_theta": 0.0, - "ant_position_x": -9.89, - "ant_position_y": 5.59, - "ant_position_z": -1.5, - "ant_rotation_phi": 330, - "ant_rotation_theta": 90.0, - "ant_type": "createLPDA_100MHz_InfFirn_n1.4", - "commission_time": "{TinyDate}:2021-07-01T00:00:00", - "decommission_time": "{TinyDate}:2035-11-01T00:00:00", - "cab_time_delay": 45.75, - "channel_id": 19, - "station_id": 21 - }, - "44": { - "amp_type": "rno_surface", - "ant_comment": "rno_surface, Power String", - "ant_orientation_phi": 240.0, - "ant_orientation_theta": 120.0, - "ant_position_x": -11.29, - "ant_position_y": 3.22, - "ant_position_z": -1.5, - "ant_rotation_phi": 330.0, - "ant_rotation_theta": 90.0, - "ant_type": "createLPDA_100MHz_InfFirn_n1.4", - "commission_time": "{TinyDate}:2021-07-01T00:00:00", - "decommission_time": "{TinyDate}:2035-11-01T00:00:00", - "cab_time_delay": 48.93, - "channel_id": 20, - "station_id": 21 - }, - "45": { - "amp_type": "iglu", - "ant_comment": "Helper String C Vpol", - "ant_orientation_phi": 0.0, - "ant_orientation_theta": 0.0, - "ant_position_x": -33.64, - "ant_position_y": -0.8, - "ant_position_z": -95.37, - "ant_rotation_phi": 90.0, - "ant_rotation_theta": 90.0, - "ant_type": "RNOG_vpol_4inch_center_1.73", - "commission_time": "{TinyDate}:2021-07-01T00:00:00", - "decommission_time": "{TinyDate}:2035-11-01T00:00:00", - "cab_time_delay": 705.24, - "channel_id": 23, - "station_id": 21 - }, - "46": { - "amp_type": "iglu", - "ant_comment": "Helper String C Vpol", - "ant_orientation_phi": 0.0, - "ant_orientation_theta": 0.0, - "ant_position_x": -33.64, - "ant_position_y": -0.8, - "ant_position_z": -94.34, - "ant_rotation_phi": 90.0, - "ant_rotation_theta": 90.0, - "ant_type": "RNOG_vpol_4inch_center_1.73", - "commission_time": "{TinyDate}:2021-07-01T00:00:00", - "decommission_time": "{TinyDate}:2035-11-01T00:00:00", - "cab_time_delay": 701.09, - "channel_id": 22, - "station_id": 21 - }, - "47": { - "amp_type": "iglu", - "ant_comment": "Helper String C Hpol", - "ant_orientation_phi": 0.0, - "ant_orientation_theta": 0.0, - "ant_position_x": -33.64, - "ant_position_y": -0.8, - "ant_position_z": -93.37, - "ant_rotation_phi": 90.0, - "ant_rotation_theta": 90.0, - "ant_type": "RNOG_quadslot_v3_air_rescaled_to_n1.74", - "commission_time": "{TinyDate}:2021-07-01T00:00:00", - "decommission_time": "{TinyDate}:2035-11-01T00:00:00", - "cab_time_delay": 695.83, - "channel_id": 21, - "station_id": 21 - }, - "48": { - "amp_type": "iglu", - "ant_comment": "Phased Array Vpol", - "ant_orientation_phi": 0.0, - "ant_orientation_theta": 0.0, - "ant_position_x": 0.0, - "ant_position_y": 0.0, - "ant_position_z": -95.67, - "ant_rotation_phi": 90.0, - "ant_rotation_theta": 90.0, - "ant_type": "RNOG_vpol_4inch_center_1.73", - "commission_time": "{TinyDate}:2021-07-01T00:00:00", - "decommission_time": "{TinyDate}:2035-11-01T00:00:00", - "cab_time_delay": 714.76, - "channel_id": 0, - "station_id": 22 - }, - "49": { - "amp_type": "iglu", - "ant_comment": "Phased Array Vpol", - "ant_orientation_phi": 0.0, - "ant_orientation_theta": 0.0, - "ant_position_x": 0.0, - "ant_position_y": 0.0, - "ant_position_z": -94.66, - "ant_rotation_phi": 90.0, - "ant_rotation_theta": 90.0, - "ant_type": "RNOG_vpol_4inch_center_1.73", - "commission_time": "{TinyDate}:2021-07-01T00:00:00", - "decommission_time": "{TinyDate}:2035-11-01T00:00:00", - "cab_time_delay": 710.17, - "channel_id": 1, - "station_id": 22 - }, - "50": { - "amp_type": "iglu", - "ant_comment": "Phased Array Vpol", - "ant_orientation_phi": 0.0, - "ant_orientation_theta": 0.0, - "ant_position_x": 0.0, - "ant_position_y": 0.0, - "ant_position_z": -93.66, - "ant_rotation_phi": 90.0, - "ant_rotation_theta": 90.0, - "ant_type": "RNOG_vpol_4inch_center_1.73", - "commission_time": "{TinyDate}:2021-07-01T00:00:00", - "decommission_time": "{TinyDate}:2035-11-01T00:00:00", - "cab_time_delay": 704.9, - "channel_id": 2, - "station_id": 22 - }, - "51": { - "amp_type": "iglu", - "ant_comment": "Phased Array Vpol", - "ant_orientation_phi": 0.0, - "ant_orientation_theta": 0.0, - "ant_position_x": 0.0, - "ant_position_y": 0.0, - "ant_position_z": -92.66, - "ant_rotation_phi": 90.0, - "ant_rotation_theta": 90.0, - "ant_type": "RNOG_vpol_4inch_center_1.73", - "commission_time": "{TinyDate}:2021-07-01T00:00:00", - "decommission_time": "{TinyDate}:2035-11-01T00:00:00", - "cab_time_delay": 700.45, - "channel_id": 3, - "station_id": 22 - }, - "52": { - "amp_type": "iglu", - "ant_comment": "Power String Hpol", - "ant_orientation_phi": 0.0, - "ant_orientation_theta": 0.0, - "ant_position_x": 0.0, - "ant_position_y": 0.0, - "ant_position_z": -91.67, - "ant_rotation_phi": 90.0, - "ant_rotation_theta": 90.0, - "ant_type": "RNOG_quadslot_v3_air_rescaled_to_n1.74", - "commission_time": "{TinyDate}:2021-07-01T00:00:00", - "decommission_time": "{TinyDate}:2035-11-01T00:00:00", - "cab_time_delay": 695.16, - "channel_id": 8, - "station_id": 22 - }, - "53": { - "amp_type": "iglu", - "ant_comment": "Power String Hpol", - "ant_orientation_phi": 0.0, - "ant_orientation_theta": 0.0, - "ant_position_x": 0.0, - "ant_position_y": 0.0, - "ant_position_z": -90.72, - "ant_rotation_phi": 90.0, - "ant_rotation_theta": 90.0, - "ant_type": "RNOG_quadslot_v3_air_rescaled_to_n1.74", - "commission_time": "{TinyDate}:2021-07-01T00:00:00", - "decommission_time": "{TinyDate}:2035-11-01T00:00:00", - "cab_time_delay": 690.6, - "channel_id": 4, - "station_id": 22 - }, - "54": { - "amp_type": "iglu", - "ant_comment": "Power String Vpol", - "ant_orientation_phi": 0.0, - "ant_orientation_theta": 0.0, - "ant_position_x": 0.0, - "ant_position_y": 0.0, - "ant_position_z": -78.7, - "ant_rotation_phi": 90.0, - "ant_rotation_theta": 90.0, - "ant_type": "RNOG_vpol_4inch_center_1.73", - "commission_time": "{TinyDate}:2021-07-01T00:00:00", - "decommission_time": "{TinyDate}:2035-11-01T00:00:00", - "cab_time_delay": 583.41, - "channel_id": 5, - "station_id": 22 - }, - "55": { - "amp_type": "iglu", - "ant_comment": "Power String Vpol", - "ant_orientation_phi": 0.0, - "ant_orientation_theta": 0.0, - "ant_position_x": 0.0, - "ant_position_y": 0.0, - "ant_position_z": -58.62, - "ant_rotation_phi": 90.0, - "ant_rotation_theta": 90.0, - "ant_type": "RNOG_vpol_4inch_center_1.73", - "commission_time": "{TinyDate}:2021-07-01T00:00:00", - "decommission_time": "{TinyDate}:2035-11-01T00:00:00", - "cab_time_delay": 484.86, - "channel_id": 6, - "station_id": 22 - }, - - "56": { - "amp_type": "iglu", - "ant_comment": "Power String Vpol", - "ant_orientation_phi": 0.0, - "ant_orientation_theta": 0.0, - "ant_position_x": 0.0, - "ant_position_y": 0.0, - "ant_position_z": -38.53, - "ant_rotation_phi": 90.0, - "ant_rotation_theta": 90.0, - "ant_type": "RNOG_vpol_4inch_center_1.73", - "commission_time": "{TinyDate}:2021-07-01T00:00:00", - "decommission_time": "{TinyDate}:2035-11-01T00:00:00", - "cab_time_delay": 387.55, - "channel_id": 7, - "station_id": 22 - }, - "57": { - "amp_type": "iglu", - "ant_comment": "Helper String B Vpol", - "ant_orientation_phi": 0.0, - "ant_orientation_theta": 0.0, - "ant_position_x": -17.51, - "ant_position_y": 33.13, - "ant_position_z": -96.8, - "ant_rotation_phi": 90.0, - "ant_rotation_theta": 90.0, - "ant_type": "RNOG_vpol_4inch_center_1.73", - "commission_time": "{TinyDate}:2021-07-01T00:00:00", - "decommission_time": "{TinyDate}:2035-11-01T00:00:00", - "cab_time_delay": 704.91, - "channel_id": 9, - "station_id": 22 - }, - "58": { - "amp_type": "iglu", - "ant_comment": "Helper String B Vpol", - "ant_orientation_phi": 0.0, - "ant_orientation_theta": 0.0, - "ant_position_x": -17.51, - "ant_position_y": 33.13, - "ant_position_z": -95.8, - "ant_rotation_phi": 90.0, - "ant_rotation_theta": 90.0, - "ant_type": "RNOG_vpol_4inch_center_1.73", - "commission_time": "{TinyDate}:2021-07-01T00:00:00", - "decommission_time": "{TinyDate}:2035-11-01T00:00:00", - "cab_time_delay": 700.52, - "channel_id": 10, - "station_id": 22 - }, - "59": { - "amp_type": "iglu", - "ant_comment": "Helper String B Hpol", - "ant_orientation_phi": 0.0, - "ant_orientation_theta": 0.0, - "ant_position_x": -17.51, - "ant_position_y": 33.13, - "ant_position_z": -94.8, - "ant_rotation_phi": 90.0, - "ant_rotation_theta": 90.0, - "ant_type": "RNOG_quadslot_v3_air_rescaled_to_n1.74", - "commission_time": "{TinyDate}:2021-07-01T00:00:00", - "decommission_time": "{TinyDate}:2035-11-01T00:00:00", - "cab_time_delay": 695.17, - "channel_id": 11, - "station_id": 22 - }, - - "60": { - "amp_type": "rno_surface", - "ant_comment": "rno_surface, Helper C, pointing side-downwards", - "ant_orientation_phi": 300.0, - "ant_orientation_theta": 120.0, - "ant_position_x": 9.12, - "ant_position_y": 17.6, - "ant_position_z": -1.5, - "ant_rotation_phi": 30.0, - "ant_rotation_theta": 90.0, - "ant_type": "createLPDA_100MHz_InfFirn_n1.4", - "commission_time": "{TinyDate}:2021-07-01T00:00:00", - "decommission_time": "{TinyDate}:2035-11-01T00:00:00", - "cab_time_delay": 49.01, - "channel_id": 12, - "station_id": 22 - }, - "61": { - "amp_type": "rno_surface", - "ant_comment": "rno_surface, Helper C, pointing upwards", - "ant_orientation_phi": 0.0, - "ant_orientation_theta": 0.0, - "ant_position_x": 7.1, - "ant_position_y": 23.12, - "ant_position_z": -1.5, - "ant_rotation_phi": 30.0, - "ant_rotation_theta": 90.0, - "ant_type": "createLPDA_100MHz_InfFirn_n1.4", - "commission_time": "{TinyDate}:2021-07-01T00:00:00", - "decommission_time": "{TinyDate}:2035-11-01T00:00:00", - "cab_time_delay": 45.99, - "channel_id": 13, - "station_id": 22 - }, - "62": { - "amp_type": "rno_surface", - "ant_comment": "rno_surface, Helper C, pointing side-downwards", - "ant_orientation_phi": 120.0, - "ant_orientation_theta": 120.0, - "ant_position_x": 5.36, - "ant_position_y": 25.5, - "ant_position_z": -1.5, - "ant_rotation_phi": 30.0, - "ant_rotation_theta": 90.0, - "ant_type": "createLPDA_100MHz_InfFirn_n1.4", - "commission_time": "{TinyDate}:2021-07-01T00:00:00", - "decommission_time": "{TinyDate}:2035-11-01T00:00:00", - "cab_time_delay": 45.46, - "channel_id": 14, - "station_id": 22 - }, - "63": { - "amp_type": "rno_surface", - "ant_comment": "rno_surface, Helper B, pointing side-downwards", - "ant_orientation_phi": 60.0, - "ant_orientation_theta": 120.0, - "ant_position_x": -6.48, - "ant_position_y": 25.95, - "ant_position_z": -1.5, - "ant_rotation_phi": 150.0, - "ant_rotation_theta": 90.0, - "ant_type": "createLPDA_100MHz_InfFirn_n1.4", - "commission_time": "{TinyDate}:2021-07-01T00:00:00", - "decommission_time": "{TinyDate}:2035-11-01T00:00:00", - "cab_time_delay": 52.85, - "channel_id": 15, - "station_id": 22 - }, - "64": { - "amp_type": "rno_surface", - "ant_comment": "rno_surface, Helper B, pointing upwards", - "ant_orientation_phi": 0.0, - "ant_orientation_theta": 0.0, - "ant_position_x": -7.49, - "ant_position_y": 23.84, - "ant_position_z": -1.5, - "ant_rotation_phi": 150.0, - "ant_rotation_theta": 90.0, - "ant_type": "createLPDA_100MHz_InfFirn_n1.4", - "commission_time": "{TinyDate}:2021-07-01T00:00:00", - "decommission_time": "{TinyDate}:2035-11-01T00:00:00", - "cab_time_delay": 45.60, - "channel_id": 16, - "station_id": 22 - }, - "65": { - "amp_type": "rno_surface", - "ant_comment": "rno_surface, Helper B, pointing side-downwards", - "ant_orientation_phi": 240.0, - "ant_orientation_theta": 120.0, - "ant_position_x": -8.6, - "ant_position_y": 21.44, - "ant_position_z": -1.5, - "ant_rotation_phi": 150.0, - "ant_rotation_theta": 90.0, - "ant_type": "createLPDA_100MHz_InfFirn_n1.4", - "commission_time": "{TinyDate}:2021-07-01T00:00:00", - "decommission_time": "{TinyDate}:2035-11-01T00:00:00", - "cab_time_delay": 52.58, - "channel_id": 17, - "station_id": 22 - }, - "66": { - "amp_type": "rno_surface", - "ant_comment": "rno_surface, Power String, pointing side-downwards", - "ant_orientation_phi": 180.0, - "ant_orientation_theta": 120.0, - "ant_position_x": -2.5, - "ant_position_y": 11.19, - "ant_position_z": -1.5, - "ant_rotation_phi": 270.0, - "ant_rotation_theta": 90.0, - "ant_type": "createLPDA_100MHz_InfFirn_n1.4", - "commission_time": "{TinyDate}:2021-07-01T00:00:00", - "decommission_time": "{TinyDate}:2035-11-01T00:00:00", - "cab_time_delay": 52.82, - "channel_id": 18, - "station_id": 22 - }, - "67": { - "amp_type": "rno_surface", - "ant_comment": "rno_surface, Power String, pointing upwards", - "ant_orientation_phi": 0.0, - "ant_orientation_theta": 0.0, - "ant_position_x": -0.22, - "ant_position_y": 11.48, - "ant_position_z": -1.5, - "ant_rotation_phi": 270.0, - "ant_rotation_theta": 90.0, - "ant_type": "createLPDA_100MHz_InfFirn_n1.4", - "commission_time": "{TinyDate}:2021-07-01T00:00:00", - "decommission_time": "{TinyDate}:2035-11-01T00:00:00", - "cab_time_delay": 45.78, - "channel_id": 19, - "station_id": 22 - }, - "68": { - "amp_type": "rno_surface", - "ant_comment": "rno_surface, Power String, pointing side-downwards", - "ant_orientation_phi": 0.0, - "ant_orientation_theta": 120.0, - "ant_position_x": 2.45, - "ant_position_y": 11.07, - "ant_position_z": -1.5, - "ant_rotation_phi": 270.0, - "ant_rotation_theta": 90.0, - "ant_type": "createLPDA_100MHz_InfFirn_n1.4", - "commission_time": "{TinyDate}:2021-07-01T00:00:00", - "decommission_time": "{TinyDate}:2035-11-01T00:00:00", - "cab_time_delay": 49.44, - "channel_id": 20, - "station_id": 22 - }, - "69": { - "amp_type": "iglu", - "ant_comment": "Helper String C Vpol", - "ant_orientation_phi": 0.0, - "ant_orientation_theta": 0.0, - "ant_position_x": 17.29, - "ant_position_y": 26.16, - "ant_position_z": -96.62, - "ant_rotation_phi": 90.0, - "ant_rotation_theta": 90.0, - "ant_type": "RNOG_vpol_4inch_center_1.73", - "commission_time": "{TinyDate}:2021-07-01T00:00:00", - "decommission_time": "{TinyDate}:2035-11-01T00:00:00", - "cab_time_delay": 704.79, - "channel_id": 23, - "station_id": 22 - }, - - "70": { - "amp_type": "iglu", - "ant_comment": "Helper String C Vpol", - "ant_orientation_phi": 0.0, - "ant_orientation_theta": 0.0, - "ant_position_x": 17.29, - "ant_position_y": 26.16, - "ant_position_z": -95.61, - "ant_rotation_phi": 90.0, - "ant_rotation_theta": 90.0, - "ant_type": "RNOG_vpol_4inch_center_1.73", - "commission_time": "{TinyDate}:2021-07-01T00:00:00", - "decommission_time": "{TinyDate}:2035-11-01T00:00:00", - "cab_time_delay": 700.51, - "channel_id": 22, - "station_id": 22 - }, - "71": { - "amp_type": "iglu", - "ant_comment": "Helper String C Hpol", - "ant_orientation_phi": 0.0, - "ant_orientation_theta": 0.0, - "ant_position_x": 17.29, - "ant_position_y": 26.16, - "ant_position_z": -94.61, - "ant_rotation_phi": 90.0, - "ant_rotation_theta": 90.0, - "ant_type": "RNOG_quadslot_v3_air_rescaled_to_n1.74", - "commission_time": "{TinyDate}:2021-07-01T00:00:00", - "decommission_time": "{TinyDate}:2035-11-01T00:00:00", - "cab_time_delay": 695.09, - "channel_id": 21, - "station_id": 22 - } - - - }, - - "devices":{ - - "1": { - "amp_type": "iglu", - "ant_comment": "Helper String B CAL Vpol", - "ant_orientation_phi": 0.0, - "ant_orientation_theta": 0.0, - "ant_position_x": 17.65, - "ant_position_y": -26.72, - "ant_position_z": -86.54, - "ant_rotation_phi": 90.0, - "ant_rotation_theta": 90.0, - "commission_time": "{TinyDate}:2021-07-01T00:00:00", - "decommission_time": "{TinyDate}:2035-11-01T00:00:00", - "device_id": 0, - "station_id": 11 - }, - - - "2": { - "amp_type": "iglu", - "ant_comment": "Helper String C CAL Vpol", - "ant_orientation_phi": 0.0, - "ant_orientation_theta": 0.0, - "ant_position_x": 34.17, - "ant_position_y": 3.18, - "ant_position_z": -95.69, - "ant_rotation_phi": 90.0, - "ant_rotation_theta": 90.0, - "commission_time": "{TinyDate}:2021-07-01T00:00:00", - "decommission_time": "{TinyDate}:2035-11-01T00:00:00", - "device_id": 1, - "station_id": 11 - }, - - - - "3": { - "amp_type": "iglu", - "ant_comment": "Helper String B CAL Vpol", - "ant_orientation_phi": 0.0, - "ant_orientation_theta": 0.0, - "ant_position_x": -17.2, - "ant_position_y": 29.097, - "ant_position_z": -93.72, - "ant_rotation_phi": 90.0, - "ant_rotation_theta": 90.0, - "commission_time": "{TinyDate}:2021-07-01T00:00:00", - "decommission_time": "{TinyDate}:2035-11-01T00:00:00", - "device_id": 2, - "station_id": 21 - }, - - "4": { - "amp_type": "iglu", - "ant_comment": "Helper String C CAL Vpol", - "ant_orientation_phi": 0.0, - "ant_orientation_theta": 0.0, - "ant_position_x": -33.64, - "ant_position_y": -0.8, - "ant_position_z": -94.37, - "ant_rotation_phi": 90.0, - "ant_rotation_theta": 90.0, - "commission_time": "{TinyDate}:2021-07-01T00:00:00", - "decommission_time": "{TinyDate}:2035-11-01T00:00:00", - "device_id": 3, - "station_id": 21 - }, - - - - "5": { - "amp_type": "iglu", - "ant_comment": "Helper String B CAL Hpol", - "ant_orientation_phi": 0.0, - "ant_orientation_theta": 0.0, - "ant_position_x": -17.51, - "ant_position_y": 33.13, - "ant_position_z": -93.8, - "ant_rotation_phi": 90.0, - "ant_rotation_theta": 90.0, - "commission_time": "{TinyDate}:2021-07-01T00:00:00", - "decommission_time": "{TinyDate}:2035-11-01T00:00:00", - "device_id": 4, - "station_id": 22 - }, - - - "6": { - "amp_type": "iglu", - "ant_comment": "Helper String C CAL Vpol", - "ant_orientation_phi": 0.0, - "ant_orientation_theta": 0.0, - "ant_position_x": 17.29, - "ant_position_y": 26.16, - "ant_position_z": -94.62, - "ant_rotation_phi": 90.0, - "ant_rotation_theta": 90.0, - "commission_time": "{TinyDate}:2021-07-01T00:00:00", - "decommission_time": "{TinyDate}:2035-11-01T00:00:00", - "device_id": 5, - "station_id": 22 - - }, - - "7": { - "amp_type": "iglu", - "ant_comment": "Surface CAL VPOL", - "ant_orientation_phi": 0.0, - "ant_orientation_theta": 0.0, - "ant_position_x": 18.52, - "ant_position_y": -1.01, - "ant_position_z": -1.5, - "ant_rotation_phi": 90.0, - "ant_rotation_theta": 90.0, - "commission_time": "{TinyDate}:2021-07-01T00:00:00", - "decommission_time": "{TinyDate}:2035-11-01T00:00:00", - "device_id": 6, - "station_id": 11 - }, - - "8": { - "amp_type": "iglu", - "ant_comment": "Surface CAL Vpol", - "ant_orientation_phi": 0.0, - "ant_orientation_theta": 0.0, - "ant_position_x": -51.46, - "ant_position_y": -29.4, - "ant_position_z": -5.6, - "ant_rotation_phi": 90.0, - "ant_rotation_theta": 90.0, - "commission_time": "{TinyDate}:2021-07-01T00:00:00", - "decommission_time": "{TinyDate}:2035-11-01T00:00:00", - "device_id": 7, - "station_id": 21 - }, - - "9": { - "amp_type": "iglu", - "ant_comment": "Surface CAL Vpol", - "ant_orientation_phi": 0.0, - "ant_orientation_theta": 0.0, - "ant_position_x": -0.16, - "ant_position_y": -33.23, - "ant_position_z": -0.5, - "ant_rotation_phi": 90.0, - "ant_rotation_theta": 90.0, - "commission_time": "{TinyDate}:2021-07-01T00:00:00", - "decommission_time": "{TinyDate}:2035-11-01T00:00:00", - "device_id": 8, - "station_id": 22 - } - - - - - }, - "positions": {}, - "stations": { - "01": { - "pos_altitude": 3247.834, - "pos_easting": -1669.182, - "pos_northing": 1196.214, - "pos_site": "summit", - "station_id": 11, - "commission_time": "{TinyDate}:2021-07-01T00:00:00", - "decommission_time": "{TinyDate}:2035-11-01T00:00:00", - "station_type": "Nanoq" - }, - "02": { - "pos_altitude": 3249.67, - "pos_easting": -405.361, - "pos_northing": 962.845, - "pos_site": "summit", - "station_id": 21, - "commission_time": "{TinyDate}:2021-07-01T00:00:00", - "decommission_time": "{TinyDate}:2035-11-01T00:00:00", - "station_type": "Amaroq" - }, - "03": { - "pos_altitude": 3250.055, - "pos_easting": -235.135, - "pos_northing": 2174.534, - "pos_site": "summit", - "station_id": 22, - "commission_time": "{TinyDate}:2021-07-01T00:00:00", - "decommission_time": "{TinyDate}:2035-11-01T00:00:00", - "station_type": "Avinngaq" - } - } -} diff --git a/NuRadioReco/examples/RNO_noise_data/fiber_delays/.gitignore b/NuRadioReco/examples/RNO_noise_data/fiber_delays/.gitignore deleted file mode 100644 index 7649c1167..000000000 --- a/NuRadioReco/examples/RNO_noise_data/fiber_delays/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -*.png -data/*.csv diff --git a/NuRadioReco/examples/RNO_noise_data/fiber_delays/plots_fiber_delays.py b/NuRadioReco/examples/RNO_noise_data/fiber_delays/plots_fiber_delays.py deleted file mode 100644 index 00815f486..000000000 --- a/NuRadioReco/examples/RNO_noise_data/fiber_delays/plots_fiber_delays.py +++ /dev/null @@ -1,107 +0,0 @@ -import numpy as np -import matplotlib.pyplot as plt -from NuRadioReco.utilities import units -import argparse -import os - - - -parser = argparse.ArgumentParser() -parser.add_argument('--hardware_number', type=int, default = 7)# default is for station 21 -args = parser.parse_args() -hardware_number = args.hardware_number - -fiber_names = [] -# if you want the data, ask Dan or Zack! -# station 21: hardware number 7, station 22: hardware number 6, station 11: hardware number 5 -for file in os.listdir("data"): - if file.startswith("{}".format(hardware_number)) and file.endswith("FULL_LM.csv"): - fiber_names.append(file.replace("_FULL_LM.csv", '')) - - - -#fiber_names = [ -# '7A1', -# '7A2', -# '7A3', -# '7A4', -# '7A5', -# '7A6', -# '7ABLUE', -# '7ABROWN', -# '7AGREEN', -# '7AORANGE', -# '7B1', -# '7B2', -# '7B3', -# '7B4', -# '7C1', -# '7C2', -# '7C3', -# '7C4' -#] - - - -fig1 = plt.figure(figsize=(8, 30)) -fig2 = plt.figure(figsize=(8, 30)) -for i_fiber, fiber_name in enumerate(fiber_names): - log_mag_data = np.genfromtxt( - 'data/{}_FULL_LM.csv'.format(fiber_name), ## data can be downloaded from https://drive.google.com/drive/folders/1mASLMMJhxWzbNFcEOQBc8KWy2cAb99GB - delimiter=',', - skip_header=17, - skip_footer=1 - ) - mag_freqs = log_mag_data[:, 0] * units.Hz - log_magnitude = log_mag_data[:, 1] - ax1_1 = fig1.add_subplot(len(fiber_names), 1, i_fiber + 1) - ax1_1.grid() - ax1_1.plot( - mag_freqs / units.MHz, - np.power(10., -log_magnitude) - ) - phase_data = np.genfromtxt( - 'data/{}_FULL_P.csv'.format(fiber_name), - delimiter=',', - skip_header=17, - skip_footer=1 - ) - phase_freqs = phase_data[:, 0] * units.Hz - phase = np.unwrap(phase_data[:, 1] * units.deg) - group_delay = -.5 * np.diff(phase) / np.diff(phase_freqs) / np.pi - # phase = (phase_data[:, 1] * units.deg) - freq_mask = phase_freqs > 25 * units.MHz - ax2_1 = fig2.add_subplot(len(fiber_names), 2, 2 * i_fiber + 1) - ax2_1.grid() - ax2_1.plot( - phase_freqs[freq_mask] / units.MHz, - phase[freq_mask] - ) - line_fit = np.polyfit( - phase_freqs[freq_mask] * 2. * np.pi, - - phase[freq_mask], - 1 - ) - ax2_1.set_xlabel('f [MHz]') - ax2_1.set_ylabel('phase [rad]') - ax2_2 = fig2.add_subplot(len(fiber_names), 2, 2 * i_fiber + 2) - ax2_2.grid() - ax2_2.plot( - phase_freqs[freq_mask][:-1] / units.MHz, - group_delay[freq_mask[:-1]] / units.ns - ) - ax2_2.set_title(fiber_name) - print('Fiber {}: {:.2f}ns'.format(fiber_name, line_fit[0])) - ax2_2.axhline( - line_fit[0], - color='r', - linestyle=':' - ) - ax2_2.set_xlabel('f [MHz]') - ax2_2.set_ylabel(r'$\Delta t$ [ns]') - -fig1.tight_layout() -fig1.savefig('fiber_magnitudes.png') - -fig2.tight_layout() -fig2.savefig('fiber_phases.png') diff --git a/NuRadioReco/examples/RNO_noise_data/gps_positions/gps_positions.py b/NuRadioReco/examples/RNO_noise_data/gps_positions/gps_positions.py deleted file mode 100644 index 4aa0d7efc..000000000 --- a/NuRadioReco/examples/RNO_noise_data/gps_positions/gps_positions.py +++ /dev/null @@ -1,29 +0,0 @@ -import numpy as np - -site = 2 -## site 1: station 21, site 2: station 11, site 3: station 22 -## csv file with data can be found here: https://radio.uchicago.edu/wiki/index.php/Deployment -## Station positions are with respect the GPS base station on the MSF roof -data = np.genfromtxt( - 'data/survey_results.csv', - delimiter=',', - skip_header=5, - dtype=("|S20", float, float, float, float, float, "|S10") - ) - -data_site = [] -for i_row, row in enumerate(data): - if 'site {} power'.format(site) in row[0].decode('UTF-8'): - power_easting = row[1] - power_northing = row[2] - print("Determine relative positions for strings and surface antennas for site {}:".format(site)) - print("position of power string easting: {}, northing: {}".format(power_easting, power_northing)) - print("altitude of power string:", row[3]) - print("_______________________________________________________") -for i_row, row in enumerate(data): - if 'site {}'.format(site) in row[0].decode('UTF-8'): - easting = row[1] - northing = row[2] - print("{}| \n rel position easting: {}, rel position northing: {} \n distance to power string: {}".format(row[0].decode('UTF-8'), easting - power_easting, northing - power_northing, np.sqrt((easting - power_easting)**2 + (northing - power_northing)**2))) - - From e64f4da7ef2a52f89853fab2d97f48831355a0b9 Mon Sep 17 00:00:00 2001 From: Ilse Plaisier Date: Tue, 16 Nov 2021 16:34:29 +0100 Subject: [PATCH 016/418] remove duplicated data --- .../examples/RNO_data/pulser_data_21.root | Bin 258567 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 NuRadioReco/examples/RNO_data/pulser_data_21.root diff --git a/NuRadioReco/examples/RNO_data/pulser_data_21.root b/NuRadioReco/examples/RNO_data/pulser_data_21.root deleted file mode 100644 index 8771f4285425c9b43a89442481f055252e693eb1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 258567 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 z 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 (F&2~7vIwgYn}OwHHoLqTd+`&*0x6w~dN=~I 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�=hv4K36L;x$o?5YDnTodbFzAs32}xKy_*G-qyT95-RvU8jYkqzdSU< z8>+hC*-yuR=OcZt_Nm>?dwv_+gvT&-)+ri9SuzvW^35GDd8(A!tiCu#=D^PQYm@8cd%d0Y415x z1%h;5J-jEPfGo!L_g=cx=UYcL5of%c$h7v?28t^mZp3{>$aIHD|dG_Zq~wTnOv#bN)@25)UxlK;rpBpO78GP&4QJoIrkGT zi6>@c&$7oC-qF2K@Xi;+Y~*BGK6ZBolcmsLwDKWINY9G(yT)1|+|Sd}IjCW68GFla z%1YTu$S=2#s^0l_c@k}rG^=L2uEz(5|IL7aRL{sag`#Sf$(* zHr#_`wX8QQLZr+Ij^ZFSz*dmeM_B6;pIBKH%g;K*=+=J!jyRStM<2AJlAZlkbp#8e zpZw{GrmW95GPVE@Sq6R{<&)vLAa}L$iCr1C& zZx8LaqeYDDoO7}PgF*!2qdj+fGpy@7yQOwXi`Yhlf>-8h;}0>DSr#dyS2kI0a6Rs7 zIAkHCck&@5(R(79S+5vM)-Q@Y^TQouQ`CxfH-+sdiE`D!} z@kG{B+#wSXLhbL$yNvwS7_2X>cA+~(X(}YtD9BB+GiPyheQd-)I$TAkp$Xo4=Zg(t zf8 zTU#UhMyITlKy9eiA~fGzL=AnmI_3%pOT?yE-pI*!YEf9KjZvOi6xe*2k&V4c6wJx@ z`dm!8`BhmrQo0#r`CbTL?VAWj)If(wtLO>VTpigRReWyJJR_wc_l&Oqntn8mobMpL*ciU_n`LkvA)b8)sNM=|GK~T^cf@mH(=h-d(xg_4J+JFRt(M zUiLYOT#aPbpqfEDN3H$SZ(MbbQ997OygAy~1GtCR^j(~gznR?H2~~sSq?s9-U==HL zQx8p7dS4}w{Hi;~n)F(Y&)OFnjshMOE#`-2unsakD3kAau6ALui?ye21dJkV%tG@Jcd->X$SdU(#UZQTRMupqL-tVlV=;fH)Ak4bJtD(J#L^023d z&v#~Zuc&|4eCrwQJThEr^zwJ;CC_$VS-m}dqmVUq7MC|7sk=r21&2}VPo(YJLU}{^ zDV*3`NZ*@LUpx^{&f5>#tv|EMI`a!_vsg0LdePvb#gzi6mfgL(nPv6eIaaLy8}-Zg zTK%{8hL<8ikfb(O!kiznQLWV`eC2yYma?p*dRJX=87D=4=3N}S=MF5ghb69tJaGyZ z$yfAWep>X)+7JJy4_+i~?OnR9Vn&~IgKVAQz^;H{t(eOsiw zE626_^;j!)nedg&9Ry@m3Toho+0v=W>~$Wz*Sr)CvS4iI$|iJdulnXOPT$IrbsJiF zfTEBn-|sPuEA?0PUNo+K5DSu*@uI^K^SaTsSvF%bhGZG?LJ6dXe>+3n-77v~&u10o z$mh^5mSBCSEF>F1_Qc10ow?gcN_^?)DT(*WgICVSV_<_AT|O7E&7XS+o2S*`knnHD9>H>lc%bsngta$$Xv zJ&G4>^o>zY+@?Fm&92Bh%J<1bu_)^Sj8zU0pJ?=E2dxQi zH7MQY8A+uWWlyW+E8IsP*j3g?rb16DPn;QlJKe$`{@lqIJZ$6bxtbA(XzP>)HP@aT z5KJlxCm(CGN#MmW4Vt*a>eUBX ze=^1t`=|SKZYXI`L@NK50w>8_+?dCTA9+x^UfGV?KC8<9sWTX*8WH>Kg4RR zZStM)SL-XU+~+hE(isaqyvkDyk5(!d`>=(owMBN&GW!IXZ0?1P!(;1#drHmVh+g&G zH?_>)vy4`KSP;^win%=zQI>z`N*>o*nUyFRAQAMg()msl`|D+oS!Z%?<%lha^V70C z1n%1L%LjmUpwWy4H4&Jp1un_~J&_;)!dm zG#GO;5gpmJM!EGKp~K+`KO2InCsJg^oQ)rBL>i*S3Jp9g%40irWs<&HNrS96Hki!# z%ods9SHo-dkr%9GcALzyGw6f<(PwYM%um#xd_B)7pG!*kQof82S)T`+@KC4k#1zF_ zrPuc6B*S$xV*VOtQD3m9YvY4TDSLn6SwCtFpkJ6?j))iZjScjE5fIF7_rSGe|z6VI&$GoTqkZ%zC+5KT(k=itx4?%Ct%5R9wcoP;`e5;-b`jcze{SSON z+=RpS!pbJ+E90Vdiu#UPaSZ|&Xm0F9%wwLSGsC%j zo*<0D9`y%P;^eH%BrU4O&rnCX9>(Ou3OV&QTTGQAWGOXq2yb6SgV0nVYVig$0rY@l@*bZR`I*<;t0PjyS2DL ztOj$lFm#?L5-E~gvj zSIk{jy~I!xcl54)?YdyYae-B0ZQ)8Q9^T2ub=Ah{JiHi#-w=<$utrXXRdk9|Ha8;! z!dJ1a<_=HAEpyI5?XoW9oAokhBzQ8bL+$QczrT6>csyE~wZgCM4hp&^d%;(T2Dc8D zAA>{bEKEqo?dWGc&dw%{S5~b^EpN>($h?h5=nnA%{oSew_mg~HC%bKIweJT4Vx{dT zu~(AR$aKx8@fUU>u`~h}TW`XKvjlcPl4jMjT0*HGC_=m0hx*-EX=8p73_3&*=wLHs z<=0YuXkt;eV55YI_@hByd?d3r$<9^|!rknF+D-PFeICrSJ6&wGFkh9J0ZrStd#*VyoqsYb3j$ z8Lu@q=)w zHrFgJfYQbW$7#`kSrMD6-Lw|LDnJA7Nv5W+9V1mDI8VD}SttE9TpDlYH1n zgeh+%=Vuh83)Ux7yGqacL&0;Q*cA9_ z@&>gmn%Q=@5`+!1d)TaPT!+h^%M7r#Y__a7TS^iks9jrQcg=;ijf6JglZPBIdFEZ^ z;3wj1JhVtuFY=M?9DSVeTjgCVv-NyrloLy#HczJ$8jx9;*uWHXlI5HBfh}JjDzu6Uh_1H)lYPLcqBkYtT-{C`7H=oU7 z@&o)3+ar27%R8or!KC8yShsND# z)j%%C`6gN@n|oRnBNHqYIXX!ln=L{kLB=FQV#e3XZJdLna%6NHI%UyCfn_@C(_E|b zk-vd6d=sCODQJ(AXq{{T6|0Knxn|`fis>$l;=Cx|$@Am$ZX#rHs+taVO0+QbQ}sFa zc4$XEPVNrpijsjuSf5r9HMn1h6>vI zYZ-nrr@l#-&6mSrdp8bHGrXraWzDBg2xKDsnIX1;6_Vp*VOCSDsmq{3HH-Yo4~eB= z<`Y#co0Y@iUo@ImEt5)F3He?+!OzKm;gQeTJP|(xtP%lQl_`P&*lHPARXA`If57|U zF#WVLMM7B>D4R#+|74~3ba+^0UezD<3N89(7`s?E3&mS5;+Z(HR#;h;t*;GLP9Epo z;B_lh{Dcw71*$@2AFYF!1K*;es^7|qZ2Iga?ppe((vhbicen^6uXp1e=?iN_-|&YY zmk~1pyd|A#uy9YN{+UL!d!S+G5d9_EL?9HK3dXlBo4^F;5i!%e_T5$y_z^oI8-&!%|=~6a4-sZZ}@>H;6OT?#n(YJy_WUZ-8@?lVLWmi zv`Y?Irc;|BR+7iFr^5HB?-`>qD zLszO`pIETx=8*j}2H)T$vLyZZOD4#gSb=?>`nBP;wGr~bhO&c;^i|z%^*HS!nX+5x zF>Cw^o}x*-$4aAn$4T}`5XzxI(JO6dq4TK!?ipb1d?P0G2xYKi?E515&7ASc zw33GNx0^X)5&5f)>FJ|b0bboXBfWgUh3;Y(*kY)0>~YtoS6!i6Lf(p9-1Seq#^sG7 z_xp0>SJ+m4%Lp0`GzNQ^6;Uq4U{#NVupoA>vE3^F=6eV0gLUK6WLy>%m_u2t znzt%?qMs+N`9qu)=( z9V8eInK*s!qaRk>NJi)n4Lzelvg*!O;c>-u8wo=~6F1Dv+NHws-&sG9>DG<0!p^P| zb2@wW$yv7z(W0&UHnS`Dt;(6Vqq8!qejshM>^RwpJ=fLj!;kzvWJ!8Oxp8c0W7q7e zSTEHGYRe3XkSD`i&!T4cqY%gWIv#Xo7}r@hk&9J&D=6X*^MV62v$Y`Fa-AN;&E{%j zX7df1FLvi=7EMDT>$~{i^^!_ZciGgFT3ExK7e1d)}x2e^GY=<=a)23H;XZ2$(>|m%Pj&B!q+^ z49Xw~EQVGF3F_)*H6pU4RYcHMX>GwJx*T9R;sR;J#BwKdN&6BfbVAA@|)Pfbr8D!vyf{!47;_BnO?CMkhx4$EBELVR3h^#N8LEQ zYfNHbU&y&x65fa}k~iinX^;71`AH4-5z>l0WSpW{euqv)m(nL1#mh{dA#-mo+CR0E z-e7%KdUpTJ)o?+%PK2UevKpU}pVf1aOtu_47YSPp&lOwny#CEf=85(&ojmfwukh&b z2*e!e)tk8kUs!E#-T;Tg0*octUm^Fi>_u5(#QH?}b{Qm^z$cMGh>8Z)(v|IU8d*;V zp?T(@SeQ=ap8S7$o_l@5Vz9sXD09HF^Vwn_aU(qB?bNk&kO!~DZt-X`q-_Tdw^rI{ z{R4k#zmFM)e4*M{{EUm&Q0;Ah09>hO{D~NhcGF1+%AGO@MZ9D#bDw8o!e!^P_bzRf z$5%~mPiRkLv=e8t6uBPWBtLhCm$2(R_8`xTo~2!0p1*FT73pV@Ji#bQ@fo?6yr_1< zuB5Lc5i(IQMpiIaOg&qkpd!Jk4LB|NlgXK7#i3fB5!z)7*~XF2Y3<;RtC8besg)wv zVQ@OCi9&uR8sN&?1C%o!=bNGwQuX|e&^G*{-$s9i_FXj z%ce~vnX$43gAMZ&MBE6bTm)}jZmYIWm5%HECdVVo1G|c%%o9}P-&pbV!A{!SGRv?D z8LeHJ`mT(W?$bA4tazgW`pFmIf5jnPS>CL3#=8Yom!oM>O&m6dWJEU7Q})!{LNM&CzZ<>!4*mlgwG-d@Lb8(d z@`P}vEd0cj^PDoUtO03LA!elyq6#(ktQ>xe59Ke7+_U8hoU2#Nfqm6p zf%$4P&Kt7|6YFK|X?Ja9Ei8Xbi|n&9ANK2cgRe93TKCV(vtdCNBxp3Xv0=P%?k-zT z7DxwdJ|~uDWt?=cMp(~_@##&*J5r2=p9-9;CO^d6$W*AAme-W~RsX(bmM+T-o|q@p z9~w)>l#zNTg8eRODPs^p*j3v#jE3&d4LewGip9Zzs2qbK;~CP2`fO;^iWfB&*RZ=V z4y(+ngpOe*KvoVV&rWf5sj|<=(XjG-M=)jzrH3&F3BI6?~EJbq} zIK@`nVyQ*B%~tmmk5eNBuvb}1c!BrfmCYKqwJZm8hI`?+#CGGq(pLVSD^+f@0SK~ zI~8*U%-_s!Yjrxd<|hVMTf0bx5yD7TK@L*>|CanLN^w$zSo=U?XT|e;rvcap?QHR$ z9gmM-QFu*gpIk)qra#(u761)3@8Uq#_aG<58p1Rrlkboz?b%yq5xXe{CZVzuswRBF ztdk#@QShhMnzykk^%F%jqs=raPlN+lIJp+=Q{PY?xlgMwM9)|iBeDgte$yI%7o0bD zn`_*py``c683O$x=d2R6MxN_mLj4u%wfWMATqiD&adX-orpud(%nD0TY|7eoXCh=k1FBuH zNPgRw57B|%%J8sx(Yf5mr^{)TT{n-ag8N1XR$(7+W!9?q=f?gUfy@;=19h>zV~yr& zCq%0qV&O$taxcjd<$0AcS!sTIVtjIB74vPED*cqzfo|ZQV7pw&7S^k=T`-V%QP2zZF z9QzJ!i<>`_K3XBqZPhAC%L-)_!TuSowIeSg4pE$VV0?FaZ+9AQoaRowTV|E!7BfOO z5dScAGgCYnUzz@=HSf%^3wutK&QJR3Y*g6P31&_%fo=7&Cn}LU($BuqTak1;jXut- zz>$*;9!WK~(3tFT_w}5e*0kPe6cgFZVr)vT#WK_)jMYz%$qweE$Q-(4!Eep}H8V+5 zDs?z#K8-~n>D`IUZs1<0CM2!#7Gxje(ecoXMySQ$qOIy_*=(M}wa`ZQ20%#hFnJ2Z z8ZAhB^8e5oTvImEeO7GtP-jNirCMlnIqX$hbOL~#)9`Fs%irO)R_Z|ejZVa(tTtIN zA~6OVY88x`g)#4JkvS1RSR1h~_Caj}G~jd<=a2NQ3XlY>!JqlUpBXd%?F1QGJQ#G^ zpS4LFxOx_2bTI8>8|t0lV6mDrz7HyL%qc%0N@un19p5!o`ss1BKcBh+;*zC+9_a-= zXQv@J9yDK_>D(_8k1WpT%}^R+@%~mM^TP2nJm={dFE6adh4m2IX1&rFooA2dz0COx zcLBw)Q4<~IsgSr>3P!O%Ph`nXI15V6yIKI*6}r#0zFI9$hou>7}~m=ugI0#G}5M58kWPVKreH z`+#J0a82Zu2KTK?B0@9U9G^4XZj4>XSK7uBU}3f296Rl{ho_ZLYz@D|XAFAD(_+cy z*>JfzHZt14FS(A7;5{%U=16QbxulE)TdgkQ^J#x}faN~kPToOJFr}HR{5NuzCyy^3 zX=Am>kdr;cYkG!_mo3B+Gpdh!f!;5aQ~^ z!N|#dI(- zKBIj7c5OhAI-f76S}R%HaWGB6YG?SxHxbxDgFF>|Qrvv%nh z|0UaxrD{f*ePZ>+ht`W87qJ^Rzd=jjg2~n8=L0q?ZSK#8mYO4q49w5n#YNNUI%Li7 zcb`5>Z!Jff^7m#y>IbyKBFa0#mLq%l-8{lB;UVWUmYuh4tqe)SPuf?k>QuERo1!*S zwSluSy!|MWn;8hApBb{3Fy1Rq!c?dRRUPM=@ymG*%WHL1XR_wK+F7n#!(_c5}w3bfPF90ga+R6!wrIQNU@;aHpCby;TON&^V`#{k z-{mvMQsf>81^;1XA$M$YtJY$@a)$^*m7O@9Up8L;0ygK9%|HKznIvN*AA<03 zKQo_CRU_~tR*9Fl3lH|unz*MsT%A3H>D?SZAu6!CG?@=2C9>Z9kMrry*M3?QN%2`Q zs7SBtITc#DpSDa?oom?NTGk>O?Ag3!IM>led2gEF#EA4LKbaj`a=`k~PUz9o;0{RB ztnpH$qF&Lvh*d%5u3V)DBD-ph885nLGhh^cT^>dM2DL_(ikaG)Q@ZcYbuukIyIAg~ z9P~s!nJ-c;>Lm?$q^X9<+%%KPvegTSz?|?cTS?Bz0~s;~wgitfqeu^0>)BY{EbCRh z38tRa)LW|v>DhN{Hv>;35*qF^*FnL&InP03hZQs5u}=I1i)DVNeky&qAdyb0X!8@B z+j+xIz<$XWWj1luI5%DdUt?ZLlHNNl4}!$f`1C*{F+TCNxe~(hM83?}u@hpg(X#xl zSyJf^p)fl9`T(4DYBr-G_ zeo2q$SL+z8CwmKji!&4ON4o~0|UO`C2?tFU;S6U z@|my9d!Akk&R&Qx$}wRn##`lc>!NjBFImJkvZ%C#^<+)pMwWj#t$YTd8sotpso{Te zS5X0cXWiIsh*my@7ir|>^q0OtRjf4`KRusy;>(=dPRq!7PPWfz*u1{A{LZv`F#oj+ z_|aNWnK5U3%7;c;(p#7@cqq?5h}uZM6>&bAI39~xImAql)f_FVEp|28V7Z69Ld{rD|o!Q|3RbHYc{ zG`dNq#o}AB2sh;@y*TgGNsCER3psPNsQC3rJ_IzM@fKu*J)S(p}bw}{=DGWbpioYiM7 z>AV)i2&CTMJl%IQ3uYeD5P$L1{=?D6Pv;um2ggH#uuqVO5o;Z5Qta#J+G9M0^RMjf zRP|76JvE$ZjdmO1$VpmhM4Y;=^wE1rM*i}Au`Wi828vAdoK3G^wZ~OlUv1Mv7ONO@ zUrXj$D%SLv|00FBJ7-Pzj8@)*COPFy4I_L2wEQzTxACHcX*GD zknQGU+|Q=Nn%I>ua1Uuw&I;!3lVtG4PPgWMtDQ=S+=ubU^H>oU!`VpAy@KR0;^HBk z6kOpM`Ygi$Q$iSHOUz@w;8f3&rzyI`rbC3}pH+ndv_Oj3cs(h`F-kVV{i8AYdoy)m zg61!-hv%CW$fNQz$*n#b`Jl$E+d*DWO}2`HgZ#NYO-`bGz?}WTrsB9@7vr2&&olkq z`!BX4RjNN|f_P6WW{B60bj)~LL&z(B!6&9q~Etg^)V+-@U8T2lx zbJGeL*I)cE&Y|9r1~r~zcMc?;m&8&oQIwmnB8N|AGLR@#SwcmZ?9v#C_zRqzgE zW2|oeg%eoeGO7BMda?ADwZd|cgX)%f3IA_qqL`m` z(Kg&lOC~#?pY2YvQmTsVb}l~S+3a~^yXgaIG@nIo)`AxJD|<)}V3B6NoHuiJ)`3;* z?o5(`(HOg&Ygx7;#zCB!5pxt-n6-yq^iTE}OHaR?nA0~uw5EbzCB>vv^p_s$Q(C11 z{?G5V#+8Kmgf8~v&2S72jA{pu&JiFnNHM2GX2##fC-+2KUN`OMBIoFfYXO{h9> za@e8tu(>aun1^OT=rwkQrpW{pOTj;)d*g#*^OY+G!{%R4=sUBav1aG^b`fx+3|_~6 zR+7QDu+8?DeL6ook7+Z$OMO_pOP-?=lAj!jn{|bw*fG5R!QM>r#z*?UlPW~-lhqu# zwnr$Zdgng1wDEHJDJKkM-XVmnSg!6{rm!{9`}~y@v(#px|C(|0(VbUc)HGgUc(U{g z&xIrCNed(fQlYgy{&EeznEF6m+*r_ngZ!`(tHF0)+=lSJFprwO+ZM}VL ziKnL@t=jOW64snHm8F6Lj;0S*B#g#bi-}>=J_grW`p%ed9R%JD!YtQykTEI#R;gd4 z$&T~9w3^k&wBbn10;x3bq!~-XM?{bGJNFj{vub(>>9BL+buE%9-n6U+>rK9z8Lf@h z8ta1DRi&1>%TLY2b^kmMMiy8fUY@q#2t;f=AOuY3`9e>1O_?+{du&1OF4E)o@m94W zW*mON;$bIQa}31b^I2n`%VC%SQj}`)^pM48S1N^K$wq&yO*M*Ku*_kXXiBc+Gp(wO zu+u}~MA=BJBJNPsry_{`;CXA6&5^1xEonvd0omH}?>4{NC@-hz6 z(9FFt8Vk?o)C{}A!!P9d&TmRxX2$Py^1Cwc-q+>scOYJp`#_Hjyysd@gv54evBD?&n9=K6L)+0TU z119&*eD)4iZ)cN=4`A)o+wa1vbKS-bCq)%i3 zQ_B(*U-OLWCHWxd2i=l4;(Tn*H#s$HZd{}TD&W!iI4qC$yQ`B`7qc`L|oQMj4KjKN(Kr|r*|x6I02(MHyqz1IR%B!0pFvkgW`3I@C98kK;m zYDhO*hsWg0vfjA^;;y}sd%Ix9%#UEMVIH%SFKd`*LSi(2{-59B4mQ55Z^oTZ%N&VO z*{yi6{9pE4-|!@CUp)(ZGu6~11+~e3htc`a?zwQ@x3^2nsgMtWRUDTGvGOn*qd?=H%D>2Bkx?)-AG>Hp!R2_k9EGI%y*xb`M>b z3N&ccY_|&Cx{8fRh*dO)cD$9z(W~;n2V4g^gd(B7t&9u?l{vznv2>BAJYCiDFdoqX zF%RoQ3Y}8}f5A|F8aak&)xe0zL@o9+*v-I`+6T)Mv#)ewO-rdW%5{SS@~N}cKbybU zj}M8+n@kl=uI(JQ5}eNyXNcL^3X%W#%JhX?W1`BfiBijIsj3lEumr5HS?FDCg!!h& z?r*#|CpV-Obw_8U&m>djP`%#l)XuY6q|c>cK#>3W1yvS}_XWB~|=%w0pzPx*O=%pu-mhKK^>%K$&$48}g?H;jn){;Bkam3`-{co|Q1?_eC)WDeLg7)n&gH#=P?@1vd3vj9+|Ctz*J51!%lNRWu7`QLIO z2WMY+zr?(`CC|57V(ERvlBbc_T66KOx+*;_!vn?PPDEDu&fMbu+4RA!xsz_NX{@bl z`84~YoSa7En$zO9*e6zKs-@E7qHJ-(oKTbNop%FKxStmncQz7|t2Ik(nP{PYSp3=( z?W(70Ce^1|E0s3-P+X}Bk;fm+&nVO<@x-Je=se@=E2Svu-Pgrj&mJmJUuDT-MaIs;mg{<5#_Ce?q)P(u70NL$-}`KB#e!|cls*VrvJFh zG6nfLy`q=&oo|i~&Wg+a)GNU!-e$w2!YgIBXuZfQ{v`h&#FkHG0(T>UG9B8anOF%@ zO*_X9=U==MTyb)=+ew|OYwk$jhEJc-iB$1?BEMt_^0PUyssK3nVa5%qVLxQX)xKhz;Xuer-3W%0<-)h9_R;4VSFYftpeY(e_xujcU}dUB_#|Vg zmWY$!Bz`Sl)603UOMZeyco6ajIhk>}eeaxW1zYof(WG20FAr1V7vLfDfUD6{b09*D z4NaR6mN9vkr4?$=)VB^0ujW=O%EIAL&e$hf%Q1Uq_G0$Tei-765`~Yh!)~CbR z8LUk_amFXE?B7M_WE!)`o7JY1b*lkwG#7_qQ6aURwO4D@h%IwIeQyND7QuKlhP7oO zk4zhIFqQ^mZig1Bn$tis5)qMj`d*n)Y$AE&XV`H0BI7i(jg0M6({~orPAhMn6ql6O zF2~h6>ER9X9M|KG#aZchM#}ok`wucpeM11>%B~-rEJ`<^Q}bPqeoCrE4(Ez!K|W(^ zMGsJ>_yB^X`80|)lv#-X$?Q2x?;g1lcJTJdB5)|xdXa!I4!O7adU2rYIQ0|deP{rL z)x5}L1=6#TgLLY1C8{e^a*JVa<^sU+M$$dR7EaN5bxlc^Z z=jU0uzuq^qnNhI-^4)wVJl*VxXNb&c9$d>0nMHPk9Uf+BRvi9rKAu&9H--Vv6;MxO zFx;m*%dbxED4)X%Y;AWOU_@Yjx*=veDLQ#Z+89rpJ~&eko4^{YeYYxK&ccL0&&6TS0%nmtTy~g()mQJdE+2eZn&?onHdXfP|mg%pFb}9-1CNO=hE+W*CDm%{dEc-)>sy(mu3$ zdiAvS*Oj$}7_k#&Dp^Rf0i(Buc+P|vJ*qB>-(X;?!f&u@>Wuj`dfm~`IX+m7QXkJ^ zyVqX8+jEb(7df33*${1*x3N(E9SJD^W0b*$`AogFHx2cTsVs@u*vyM2nlBa&@uEDc zs$po84X>QTy3mxhA<^cLX3=?9&~6-a5jYDi&J`<|XVDrh)B-Mv=d%CHnS~^iEU-Ip z6)V9zxr2}5k45)=AP~%WPuu=;T34^*no_N9r4Z!cEDfwN|H0?cln(Uj#JuA8FeP^2E+H>sZVk z2F+Z^I5l^`&#~G3@M)wg%jb0Md!~h)O_$$J9ae!=6FMR9IjUJB!vefW4qQwrW57miu^NnUAu6vOxGe z>sodc$}6+XOPb-SHp!gejrB&GI3frhqN*>cwcsCE4gOoJ*2njJntMdLs&td-jeOud zk|oOM&HYqqYJ27i&VtrpL;fZC{zy_|B(`uEoQ%T0N@yRCf+^8M*g||uM%g;~FT6P( z3Cd}n8iRr1V3&$GtPvj86~?QAZ1{tjRp>~Rs;a87rKe>z^LO$H|Fe;Bo_URJ$$fAx zj>e3Uszx(Kn~nUxzzU|FiFWf$_F}4cb5Co5jEM~(TV_El1+9qTNDnXAcn*3Y1yl2% zyI4yo5LZpRMZso-?a)i!Po(0Thrqo;b$n!6%pI&6lt^Dl9BJY+oZvc`FTa!7(T_ZX zM>6we8lf685$m3Q;uFrw-8^-p4v1cbG1ek;m3Gwrzzjvw5Lj(24u$oD5X`u>6^B|e zT7wl=T?HvcXY*GPxNOI8C$3IgCq~E48$44@EF(10srAgLjcpi{{OrqY+OsI5Deu9$ z8LKOelf0Akv7Py=JxA4IYZj}Td2^!haQvAA5raCL$!w){b_0XaJ%$H(q+C*PVm`6n z__p#*ys!1eD#<^PY)H#4fAxp(tf-8a(ZA;3abx;mga=HYRfSI7!-8nlevL?Jz9F5= z@yyvN;^o}OE6G%-guh|%;kAlnPR+CLnWy$lBk?fwNqgA4vRk}vrOVhnLlu&U zkN$iyk|C8-ACOO-(W!#6*;SKA;&!A*tT3@c8ovm=Tj@# zbr5B!T&Uk51^A2Zb~&(y*3D_;x1|E}W6`FpRaQ)tW)4pahLD-!d*F6hV1G4c71@;9 z6Bg=V*2xL|tlbio$Q|4eO@$MJiSpf?3TFc!Oy3BMWE1&SL&Ha#=@kBGqvTZEB8JKo+mv1(G*z)w0MJexEedfJcKPQIb^La~q zjUh>U1oWs`PBwRbZT6$J2FnnV^!v^4q^LX$WC71(7ifx^j0B|} zF@0=c+GGvz6JLVI$j_t|Dsk4F6SvuYn79^C<&J%q=cgs>!J4z`2hkk=c_0Ij=RI?U z)_INY=$I%Wy|nJG%}izNdMQd~u`uiGILlX@%BG2UdNwTEMn}kMbSl>w2MuJS^0bWC zoXcj|hrp9G?iju~W5@52O?|0M7kz7s&%Ptr<+}J}l@o{ad*jeN<_q(HCx=~pE`3`%5i&_LdXmPX8Xvw6*ValZ3`lHjo_hZve*3JQK_@1#3mcb(y^EF08uNeZ zJZS*dN)1cu81rNZVk`aaDXQg)APjzP7~+u-{TIEn24Z`7UG5WCY-KThEGEx|pA+jh zTj(VE&t(R&p<7uu`}W9DBM>s-newOJ`e~)Cx>Xa~nF&4a%ELJM%3s(|K7st>JLUL9 zq>%UNw_c2c{O&l@Mh5ldQTQAwoJW9?ld zMU6|WoiXCH4n_L3;AvCZ5Wv8x7uc_v~PoQH{XwEgFvU}X`hzj>gWa^IbJ(I zvuxU;cg3}4n~XqpwY*qz*rL3Vm4x<1e0plG^0v*i(O3_5!?Qy^7}h!YCHH2`Gh=X! zaTzmNvzsF)Rv1^F%%Agy^)jxKN5H+(1oqG#!sewhzvhl-V2_3|tuY$6J0%Tyy__`((DUkszYXb{QfNSpd9@q2#HcWtX|dt*1cfI}Mp zkP(&BmuX||dgZT}NIUEut{ydO*9(>$~DxXQX=Q&OtVr?|LaaPjJ{)fCSOC*=aFP z=8I)J<+{4U7;q;%$dP%X^%WKCZP9dd9_*d0(HHl%s@pn}HK0q4QTOA{%p%?nMqrho zBm4L5?889QZ|oSB1e*W@+BKoFTO?Y`Wi8Igdl|4SB0HmU$tOnJJOQt-0i$TcE7lXmD3B>k3{zT3!Wa9WXZLn|M0l#Gf^cE3U%R( zIP^-$rt;OVlo`<&A*jT$O|H3lgH9!WWz_~x%hL>Z@lZgtVmp1#@x_ee56>1_v&vv zEi8=V#FkA=KeOqtB1742@dRmL`RGTjaqTRO<3Bb7+AI4aQt{p=R#?OdGoLUL!yAfu ztc;2TNCdAtEK{CLPGN7_hG&Ks)h>30Srpy`vjE}HLEmF*G7o$uTp(`F&l&rm%B&6_ z=~?xcI8(749}YLLnUnj>_~yEiRWzvnR5h==jLzE%&P#lMe*CMM?e2ltc3ha zyjoUY$v-KahKX~ZATd!Jf-?{MkcOL)Kofqz2v3J_~ zh&%ZAOymRy3_bkuadd~L096GZ7rtKfte&*)eH-2XQuH8$Izv9@jW5G->M z&e?g=&ck+Ix%+^<2dqz8p1ARxtt;>P%cEx;ea80JY~6G7d$%69^;=uFZQi=Mxg1@8 zXzwYzU%PY3v3K2l>)pS1_tnR?kNw8+7w$ZH_sYF5TOYMNdGo5R|8VH55B*sd;IEFp z|Ii8BKe_#yt)JNZ<&AeQf3v=J?&-zp(Kw8;@P?T>gA{-SX_{!f&qMvL4>MdhbnpKd|?*z3<-pp}n8pd-L9( z?ESyJTi5f~r>{S<{@<+YW0!AOzJK|-?U$=hK`i%9l>l4<;tPjcRK5~8b`l9s*)}LSh`}#ZUyHcNe^77#2Y0K9y zFI#>*ZT^?#SC*g2_YW^`Nb7H0esFn0umOL7o!MFcb^Vj|*VostuU-E~{(W2id-M8R z>pL) z(#nU{tJi;A-?zSdeQ#R5Hlw&9e}8YDd~L2c78$=HEnXfz;J$gn6PCv;4~-O`A6s&9 zbjE%Sai$3Sv&oEnX#L>&(e;|#`|)r~Y}tqN40{NmQ(i!&-q~s40n3*zkI46f()OeC zeP#YClBgf`9!7i%49Ux0lkX3uWhY!s?3}hl5#FiT@2N%@yT&`HB)?BuJSP$SWqHB{ z`F5I$u|tUVA$=yjx*dI-ifD+#ZHJFYF2h@Y)igMQrE@Z79HPCcY?PDA#X#Q3=`@j#WSu{h^>OBy zXkBy%QLx%h5k8!GJ1^hxiIKV2dlp~@`9Uj;s}^_giXsuMu;8_uCuYnSWQ0?_k(R@v zWInuk!^%RYm?P5CeFCk5gqzRGeHYHvYA)F8lhcQrN5-y88}R3+vTpHN6Z^?ZI`_DB zT$g72GFGZg#Xy*QGu*fLsVc#u@1;M7BM;&doTU2W=0h7N@>m$0yxTMFz(~Ax@3aS+ zJb34hh?xAS&r>;#PwIKIw`V@F^c|O6VLc11iES4z%bnl`jX>m9WL~U`!>Lrlo>0%7 z!|2dW_)WAi)dLx&Q&R2Dg%L&R7%iE9*&Nvq*v&4R`2F04NrnyFPh0SsWj_+&#%F@8Hg+^IR1h&lD!JP*=Ts;?SigkOsDHNO@87L&AJGEPUah!Cc#T)9P4r?c-(SGt@0kUO)HY{UAJ2E|&mzWk*ir$Q6kI(yH_M zU@msg-1fvqv7LN`UU{bwj1kL`>!Gq%Du}C$C0xk-9j28>Xp||Ji5rv^usZA*yP>KG z{tm;D&#e5T#ER6<--N=(js9DCk?!UD<^9AcS-z;vrII9AyixYB)jt4Fil#b2gZ$^URF?g51TLVjRRUH^i4D^O0Vw zjZrlSMd!VMBQLEzYL%b}xUmI1D6-M-gFKC#TjGTLg>CFf@$SIy*foAi`olWiJD&1z z)>F3W)0vwxG-aUqJj~Wa4{2WvF)K7{{`vIk=7~SV&iZPF)m9t1b;3WG84_KtA2)@K z5ZPN>@c~XjwuiUC$M)SwVr(az-!ESBlKlUQc;@6<(k=-jL9Ge>L@e|*@s$6X7CxLY z$VYAOC6UV$GOkMFZ5fAi{NK0!L;8`K8MzWgkq`2$`h(?Vz4(c~HEp<- zTx*xMs%>Wiij=UxqM7>h?n`T4HM`6*AFzcv@jiqbb2s+7KH_Nl96KE85pA`ub27*2 z2X-cLTh>{8Ra*&zw31VXMzjP!l)bS&u~lKwsYyR((-t%a@^qtXx zPo&-E3Tqw2ZYp46e=>4xlvy^5vW&8bpN@p6D|Y=Y`Ppf3;$Lh5X6p2;>tvrZV*3_y zLT`Su`}>P;$`H|$J2XQ+_`b`a`E2tc5m5x+j82*BR2l$#%b&K?OnY- zH!c6k^2y~dm)9slMte34%UB7PqzV&AlqyNQvZDixY%U6X#c-8WY z%kM64O(*ac|8#wiGa8~9*G1c}iS4u3L{;8}@kU><{M+>D zMaws)rLSI|v%D}*`u4CEPhTF%pGU?&l^FML!cY8JTKt3j_iOq7uleuS!zR2nW4JLA z#lwl2FG*jY5q{(w($-U#tCoMaJU9P7GU(vq$W)^K^z+(`>Vx47wE6x-&;Pu>Gk)uR z`RT*yB@PjTT*mNlko|d)e5~bz!lry(`unIz{yEWs^D^5!ls$&!^MWYS6LlCgP!^PB zzdGaphxMPv&S6%A>T@UV??^1-W$D$$!5-H0$R$y|vL zn(u~FldtWpr3Fann#lMqx%t4;s6M$UD|J~$jORV5IKxKy z#+-j7y-!3x^U#w#U~q`WKBbGYPT9AZ`I1e7YKjLi6y7>@ZSKE5@&UE+?mavGf~?Nj zS+gV2p$BH%d9P|_Qg-sTT>lS|=G)R6{n_Uz%tm^ABv|~Cj8=uzeP)eifAL4nOn6JY zH>7?v{r0X?I93+u9(kTzgV{Pavh~2}H^d<3X|?+&GSebIRhuw!&IZb?o*zcfZc;e{ z5vP9VJ#Cpy-rp$Y=|pU0$T4t1*O_GzS;m~X=IIV(Qso(J0rmF$Ra_ukBhprhg>w^; zLQ^u3`291Z1?-e~x2MU8emc{vz}3+Q^>=!u=C9Qx*2hjVQ5bw5oH*Khcdou65`AO- zKUH=k)iD08X@l(v(n~*~f%e>~ZaltxA^W8c!|4Yf&&chgfoZZ|HQrrKG-N<8FfrI3 z`DZZ@eb5&Y44uHB-hhE=bH6<~W!cOSZH6X9PB=UHjpkBtT_4M+Spn6F;!csZx*_`j zy$KxeQ_ib((awvRGhedeMfq}r-9HKqwpU_)Z8U3vQ>TmPTy4Q z?ejNAcdrR&eodqVFM5!vzc6<^d?fLHnP*x4uCu5@EKj!ZYBxs@Z^)AyvEc;GtyoVT z!x`y2yecnmw#EbGDXazwhR4O!&Bp6>IX#iR$^onZZ|d}B`Q3UC5<+*IBUPDr%gl7& zBz%5kL-fZUOr@r*Wmfg0@kAfUNIyB~G=0j%P&4yptxfgaH$kTpzCan%pOv@FsV@ zL`?yiXQyPFv5+ExBe9gHM%vkl+wwGW$j87ha=@6qgMD;ZIkm;-WX!b4u1@PHuEz10 zFHv%H$f9M@gD2M$;)+BAr)8FC0Dr&>@n}7*jn~H$RqI9bB2#&8CyB>nN1jUin(e@@!f@jyw4eK@ zN<-Ue(VY;cnPnOA+eRU7pL&7$9Mdv2Px*~+ZPnn+X|C@);|0uy{;3V({m8BvX|1n& z&17bEo?9QQm6_4$*UWDI;&1%wRPJZ?_B~+6VGVgvy){>6MO|I`J$)=|uZ9B0;ky|Z z(m4Jv*GJ-VC%h2Oc)wRrM40D1OI0tP!mOBaeZr%f8I}n1d17>g9hP}fBXv^z)cs>g zPl*;@6FYl-?6Y&)RPx>UiFW#D zSFXRbzB~Q6YI)Og^Ts6`U$OD1jr%VjPnP>DJb{@4a{LC-%N|@9BF_+{Qa!;qP@MnJN7=i zp159+i2vz{&0n*=C1cqPT7AayP0K5mAI%M+I;Cz8KvdDi^*#LUtI zmWyJm3U@W_Y8fAO5sGdSY2}c$w6+JmO;j%iL%qsBwRlW@VvpFZ+E960{)|oU6?)Qmfewq))g-~pywKDqWi+)fxo+kc zk6tF!$RV>>+|f%`q!kBdc6Pf>Uk|j71+YR>v6LR@N7~FaW-JynKk;2G6RQGimSr_2 zz4yh|@vOz+`9rR(t;0^wv!)lRGMcN40gO89KHscp>}&eWS7JcLDptx4TA0L~vDf^L zeb)STBq!}=1xecUbm}rA8|;`>?_8TLy)`f9-m-$oqT6BMy!Qd zr?e1hFxu&_9J{&n`^|l`jnv<*n?CEER?OE(nO^5_gK}~`U1rtXO&pzFDworn{H9-?GBT7F zMy7LXpQ}d3Gx&e?!bXqPw<<*tU6Z1U{i@cqN(M=x9@04@@HO_yz4^Hj8e43|I>T1K zf$!M($>HSalk&FJ!_R8JRhP)5#t`*4mUoAoCHxX9LLbK}q}@vJ!Bh78 zGJmhG4Gzsy^^KH`oim5?d@@3pv@)4sZg`fFB$jJTJjG4qvL zf6GkoKdE@bbG1$yJIn617L_7nUy?b?*Z&7j6K>xC0J(|->;M6P3~JKV+5lYu1ONa4 z0008!JOBUy00000WCv72VRLI`bQW@9WNBe;bYEm)bYWXEG+kRVFf=$_2xD(;Vrgz= zWB>yI0f1cq000UA000310f1cqT1*Hexd04+0eAsK-3id`)qyA>C=7o z*@uCML|F}Jr4lQlVyKWrgJmk9kwp#BBxn>PA;xIMAc@9U#8?OzV+tXb5KXD20SqA| z5Fi*}7+{8(Is4k(XX&%{qCp^>#nc^Z)3VZ}rsKUccGBuk?4d zcFy<2y@$IF=MHDOdhT$cclY$!&Bu4T=W2h)K0SN9alBRw@AUkI?!M)4)8V$BJ=?Wg zy7%4se{)84d*eFOn9g*^nd7lm-svPTgd~?3g->r?PtBvW{81!~~&)wSV zo4WVV-0pW*S8qLBJUo0j*PYk;eWw;L%-nCAC$)Ij;r8ZmJ<8qOGxvA(o@wn&<9fGG zZ|$D*^`K9byuI-o+ntB=U4QBL;_;1MKXAA-&)r@d=ey_7H6uCO`}-Qh?al4A>EZI> z!D#)~%<5dv)N=RU=-RFQ-P{u>em+XwGwXcI^m}gRb7Ls=Zu2w(<9V>(3%y!u>FthI z|3I(*x~CS<_pK;{$L{EET=7n=UuaHoLG8TTGp<+O2KZ)j_HWBIfd>xuLAb4NXz*E`dfwJ;-66D|7u^`4G* zdfLoy>i)YMhglhUT#c`-|NMWLk?FgZPR12o8rzN+N>kMfG%Bzs7cVvuhQm@90&#H@e?Coa^c9 zwSIf|&<5_jsq3%TLUPqe?u}FKni=CY>u3%u<8fYeINMYBAAjFIyg}={9Tnf`_eO2p z+}~~WNT%ZHuD;WF?(CB@C>foWyNs7)(Fb=lj@O#|l}2%AQgXk$Yv-1((gsOltDzkn zL(0zfDT$*4rcdioZzKzquJ!(G?Obd|dN#uw-GTZz{+3>y>E6{8x5ej|yZewPdTIK( zJ*vEvG@h9@NEwMgL>ruLL}o&k=qhtT{kyu0Jm?=iY2n+V&YSgp>j?)LKN(IQ`j-|W zUvJDk_w?@E@QK+h-``pL_y8Y9=bky&QzQ+an7v+UvbUn&)wo4lbO-rZS?jSyFJekt7e@k(Bf)9>6Qt zhnE{|pItdVcYM8PFGT0F_43N``6zw8@#Ei_Sy$1R)_ZGahWmz(Yw61InO5W7M$*dl zJbq&b4)M;zhsSCc1$X?k|NZHlcN_mZwQ=!qcVl}Em)9N+A^BGR?io8NCf&65sjZ^j zZjG+#$!24%UyBzG>8TIIoo8pR_$WT;mo%q$8r2KOUp_u_c=Yg%hrf9E`s0t>_~?!A zK0bE5dicbdKYr$qp83MV*B$@D@o?kEZhY$aCC9&V{B*qerH4O!_^XGXJ^cFN2fF(5 z@%y{uyN*A2{Gncb-|_!E{?zf=M)i4z-+uUp!?z#)_V9)4fHzvuAfhsUG)EsfDAuSd&YI{w1(ll69` z=U!?Z?uv>JG~4t2|7gFgGd^Pt;JQag$<~H!z0;E{JUnuL)VY7O)Ls35zE)b5_>^XTx7plP z>o?6O@60G@%GY|bb*-h>YPEd5cZJ?x{&~H7)A!wfy|uekO9%X3tMOy4;z;v= zWwfz8*GE0IPm(Jf3sV_AdqxkC6tZ)rKR@sE|C`MmH^Ve!7RTMvIJ1nN=uDTFB&#VI;H)fg@pX(z$(p@MG?cC7{Jkam$ zgY0f}SNNvZPb_4ukxR6P@SrF<;nectBb;$+8E9{IlyqKhOeBVWh5%_>t+NqU4}v&B z7-%yqLbt( zQ`(AsKQtyh;Qq^phtf^U1KHc|eKyHB;D&v8) zVNbr*RUFTf!>+hsFu>5}-qV)Qs4-|OZ8h3?QB4@N_ixo=QdxU%)c^Sz^Z6(N*`NW7 zcJpx0>T0M6RnR+RGb4jl*c;lPHph4P-3-D8jr94r^_50)cb{vW2FD|Jbd|qAs$i>l z*VX!kN$@Z^#tC?f+(xr{qYtA)pM_`p{LP-m!Rr&i#%KEcxlr-jjceAb@o1Glf}YkL z773x(_F66W>S|BDJZLB$>GRhb)#bx`X}8ApZcjps_&;1w@AzSP#LBbA>;gozI2KA} zhnJ_%H9O;dy??D8DWTPxU+z+h>s)`cyq)q2Mh?pgHYF5C-e zE$X*^kkP%_khjT3_uk*tWUN;>dHaBqaWyXhRy^0;*P|yNSmg0`^u6A*Y|>B8GZvg0s-2czZC2~QE$%wjDow4G#bsCP3pSv;QDxB$ zZf&I-_2Nmi51)0N7D!vxyS8|4^fIiY#YKb56ZE6;<5E3Bm?5a{w8o9EmO|~ldc867 zP*^yh^8D^?J`uR-Pll<V|%CP)}FEf#?0TqyD$lk7K1uFT%6w= z9q`5aKH0WL5W?4OchZB_%nyyRuV{_@jh@NZuSK(9ab8KX-mP``^sThy+x18XkwqMx zH_*RpU&iy9S?c#&Kk`vfi_`__ur`c}POIiY+OVW^FQM(YV& z3Q<@YdhpfZy7m9k=R?DlcD%5j$thi}fyho=JS{*7Ua`~byKnnGT}gmu&1JO#I^Y-j zPX8>>xuHeKz4!WIeQ@G>s3dr;J}W3{$m-IKiv+DByToqc61-(p^x^8+S?}(~ukIG{ z@fqvN!wkXHw>HEzU#t(>W$^|1fXdP9Y%O@_HJO`t^|O%;`ee+jA zARRl~II#Qtpy0Vi%_D|_qCofFF)O;h=1q+YYN4CRF3G14@fwWc9f?9goQ3O~>2M6G z6{mp)w{7bPZ_)0gW)a$rX3f%?i5bK@Mq2Av@(rO{^EOL1pt?@)5gh8(;RsBQgePF zzJRce$6C{3>p2Z3>3%c4HM;V>tPi~OT;BYBhu?qrZw`O9Pd@*~U%m13$8S4){h5c) z{6}a0z~RU8AwF>9CvN=o@$&IIkIx;x;P5qvZ$A8|hrfLI{==UyD)6Cn>)$#4kH^1p z{DJ=dyFC2wKmN$^sapK9!yl@}@9f@hI{dD~M_Q3j9{=v~Z_n=!7Y+Eok3W6<^(gg5 zW4!>u8j827ZLcG<3B7S@XNejZXM?DZg@aAuRr${>1$bwfbWI0&U4FAIw=FR?ppd z`)qyO7k;Db##gIt=n)FLC;o+=XoK}Uq3~9Ye!dnZ|Ur_ShPFh)!FqypasH zb7Qpn;BmjvlP9@@xyF|!^~v3|eKjfM%a9&6uMFiDFN{>w-hGGn#?g1x+AA|>ng^Ca8Ma)6W-<3lcX~#P-GhoW4v&c? zLob;ip8WV!K5MqtkNlA&zOX0G^f`YGwkhJ)Dw!94!vpK*Pn@6@psI<`)q=>x>RkHJ z4C}dnX;m$+Uqw&(gx(uV)kw6RHtv78YAw3Y;Og-J`d9oVd)pZ3=EWeWf3-RDNbZc1 zFCCwZ-ezMh-Al`8=f37HlC;10idMwkJPEyu-}u~0!+N~MH)@G>J=>L+qRHF!OsAsS zVod0j9mh9Ap+y#* z*J?tZ6H{qq8-L(Y(HIw#5BzR6Yr8^&-OYwy?-SaV|80fbBj$DQNbe#FcP_3o)Ab?I z{M}xQ(b134@aj-wY$iiLu|zz-u}RpArfDACy%-CQnt8<|ry5`6$PZ5O44GsT$w+I~ zr-Rs<`SjIHaNC{D6Lv>a*j6u#*HMFHuSc=o9=gPp-6=ko*6BI~C@wGS{AN9}ysXVD zJ;{3!hrX6Pz|F>}-H9&G_;3i0BxN-7`bw-E+1T6?es&KWM`~J+#wlC#X7}^DCI>s5 zAR2a4eaTK=?H*DDv6|z`6W#qh(0g({~cuk@(H?%tBjBB zSWXuegF$IL^uReNdbwXTXB%XUUg@srYm75)PqT9KbgO-#5nKt|yx4g7JUE}7;^B)h zkg}UXUX31aM{TG~OcS@cXE<-}$4Ayp-1Yw2Nr%*5k&)U>6ZX4)#nt1};vX|V zc>tQ8_M)TUH(upE>0O>GTH_rfpGZ*G%t-ygu{$meUB`wF2bd9EPewdVr;_Z|cjbT@ zuX*BEtG$slF+F}{9MyBQHfiF|#CLrna&}9r<~3PiZN?I7O)vfOdPGP?wn_iJ;g@^2 zx4NfwX?0`M-bqBS*CIzKC7*q3^U8)dXOa7>QRe=x)3|qpJTLXUk&6yI+kFs>Sl89D zfZ|(Zjh}?Std;1{>ZXl0WcgZM7HX+Vav?hwdr;oYg@*6)*z zax?aHCriJv71~t)xYp-*@epMnXdH5z0_Cx{T@XwRSPuG{JXU87V#XQ%fE`gD=Q`K0Ks zDDrevLRXoB{HN|@Gw3RQ%K13!eZ#BI9-nUp_capvZ5}q{LBq0Ze#BjQBzz{A2)-Li z_XKUXQZu%sak2pC8X@n!wdonWO`n}wvUEnRmRYQavZ%9qi!ST8EA;29-EC!|?KEs{ zuq6;I%@O~1T|}OS+}O8KSvl)uR5!YQd(S_ezxmu~QTNM4-P4L+&Cg*+2CdEgZ#Spq zF5In0m{b2S0Bk{q#E9uOYa@!k{vT~~ZKM-!(mB1R3$Hd8Ex%D) z{CFB(Yziim552p-H*PV~JN&6017GkkwJyVbw$ETMbyw%=_ha(mz5CL9`>#7Zbo}1q zhmVgQ|5A4FALQGgJN&Jp(f{r7HUUl2M=F#_=EZE-<42za=mK3l0y)RX>+M|Nk6+qCEVk zTL-A-)YH7F@qEtVpXuJ;P!At$q`Xlx{N&snFE{c}W&y9oCwJBUd%H6n+M1ABk|k$I zw%?4hFVuEEZ$EGL>iPKeY&5&nOjZBT&3DK557ffDQ9)jOSMG(z&cetH-8t9f<2FY2Djc7A1yi^d)rfL1=R+uJ|ca|N>9Df=&rOf;&~4>nj(?iMKgxm zyK8OWYM$}s8wX7|a#5?{=31dEp#Y=BPm7)4A9_Vp#}oWimX$pgi}Tr5Kgw^y*SrV% z4tLQiM##6r!8{q#%Hp5KV`VTuS#*uh4jF50HKexj`W>y_9ews(@6wlXW_GQXj12aZ z$1aN3?<-M)*EspY=22X`QHbC0Jmcs-Tl63%xfpjPn!UGX`9VX;jVeNB{FbFT3&DEb zUkv9$^D|BvMv)l!n@$jkSzr4E`!`OQmuGfovkrwv0oG)#gcz~B`+B)=)RS1Is2?p( z@3o4v(u@49Da2is z-(F1?o*wJTqVfpnKdXMV)w$Yx{shf7{#hdxDXiXZ+94HJdktH^5WkQXEf@1^T|_cz zM6+fIah{c3?hQ*!tI!!Quh>>IdVZ`Dn}KK6#y;O2%bW78q{y0%S6r(qt+W6M@TW;2 zJ0QNot~}U?Z)ucIM7PN?bl-SOQGpM_LJ!`X6&IiKbLxlVsaNZ(O3t2RiTPgE?yjDN zh*XTRG$e%m!Zpz6*4!9PnxRkE)8OsGkosZARNAS~xzH!{0UE_O{eLAc6ipu17QYe3qoK|RH`+%p~9`9k9(TO^IbO8wVD z<~Q{;p9dOHA06Usj*C}F;CKh-(JR@&T?aG6o9IlMPx07BmL~erIK?}x?x_v&icRp0 zb=vrUYuMOmKkcE23c`0hhd!ywe&^n7_QNv1#OUYS_h^cHdBN-Ht7aDD2e*DM~ zNv-0cKC4Yqypd~h!mZg-wM*k(iAIqBXs6nSFkma*26@{&6rR98EHO0yVy{(n!R)V1 zB_FK|0pjhRwI)N=(P~|B-}BW4q9}W~J}--h&)~<+vOr#9+#@kJeL?3JhJcj=Um)43rCd7`T zSa6b#!;IBjjNKTF(hU9UcjFH{Lpn+eIF7w(ZFJc?I9v>3r2C{V+~iYH5;Pk*?;RAQ zHL{1(=^?U-AFYBr2G!4)PPlt|!HKI$tn$`5F4`pvXtmF}i`2tq;_{@3o?5SJGZgML zqpkPY(UAqe>4g456}5R9we#$16z%#Q3UoKAW1o0SD;2J7bWBFUOmUSva2gq>KcN

kZA>4mrO~XMkvg6ZyycZq)92eO8QB(xUNeeWxgBY(jK|hk75o>{ap*~ zlG?RLtMO1~W;b`?R1)GTE4|bc-xWzBBYIwrTurg}k-eU21bM&R=Wb&m88hmhjF%fa z^tTz{q4D&pCp-pQnH`RWwAn~9hF7ib#`d+cSB+rp%F=x$T(65D#O6@a$f9$v@zms< z;%@U+%di>+O>v()N88RA=qG(lFVm{k91fb<4TX%iv63Jdb^muC8&2l*KpWw+l|TQI zUNy2faWs7N(I5SU0>!U-t!JYi?b`olf$vy4`qdq)c~+lqoT1K|Cyh$~j(liu@J?fB zireeT0WFVrM&oqNj*ZuPzmXU8@@v*)b*QAxUeVp-Lv>YKTIsXl1d(Zx#Smlf-L=|J z;ES>bCer@{Oz|Je4qN8}!oale&YPm!%xBXUok`)@z|liBv~IQ}cg zKY9G6D&_y$;ivQQ|3LHkOUJK2{_Dp-oiG1%nE69h&;JXDuRnat;oqu~{!&){7mt6x zI{Tl^hyUp^?LV9M@kaN3@bFs?Uv>D({{4;R*zayO@b0gbkN;$T#kK7Eua=V+SyD4D z>Tszj<>Pr|?=7D6;5@N$lWRTqY`6t3P+P?xK?}bAR)pRc61-R&n_Jyj3%!8GaI^>* zp1~91oZ^3~LoT$&&?RKMa(XJ2WPdr%Q+RYGLd;9NMx=mz;eA?wmKCc*`N^X6)QNnw zs`MUxw3k}O94!lqEllv3RPe!85wvn$eBjBsj<>Om-zet3v1X(9}Y{2NK85b_* z)sO)CUVHAr>2%e+Gpbr${YNtWLatI zWAw!RD}_Fl)uun#f0}Q4bSG*Ih3UY>>Gj;x+ZMXft2B+d4`sWiozb`5IlO}kwVM3* z9_OTiyS6rV`kA#`^s}w6$AyZt9PD=*JHTh3U2oi{_Jb{L)>=JTjnzzOYkg>xT_c_& zj%h`^JN{{0vXbKT`~+OP>u`#9Xkz*4@|$R2gU`gfcc`Pj8YuX zYj$&WC(W+Mu`aWw>xC_c_}3bq=rxqpS1tM5)tZ&`Nuy?US?}f4jaZ55%Apjents^s zl`)h;e^hhNV3ryE*uNS1Rxhv)YavhUPj|si#xZ)j|6xPAcq~BA`d^FlGb104o6lYK zXC*dzLff!S&>v1fU;i%O)8=Sk{pb!fM*-5vM_Y@mw_eS&`X1gIs^G-MH~RemO+d20 zjO0Zv^I03BHB#j%5=4Tn>uM68;1PLJ2w3k%$0x&Yqkn243dB2h5x{C}t@W~sW;7g8 z`}7%pv=Zhrl3i>3>$qaBv0$ie zZaDrF52G&xfv#}VdJ#R@)5BdpudPM7xN9T`m3q!hU_?Ee!->T9slHE;P*+62PbF;E zot&o2W^Ijjy`gPmlJyXMNejk3*Fl_Qb`w`aNB(1{?+$5 zX5_5QCr?~^Y!F?| zYcq$nmUzh+);2;&Yi%0ejKsCY(8D*=9{HgaaI&$PFBTWgO@ zqB*Ul70*tDt=3T1de&xG3EondoM{Y|`yjz)$%SM#;b^Q3Dy%a3S*2u6i`6Vx7#~R1l19l3A-1bBR@GmWFh1ve;vC-o#be-7kP!oSI>ZXxa z7qi%82Bqm=+T49xrL@v+o&DjswJ)w(vDJ{~zWN)rjJGzrbA6Q2{WBU@*V7Q0;(MIX zGv28NtUg?YLvRA=fIHVS#_KSP8L~~*Y>-;7ta!ZC{WJc#Q#&JHdL98=32^6nYa);; z_BRSo3eA=+S$?3w=@a~G4)J$aPg}D#;?#qndUoXcq$hR)^Y!=?ahyB~r z=80x>IUbnLyH{KNG%A*n4qGo~Tj>eUPXAhlj+Ucg6w%DZTPuaEvxp6@G*)qa+%ouc z=&&)+p(Oft59vjJCBoyS?%q*<2@rFSy5@8sd=wQ_KnpZgY9RL5nYY`u-fF=Yt1Zq z&or2bTO86DtQVauo`z?ZOVCCw(ApighWBa(eLC@&TEb`Ro0}C$Wer%CvBjf%S=G@y zM$r8v2H%r{ny1w90VHJ&jYN-Uw+4)#Ch);J1`onvZtEr`|Yww;aH}Q1+SAky}S(EOv-(GbXjje`8#zYQ6g+wDo zcTYExXKMWuB&qvlF3@#3Sv9wvcGW+0*K3XBa=DlLq9iT3Q84@AF87>OQeE}y@cZ^O7rBx4BlPPjkpWe;d!i70 zY44aCTl-4Y9I^81yl@ykL`T?(*AZ^5-PdMj>Rs>eGqskaj@D;6RDM2PHtC%*NL5=k ze>=k-n<`OfT&YM>QU79;-TfoYX?|&f2g)i+O!7>0Cy9j3SXW%YdfwDH`Cit%%DzT=OYh&)n%otQ zp6TyKBYEH9y=BDJM4ysYN$_Y+!E|>~QBX)9^ew_(6wXL<59dC|y58XB6b21OE zQ&%6>>@$+pZ>xAmHHDA#Ni~-}*)IR?#ZT93x3k1rvyYXzdu3Juz2pr%tuFD!IO$x{ zh5n?ZnxQ_g0iE%i(YzVuenXYL54E0RRp-0sw6>rAFt%5B z&OOWjo|Ag|^toDiwVt-RaQ0PqO_X)DHK}QKBO#M>87ke|7*!}O%BPh@Q+K~DE_QOl zRPZ+rHF{3_R1f-Ds~JYC_iTDCI}eOTI#;H$v$$rpA8Y+?nK4^myi!)P`+xTMGrj(X zc07OE@dt1G%#FWxeB}5e?P~t$nfIUhsub@xAOF|mqc?u>#t+{3|BhdL{GLYgO@|*o zynW{E;myO}IQ+g=^oNfB?(yr6|K9O09{-EuA3uI;|NiZ${>4>L|Cz&gw3qt34}anC zZ$!;At=Y$pKYsk1)mr~RXQuu2;}2I;{d9D9_TYP?_6MuC{%zG?|IWjg40nC7^}Ric z{_OGpJ^sDUKzll^^sB873e#YZw3qtx(g@Bi`%qQbUtEUP8CXz^b+8xgO1+Y>-91FI zWk_+t`w#y_zxPDZc2l>?>K@^l#Y1BeNpW{?&Xh-m%dOBf~rpnWvA z7uSxAOSNz30S)Pts&mo)6OF$!6I-YC%j~4GhidEE?;8y+hs?UC#o`7Cjy+;4afci} z&sS_5Cc^>hgYg+%zfp47gY8?6SGP+8^V!XnW*9rz?X;PF40@5FV&h+nZgzO!^Ow!7 z`_%fff1=K7|6fl}KUodk*?7zuV65=fkzo7(@=O|;+&IcF7P9A`#`ip5OP}-@E5shW zRKHt6NvH4Li;2&5$JRT~KH#p&#Gh|gi@fP(NJQq{KDj+*RXy;t_VaYVGwf76vRjY> z4NkkW=IZI4C3&{FW?#{FK6e_)&Pk2W<{$^}H)4BkXfFH1CYKlGU^+kSqaF9or4-NN ztKn6aR)ygGwYz=;-KKK+9(KAXo{W0-+peV305oTHYD3L;y2GkmOiJvcphtM8>Y-I% zi%XIEMK-rKC#T77zq_4DX=l{=u4_vzw90?69@KlbcWA{EQLzsP^2_+$;!Nx(dAS~+ z!6f9^4jt8R@5ICk4Tr~DZ6u7sM+t+}< z>{r~nYwPbcR#LyGpOEo*GWycvW^-%Qan{A|?{K;??2BjZGoerHQlo|VBB;;*4Iy-& z^P`>DU{~6`&Fhuvh3$4u>7_<$2jjC@zope_{LPBp+xkSYX6dBCTjQ#yXZ?x=G`8I{ z{$`XWD|{|!!91lNw_i*RIttTBYIpWT=*5hqgL>kFNv|C*aJdtRXe3;$Hc8x4 zgwJ|9LDU|IduIgj9vOoyo`*qtEgwQlk$rm*SiC!G^O@!d4LU8rNN5Or_fR`LE=0K} zyROz9ZhR@e5^I95#K2U7YwPXW-Yknsk=Z$1|4tQRVer{q^$Yzz+wAS|ft5u5CJtUN z;`et)%?q=(FV#ohPR}e-+S=tCJ!L(f=~L(zAG}*HcA_|6C>pl<>x<(sc7YCgG`j^G zf2`+u@uH`!zlsSvS!ln}i`_5IbGqAQYh%V==_w2X!)(47`xFB%_4-ZT8j zFrB?9Z+8tf<638@*dJOw92b9txcc<@MyPt-N{InO)3{BPUrynb=KhJ+n%p}dv(x+P zcM&;k_Q`BL6x%7gwTu#^neT0f1$(pDyGpCxu^)Cezu2GMFQNl1{noY8UvO!Fc9!LxwUHg|zGj-{n;dX6c0z=m!gtjAr+WHad}MYn#KBJeQ*AX`w6>wI zrRhc^#X#5()i7-9TEg?KpFO}d9g7O1v8T^=*ZU72j8u~g_a>LP0LFZ~)}D^5$%Kd-P3nwK*hq99vTMgxqdNWNSJ`uSxx080;u2OTyV4wZ z{&r!Jez70>ELYjoX$TNjQtOahG zD8;M~>GTY?rePhlxHrlBqRu*d zFwU~;tVnNnf2xuGd>qO?TL-yJamYuTVduWLrmC$k_U_?Ugm>|3Be<{Y_r*7Sd04Kf zYtNlpLcR?tWS7KNFJ@UE>KSpOV>I|gIGrZf-ueTl68B&+hliTk`j5_5c`@FH4CwIP zl|V~ufN9`;kfX>JFn7YoX6ZqmGo=wZ`Uk)?d%i zYj7~V1a*)dbZ~+j@BGcy=BdsvxUK#kX^-QT^x3Z^ha2lvW@FW6&*I!kM@);|vlvuA z`z<^azU-FZZt%#3}5gI37(t z^*z1c__mqscOTgCy}D3_3k{5Cd1kUXGbg>!K+ux?jv>nKny6q;iG%Y^oOH%tacYLE z=rZfj8qrW6XzedI4;G0m()iE{3yp%1xGWf{64me>Ik*~vexx3veC@*CB-r_pd7M_m zd>ivdHJs$PSzCM$G44FbW;nxq>S?2_bbzt?q>+SbmTgwWNjcK_nq-Gg$|SShw?afMwQPYj=vRT-c9XvBjY z<7#Mpc~;c=YR~!ZlADIVp%#{iKd|3jp+ZE=l~*9wBf~`hO_giylPTZi06n73)BttA z*rQ!0YYRPL=cyn_-guMjUwxc_y~sr`FO6I+x@5bVnzJv~m#qeWPW>8)U?t?L$gMY^s9H?j!}_ntHmF&E&7qWvn~A0xjaiN3vZ|7;Ftm^3Fo-wZ>{k)wqOaCr8dO zgbi>KiLJ#(4&6dv{D1bIKT3nik<(giiTs7^g)@=tRu|>C(&#>r96VM_JYXlN7{7f* zo&AX8d)_y3IJIx1Gw*3mqM>4{JOuhiE`nEW9hXXb2B6&fo_iycBqxFo#aMj4I&e;y z7+&O?*a?KQ#dXAKpqq)_#7XQfq$PgA&d8_Yc9^8>N>q3}i5AOuZU;XKy`2RhmIOc9 zU2fbE*63BM-)Aq?3r|&sjWp1!?NN`Low4&uw&Y{+{5!Sk8@4tphQd6tL37$`{^Dm) zC@tvw7o6j8^@NHWYnV0Yx=hE|!)V6CdafD3XS~=vn_6*B#KX;LxodY_lakMzEnB;^ ziI{-TMcq_c(BNW>V&k%r>|N2a+J>KLz%2Jr4sK35n=dq=a$v^a9jx5uQurks6XXZc zpseDeRVY*xkX3+Zop(awAxC~J3H6Od?5*gkJfYa*wc@Bwd%?H7z19}YV`(u`;walMI`)`s)ctmt#|%ZtQQ)^_8&G$sj_zoeu3h(zeVx45lg7liSu3DNd>3^Z#m2{9YOYN+TnidG}tf*shVW`CZ)@)8<~-nA1Fp zOe&=P>y2XK`cVc(WFtgSpdeO){*gD;Hy>qR<1X?qA~i9o<|C8yQunbt@xlBnwnew| z`ko)TcJ2$zKubcsBw|mnf)<@J;ghqqMx)^>G{j@PTt3ukl^1=n_-DBVN-_3FYfql~ zlY`5{fZfN^Ztjr9hXGh~wDAienfqx3*Z6tT%Wt?%Bxa*@EW~1Sh>GWr7o4FdLQQjR zHd95Ws2(psW{1UR|JSlQd5+c=?RO4_2n8J@6R}lsvevgIHSeztkx4r9CA`(B(A_$- z+>gfXY!TZG!yV$Hr;WoLYjGo7qV8fjIDaL<_k6)e4@a@{(O@b?`yU^#ZCq5gkq^F! z*uPu}uNg1kQhJ0)@DQ82B%Q6{*tEL5YC>pSHV(S^s7Ly>UtGt^&g zt9C~p&<`5XidlnZ?ubSpr!pG37U+$79i4bdt9A1Ci3EFe2|==0FreBum^yodGN} zwKOxM)~zd_O3Oag=Z}^DeXKi%Qhokx-ubWf_wlqehKsXXs~li8KyC)x-6 z3tfMjZGzp41_GtCz~nh`nBH4?Wi&K9gY8V{_U6Ke}AaV z_T#PT&^#JHRqH=~{9Elu{>jNy<1XJ#!2kY0qj6T)Z)rqdRA0WmPd$d*+0ALRU(G-M zc$^QJv+Vpq8A9=%2YXhY5?|6Q{7*5t#e=ZgVMv-u>05Czl>?+<``}SKN8BeOG|nLsW5l(x++x?{8YY7J#C&*8EDPU>Owaj- z^-3amZE~411AC6k#o9mzdFlOr0J7o)S)9UZ%Qrb+kS3%xH{U4}P11~Z&zAFTKji>= zzgBg0Ve}&DkmXbH&6~ac+|d@_~q4u)8GsicB7k~I&Tb?w1Ho#cs@gMnBMRo~=B z4hr%Y-z0I)w3DNQ=VYZhAJQM|DwegU0l`I=k~ZgivV!6m zyfqVs;|xEbV5@^eXnuqKE{t=zIW`Ag5jmf52I9BCzO)5|EinD!3UJ!Oe?}YPb>a zIsTt z%$pkZ6WzNpH8v(aPz(5z-^0Ted+a2R+J@8R;5RljoZKgy=e81f(g}^Hk+kuLyJNE_ zu+ml*h{o|%wibijMYZmNMra>#Mf?mUk`7cUPZG^x12Ixo=?V9D2Q8)UW@)2-bN$xU zS1K`@cYX78%#BCloi=C3^t5Mm^ad|ome+Tw*riVM(2V!C_FKh4-+r>*uhuh7&srJx z#v!zmZfNcJ2r3+JZme6iv6)#`myYJ8;P)q!x$>gjZ?14mQPn6(my1mAnSm@I&AstN z6wvGX#47m0hh3-D)S8ortV<(#Bo4XUy!b7&!P0X*F7+I;s5~?gR443<#)*u>!t5wi z1+9`dHCSs^=+C95xT<{xS-Cz@bH)yC?FbZU&N4t^pkk3L%Y0`imP1oK4IV8Y`|Z}A zCR|&*-hoxBuUg8puN9}n83pd$oaL@)BORWSdEiUY^2RRWu;0Z6Cy3&2wwCYjJ}1|T zUa2Rbd2y7O-Bfe8n(&p1Sk;4eCGsalw(tacEgsy;ZE@I$4C0#U{BRvJg9X7@YLJnWPBdjCcj5jfck zwLWT{@XOwXzGQ^{p;vLS{?`w=XI4-yuJ01+36VB+R5*@KRWF0DaW*d6I6sSt4*H~r z)H*B%VQ-UXcaH4&4gj7Cx(q4tyg~gsp!TeHV=q-xAwhba!7m zS+-LIj}FNu%~PzKSi1QdGhDCwN|f*MECFrS8LGpXFebW9rl2R-?j)>sWWuZ;JG!+N z8@1TyqG@-tJY+hJxhppJ~ zb?G_uV3Wo1#84qEx*;pjr=%Cv)NbR#@lj`-M(gQ4^$ET6)n~S_touYRM9A14G=WVZ zC2JZssBTRgDCcnaplEm@JzX;p64%%SfC~RthUJ-Z*&Z1S&c-aEzaL; z6AdIn$O5TyFdtZM5j+iPm0(a*rZ3njGQQeLgcJf@FV+m#6aUPP=9wja8|%?**i3eS zW>v8$E{USzk?4cA%Mr$$j;IAZC7X4!%6)ER`l4$f#myhEBkY(JgML*~&iZyQDTO>x ziS>ZFCX&-Tej(b41z2M^lU~s>ju3AVU5K;#jMb&lX760rjh1!XDl~WiC3%JXgQY5* zp?zp=5wrdm&5(c6H`=n?y~b8c>Wf#i8z1?mjmV0uu-JsQR=Q9H*Xj{{#O3$^ zX00F5!}T{|=*eJqReX}B5fvN`noo=r{v3_c_|yeon-*9wlDD5sCT@C#RZje%#>C%% zE*7)RJ~mWuOwqOR;j;L$zeW81C-pdDb@rf!q3=ctSN3|UIjzU%ylT=4GjEo`ghj&ETuKllLUzOpaKgUU!8Iu<7f|@DO>9t5-+}S(KTj5%4|aO^cx(>|_>r zg4ea0jb`R2x{h1tJfS|pqbK}oRl0**`1UL7$nUX+yV`6Ys*SE4N)Ol6R;W{-Q4?i1 zil*9XEi{|4V`D+=0hq{KugpR=1V=AFh$(Cpc^IWTSO%BOz9>@NT9Up+-=~@#rD3@TYENEsJ=#HEjYiGabM>&4Yx1hWye6z9M zaFMaAjUXdiKfHC@xc0QKl^)Ul%}(JQxv_~xM45C@KlpI}6~E+=sy@HeZQ|L~Uj3wyx#(h1ZHJ?r#ZB~fBYxQP6wcN9Mg#ziQ^+)|rrlB~9 zdbtrsP=hu2q_*ktEWP@~dA&O_u-Z7)XFd-MVMq2z$BS-qrz-acjP71p~w^l9R*jge*L5uplQ zzB;j$>lv%D@x6^T!L+=&@Mn$D!h8&)HlBx))I-uN?`{ov_w+XlqFTc4!r4_*yUPQ# z%pjUtQmeRL1#1DF?H(gh3$h{ZP6Oj9*KtA|-XF`W8eLDatbS^_PspY_a7YqZza(Jo zFD`S?cXybkM>y91F@<+AgQFLJL`e;Z9c$UjE|nt-bP*MX9xl!JM{%spqU3u zV9&{Ldau+K_^zu(*c)HmwbIXK^}2u7jKu7nXu(gJ7;-Cjvi^M*=l0a%j6nd+pFZ7K zHQO`s4LWJ4f->We8}SLPtdh)!{qU=C&Chc%tGiY+w_+!&WlrKJWRi~8s#RYJr(yi? z=fx^~FGaD8uF^kax2I)XXT|LZpsUm|;Ns0b!oh3nrgl7@9PYOk!?lZz)|cUJv1r=I zG105L$)y?xz5^R%-dnFM*SG%U>VKR-&-q=AL(h7iU$+@jT1p&FeTFyydeT8+h-5ll zGQDpVF$vlDG8=q)Us|x|27P}4+?7PspZp0Pp7o03pkTfYJ-}pS)7Y-sTSdkck6qK6Bmm71apzt=c1r*h9uuK4$ijbFpMk(q$eJ{ zo-}=lO@1mBcTbnDb6r8kjF`UttaRf{xC0C>|R7!EN*!R+IY3Ke5p~= zx+;J~t?evuH{6C7*yJ?mj1`)qCsYsEx8j?*U~tw#^m8?x`1-}@@L+$%C>!5eIvUj+ z=*u@-HPKf(9S#*W^zBZM)b=8b-2nrQvgGhJtp~kKjntqZ?fEk+GV8tv;-*W(w;S!S z_lfS>lO3LmbLHbzG2)fQuB^r855k0fc7Ln(SZnZ968U`hvwN@PYub-Q??PL?^-T28 z6?=Ua9pYSCW;3Te9~>>}^h}(Ew|LB|z|AaWWqBX6sq8t$vapkPV(1#roRsx3(A3F5GHBqQ6>>{f;&fC^Al$kfNoj zS}QfRd=E0dnB7{k_M}zZ8|Sis_eXaTt7NVp_o_3o7LTN3Kj-k?boLX+|Emg{7Y<*0 z_^HEjT{E@y#;Ex^uOy3*$KeXTG8;}3;@sIQ!fFCbf{|%j2@l%JF z5C8b^V~0Q0X%x4$ljnPmf2!Z_?E44)^W(So?_Y19&C6+zf37nw{?Osy?wN0F=g%K( zKhFDGCBD=vt@zI!f2?PJq2FI>N6sf&lXAGt@Q&v2MSXMOmsEA52FT0@IVMF@udO~qywtvzn1 zzhu(v1?S(q*bMEP-Me@KypfPiuXuzLxvrPfctHHv6_#A>0N;|f47v2&=Kn>YUzpep z9e|E}9zNmJwTztbAo#iyhbBrRCnqXn717XlT8oT`7~pMMjMuvRb&bi{IchI__s*sG))`79 zSbT04i74F%h&8qlHP>>h%!Wj?uTZ#&03T52kth zws+6e9#85dqTl;Pzjk}6Yhhchp86!7BAaHGqUwtajMX|v8LQvBjnV8%;b!(xzxZ)H zqSk(P7t{u?M4VU@1+U^P=iu?QQFt&eQ}J9fm;j-no2@7-xW7hljA8=EGh z=5S|RCI7zp2OPh?Drpqsb&@fZW5lc|pI0TwoJjK-9z-D=$l_RKk(${Zb3$(;h0EC> zs6b3yJG>|;oduw=*?`WFMbg%BjOCkyo&LX6(mRf(GJ~}zEVKl{PsqVu!%jeJ1;&t)jl^V${75*2XLrz$wHHh76vfq>O~Sh>xb(8$i4q0{t7 zXFHF}`A4dsHm*Y}T?{Vet5orkJ? zuJhTZM@C-JV30*v&O)g;$S*cn|imzNcQu^x7X0Ddz_~-M?(>#x)`OMhYma)C!AGEnVp!kDGIyoND#pl{s(8bq2>r^D4gP@U5Lm`F)2UI{Z() z`sz+0dc7S%-(QsAPZtUJbNTvzv-2jOj5cRmzYpc9|FfM(`Mdi4=i4dNNdb-crpEd! zon+D3nfdlkVo)ngCv2|mLj8PRr%`@k&o2^yRo2>x3-WTF4vFlyfZ;n;gHFKw2*0I1 zaKBS+)Kp|^d-h5+`FOqBHzRVyzqq5j`p)a9iQ*4+Qpfx2(OI;7SheD0v0Xj=vZQp> zS~kebE6C>VKDQg*H?2EKie1433bB@}dD(RqkdB1D!XVv0wW8g#qk<4ltad%a zHc<3(i!)^4cd~+(W>0H6<6`z7HcFdeV1%di=!`6Sr24&tsRdWb5ER>r4-+^y%kh6}KXIGdU}lkhQ#^ z_1}78nv<^HYyrK!T9);N^7wlC_PP2<=uVx|XxizYzIi4}*(0Zp%1%^uK; zBYZ%IXRGH9*%mg6_r4J?@mY94?6>N6^KS$^cRFe6ZF+X)5?@#!yVLo?OR4oRNu`(( zUBolo3I+5--Kn*0G{(Qk#XdigKC%a?c$Uw^;)@EbXJPiD&7{JPK^kQ$wT5!|VY2nL z%qw-0j`$J^n>Sgc*Ko7lVIp3erRGbBtF_dIm9n3!FsIJdp7=Slo02} zYtTn#OCFZ@qwZ(@W|6?f2u|j*mw*(o_j3Zr@G=bSv^x8eR?_W4b2?IS*hZf`&I-t& ziw|Z;c7~VER;`{FZ-spMlC%R2y?oE+ zu}H&zLuZ;e+tF*XK?;@%VZ77pePZ`ME*qKd^TpIo-L|{t-p1X@xvi|IEz7G))$SY7 z6`A*F(dZThI*Y`Pc6yHe+4{@zXuCUU?@1@a$k65+S);~F2Ro61cP_dmzWttJ?hnsO zle!`i^_`406K5(ovs&J7xT>dl6c6S<;k=E(?Y?)jl00Mr)@!>>g_rl+m-w;_bUj!aVF$;Vs+WN-|`-MH-&&R~}V0 z5=7&K3m&StJg-ki_hPRux5|57xCk_TfL~Nmtp7`r@E1C3#c4qHnBq)zwPM5eN~^|K z5o7&*kG6~@eI$b2nd$LKF_^BC2sIQN6dzLcPEYhbk zkH^G2q!Hl^x-Zl*w6fbD?Nnws{|K&9$8fICWqPw!Jqh*FC@*v`pNfq`Ss8RYjO>?T zH+GFTlK~lvq(TnQG-7DU&ccT~{m*xZhz32L7hjg8YoZ*_96!;z+kJPfXXTR3+xn4G zUO20?nqFppxs1(&3Ls||Mvqoh#Do227vvP(buka+F*ND5Oaqx-gkuHA7PT&F%c}@Tc04 z-P1*OM5)l0Pv$IcXSP6GkcK)s*(y4iwr1Z+CL2InjuB~G`)*yfCW^;K68yiF z80zCu{nvXAMq8hPmogFW`q}f69*iTzm*v9MxYS#%@@$|j{*pYuYz;Jsrsisms?&+u zBlFE$6&HUk4Nz||I{u}}trad{<$Z=GDz4Vw96zyn(*f364Elk1!I{Y->@q%fct6wq zowyi(qX|!PW6HQ^Pp`updv490U!USG4jJmB1sjG3q$qk*6;WR z2ihKw@j&HLWww6d_;-(grw9UyWYfF;Sl+dBDE3^u$MUp4H_n$I5JMM_6eD}8Ij{_( zjcgPBqVDFy(Of*4Mclo4JPEN&r=Xl>+hC`2`QV?|6P-xiGmn&~7UOZ6jWvE|`r7wm zc=tC3r+SI3iVVu9tA4Y#P{7u#;!zZk?eh%<&kmPBrR<0O39{B=)Od>j>r4<-TExPO zk=N4>J05b3BjO&v(RXbr{pds|QG~lmXDy2`!vT1f4O(A8B;Kqb^jD(CrRH!)@8i1e zfsRlKH<<+tisNM<`#zh|dNhRSFdXx#sg97-l*Lxb!uF#wOZ?zijQbnK;J9XGU+kWb z?2HrV_&Z^RZZQ{n115B~r}*T4f6k!Zt~z1$nbxbBOy9T(7UVOC;PYL`Eorxxy68#w z`sSO5<19LYjOMrZ4BWwb?LO7baHB6&ZL}ok)A7_+K88c1!~2TP*nM(O{P>ZgLyxEB z#k|>j*a0_LA9e=+p)-uLXFpdf)M)N$W_Co8Zr?DnXLsT$m=G3YCGfr2p%^xl#$&@} zsulKJ0vyF2Lr}jX#sK&7}@(9qZHU>Qp zhwve-JshV$*;U^1dLDG4m@Zw$8-)Z^FY!8jmzDe}TH?&KP9vCDNG)uhZT(8SLs3^w z0+&PZIMmK!b#Lj~o`ibj`(BSSRc4q?cZhN0AW?13g1bUU-Ha;Zin>&bqDnJ{?B3s@{<(=nq~IU(&D0 z3Qt262Zl4Ee)``kg!-FfRP27S_fG0>Uh5~aSMmeUCGEoIn4>rVzh%7YT7Ic9Y~*dD zBQi#!^*oBr_^G<%_rR2F1FuB{2VNzE{2cYEp7=~8#{20*_JUr&992n%C=*>t$K0Ik zemo8EWSjzDOqFWWV>6u*SO$7VE&HTm-}#E-YMrH78(R;zk&fxPQC+APoGzn_!`A++ z{^LKe9AeU20fRGNYxdWB?)^Peo^UvuyoWKn7Ye11A;IzEW~B5Xe#2Yr(^ejAHdQ@@ ztfCbf-mgV>Lq}Q^7uh@bdZHWTTtq^Z8Y!$U2DuLGh3`ao;Xt(xgqX%MKEQm_8k*%Tn)7i?GJkwgz z$D4N+EvrTCMNjrm26;95;yC+3MJ(K>D*NP=wqBFkjiM~CtI;ubwQp)VoY5kp)1MZ`mk`- z)H%mdQ(w^igZrB+&dIWOFWwbfP~*dYTAR$b+qtU_TTQA)Kx}Hin@a5lp9X>zBa~$n zYjHL|>#+6j;slF)RBjikZJk+ud?N?2`d5^MPUjbrU}#)^2P&j9M!Q8JTHpGqTV=_` zzWJW~81*GZv1Yw|w~k(RM`t#;`)QH2%ij2|p|YFN{;B9`J$XK`3;CKnd-IrRYVR(@ z`PtZ7fa^rFH+IXDp^;UzK}cJZ&SSx2YP9h_k4&`_&(t}_u30y>t@zT+Yivj3TpvvT z3Z9A>3Ex`#YNMcBdTedHtmVd_llECb`h4Rt)<)i2EwYFw4QU-k zacDPn`=YfQKa~HQJVzrCZ(nb8z53O*#)IP8WPhA%AuCM3ZANZa2Y1SG((+{)qsn@$ zB+$8>Ms8=UJvr+BRhfwdi+`XtyX5HDpux&OBu(ZR|(a*Ap^lloe&On(&C6 znyB>bE9rkcFNc7eMwVwwP zzMUIu+aTS|u}u7K#&4c@YW>VbLNqjg7FH$iVihnx-eiAZCi;xMJ5#5!GU72lGcTxr z_X+Y_a1d_Yb*CX=Er}P7$66BTTku*Be_@n6Z$O zbVaQ-$LWWqxAHihCUdtH#`o@G548>bwAMW%r&`pt&&0+zQYacn7x6AcUU4&D7#GkJ z*_;_a+v2{>3Hn9>Csl>gqJU@$T*F4fQ!?I8&EfacZ*+wSs`2gG9lPc`5$q4#nW^h# zJr)PEA^d1@A-L0;4gFiEJgD00$LRV`4s$D8iqtmlr7+#X^Mc-SFCAYwP40*$y4u>RAG2p3iW$D{Nqy)Omn?NyMz#hmpm|t)=SVa2k*$eyg-NN1 zboy;5F%~B}z&!jSbF)_nRu#ugyL6SUpzBZ!4&Ta)Mf$5xtd0nedM*ACjqWayA?IQ( zf13^Nq@ToGWF16Teea4m+-9sr-&ki6&-KfAGVUA6>RH%$G8ny zHgZ^6fSLR0J#Wq(vO-2@{nj%;6&akthV#@`4v;D5u)#s@r8A~#vlWH`<$>r@zMN;R z8}G|AYvFswv*W=z=Ug0*RfCDiD=%{6(Bi^nGMYEN!oOc1iH}9c+uKZ^drxQbJlBfR z0%E~*hrASz(6t?ryzY3r(N$d2?%WTw5_}C<7WUY^-y7?kr1a0CgJ(A`kosCF#p&Nq7CortKsJHPU!@yGNI>9BQjlqe~>tBQiu<14cz6Jv$CPVUJ5${*ch zz11t&HEECALx=aqDNgx(p?<2)Z{)Zd#?=x87G;LwqBW#g27zUn{N``~T!Po>J~i&V zU_9d+X5k?@Zrnd8YPc+0Rcm6)^j)(z{-FaLY?jL_G%M83tCtVp;fN#f#<$|0gsgVK z&x0|WqX;&gfJ^)hht`(8vsZfOyBbcor552+{6+_p4;4ywSE>4;HMYV-rG_=4clp;W zg*L=)WZmEv(kX_t`+eo!cAqz?Cdn+goxaX2c2b5q7THC!5nsY_Y^f1hH5vn6fFH8{;?Cdf;2IFuXRT#H%O?u3Z>O7uU(rWTL|B0VA?X2thiPt@)dyX(+) zv-SBWQDt{$JJG>fk_%j4oNs6|y;y-hWdkv+?P=Cl1PbTK=x%%h>XJX2@2H7B zYRh0HC*GZU=VC4DdmoNJc{li()=JydFQ36E@u;Y`8Vg!RrMaslk4}UIJj*M9P@Ptr!~( z4s%=W!Ap&SS1~n%^#VDZTGm#vnJoHc;p{sLKh`S_<{g_UoNLYY2eO%}rmp0p^~VOX zBkQb&XFnY<9+Wg{SvIt%xequDk}m7%eR(09V16XpDobFr3b2uO%c; zo1w9)6BCSE)mY#w(GI)V;#e8ol%=bSdEKUMdqw0+R*Df339~8c4DsjSXPpC z+xWl8B~4?M>1j525egl*zB?2KrIV12qCwVO>nT_d*EH500D%$kLrj7XHT=9gPrb)mQdt`=D(0elnQ;?y?uJe$9M{Ekb^Pu)C< zYl&BMYJYLI-x)(s;ydzU&&8Z@(->*xs4+dVm}F&7*C#1-GaWtDu3gz9UMI{Ojk=e; zL0J}c^A1K1%es!%)|@X-1~v|X*TtvUr{x<_o1W+{+5viCpJ*!xpH85eXeiu3k85)^ z0DC(~ZLTlgUClyE@wMrvs9tMU3$NL0#-k!r^op`wWfY@3pa$ zx9U2?06B;Z_`U?YE$m8}Oh&E9REi+8S0s@QWW&~u@foa-s63h771!*#PZXMl6jzv2qJ}RZf^FR%vus-L@ST$(*#a~0or5aP^o6D} zpr_SVtHHAPt&Z!k;YNUQ^H_^Ub}GeiRyu7~k|fcTaKx?|1gsjM?>F>WcgbPn^|gfX znVlJn!_jfHTpS|ih$BU_XcVZ3tn7YuSz;rGMy;-zpL?Q-8k*G@ITuD=$+{m2Mu(IO2s_b+isg;F&qSSJMBFN} zh!^qnesdPzadod(e3P%@ty|Nh) zCM#_pqxvHfgP-WeJ$Z4@VsOXq)updQ8Ak@|S;hj#7y+y4b9siX_1!a@pbXJR-zPu| ziJsBk%W)#?c8);0;=QwHt&y{<8~tzfYhO%S-}ntOSWexHH;FJy^l{csryKPNTO-Oa z=YB^OPsm}ZZrjWq96+9og^r`MAyoN6^Odh!-+A#b4QQlLw+N5;zHcB`qrqno(}&`D z8B^oior`(d5P4#DZDBsOi!0$$+G z|D~zff{zw6sRnZ{j(iamyb&BVUF--;LBEnSv|nGD_wLlQt&HA^viUyydPaqw$?Vw|f2ZD94lTUN(Rq=2Wtzd8h$d;|P*LTd9)J zhF{dMJ}0eB3)V%jd#o?mnY_OVNZNmRs-$3`V7iNfZ zCzdzrvu!kwY={Ww?kf;qqrXY~?lRxCF(SB#&VU=thDR2^4Nd75l8N%@!K&~wCdbx@ z#v|`N-sMNIJ64c}u-|}&jSlrfOS|Swg#GS`Q;MyJBC4_VgL z^&ciS-TdWH`BWSKp|kfi%lKlbfgYm7Yyu6V>Q=78nt3mhMq|PqTeD)ntVpue?Fw9ua@K3$maIonJASvAICHtze_DqnuCDXZ1O| zziWYAgwYno>JQFB%AVpK~F=g^{TI!)>6&EdnSc-pBX_UMQ`ij=OT zvw?f2omIqz8?jOIBkmwxK35udR-xzC|3pz%M2s9Fq!UmahFomM&anIBr#6OrCKoYl z?>iS&FY@Aihc55y&a&*)V73mVg~q@Y?7j83;(lnQwb^td4I4cgwOV*pY1U=el|MK^E5>b{6#jM!Ik4Sehwx}LUx)lp8JsAw>M3T8G&_lX_sZ&KN( zr+Zy_j;vEZeWq?;PXvP%ARluTK|ZZMS^wWBGAmHYdQ#|5tDVFXTIcn#H)=zoNh!~8 z5$)D$k=j!v35TFGjV)S!wz;+|sZWgKdgHRwjCYVv*qw{H=r>lxT*akkg=#~c{pKu4 ziq(V}Lb|=it@flXR^K!5@VBTB>|*9l0T{2c&*(QgLqvC@ArSxM=;jKaBOTdD7Uj^) zkPxp`j498p@ohw#-8aYevt$~!R$euho?*?&OV%SlfxcL@&c?}Z?7kbmBW%K-*eI;X zswnGv(zs{mj6SHN?oxCOzJw)dR3qMf9wbmLrY!B|rTK`96-4XU>MVVu^Id@O6dle> zrc>6(Nownd=2Yd848#SmbpLbpN8_#>(B5pmJTPe_JN8BR#yPd!w4F8}X}nB^S=+$_ zGkcLq-v&runAu`eoT>kQ`;_h=wPa%bbozTNPyed7$BR)GZ!`;b+^XUgd;nuY?6}w` z#w1dsHafna(U~i+jXfBP*6Y=iqNSu6UKNjEGe-Y4Dx7bvtRtO)kD-4WZ6$OuqTSkJ z*Y=61c@E?Djs<}!_-v;(xG`(LF&ZhWrj}Axbx-nxhoCrmmF0f4%7uHIBP8Fvdy*aZ zG^-`Q#k*o>tv@|TO2rBm$KXe_g1I1cD|Mpp>;Dwn!Ln?c=kYWY!}ApJq^o@HUR>uK z6h6c95-VW5CsJFlG@?~J9f`FPsaIECrPHjoQ(I^UI*@+gAK(Y4QOXd%*;_V<*HDZ+S)2rDJoLAETR@f0liwGw1Nw24NAbU1qdMZwFQ-5G#GVjH1QmKbv1 z?|pjCPwI`io;+gagx15BMdC26dJJ(1p?7b>(~LBv$v<;Fq4G zY6i96Czl-}zxTvfkdW#V?gj_JGZ)p`d8#&S-&&^)EyxedsTt`Ny{?@ac}cG~8r-}i ztLKc#>_Ceg*(K?uC>~UV#wLi*W({+t@2Q~3`0G!w6vgi}g4L_NQ-3P<6UiC7ohvtw zj?(t#9ITFPBRhqugLFh+a3KkSkVuPpP&@y?{>sY!iwX0Ut4N)v>KB}hUGVmR$h3JG zNp1CfeL}97J0K$wlYC6%H`kGFwu~1eV`jA)t^cXk%6BdN=TBaRcJKg@2d_3@h-3DbI7ptEqQ zxSCz?MITu;^N`<-CgqM9TX``NN9z_Qr|G_o#1k4_un*Dh(eGBQI=6w9pOb@ftw@x9 zk_h&yOlYz@`Hi0Nq~;FxPiwi;tW9Poy`s6Ubh;kKr9QXT%KjfL1*19%QlE$>+JQz$L#dj0;kJaOmMP95@(G{KC zNCSp0GL?D58Cttqe<;K1TL&^FuN{;+lE%N#waP^IF{!WcHE1yXXSp_fU73zm+L&En zY195W{#8YpbHU6ZCJ84ngB-6Yr6821ibcY{W6G z(PjVX4}@WD*=oE^eIVXyIQU#a2H60S7<@`*GH3Z8Z|1Dk6VuPU!#HiQpwXjT!Fmk# z%k!H5@EdKh+KqQk4Nq}l`iH?t9G&@sCa0bwEkH4%RMOUHe%Qm@3w^LdnDDNK_@wWW zNDniI)hN%UJ6JF|Z`tok2F8O&9&ev9id@yj&=~vDhmA}hAYZ>RAF70S4mPpzIE!H( zx})2C%C~qTyJD5aM=*)Cpl>vj#FIA+FT?_mx3)uGR!*l(2zJGeZfFbsi`U4{BnLY2 z1ifTYvWoe`Lt6n+D@$FuXtaV?S8LlfP@|?|!?pTW%*boOg5(IN1L0zXSVDSFT39fe z+qLmiYwY1x5d^L~l0I`iwHo<3QjmGA$KzeIc3CZTQucn-7l=hfX| zqj)PbQ9R8GlP5U}c8cX939VPCePtsyQ7-&Pa@=o@#Ek4a4xn6ndXqL{*)qrcQPC(Y zBeqQ6b2U!gIyi^fX&-aCSX$=qXgR&!`2X?7^AsE+>mYJrabynQrDR=ZzF-7(39TmN zxnk|}G;5`5sXE7db=N{G`em`82drN62IfF~%HoUYoLRxA*=@#7lfTArqsf_JpNZYA zvK7T1uxrkD>WGZZI;-R`cf$|mC+LQbYC~wuTk9LJ%p>>33y{;OcX-k}OCwWh!b?+n6WR)AGN=_@rmF zVLVfQst@A*;VgU<#=$!A-DVeuLW*F@@owpVq%ohVLm{t;8q=z1d*)7?V?T_eT7X&A zp5O2+BC+O3=nZQm3l75sJEbkVRb+##uQztXaO9V~yP7=qPdrTeqq>1j!3Sd{up`d5 zOZ=P`njMfI5TDN;-24QImzhd@lBX1d_(>$s)>uv&rc z3v|v7RRVEo`eDD@8JSmBLr4NwxTmRjI$BtMFg*k)&6yifykCwo1Ix z;N5&mhxnmN$oPV^MKkM}*rwLhK*7*3K7h=LJbx&{DA*;hCXXa);n^|M^dJ>ZiQ+YcUdAPbfM=q#{qimo#8U4xg@e)vy z&&4SlRLHB$DU#_|bB(MW{9`S=)lIzH%t@t_2C@vbsj6*o-cCG&WXelGCFZG_oPDI! zUgXK;c=bnhn-~g;Zk?`pl$5a~Y#naHTJl) zYZ185T-7}c^(VLzItaI8Rd`SQw%yo+ebPG?#?x6wcB_oAoUIcKye-8^bg%@bl1!^2 zw6C-EDQc5lhfBpoIIVJ!*UTjpIdN^q$#>P-lIKWsJ_~=IC&LartejHM3sV2@d1W`n zl##gfR)05nFu6D~g8eQFsP{M%V}!BU$3#~7$@=&NL!b>;s4n4OA*sm*jE6`Q+m!CqJvudMR8IO{3TG_cNk!YevI<(985%jC zmgVx~Vw~tD`|J!gKe^B8GrUB4G16Of3@5>i&>&lSBr^a5LhJZsD{Ky(g~z)(qsiI+ z-le3H$(mu_;53zD>N_VoON-9-apD&aB6^Y5<TU7C!EwJQ3Q_HxhX z;xSo4ED?*!uKU}0qp>_`(XNr8+5BWb5-e#Yt*Ba#dQd%J`5V#jn)v16E7Ot)V#CPL z^PDJ=nTP%GLoltgysVq?ihx)pjLuXnOuytctbpjIT%0$#R9e`s#08zH`Mc6Kwkc!n zog@zaWcAcH&@z^o9_S&zt$iqCgVS&ntg3NYhp|EWWBM{mas0W_$ITf6sgBFlPK1$X z#5~sS4ttR?!+cPvwWOE;j}@G0p7DOYc1mDz7dO?50ZG*~+K%$F->Uiu`_tU5ENt6mrF z@b)rMv-!2A&Ny~{2(*)@=3hS7=?U`H@ZIn)=>ZG_-{PUzYP%{rW`4z*veP&NJ|Rp- z+7NNLMhvM}ta9cye`Em58S*_vpmsx@ohqA$WwiDW`@APLsE&1BqJ5UInCNqGa(W4o zV5iT>*)nI26kxsO9M!DA^{fPYEMh5NT6UDJ5;=)o)sKn(WZxiy!E3o!OwIR_0TqFy z58e=;4g#L_qXD$@`1HUDs@}S|L5#7VbFCSZQ=bgz#6o)Rx$G0qsjBdfNFV>vtO{&w z=GYMUPh?6z%8kiJ?BsdgV?n<+kuv{gmOsb2)nASx z@SKd7`j+$v>VenqoqUDUq9IqdABGSiXWk;&Y|%s@({~jH@*pA#tP%XqdloaP_`>yB z|3*sc{GoXM1G@l49UtybJvZ-1$LNKalD_hvjnMPlJim;Xsx&7mH*YgqmR8EoWA>eQ z4E2{~yDO{pVAffcZ1woAXp4QuI24=*f7}XYXp_A14MsuU$q>{`-f=8s#TaO0{A=z# zCvvTxt94A?=P(RkKI>@@jgX3p+pdU!tXT~VA}gv&8E5ZA3@h(5{$#2~qdT)#DZeW_ z$MX3@%IO>b#a4<=?8%2S*?&?K%#wEN3F%9GZtlviv$Q6{rA1bRw`{$DmEliV)pFZb zR8B8{XLPY+xpKcoC2i*^`%?9pncMp__owAzFzenq43tKT(?+A7zv&S@cE>0RZ$?@vmbnblTVyGrf_ z6Tr%uZ+05?8xAR-V3VfCV(dN1?K`~A&$`nzHkPcHMb}#KeXTqV#|nytTLl#FmQK~i ziL2n0)>l9f`dCcDvx%`F-R8rr%j^$G@7U|{?P*nO@B$6uKV%=_I)C#%J{2wKQP$OW ze#fgDs}*MB(n|iFNH0Ho>M#oVoHd4td34v{A9cksxOsPxI1%67TeU(r1BaBt);zB%o(Jy0YJ51~vZBt4VQ zSKn*bo%$7CTiv8Q9}hqaNVdA{$pq$8y@v@{WN4(4w$C%B4eQ^N_gEdX|98<3QMnk9 zRpd2zHcTZLd!x>pc*(9>T>d;S!&#YRN#sxl?7lDH81hH$-iS%Mr z*$duI86I@ z#7)ku^_ymO`3)6JWyZ!btZHUtzNU+{0kAscC|ko<%O~L=M1wpb3nQb$pFww` zUbbmIOJiBH+|fvu#?g6e=gDk{zv=W~pph3cqXj1?o)I5TyUM+aMaU+!Ga0k}`ymdi zQqGN6b+$Xq${=l#^UvT|s+>otsQg?~k6}JeCA95)~z1m(dq1t51d$M2E2d z@P7H(y0UKaP0sD&#pPa_87D=s3(r;VRIgyp#t$rtd>CvDXR;jdj%?>xlH9G9VsK~H zXne)|OX{loaGw*IJu@C9EznuWwr^iliGWe&U#za@y9XA=31J(ZGdFqkzs6pT(g(3hR$O(JSSaP~D852{p&JY#OQ>0oA7Y+Lj9242! z@15FC@&eo7>0~Nvp)d}oMB1|3m;k38HraK2IVStKNU{nlQ84QYhpU}sQ)sd%%}UCQ zvYg~eKH6#C`T}2wl6)R6E?2kK0p4WKoe?%%OInlplXGBc^Td3sj%Y;`8N;HJM77ZP zH%}!4yu6dPaYXgwbgVLN_1O>+OGcJHd3XFHGP;}M6%)Ut7kqDYC13d2$%kd+Bv{1C z3hE)9n%FMwkubg?bCQ4Q8RYZXTrD~1(F)uYxFbs z(EZerZV%3%M*1C#6Ps2R8RCUPZI4wl8*pGyrW2*b&hYjix$2X7o^^#}*hziCvpECBEZezN?`$;K zo6N+_xHF&*rx%bRi862XA4Zg~T*snldCo%4r)6A3d*r3r2RPI^K@?`YYsO2HVLD9X z$QJADR3I4C4({r_eY|q=Dm&DIotzbL3h}Z09-fS!%$hlGP0a)}*r=G4jdjY1^+<#u zAI?j-lg7{&jFK3L<#cW$1moPq#;*`t^ZppK?s(7=Nz7SQ`K(o~@&bGUzS+MHUTeD>>(rh?QzER#GTTwfVv&7iZ!Vi|9K!aG1HbRDz78bM&@ zsrI2cM0K{f4z*}3tX;UR#md={xyQ4nW+N@cPNuIknv@ON&u8O*^Q^WGMe+wSBYa|O z{T`W?oLGP}A}9E-=IG(?vl7KX@N|fW6a7FI`pqiHBcGbn>CVjmNk^{C7@+&{ed+bX z^Es4jmd1zX$|9Q$IxdUllsz_8`*>oqQTCEvSqX@$9v-t@@5lnG3hNvD=v(7oOgOBZ zj8sNi>_vy=QN&`Iv9v!~yJ;J8gDXjf@s0hRHRRi!N9tq=ZxT_*(`aU*{CtAJ88&R% zQ@7O23=QYW_!(`J*GO9aZzfcWIs=s5fwSOzmA$M{CD`7+L2;RB^@JH&bs_z7rabm%WeIto<7~5w?oFuD8ycrCv@U-q3TphU zZT+F0{2%-%g9H&ntNenDo|E5sYV6V3$(bG(3#)Fxn-RP<+TMts55Y6?h&+68Uo#+j zTI49AD85rmfs=H)q`k@Ww%FXy+QKQaKR1l^lo_?k@;BmEwL>b=*g%>pn!{bI?Ukt^ zdvI~HXyhs~nJ0-R*?Fx%AN4D+3ja6N9Mcwggs((1c5%(yj%UWbdtEjEXj59G9ac`1 zQ(tUvi&#Z|lwZM*KzC#_BhNjgfjx5$f$VYcVP;3n=PD<^$w~EHe%4A&Q0!Iil*{t| zXLVRJPq||%!_p%X5KYTx=2aG9uuEDT>oZcy`|h9Jll!$WQAh639zVjCLX75=#P&?i zo_CAa4N^~E%&<4Es48F+$E#!v>~(mZ`5nx{;~Kl{ADd*>XaU5d{aA(E#a?(z0hBm- zg?t7zU|1l-Rp#k&nH8r#7X{Hc7JTXhA{TO8JYMigR)K!;Wn~U>Wk$`0x{EibdE{i3 zeyK%=n_wxq;IaCd3-6BfCJ=n3iiC_fy`)F>p%xn6XzhnWXw#wBRJjV(0Epc8=Rr-{f=1Yp{E+7s=GOnIqN+Hp8}beE$|yGt4b*uF_nIH!&nE*)L@EfgB)4& zc(~kiD1BE=M807+J1(7=EbG)=*yfj&;Xg6?MIyC^#bTJ;zO%0Jkz7Qp-kN_gu1!s? zOe~M$WEnV6&+d&qyeCgj-ZwpiURZ+N$e*3QA^=SM1_6z(rH|dO3Y+8H^sDIFt}jTK z?%x+)BJY{Ytb20|58P@IKCCj;dO^0=`vLF>d?|ZUoMScjD)&ZuS)Aa6{0k*v0rAJ>RY(O{#&gD(41S=evi^{VR`^e68CgGBlvsnYbVdW4;xwRh*$Wn#Z)lDdr|k`#;&e5f>=2#= zwh&kIi2S#x1F!6)hck0M?*(yq-;%0P-h3m?vAg+ya7Nk?x3%i1@v<2@IW4gNW9{+` zb=Jkm|SUEW}zCV6iH09I4i+(SPPh0PvBfAnw|HIM9BFc*`^=(De~GK&u~gDUoObF zlOxTHM)NZ=9$8ijTTS+iVLV`F$l6ZDMOx&mSh2DwqC7I+Ixu@PaBDIotdRQOsa{We zn~1s^3}ccPR!GdbIXeO>RwL6kc#?S=ZAM^CSP!0@To?faDkrHz2_M@EB~}B|j_YyW zL{LHcOE+T^tlEsNGGG?1rWtT0P2qp(Ftln%zqOE4FCzdgkRkjIY$pQ6)HSn(am8%a z_77|9skxVJ;sMG$J5zjk-+6`^#1@o+lQF^j>V>+Do=;5LNAfcRwLav4ud5|w*Vr!X z9l6DeR)_s*ELoZufIaS#!FHOQ6wmjUwmTUwv$56T@!CdEk-O=|fpx`URQp*S+Ve za_H8=oDO@DXJA6v<$46{GHaN5$(X!tIqXb6Gy39PGp$wGJ*(OpAghmAwK1Y%813i( z>9euW7+#0$@}Y?x((lHBBJ?6SF@vkI&Ay!SpzegPC&400u?N|Lld&oKqb*X>+>i(c zt38a&T+N2-T{Fn?Z{pX+ZMClKK0YQ_V~LXJJOkXfneYg(js0`yWtv`zwd+P?chFV0GyMtcHb568#IFPQCSAr z4$4T|uz@-p^DnAN4PQRzX~+#}gUtFiNHR}WWu(o(#0L74wtd3BV=_q>$>@{4qp&A@ zv*-RaKjRHXqR!-Da;GSQj+fJdb;%^lB5Ie?9V+5wfzw%coTuqRL6UsZt)NqAmb;gWF@lWZy+F zW`V_v1m`NgqAOjjC~g*e&?R<$|Ft;TVrr$D6 z3Wv(`AT)gN$&dthBM%$KO*VQpxQPw8y4D4t4=jKqu; z1?nM`uR5ktq*byjB0R^eB+E>j{Vhg*DRMZH$r~0%a!2Gl_y__`dsCDf6hzy-{Y1a8`els>Ny%p7FCbQn+ zSD71Fq0+8r{eSs+qlQ-MS8+0~@RhhaZ8S22g6(|86hrAn$&kyiotX*k=!4i3ZmPXv z^VB-oeVutRo372s%vmG3@|)(CEm3c4N1@sWdd*91@}L`Bl|>|Jk(J7Uc!AE-ca~p7 zTI@!G-39g2O`et=C&#n8`5y}dolnjqqZ2t}-*^L=Z2Ji|S%&Cp?uHTvpUi!9j6{+Q zzFYN1>ooL=Jf9ogSG&zCZ)^|$v(KK*EUSN!Su+28DXpSOM&Gkc8hcw=$i6Y2b%k|} zSuK`UWG=HoaG8^~n4d z;$g*PCa1z>G!jZylWSf`QBOy4J{%lR*OFCAdwFK=Re9D3o_$f<4Pmj`(4zUl8>(Ka z#ZtXQqs_^jM4T(fH>7{0o<@k2T0Lrp?G<}?R{Y#xP=4Q;;o7C!JT}a4T*Vjrb28Y) zs#|^8vG%IbU@g9!7(SA`nl18?H5y zoy@7qah2uaL5yRr)f2Hi3q{5v3waKv19E47`0I{jve3D5vPl^`-#l^s%#R*fReY}u zzqrqiB#1=>-b!ds#(j;1MzU&^cxQ3n!~yA@{?Kq)S1ZDYo)hVCmW=p^bh1DAIkDR5 z=~I0QR1`T#d;B9F6*?h}Q@7V=%xL*KD6-LGcLS-!x3B17~|A~<$c~j$* zcB4UQwXA}EkZ;wqJd&K9eh;q5Q+Qi(02IWEV{4C0^uprFK{=;9H3-ulR$J|1-_By6 zG_S3eM^r;+YU4+?(iT5xoyAfx1}!tSz4grO4<<7R zAwNy!VD5BErZWOXD{PGjGrbylCTaWwG-Wr*?b9ZS;FTZ*wjsNmXXdpJZ`z+x9@eVy zI##3ST` zyy9)ASC*Hy*IG4gckr`+WXwB6Pt09bhK)93)`MI?9}uj{54zwJCrNJJG+K6JDcxO?EvBQgzqVL5{_&dEI)8?!aG*LxHtXEJQ zj}IkV33j8tgDs)e_3*qgmd)va<-^1QD$4L(t#aev%8Ahr{o`u}7vyK?7P4%vtz0df z4gcV)aza)5;f#_8bFG*F#(@Y)y7eTl_rc8b`{ug%^?2&^lU&mD<8zHw3cjBi6N$pQ z*uSi6`Y0n#;=`1sMaVw-l|SMuy~O5;xn&3O1o)an#d#`J!^g1F#SFs+rGK@&Y&B0X zxFYw$R%VlixyMLoFzcb(qD~P8e@?emXOTQ{aRk$uE^Q!h|k;^51+qXY0q+N;m5}1etv=E-yQAyY@U2Lb4t?T zXZ9qcPMaIP3x6nnz@N}2EWP~2MBM4$?dhRCwPY6NgICO=_zd?lz9(&3ZFs_yU=LA% zS!`^r7M1tLZFXdy>CHE{rB7x9A0(d%Ra=9Kd1Fx{4>;YU1C5m`xG`k0#vU+f$*_JU)l$YN-zlJRJj8e=$6v5ZxFGN?Q z;ArMlmdUJF%bNRSJV z>m@=Nl%3u|{ASx5PyTk+13H8z;x+Sc)+ys*gJccGopju);zz`B9UmJYYQyrwuU6Od zWFN;Xr={*Wr$v3!PkNrg#p>l+??V-HIoC1c)x&8Wzf-Hh?sxApdr#`vi{xi>U656J z6iv=gH)b5F)yzDrQ+Etk%_5Rg-rp%W#$sn4-@zg$y3fer3kVHUpi+rMVsvl`_5|IV-;3m}l6NjfNbj4nO}+w3VL2?Q{r=^F-Gqi!f^qUFR#$rPmjw;~|&y8d8GheOEgk$iHxqnuEJ?pSm+KEQzr@RNu9HA*2usp&HAWr0F?|yEiNZu&dhHzyr{)=V#Ll(8-S}kD+=)FQ zTX3A33f_aQ!lLw)e74nDbjHQHIoq*&MfZ_&p2Uw~7Cn`;sp@5y_*?oD%bhFyZX)cA ziA^Ri%`=PR%>JB+m)88-UB;{}d+LNZQruJTMKV_1X+>J0JySI_GF&{R4xxy|8ky6n z4WH48L$oL73iE`s%y`A(!EkAtpDcrHerh$vn~jd(%WCxC>)g+ZvcVmtNXLray#84H zOSQjQW1d+rP7l-d*x>|JfU4~f*UR?9Yqv!5TPH+ESsxlb*^68YyuAfjR9hQ1JTMXh z0)j}lNVkNfh_rx8cXxM#beGbNq;!gOH-dC`4Bego0OIj@&UxSSUH|)ii|cXkVfL*1 zUe9`Jtv$F&5e(wk<5EW~raJ<8Hd!eWaB1bF-3+0aPL-A*mIl&0v?he7`|28bJ#&}! zwW0he*xKwh9W$sSsZ<{2)tulf51a)K)*oFshoFy>3^hP~ysDqF!>Uy6LVxx6z>jl~H{e`Xq8<3Y;5xV5z>iR_B z(Q_Gp%)PkSDCWH!$Grss#)#s6L~?F6sZ4=Sr0N;|drm96%L94b&UP>53#OME7TZr! zgm?BAg*q7{bwFFh+d7r#T>D+|`3g?EGpLBll^1(!^ETG_6&uNulPdBmH3thDAmhZUgUgLAF4OVk zNL;p}i_<}PYvr1~z{=JwXVopv?6TY|Q@ev*;_Trq<% z`w`EF4i`H`v$L)9$4*u?9N0599JjhTE78}LD;%0P6^@*B4~o}RoHfs=6>6)`7r+lc`0S9ee%@V}Z@VmxXFtq~&vgjZnm1{; zv1uSZT~wog;+l&;aybj!`c|xLw=9PgXS&SjeJMA_x>MI*mRNjX(HWedSbpkOow3Q~ z1mfQ0Fa|BeQ`$J2f>^AlsvTB0^EWS220so3%T5akEtvE=C(T*&0q>Rt>S4Cm*| z*E(JluU%DKZX7TbYU@y|R8^_kt?U+e8bp-Q)Rt8_*){I^cdqRoVMpLA*N_*P@uUjm zSahDwuN~z~mtRh=O)FgSY&!3q9u2#MT~*s$xD4aJ!Np@IeD{eYtC7aflGFL*!=hd% z<1WZ|<*2u90j(2#A({^g19q3@sr1{~fgtQ*e5I?=Q{EL$y#16lZm~0$7?=NF6Fy8)ED^MZChUtjMPQE&S7$MCeTe})SM?Y`Zsa1$3UD5VB z{wr)m&$;Z-<6(togg{EaFX(H!>k?~RW+*vV@zG|WaNf!&E=-asq^B}^S}p{!9a)__ zgYyNTbCSfIFVGCeOpm&#;c`t-B30vMoox9Bd>N1MkV(HaMFzUOnFr`002wbI9~$7n z7`*jro66sVf%kDCBx99&Mr7gpVA({{U;SAu({7WrnU%o4S$P?#Mw@(|kshu4TjO_GmI?LRS=wTx5 zTi-qE_IG=4tk+k<5x!^i1-E2X6`=VzYp*jP+m00o>&?f>2JZD!2+@&FGTIVwB4@O7 zvTikv^%Bz)KT@8~`y^Ne*{Uu~+AX*>V|2V&)Ac&{Jz133j0}M{(c|HHd=o{NC(QdM z{pRy1anP0Zo%llV<}=vckR~%uvD@kvmtx|O!jnY@ z0sW{)?f{#b$J5`Hb}kPiX_Dk@yN7*M#y2(-5J?PBX@pG!0rR%u&r zIw|K*ox^1~W;J8!)QM<(zM!%b8bcmRSw(>^g(os($9l{GFKo;iPX@4lQcd)&pK%MB z{laQB-v`2kFT*>#Eq?ZD??`qhfVcJ=lN~3!#We1iv@grS5G|;4JL_;(6;Idk?AxUS zW0q}!Rhq3f7GKQ*k|x8b<>gvQ+dwqq)DokqW^OJW_Xy#6${zB!#D^Vy-wi7z+FwwDLTk8if=$SG<8d%MRN? z!+AGOHs-wZL)%yuEw(`n^8%$THDmH=oz*`*~=Lbv=Z&PpVbwHW4*whQc$_FIWd18 zrR%~~ro*aeoF}EQTVUHO-b0nK*cGjV(do(|XUrC=W}hg_T+Et*rb}|+M$=@?u)AO0 z#q*4kJC=5>NuHUsWq3x5K5hX9CSLA!@aUU}{9a<}>9|NWn}<1Bmr+RSgR&A-gdR@% zO9o;BqW;=3ksr}N;y0nO%hky@0;@s?XXTVuINQ6kRJA%gWvN5yRC>>oLNitMm4;=b z_LE5;w9Pl1OsQB&F9jN5L38AaCy-SzQW+&ceVhKE6G~ZI>V<(G?zU(XGhFIIf?3e@ z_96PE*tB4h{^-*Ax)F$&o+wJ4gJfe*EF_lSfrDoelFCPIyH)Pto2-a-1aX+!gb;^j zK$iDHV=l(H0Ncp3i7>g)VO87#;2wQy1Pei;>?;FKN98;U2AtT0t6uD}>7Ln6)zKWt zPO>FJatxQ7VAChLRnPP6-d!ikQLrnSM(3$g8(8u^5oz{$R zHhI(02Fj%eC!H`u(-k)Ts~!i7owSD4`fIHbkvV0JREpK-GrRRo*|k-UD)v{N*^Lf8 z(@v^eozf~*myw+cWn2z3`|c-P+lgPUdWOa$J{~!{9Ov*1*Q zonOFgIWG$#RiBK&+c+B^$sFa$;mdbV+qWO)FD6Q@!0v)#2$iBF^XO0||3=XAgxd2XYNri0#t<~4yl z{4dVOr>O^eYsIM9E>i0Ii7K^v7u+Z+(;-r)yNhR$iHP323Y}N-&Ng;Oy9tX??7o~nlb{NmbQyj=2h+St^yJLmSU~(g~Xc7 z1D)-b^E1XZ6~(KTQ>C?|)`kw}kMByAB0Z>Wmv+w=6Vp||TpG{!Cl=Qt^Ob5W?SvB! z7hbKaM3J4n^|hA?jfzDXyplS0FVjiAGP+njsO?N-$(xSny0kJiw`Sqz?)D2WC!)XP z7Brw$u3=1Z;u-PKd7@s+vFr3KrpbFcUinhANHwwTsI>e{ynoYb4Jq%6;c5y;F3qmq zqPO~^dCz=*BxPSPJj%{xb%Cl%v~waJIrsBKPKuPrqmInPY%v)iPVj>a6RB%WRfaYz zWMeDUhmE_7joZjnC6=Rjn+zzDXbf6Xe)zq&3+idUZPLm6N>mdUj_RFmB6?THFNWJ14f-6+ zM+KVep2vIxwi0>bIdKo!c&SW|eG~kFIf;sEvm>tl7Ds$`HLFljk<>Me7mg;j(MRb$ zi5-S648;zURkKrYaglFTqC>ezEIM9}^Nz%qiJ4T;_Y{6STRLBen~YO@9NUboCb(eS zMaz*aj99@MbH*qk_dGO8LTki^YwgR#)lSJ175wp-sqB4jT25L8d;OMKDnYcIL!mu0 zqI`ut!{q@k7F}P^7mYKsmA!sqcmaW!pmZh-zpEWYMVrYmZm|b+&}iCKa9wT?<%Uri z{<~d`t@b-c>_FGo;Nz=;`yZ1CR zjladYuu0>k_oq*W1ctp@r{cEbBF*VX?L+Yr(+r$^t7IV|O>zEGT2_g8x~nG506T`#ywy7nr`_2)=fUSMkpO=+FJr%F ziir+!=yo!j468$YiX1r4eBE{k93E;EC~rzRSZI_i6Q_J0ewC2J${EThy2?@okfn_y5Q_p+1j@%H)zHwAMOF*o2dYq}g~d_f5?f zqjmJswvhOQ7<$ha_rcWYtP%A36sdOlw(qAnMvLH)CBdN;-xMLsdiJgbZB)C|BimP` z>(jBLr*G_QSu7m7bKoXU?DXdQ7PM)46nQA9!j?suWx}F9rtakm3%7KQ=V&$}E|Q}! zen!v8x4oxR`PwjSY6?T#)TzZ@#Blv=FJs+TT1&n;T8!D*@!8Do{%PL?lHSUF%{?2& z?zR4LgE`TuVrP}H)w2jh9m8#6qvrnElZN>q<>H8sxIy=pC@If<+nTIas$pdeld||G zv)J27#V~Bfzn&*d^rAAvEf~kgBNGr&vp9 zKpqkCN~i>fQZ9us7g@%*XmG&T^Y7a^Xx7Hw>se7@8!}b|8dTO{*xWW$-SZ3@6qALM zL-#?uJ8gS`Cy`L)gtdCwC}SKroVJ!Fv-ByQphXr-b~B+(PrAHs)rnp4iEXu0(7hF< z61!BH&;sp93gdgbUHsLnMs0)C(Mpa77klefxSUSSpL!vB-Kx)z-;&DBBvTw&v}h*K zkm_4j2@yw%CZH$~a0fE7a_0Klm~~$U&$@TS!v`n6)4Ct;{kaWyN#YrKCxl*N1W03e z&`pl}8H_EJ`^Ao*eI+5FaP+HDRZmgTtSB9Ih^x5@0mt88^NtM5_BYo()16l0Ot zWhUW|*(azSZSyWh%uVg?}Z0Wf;zpkbt!o3p-a2rD*4{2-7o#5CA`7f zK%Mnq?d0C!Fey#v>u-ACKljUSY^GX${Inu!l&SVyf)Q9%`}Lkls`i*g6MhxCrN_r& z{Cuk{H41Z1Cr&1FH;pCiD%UJIz#vFF8a)hKW?YbTvqLFE;6oeQy1Nqr?i_6|o;E+t zoYw^P8c&gI+@*9Xvtnyk#8GzV;Mhl6TKN8bM<|A5=>E3B2W`S-360}EwycL4b_6;^ zO^G@~1<T$!C~roNlgqzi^|DJ zUDz$}r%tgogkajJF?}{-Mq4!GaUBB=XBFFgE-hPO@gDS(XSjyr1-ADzdYvlOT5vD9 zhJD6v6tah`A?IvEHM9MSn!~$KnHVCp=QWrbt^T&!xVDo}gRg^X+5J>5Gz)J>SC%J~ zbyK=4Paf96+x`2ew+}KRNLTGfAyABDvdyvut({U%zX)b{^K_x=eQ@+2I`8zd^>QE; z>t^KOY01v<#=(t+y!gU}qM_?iQ(E^jti1>w6>@AFmLGDqA2{F3vT=06pC&qtk;tWv zv2URNV((++v3$gf?4>lyO?zi9DKZNr1(nNJ{zloO=xf6_ClD&N39)Be8f?Hvdz1*Y$E^~ zq~qX>*^X+8P>EjNU0?1@%y%)m0IubO>qMgUErl!1EG*+r&~#~)(dfAS#E``onsK%d zx<{lD79XmemsTSN!5dVi75WDs1`T9}b7%#-&Rv^C^JTfpt(JzQd`DgE*U-z9zZ|&b z_M_UlDA@1#9js(?D^{x?h-QOw5~@!@*)q9#qUVUMDDa#TP zK#CPs6Xx@~>D#!$L1|9B_Ew9h%lf4i+@JRB%Gdk~plFq@gg<4SF#^TAU~7mmj}nzH zdCkvi<8-e;AH!YDh?etVPpjzIPG7WKM9$uGW;Z)GNv~$fQAylV>4BY&M>zL(e9ohH|MSSy_9w%Af!46!%}Z^?2!uD^T`VTsXvZZM=d zHoJT=CX5?*84>+O_!7VSxw7Q>bViV8BIb12*U~;r!mV7qb{lQdHIvd7h8_!f-)@~J z0*fC@6f3(JFtwz$6C}N2Yt2i!hK|B7aGjl`zw53GdBRU%I+uMup zGkz-&RIRPc@Lp3)Lw55_Y!RP#yGWm;m7|=XkFwyo4U*cFcCl`SdMl1&Zpw!c?P>%q zxW>u6D5fa3S2*c%?7CPe=8{#}_csi6<}{*$s~t)-ta4iH)0axuJ};MmKX{ek^L+S& zoyU@Pns&mv9x-D*da>~Nv(dEPi|EZFs8spjqaC5t@@&5O8CWB1t?%VhJ)i<~ayJ3L zBu#ApROU>CxexJ?MsJjia6aKh7wGPH)f|L*A}6-Tt45T38Y>^Yk3n4uVJFs$)hXkI z9{r+k?4XRBNbkh7D@3P^`im}d9BI$R_n_$!)V_>%CbmfF)FrMHYwxiv?gr&N)0?vB|o4EApZ2D$^lPi^z{?=!F2tCYvu!Ty{frLQreMgm}lvJ1-a5tsovb>}F1JJ$6g}qNJiBcPs zQ3g+}^Ttz_N41~Yq@lfg!IdQ4>v>?AAH_qdZj7ewJTC2DN^&|YZCu50H35) z9zA=zc4J5OG8)r@_uUu_T8;efGv;CO?q^I`l+^Gwqtpc1x=xcq#e$`n11=L`2;uhk z?KKsvF0~^XxfVKBA9K3GWIfdG=N#l0&*ze|;cNzJ8;9r&4dLv|DUEiQNc9`o=s*)u z<|uB6SFb?(H!P(VoM|S@F@XFNwdLf@<>{wbuKNAtZOl-Fz8rGRJDtC3Y3IzA!_=x> zM(vTlNcKc^(CPMbHaPN!(DfRnxk|#%4UVhaEtdT%-zn|y+oXLKVY*2vul8Aw$HpB? z#tHoYdFS=$cOM7#WeQNXs(+2(Q=M%8qO6IxR9^MsE#em2&Und72?Nj|-b!+)J z{WQwTCs$$lS1_d7HroIIKohtQ{`Zl7-{2VF4fyQ30TWwpPXL-Qk}uUP474ooYfBmH znOSKGy@J&+F;dqv*3tw30RX4#>+XRC3M`t}FaEAs-C)q&V7&fu0WgW;$JtK|DD9Ve zmKJ~MAHorQ;dTG20QuLj1ONaX0ALHDp{}Z``m*r_4L0%_zzl%w4KTZh+zOxv0?^?g zO2Joa{W7q(;Mdm;n3Q;X^2fm7%&m-7jIE5+waov5{BvYl;7>tJ{8a!tzko>m=o*-O zt&r>Xb7Tlw)>_7v{}o2(`a>{afd>mRSZKh)0v44U7`Ph+N`YTrH(;{C?a3c7h!&P= zmU<@tJRV5!C$2TA0sx@>`~d)zf9YQGN2kE#j^Dd~pl+qDt!1uasAa5Usry%L-Sw^v zfc^Oc?&EJQ>=W7Vz5nkm>{Gz+82=9}ECu3s(Eke-mZJST$p2pp)BDAce_B||x8Gq9 zEzR|Gbig+7-#kX|$0z@C_*+v>W&R7$|I(CG!+-Do-<$HE2B7haqsaYu2bj9|d+#Ww z=2~}(vQRTJHPrfRR0G_3i^iW201h`0WH+wEeNGn4BxXNc<{U5p&@FOnyO9_|ZQw{qlFDN53NdcQ_LOdrWPRggG~~8FxbO z6QogXxsoy}aHoH378ypr!y(+6-M=#n0Q9X{0AOy-;`ViA-R-dk0DuMq+!{U9jYTT| z00d?%{|=3Q2d!tUZ9-$Nt@7jbUv+yOA+L?|56joSQRXd#+8sou$nOwXe}d39G1t)g z?U4!pfz;WjE%JnRgA#p@LwnCF7mnl zRNikV`PT#>5N@2v>c@M)Z0g?$(EKw2a6&YGP3!> z=;HHrtx?POi#-5uL z4CVsN4gH-F_MavV?5{WWeaqx81_iha);a*F>jv)ZHpkw=X#MCMn0x#?4Bp?ufa?a8 zn_2j0Bz*wHbp!YJx6vW*ZfHLz{m;?iZa~(irbZ^3e^VRXjY#(=&fl(3^8T{^`QNWl z@~;_ZzRdEhc{!Dfub4n16si`n8x;`H?C9Ize|urTcAB`KV6wrh333 zt-Prow9757kCl_k_pXmMG^H6}Am?8w{H(|d!0vU^evTXIPZSI-{~6u+799<_^A_DU z_Xb@DA?6mn;D%KVEzBesA@CX<;`}CTDE+_$7Nq_-`-%SeXLi&z*Rs$xG1R0C0XCUNzdt7#L~qzry*LxaL3uNVXuaV}jSs#Dv|bM)j5g09aW2T3v^y5J6jV&L%=Jt(|H9zshK=cu4*qhu%_D|4qyAX~7M1>vhw(=lqhk4oP5h@p z=U)#Ryr%_Dm)E&WHAMBjst^J7gQhuMM|zYK!xslTFXE7z4qi+kHSM`ZK>!l{?wNpb zBX2Zt%jlju*K~YLz}dFj z=E$6+NQDf7G^0j7g4|Ig02j+2G{wso!Z~f@#qU+N=C9jhp)A zp8`B2_`^2|1niPOe*l228wK3f8h6Dyute~8B>cZa0^5Pgb!DdTpJpZqoCX2D5GjB~ z069Ptq5zx#i~)8K{oowq3a|(JbT9bm1mOhO0%Jmh<(h>tSggU~3>Gi2TsMOornfp# zyZsdaShD-$?5E3M{l@fm+WsNy-6;jUnFj>#2|$81bX`nl|DqI~JE+n-`}he(@V8L^ zN-Mzt015my^foLV#9Np!=waAuD64yi&vrqHw_3T@+;szfxlR_>?I+c{`O{Ie)YAMvvKO#3|7tG*tz_C0HE6;sKTbuv|B@U##ZmRF;w5zWIlK?xyn3eE*g0nB6G|@}^uX{6#@` z6*90a`gg#mf2*Kdz<;G7@U9v(1UsMs@ExojPCy=D9*_jS2~Z7~g|LJ`1w;VK04WeC zfCRuQ82Va6*JQ32KTcrr1WO=TuAAX68oI0QfM11g-~2;E*w=*V=>89*&7Fz-=q=>zS9q{Xy-?0e)9_wG}CFDBt;{UO#fuwUAEP!Z7AfN%v!4Vh(<`A#rEFL|iDj3!1 zm$Bcii-G0*zw^QQ3!i^w8F$nFqq|SP4E}D17Fb^VI~dVFfc>k{hhC2!e2eDQbsofR zr$+=3AiR9*v8;p(Zq=o=5gaey3B4ueS5mc<*1Z}qQB_x)pLvP&Bo@*K%;R<^=(b{g z`-2y-Lh5&haA1bU8g?3gyR&*7dai?(-8B;g008W2H>*oT@bAcOJmhw#^EPD3{^%Q6 zQTgNSX9#%+M)^^2XqZ?TTmIcGqPzI54!Ea#&*+}{y^wp?o+f{z>Dxup9eZFUxF))3 zKN0@x9h4>=Jx6$~eMG{DO1fUF56DQT|t$7%+Hi+vy8{I;*qu|Mp_!pY{b(LOahjZ4TE=iZ!rGvR@{0@lXc2RXK zak0%|vTgHRN(E(=u8Gy8>hM+$HgxR~3K^$D+HxVGQ0<%8egX8*ZJsL;sBv?Ry7Z9Y zW9KJQ+&AaA$}n$fCEk~sH$pu-oaVHmi|+_caS5EQ<@)+?`M6dmuGpU#J^vlx`05fM zz~#JJZ(DIxtm{_@i%OTI6{fRtAZgy1Wo==o+Q~++2>@DT{FIaNcrpK_NKBUAXM_g1WlYKYe1SwIY=4utm8$`$P z%6FfHk0$_N5R@31tDGvVR`eaxIbuF=IH7NUO)O%GoTGo^AZ*Hn`|Q3u+{_yp39&{G zau!#U=T9e^JQREN5#_jM)Cnef-0pEZu;n5;JJ7{=d~0?Yf@UMF2r^q+Oiz)7lN1{O z`Fw{lh!wURCkTIJlLf_Gb2w}^N^E}L2Oq;oOq8iC-s#Y)FMQ@QrN)L~oI)M(11cMZ zpx8)r327^XfQeZr?v&oqflt%-tl7^(7oQ!^srY#M1kp}To{_t%$)j!egQf)X5JVKK z;IW41b~yO8p`O?pOL^z4+L8;;eZK#wShhKdftt@R$Qa5hd3QvJuT)ytpNFqYHZCFu zZZo8I%|EK-(UzShzlol><_09;bn!0z_Nk4_1&z-~LR{%ItHv7Z&=muaxr&4L*_hc% z&6gxj&LI|N&ar9z46*S1;ZWT|#_wyVq6aiy)Tq<%ppGnA2iAsSm4`d4Hw^{f_%T76 z)@@_C-cL0il9G5Gm;E@t@CB=&gCOFtsc$fszH4A>&10ocR2q1(jsZ|Y2E(eP4?uVVw7W8W4`BdIp%!lplfPN&33-y^8+8bSuNEhm)M zz0yyhdNXh~_a3GC8sbbOsN%i7q5-vf<@2ST_Ey=XCie0dN*eFwd0&uNls^y`2A1lY zXFX@)pqXkfmt^7{)R9j`f`UmN!*g4;2M*eM>7zX%YsLZsf)2Y$w3E*AVufLoq`tjG zW0XLi1S9y!w!g)e9e<@h+{(d!f&u@y6v@-`G>Q9R8s!7oNCw#o3mS2Et2bBs-``|U zvh-n%bCi-er0KWle|&3<3Wuo9gx3H!?8z~y*eRQAMAjSwsjJ{h9u?>9SM>r%^3(Ij zu-#zA&6k{!-AX!IqV{Eus{XxLb_8VH~!}n|tYImkx=1%Y(cIl^AZ0p~);Fvu$ zmr1kg*J1$i*TpI0o}K0&v+4-jcr7egImVxNK97FKhi*5rOaGYr?RG(lAXLGq5x4Xs z)S(y!^r^<}b+cqsJ#q=8jjz2!u)_QE^9wA^9NxLZqV9SW^;iT`vAEjPkEpb+1+~+kK}z`JMiO6<#YpEx zy5snEW99yr+1{>i3SEJd4&!A;J~pnKLk<;2$4!Zn>d9mlg7UJxl9zQ5Z>kE@#(e(>-M=WZgAodZb#JmRtZ+JW*1B5_ zl{>)g!vD$ZWp!`5>}m~!AyIuD(%_P+Kwe?XR>)a`4Wj20&>_dmDUU}+_R4xmIvCgx zo<}|=mphgbShaENj|TXU<2#D8#3yp31cWVHdJ}^Bh|(&Rohwhw=hJ93Y17zKCsUfW zgnIFEvqlBl(>KnvDx(zzal}5^%{s+WBONR>dJakpSst6wP>aneP6jSBsiz|KMva;^o)AwA>_U(1)6)4{cCaQV)PbM094KpvITR5^?NXf2WLOvAxP5 zxZRHhRmiW#{~;3uPlcVYOZps2_*W7}F3v#~CXO-rsG2uS8m0XsUs0i83RmZ{&r3Ejc?*;)==Ve~P7Ao3 zGowrt`LzL%2^J!07@hUd&eFm|k{)GqEey7jRb-Fqu`&ryJX0)bhMc7{ z7&)g?)M6SkH!o5!8q@S=}Je%WdhsG5K0f+aY4XLjKE;K+HyDBv5dGMGkxX+jo*Xust z%x~>A9!LwCjhNF=>t8b-=*XBX%9+=*Iej@85b;_?$6zde$Vu%KGS+jmqziug5inPL zDf{T6hz(8*;D3ut&Gu58l6@%v9Zp}gcmPQ6Z-I08HbZ?6VW8m`}tby zrnpGnn&x7B@1;wEbKHo}vs*7IXp){cI2#={et&O1#}0tZK>R3}PmsB@HRXYbhSz~jZkj<+9vMp%i2Q{@k?@Y%o}e?GBw1E@ctgkeUDF6Za;|Mhv&a1O9iC=o zu4XWe$MjwgUEb)bac}^MHkH>>Q3gUJO=n5Rd^IwQEoyT z(8g8UeZF@vj-b{Nl;k=RUAABZ3Kzm(o4#F($tLWu9DOrP5^eWOA){CIo<(!&TB-9G#l?2m`TG2C(~p2; ztUl^W{%8jLZ5)OT9PdkFe1LCq>aTqfaQWog7x4{iSmBd$zA6GJ?VHnSioP-cYICDC$*?7IZhoze01{s5ss$4iH{zR)^XXQ4P!q$ArCn)z6J0el?XdU zoib?w?O1%ADx!Z!7OmLF9?>EK`XMFen%i0QM?P?+gxN^_1vge2qKs9A(X_VC)I{^^ zjvf2t_k|>Gl$t~trLG#x@+pi+kwJe34wC>o02IvI%RS@{8>}!JhK`hwq%Z@vbYKlt z=EOd0<=e+bnVOu8%~TTf+g$ITi?~mywu2u<&;8g}310^xf1RINB>Vlg^Kji6L*sbP zv&t8?tz^3T)l{mm4+Ye$> zHpoa^>_#Qy9cx%RFuM zGPXqC#_T2wd-=y^GOsnuBrg}pp&gGoysY_R)T3`gD+DV{BqIbRyXK%!6}iJ3vMk{|o= z>=N>uGZEWiM$Bj@VQ#=w3(oZ~IdR~V2}v`#mxmwF*b(fzB1e^B(UD?wISanwG@$aM zDNKKY3AM138pX=d%uI!hSnLI&Z2%{a==%xk5&j@v=pF}*o<7?ACXFc$dU`glk&aDe zHn3Md(_-IaDH2^9d8bP@#pRziA%Zm>sfrrrl0soEB((K*Gx5pLB2(=oElMR<_dO9g z;pf<;vj^TTYI9%2zDFzv@Z1-BxdEA?;_~v$ZNL$f#`F%LbiP2mw@dqI4MTwTaZ040 z8cD518AR7!&H(hl%mAWgSW?mv--fV5BB9I}dpofc(ig%qqN_Bo`X%dAt;_udhG_=7e#H2zoZoU>PoGwmM&)XldRVW4gK>5yNWkPv0gYLq9inmu6uWkBb5) zz-c0oV_tcE{m=Wbt%+{=y_t8%AxC_ zgrj?;*4;;^kW_6duQynTxho4^Vd+*VEb(-5q2;-hr1d4?658CG?$MH6!{!W3cm$u3 zX`k$F^E!6I)6M<+xAXRG-s-1b-*}B+Uwrckc{#5#VN+@Y?vg;AL_?`@4c>(uY}HF< zovpHf=Jy)?2cI(b9^~t!L99>UimFV%%I4(YS`L=t+Rl8b*X`Hoc|T?S9vq_E5vEP0 zA7vv7?^0#HC>>1x5U*R}(6bkzkjfrqaT-3T>NljyGq z$9BKp;XTy_vf5@zhr)YR&$GV?o6KVP-GISfhS%-gWkG*7fY1H`g1k404~J-?Y7uu! zQ(*bl%AVA;9VR$CFUWxhcbe%$M%52<;k!TEh;`0(n)`a1p~nx>q+2uFY0p;0tGe;L zH%oiB#$@1v2oCXsje}2B1fdD>$1+54oYju0;^mOOM+L;UD&g`^+4PSpeg@n1fqtIi zNl^#5La(wF3V-Qow-*4O8>=E`t4syk_;ll0wok^h9O;{>-GMxbWw0h)dew=mjKv(F zcXnj{C-M{p#--4dvLR;;-WLdmVU?ody<26n^=#QC-2$3cOFD-K5)8AC5=nA`l3ox~ z94cK_uJiXmEeXOzhU7jq%BEPRO@u#)r0-Yp`dX`q1TLSRLcSOYF@<|ftbuZ#(Q|x{ z`*BuOyPNEjv?>8TY9Y&5zPXfOdDZ!57eAV}5%dS=^@CNfYf?G6IA?=B%LTaH#3?df zbtw3;!l^l0Mp};t7mU~Vs5RAo$?E)Wq0oA&+O(pNfAMBLJsi8UFFeDar|Hp4OY5yV z<&OpEP%yYB7ld>s^r}IOQKEuxI?`}0AY8_kG>xNkWfR!!BHrj<;GuyZrr-tDK>;7u5^W%%ch&S{(q)LP+_W6YS#ji8BtX_0e_kToi&f0D>{jh5$ zB;}8XhP%X^a>)D$XQ9Y{7{Zg9oUSkGBh-hyImPr5&DVSQsnt(PnF(B;f(`n#cdu2R zz$#l!A#F{7Ad&8cbF^z!n9|eBUYQ4oLa?;A#=%PMA^N z$og$#{TU1a4|${w0<@)(Cv>E|KgzCgF*vmvO9V86ODl!2nkxG1+KM~)QdWe#6x9>& z@)>^C4D;Dm?Kqd7Ui98_K=eB(^iueoW6vvyOl+%zy*{=%^|^dY7L{XYTI#WhZyO?V zg|W0u1182|rO;Zgvw@Ncn~K8>^8&{C;aV;8Euv1olaeO3+L687r6VDuVq}v#Xl2P0 zy?(^Y9_0|8XCIKtm&~;?;WnLj#8b!DQ=tj#S=mFO*h3#gOK8*hB~|Qa5f`HNBF$u{k=vkolx{aCcbY+8pmWo zY+Bo1OBM*cg_W)T5}n(FhJ~WrSdx*u21Va&K0C_ydY#i&&2*!K6tE8RFor(nJG-*}3lU7EVCCS;F z=ioxIcBUrHaec>ZGz@8sCW3}GYRM4-yeGCX2ReNy%_kq^w=`*Z&cKhrba;wX%)b?R ze(;T8sOK~HP+z49=0}6o^CQ9&jI#&rkW}I{bxJMk1CuVZPpqyyNq1PS;40*v`dU*W zrsEZ;dtL-RK~LsTs>oaHl$n_2kDx`uC`(geSv?D^%(l^AF_+|t>A^B&;oSdTIG4%x zQj0Di6B1^y*<=F#H8}$+Q%7)Gs?LNgg*12`qNq*wSGDRXvY#Gb1aS}96Mt@2%HuFf zatv$jW15H_%3$wjxSAAxkh1tZETht@__f`TtOYk5Vo;Kb=^5d)0+s8f`|#jLjtv7I zH!}mar@+gh>X8L=hqwIB6RE2X1zEe^?>Aeo^N*lY+I9YMehPLh$!o`YKqHRFoI2H+ zdg{ELP-*lzn#~110uNP8h=c+^QL=jZU9W2p)}X*!(~usTsUZ#x-asLHb?TO0sW^DF z$^g4d@P@=dMFera64kYLJ=|}Vr?bjlj3jn=5G76*B~t|7%$<`yn|#t{=6V*soBU8N z45^PMf^eGQ+c7v_ygU_b^PK~>ufNI|^)>domzJ}J@j%<6uYa~_8P@-;@Kj(6Eq6lQ zE||HlQ{fGB8Zh%Ar_Nx-vn6!w6O77pR^(2JNSg@!cE0q=M3G6SZuW`E;I)w8Nhb*F zqe53);BiKwL`KK3lMo*v9bL=51Rg>j_GEI3njo6x^z54>C6fvhTAS%&@G4*k78Vn{ z(VI8rfZnVpTrSxB+R%$mM-RF1Lobu!ZInDP_#_gh)ur(uwU09kX9{M>ri2@Y(8iXl_$pi&EP%o_mT@4@bGDi}2a)}AkGGpT5r*MCq zoYtr9P|k|ksR%u27>-PtAy6LYRbI27FEw@bTa@7er(28{EMbFFHhyb>6bn*Uv`GU&|U8qg=XT zRqX*Qyhg7WgD+GG|eNoKRb|DG}usCbbN7*?Oc&V&BC!VO?{LR8&~2DsP0GA}qE z8V2we2JJWizSP3gF(I1njRV-BOziw`O*c2!UR>W?8ydL1 zx%OJm!V*Ek68tSSBQ0|w@HgC1UYS^_8`=>V>KPkoX@UI8@NFt=$S2X$c#EyBsZp3x zk^3*PEPX~NqsuL7Eqb0GO<44lMx8d9#%bexj{5k6SVE4i{|i&MB-&PTb0M`{qE zi;HFVc$4E`ZjbC>cCY18fDiNHo9xKovQL^JWjZ?A=GJ_hGqYTA(etRojy7d>DJIhk z6Fd`uz(+dod%KgW+P-g*!Y8)gJEeYVS=+NQk@bB&X(oKW4yh`{=c$>pZ}CQro=Jx8|xg5#JmS?h|cw zLEpMauw(4CgSd)~(eF?ZmY51_aQg}^E4*q(^D36#`~Z3*^QvUhlMHdv(U3N2e*EMU zHs8~Y_O1D=bD2aD=RKRgbY-6mP%%^58m&ld9>ch1!-u?kid%9GlsQ`&Se^r&rR=Z# z$+n?uXx(t(^gHmrYC>##Ebocx5yQ%pSc7&M0)mxxHf-AmAUP77MnCU-UhXayjNn~> z8&N1$wWyy@P|AyVTop1~^-0Dp&Hwuu!XofVvHqmlRrqR`ml)n4R${7 zbu6U0SEIh2a^VA+fl|5HVL)rUxewl>_t~QFzfI}2%{mh7V$FHH$gD3lhJ=0ko|@!! z5JVAX8FiddaNz)lfJk`AgMBwIyC^Ef#Z;2vC~8cl%+nh5ZuIJ1^{Q8_%+7L>inGHmA^F?_B6Q%VRvhPIr8y~Lg*I#PenlB18o!v_K3`N zwH|8KZI#PW7Mmn5y#KGYv+9Zi*ureEV4<-9K?4N0#tH83?(Xg$G$hbya18{v#@*dL zI0Scxrg7=v-n-@(%)Hh^ty3>mwd$+APxvE@%vsd<3D&4;JoKrzr9|s($2Jx&lYIW5 zYqG9Rx!qSp8Pij&XAnkH8t6Uta-Ly`qSNFc3{G;W8(R8NW<7-0_O50?6eL(y`E*#N zfvh+8?>E7Dr*gA>=D)Q@96!|WUz+OGpcW46BE|tZKmAnxtgn_;i7_PG2~<&kA>~-* zr2t-k5^=p32h8-fLUe0gxR{d{NsU7L+G=rXer{UdQ94Wd1>AloLe6WTGd5UP*{fjM z%T&a6P)(ld14bUqL}TRE<3O81wQCZ*z!I&0qX09In4`$FeLC-Ow8A6Jm_S=WqQ%yA zE`DV4CXztVz!ggt`|hP=`Oe?|&VwY!8QhJ|i$x2W!zX@1oJ#qJaEjbLM%pPpSmYxc z3-kqGG|)VK*D~m8ih`8(%vI4F7yqN&(sqzv9ntKdH)oOASDqz|0(}Yd!)B6Xqy11C zsHU9Te|X`?W@y+R7;RFEsabBz5hnn;Xl~z$siCf6B7^ zt1{x=6?SCI$#n@smFuJ;E6oyLg_31!HICj6U7qVAD?KP~TUgJskq)l&!*G0ylg!s* zPN{Z|Y7IHTN@vPkhn*UNlr^*71gCD}zh^6!zn6J?Iwj~d8h9>fXZ?&7LspUtuj17VY+L>DA*A-pLv&2Bo;=g+1V>5 zO-1SjE0w^LU^hK?&z&8to(n9IS=T9mt4SBgQ&yi`pqZ&BW0H`yT6|$EBcrsmL{+c^ zp127R0v)}w?gIHS&#?v*`Ix<2OQ|o$!8;sJ3QmjwTfl|a)I2LoCC7GWKA&~pW#OI; zPYSb6pzb`(|1l^5kEZ!CW3N>zqi+cO-oJo;QncnJ2YPhVV6aQ$SDq7KDX?CKBRuEz zEQ|j|EQRrPh9sWs;-t5_D#nObYMnpfS>1@2bY@i{?g?~FLfwBmo;c@qeR(&Ki}4Oi z<6Z81R8f}EVBY{afwWmE1m%DmT7jF3o-yxj%Y}Ty7{7k7U6T znE#UYK>gMmlT}}RE9_}l%p4H$XyFe%N>0WZ=aji{p+nYwpIwDIg`90fJLhHs>ET6< zP;=fe?utETZudb1hHfB)6F*GMsO{fTqP2%yL}6js&j;1LGN|DkIhY!)>h<;*Mo%?L z2P|9$G6$3B0%i~>gTW`i;phhqtO;)XTVJJz-6CS;U%Xb3RTdj9qGg79=G3x!%^O9) zbg(wg-pa0&TpEHesIL)BvcmCZP+K72t+!FXvXHNCOUoqtFw^bsGd`1{3 z|9vKKEq=2m#thu(qu5cMOgVRkQYHt7xAGiG(A&_1uv<5YoppK_g_oMIDc`DDJls3q zM_Ixov(}LAoPziE^owMv%Oxq^mNH-19oc^AvG*;WY@VzSUKdbY|9F{>aRYZ0+ZQ)w z&x;MnCUQLZd%B%dRX-iaq~7&PN#S*AFNc(@e!{JOwL&w zu5bq1UvAOo2NU&_V^Pm;w8KPJ7Zgt z_<~g43c(Suh|f=r&jmbKO?CstU|M=CR{rbLhETU!R|xCO0uATTn6m8zJ8tg{6aF!g zDh-7v5BGEefHKw0YqFRg>!I<)o)Y4?7%_ZOs@ClIlIG|`_Txv;H#EnU^XY}0JXVSJ zo1qxW{an-r>`=IE53m}rQg8ek`uDpbuYy~=s01fs4a#Z*ueR3o3H&K)XX`+U0N)Vh z?anxf-%vXA<5{p5MqIAM>#lb5NmD|S4@R)B}pO`ev@fa1$=Y)k? zjy98gfugk}Zwg8@dY}vgSz9^kk%|hF(*Y(iHvS!nOV@q4A+X_l9|{GAKGs(}zOe$* z@D|g%wyjzMCr#r6k+!1=;A;t~Ub!mw4*!Qo^+q*?t<{DztI6CwyMtXRC9) zyBxEnp~{D^P}5o$Ppvmo|Hv?fur}zfLR9K*6M37HA)uS09;tJzREdDZ2xZMJ5Oonf zD{~iY4-(8oA!I*JD2lVs$i~gc#?N4fOQL{nnMm6B`CD_g2%W+neton}NclmfEYmt` zF&iNq4t5ZYXf0#GYa-I74E&Qe&rDnWEZRPd7ZRXh!ZG$)>P39OuD&2-BME8!tlXNo zPpG11EVN@Tx?@E694Siv>T4#0zh>Z_S@6+YctJI3|WHN5UpW<1*YWV#h;d>jqMvkOej>@XbpD2JgNAvu{WJi$+CBx=A*9Ab%YI{d5(j zI9^QXF5U2eQnPy9+iC|%_T{zVo$HL&4Xk4!mbn%hPxDuVr`%nvXRy8z6tG~K=e)`) zA0-3VErW;lrx`wyK}-V)L8a%K4d8lE@2!+qE@!cV@< z#y)@`@O`1(2y1S3?TUhNHo;AB%mewjc9fG%bva{{(X0T!c#8N(v?+Ezfs9{Nt&o&k zi4fK4eSzq&8EbeLKpUcQ&XFYgCT4}c8uI9Jr})Kba^ead+_6u%SG7cBrb&ZKW9xEE zYb%VJy$w#KJsCtbdB!wj6n>gt)!0i3A-eYt-Emi#+)F5)b*lQ1QLo2orGf^c_pZ^j zE;(L{IZ9OG+1kyraWN*wxfw%lQ!Ed67>ZXHr~}40k>ZKlrXhHq0co;YMV;|BzU$d` zH}~)fFJPLd#jsNjv0Kr^Qwo?#m<0{fQpHVnh6~>D{!uaaUr$#{HV=6(HagP~v!)Nv zN;EI@@~m;>uju?em5_3=95*KR`}XfApJC;oUY*0`nFVHR}xMIBK?ras*3{L}G@ zKi6bgC#}Zfpr;0O>Lwl?*1daviH*vc3E0mIVRG~wAUg0s(a1^3X7AO#8Z>G3+B@ju z6i8pF;|q&|(~>iEIX0e$3s*+J0ixavDI7~bm!^x8rDXI<|KsN}e|l`v^X%2q{aIhz zq-U`D8_L5KOCF{Fb7bL_rY`F{8;QD|zr$YPl>hDSaT)+;gpgE~-faQk?r1uAMh3aF zotF2ZU>p-}f!po)dgb+G9-(bMM&$gFUq4^JY4gdo_L30&J8Ovcgh`NTqVQP{K$7P( ziWu0jK|ASDYMgx6EOb^Bu2H?Nheb}eeSs9OYc&)}N|=on2{WS~<1umI-HxV*b1#av zVbpXx2j~E^3Z;;>MI$hHNkiSm=J7GWQY7WWg;-0%0-ZbcwNqlz#H&Wj=5OA8{Bk3Y zBa)OwxKCM-$)!tdS4#Z(B7mJ0q1!8#~11|o`Y}F3N}o?q%Fb; z(%SpFz0{!$*~jGXKS+Gkguo3c`e`cG84%~Tjq3d+Ek3IZ19%bo$-jC~Ea7{cY*tD3*B|LJ2n+@J)Z`7;XnVXw zUza~In6>r#xyr@OT46EchLYX#3Vkm;NOsYoQ*lTi z9TAkbfFA2AK-VviW}Y1672ET#tFfp#NRs&6{Ts;R^6irFO1jq*@F@D_uEntAm%u~- z$7(X6_0NDx_2#ZZvW{aTL{fMV%7;HJd))$lMMXZ)g3A&zou9pg@oaxZf#}ZTTNn#7 zcie9DGc%$42`znxQnTa^gC9e89D9o=_zo8Y6ZrrxhGDS4#_w+IQ!WX-3n$a!xPD7YvoNA%vkpE%X4kAP*$`VR;@Gx7i&C|aaNK&mn#|#~ zB%co*y~kqnhvOu;wA?@bV#5fJ_jidHS7iC2Z+0uokB%kEF`9MlS1>mZb=gT&dUrcT z5G*0pIJ-Qhkw&nVt?34|RPrdIVIDH3N{mc~}E4VEufeEV`{0n6$Zyr=YcTO70c-1gxP!nEI< zS^xDXV~K{lC{CqNeFg_5rZwG=?lJ53jbyXK8*Eo*z*UZquBs*`@p}{1my|$%_B2xdOT*Tw9=x>Y0Gys+=$9KFymf(f7@sBwIMB#B7%Z`%yXwWkorvvQ{5uUvYKQ@`{nT8+CG znimy?cc%%iL%H>>5GcV5?y1)4G|GZkVoJt5E;DA$Y!Cv}tM8g0zT{2>PrSOiEU8a) z>QTBz0A1`vSM5mYjzjSd#)F)+z$#nyZMWLuWH8TnD)~y?q&*+f#I-J0sgHw~KksLa zLLe6H<%bW~e2_~{U4Wa~gxBPU>@}PBQ%jp=zjVn4vx~bTg=YryEjkzQ+(!&(KGcqA z)8~wN>?23oa*{b-co_5nvV}81s)0IC3pX9K zzPfB(BUJ3U1lPi!$)yVymHKEE=;4-HnVsJtz4xxl9M`6pM6Yh&%+H{7FW#*mNqvNb zw(;d2wi6JLpD@*!aGYeRKKpI@e!FWsrP?j~h|S27;b-72YNF7LxSr**W(oO%D!KZ; zIc3mS>`N{6^uAH$_&ra_P}dL z{_DNm>^ePH8Z9DDcPrt0Q!MM%e9Uw@rPt^Td}h}~uKwU4BHNQ=P^cie#Wsf(CCN0&~2(r%9LcQTv=iuZG%E7x@ul>7+C zPWEkc%KYB3+k{iMgR9OR!msUTKVc)P8zetM+}#1XOL1bbS6+Y$l|kP%AR(DO!p-u$4^RpOBS zpsci{ZIXQ+EupzIVS#koe-g=sz27BaC&L|r5^EB@h^i_NSf0R3?bn!6a#glBa5vO1 zGN%HZVXWjzYV+(kJZ^BfHe;{|d*1@${rxy0Q*UQNAmsvNO3|G2P+79B-RQ_3*FV+0 zP8zee5Ifm06y&Oz@`~^OFue=?C)x(TA6~Ar=QUf=_n81U}(_PG*AHCky0u z_S*myCg_!SN>M%4pg2Y;^f^?uRt@dn02)RkV!J8dl)Oiz{pfSea$0CoNglb9B$3VVm2XX>aDFQf*2?&daLyFBYfTNDx=eRNP5w z1REsP`Z~w+id+T#Dj_^X%xVgq9pq#FXhK9_PrytZ+#HR#GTy8}aq z3_uBMN%EBCsz$+DM04qhHgb8Lrxqm|av60^wC$4mS^!#C+)SQ!+EQrIKPAM!!JaHN zH1tmDC z&ZQ!zQMU|}m5|d%%Jq*F+0$q2O=pY9R7uNWlHZ=++B-d?DEY<%^+<1+zdakn>6`@` zsM{?z?_tc>uM0lF^w$$$A&)^GWBOCNY(GhQ%#b2#Zge~bd*@NAzGPlmm)j|q>|wpc zC;f!`8;I%j;#IaG0Y#hIy`}sc6Qr+Kx(z!Yb_?#}AruNIz22iZ9B+dFnXSL+Km-K{JM`#*KuChl&<2^!yy!n-5w1Cm*_m{x2VrvURW&1Daa7 z18uErSS&1oo^N~}&>iS*W9s1GXzB!X_cU|2^mrTipQ4YQ4frM=|k@iN2{eLU+ZQ&4PZ?2?w{|E0VHN5}; From 1a685136e3d10a9973bdd80b01194d14df23a7d7 Mon Sep 17 00:00:00 2001 From: Steffen Hallmann Date: Thu, 18 Nov 2021 09:20:09 +0100 Subject: [PATCH 017/418] remove (tentatively) unnecessary split between header and combined --- NuRadioReco/modules/io/rno_g/readRNOGData.py | 37 ++++++-------------- 1 file changed, 10 insertions(+), 27 deletions(-) diff --git a/NuRadioReco/modules/io/rno_g/readRNOGData.py b/NuRadioReco/modules/io/rno_g/readRNOGData.py index e1fc23d08..9126e8b03 100755 --- a/NuRadioReco/modules/io/rno_g/readRNOGData.py +++ b/NuRadioReco/modules/io/rno_g/readRNOGData.py @@ -32,13 +32,12 @@ def __init__(self): self.__t = None self.__sampling_rate = 3.2 * units.GHz #TODO: 3.2 at the beginning of deployment. Will change to 2.4 GHz after firmware update eventually, but info not yet contained in the .root files. Read out once available. self._iterator_data = None - self._iterator_header = None self._data_treename = "waveforms" self._header_treename = "header" self.n_events = None self.input_files = [] - def begin(self, input_files, input_files_header=None): + def begin(self, input_files): """ Begin function of the RNO-G reader @@ -46,8 +45,6 @@ def begin(self, input_files, input_files_header=None): Parameters ---------- input_files: list of paths to files containing waveforms - input_files_header: list of paths to files containing header, - if None, headers are expected to be stored in the input_files also """ self.__id_current_event = -1 @@ -55,13 +52,8 @@ def begin(self, input_files, input_files_header=None): if isinstance(input_files, six.string_types): input_files = [input_files] - if isinstance(input_files_header, six.string_types): - input_files_header = [input_files_header] - if input_files_header is None: - input_files_header = input_files self.input_files = input_files - self.input_files_header = input_files_header self.n_events = 0 # get the total number of events of all input files @@ -70,6 +62,7 @@ def begin(self, input_files, input_files_header=None): if 'combined' in file: file = file['combined'] self.n_events += file[self._data_treename].num_entries + self._set_iterators() return self.n_events @@ -89,25 +82,17 @@ def _set_iterators(self, cut=None): datadict = OrderedDict() for filename in self.input_files: if 'combined' in uproot.open(filename): - datadict[filename] = 'combined/' + self._data_treename + datadict[filename] = 'combined' else: - datadict[filename] = self._data_treename + print("Error: Provided file is not a 'combined' root file.") - headerdict = OrderedDict() - for filename in self.input_files_header: - if 'combined' in uproot.open(filename): - headerdict[filename] = 'combined/' + self._header_treename - else: - headerdict[filename] = self._header_treename # iterator over single events (step 1), for event looping in NuRadioReco dataformat # may restrict which data to read in the iterator by adding second argument # read_branches = ['run_number', 'event_number', 'station_number', 'radiant_data[24][2048]'] self._iterator_data = uproot.iterate(datadict, cut=cut,step_size=1, how=dict, library="np") - self._iterator_header = uproot.iterate(headerdict, cut=cut, step_size=1, how=dict, library="np") self.uproot_iterator_data = uproot.iterate(datadict, cut=cut, step_size=1000) - self.uproot_iterator_header = uproot.iterate(headerdict, cut=cut, step_size=1000) @register_run() def run(self, channels=np.arange(24), event_numbers=None, run_numbers=None, cut_string=None): @@ -153,9 +138,9 @@ def run(self, channels=np.arange(24), event_numbers=None, run_numbers=None, cut_ ] self.__t = time.time() # Note: reading single events is inefficient... - # for event_header, event in zip(self._iterator_header, self._iterator_data): - for event_headers, events in zip(self.uproot_iterator_header, self.uproot_iterator_data): - for event_header, event in zip(event_headers, events): + # for event in self._iterator_data: + for events in self.uproot_iterator_data: + for event in events: self.__id_current_event += 1 #if self.__id_current_event >= self.n_events: # # all events processed, but iterator should stop before anyways. @@ -169,20 +154,18 @@ def run(self, channels=np.arange(24), event_numbers=None, run_numbers=None, cut_ run_number = event["run_number"] evt_number = event["event_number"] - station_id = event_header["station_number"] + station_id = event["station_number"] self.logger.info("Reading Run: {run_number}, Event {evt_number}, Station {station_id}") evt = NuRadioReco.framework.event.Event(run_number, evt_number) station = NuRadioReco.framework.station.Station(station_id) #TODO in future: do need to apply calibrations? - - unix_time = event_header["trigger_time"] + unix_time = event["trigger_time"] event_time = astropy.time.Time(unix_time, format='unix') - station.set_station_time(event_time) for trigger_key in root_trigger_keys: try: - has_triggered = bool(event_header[trigger_key]) + has_triggered = bool(event[trigger_key]) trigger = NuRadioReco.framework.trigger.Trigger(trigger_key.split('.')[-1]) trigger.set_triggered(has_triggered) station.set_trigger(trigger) From fccb035dfc18d5e6760def8fe829051f020d763c Mon Sep 17 00:00:00 2001 From: sjoerd-bouma Date: Mon, 22 Nov 2021 16:28:05 +0100 Subject: [PATCH 018/418] added file and event lru_cache --- NuRadioReco/modules/io/rno_g/rnogDataReader.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/NuRadioReco/modules/io/rno_g/rnogDataReader.py b/NuRadioReco/modules/io/rno_g/rnogDataReader.py index cf7913dad..430ad1848 100644 --- a/NuRadioReco/modules/io/rno_g/rnogDataReader.py +++ b/NuRadioReco/modules/io/rno_g/rnogDataReader.py @@ -57,6 +57,7 @@ def __parse_event_ids(self): run_numbers = np.append(run_numbers, file['header']['run_number'].array(library='np').astype(int)) self.__event_ids = np.array([run_numbers, event_ids]).T + @lru_cache(maxsize=1) def __open_file(self, filename): logger.debug("Opening file {}".format(filename)) file = uproot.open(filename) @@ -67,7 +68,7 @@ def __open_file(self, filename): def get_n_events(self): return self.get_event_ids().shape[0] - # @lru_cache(maxsize=1) # probably not actually relevant outside the data viewer? + @lru_cache(maxsize=1) # probably not actually relevant outside the data viewer? def get_event_i(self, i_event): read_time = time.time() event = NuRadioReco.framework.event.Event(*self.get_event_ids()[i_event]) From fab076a6dbba6d3ca3b01b3df79ed16b12fd7697 Mon Sep 17 00:00:00 2001 From: Christian Glaser Date: Tue, 21 Dec 2021 15:42:30 +0000 Subject: [PATCH 019/418] trigger new build --- NuRadioMC/test/SingleEvents/surface_station_1GHz.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NuRadioMC/test/SingleEvents/surface_station_1GHz.json b/NuRadioMC/test/SingleEvents/surface_station_1GHz.json index 478184253..96609b171 100644 --- a/NuRadioMC/test/SingleEvents/surface_station_1GHz.json +++ b/NuRadioMC/test/SingleEvents/surface_station_1GHz.json @@ -256,4 +256,4 @@ "station_type": null } } -} \ No newline at end of file +} From 5ccd4dee68ad5c8c5d5372cf29fcc2b18c82f961 Mon Sep 17 00:00:00 2001 From: Christian Glaser Date: Tue, 21 Dec 2021 16:03:07 +0000 Subject: [PATCH 020/418] update reference file --- .../test/SingleEvents/MB_1e18_reference.hdf5 | Bin 352120 -> 352120 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/NuRadioMC/test/SingleEvents/MB_1e18_reference.hdf5 b/NuRadioMC/test/SingleEvents/MB_1e18_reference.hdf5 index c98fad65b40b95f666b615920adcc3a54218b8c7..7ae57fa9156c58f6db256ef3c6045a5e0251abac 100644 GIT binary patch literal 352120 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

2qcAJ{Bi~^GL_dBVO$w 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�a`&(@*ipfykduRILX*L%;L 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 literal 352120 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%0D(!#8{*E59@h;KVf1-!q#1-9CQ5~&!TX?-< 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 Date: Tue, 21 Dec 2021 16:21:56 +0000 Subject: [PATCH 021/418] update reference files --- .../test/SignalProp/T05unit_test_C0_SP.py | 10 ++++++---- .../SignalProp/T06unit_test_C0_mooresbay.py | 5 +++-- NuRadioMC/test/SignalProp/reference_C0.pkl | Bin 16155 -> 16153 bytes .../SignalProp/reference_C0_MooresBay.pkl | Bin 80164 -> 80162 bytes 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/NuRadioMC/test/SignalProp/T05unit_test_C0_SP.py b/NuRadioMC/test/SignalProp/T05unit_test_C0_SP.py index 2376c190d..20434e709 100644 --- a/NuRadioMC/test/SignalProp/T05unit_test_C0_SP.py +++ b/NuRadioMC/test/SignalProp/T05unit_test_C0_SP.py @@ -5,7 +5,9 @@ from NuRadioReco.utilities import units from NuRadioReco.utilities import io_utilities import logging +import pickle from numpy import testing +from keras.utils import io_utils logging.basicConfig(level=logging.INFO) logger = logging.getLogger('test_raytracing') @@ -27,22 +29,22 @@ x_receiver = np.array([0., 0., -5.]) results_C0s_cpp = np.zeros((n_events, 2)) -n_freqs = 256//2 + 1 +n_freqs = 256 // 2 + 1 # n_freqs = 5 results_A_cpp = np.zeros((n_events, 2, n_freqs)) t_start = time.time() -ff = np.linspace(0, 500*units.MHz, n_freqs) +ff = np.linspace(0, 500 * units.MHz, n_freqs) # tt = 0 for iX, x in enumerate(points): -# t_start2 = time.time() r = ray.ray_tracing(ice) r.set_start_and_end_point(x, x_receiver) -# tt += (time.time() - t_start2) r.find_solutions() if(r.has_solution()): for iS in range(r.get_number_of_solutions()): results_C0s_cpp[iX, iS] = r.get_results()[iS]['C0'] +# with open("reference_C0.pkl", "wb") as fout: +# pickle.dump(results_C0s_cpp, fout) results_C0s_cpp_ref = io_utilities.read_pickle("reference_C0.pkl", encoding='latin1') testing.assert_allclose(results_C0s_cpp, results_C0s_cpp_ref) diff --git a/NuRadioMC/test/SignalProp/T06unit_test_C0_mooresbay.py b/NuRadioMC/test/SignalProp/T06unit_test_C0_mooresbay.py index f25f3ed21..f7f9eb2ad 100644 --- a/NuRadioMC/test/SignalProp/T06unit_test_C0_mooresbay.py +++ b/NuRadioMC/test/SignalProp/T06unit_test_C0_mooresbay.py @@ -4,6 +4,7 @@ from NuRadioMC.utilities import medium from NuRadioReco.utilities import io_utilities, units import logging +import pickle from numpy import testing logging.basicConfig(level=logging.INFO) logger = logging.getLogger('test_raytracing') @@ -33,15 +34,15 @@ ff = np.linspace(0, 500*units.MHz, n_freqs) # tt = 0 for iX, x in enumerate(points): -# t_start2 = time.time() r = ray.ray_tracing(ice, n_reflections=2) r.set_start_and_end_point(x, x_receiver) -# tt += (time.time() - t_start2) r.find_solutions() if(r.has_solution()): for iS in range(r.get_number_of_solutions()): results_C0s_cpp[iX, iS] = r.get_results()[iS]['C0'] +# with open("reference_C0_MooresBay.pkl", "wb") as fout: +# pickle.dump(results_C0s_cpp, fout) results_C0s_cpp_ref = io_utilities.read_pickle("reference_C0_MooresBay.pkl", encoding='latin1') testing.assert_allclose(results_C0s_cpp, results_C0s_cpp_ref, rtol=1.e-6) diff --git a/NuRadioMC/test/SignalProp/reference_C0.pkl b/NuRadioMC/test/SignalProp/reference_C0.pkl index 6bc14720ef84826363c1c7feb97f486c077f800c..5c2c403ba3e12b76bb2b4656386242288af70328 100644 GIT binary patch literal 16153 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 delta 7399 zcmWMrc{o)47srfcxb|y_vBcPiR3oyTv4kQON+n*UBoxZhTSS{AMZP6zc}ddptE9z} zN}Hrj8!b{v?(Aml%iwqay3cc-nLBsR_ngmmPwzRihnhn@sd1c|Kn;`$ls%p@AM1Hg zWg3*Pz)pD`(saCrg|FUe@+tjHKb)$ciCF)vABM~aE02%42Q?|imtBb>Ks3L+zpRRY zjHA+8p&J2I>3XfB$plE$M}7Pr(b+SV4s(=#(%EshM*Qa2aX~BnYHeO87nZ(|eh7L> z!0CYdF(^ltfpzb3pO_R1!0~p>HB=+ZqHO8PL4<5p_6;w)bK?R5)Etgq?V%_HjZc{y zouoW?1|^zdI3KaV6 z7Kcw7dv76N-j2?6WJtrR*_Zc=$dtMfOMGPS8>q~ObABDgsEEp3|FV141(#0*++FFeGwwt{ zeY`X8Tm=D~rQbdr-ynvTnDExD9b!neqj^T~xsV+9F8Y`}4`y#KFx@IIg>X;j(4F(8 z5M=0|x8)}vw)OI-#;5r(Br^0}^0yy+kdeFqbx3mKY9jBQl#5Q@9YH)Y*TG;KIcxs(+G_ z#lV@f^M>|5F&Hk+Q!+2+z!IPQy+}jBm-b43t!2)xN!WrS6~gJ~vtA`U?i7Fwer{>( zqyTt-H#EK3BZPu87wu8I0&}Bnh*FW?6>`*e)AjM21UR*2wFUN(hxA%PHT}*38_HB~ z-53Y5Iue7Dws0WlP4IsIBOG|OO;pz0AON;B^jXp;0dyQK#6CBU!@GBNe^&Fxq3O4N z(oV9`*Mq)AqG&~5?OH9)x5*j~Xy=*_8;Up(f0Ry9*1418_0{(Z8~v8kW*$6DT^+uc2UlZC zt6!bv!QCODPMRtY1f^-`r($_9xuc4gxrhU5uNLW{X7V@xuHSz6xf};3?w3>{FiE zphLZU9V()QQBHKdKm^T*QZ`_W6qW6%JFe<3MlQ-s?S)hJN-+XHIAHaPdlUtbA-In+ zlektQYaxI^$_AcUr`#nc0Es+bIsvCd2S~d)O*DR9L*gOp4=B2^6hfM9HcwEYarn`KSXtFlec^LN%&5^XlH1+Ufrh(2hM{ zbLk5KOT1T}deTBZ-j;P7Ir1@mXP={mk%#)LC^8j^RdHV@Tf2=b{Y8))vvcp0coATy zdgVSJ9EOmRizCtp!(itaxFlk(6y80(H#|2&3J}Z++w*-89+qbOxhENf9&f`9C_s%# zH|UfJg6+2BW}{;y zW-^<7og}akz0q{Wt~R_eJNSaazAS|Rq@jgVCNF+QR$3mI?RA~2ku)y2tj={p$y)fr z)E_c8@+kt?d8s&4J466X_lB4aL0s58*C&rlLb-xq3G>aWe)!gVzw^V9esGti`)|n@ z16lMy%O5-VZoZ1zTplpKZOcI#+AP`~)icRHQXvWGOSMg?50@ABqhxIy^GiE^DQ+_t zGWh$=P?0u{Thh06zS}1O7ll0Iou?&`-i7v~dTn>?s=sX`rJe^-{?AVq;|yxEbjbv= z#+kD$?o*fP%t`zy>jg8$}pM! zFFfEgQpBhn$Emre*S|;gI1}^c)X$eAhal$qBPS%r8Q9!)HJ+tze2BSt^&m3U!Htwz zfeqLDxX^3&O5TOagOqcPjK>GZAoEq(M;e-oo6|?sD}L5m5b)zbROR_#0xDnpIe+i~ z2WAf%p!g)`NK?u8V6Rr^*tO_!U6MSDSv+*d7XLK z7$DDuGv|fU0&;duJ38hsM7LD5>3I!ppPasti&u3lJ9bD6=BJ*jo1G!x;O0BWP`MtC zoy9_J7M77xsKtYin#qFhsqZEC+6buD?|+Pb>7^Q4C1x!j@FXCAdvNCE5&|B&Woz!g zNWeccX(&nG$$kH9>B_5J1RNf#cOKH=Ky45@rqU*Ye7E%C9?gD`t-K}Hs;06Z+?|-G z_=w8(9UrDtatOHaI$#m{rO%+Zsn|;No)94I3rR~QS!U#JZh7%ZW%lUPuVKh^7LFNr zm1wR?=0eH~vm1y_7IsYS-j&K0z>;w1n<#n~&TKRmxtzm!ur|ky6+#Ta5g8n ziVsn`Hy%H}DFBNURyoozz_AMootpzba$)D9CQIaK5QbUr-n4p000-1Zj~zut2CRkM z8`piGO^V=>y@y8DOh^DzyceYw#RHk$$?NNG@*rj%_IY071XxvEGl)Dg0hY>gjv*&S z5P_x){8id+aVFRJ6VUY587(u^aaYwH39oS>nUPp99lwi!=VtC>Z%L8g^xV*BBT20v z|J22-wI-l$dey5U@_RW=G{qM`x$t44Q4^IL;#gd1*5bq!9JmvQ6R6pcY|?#-&h7^s zn40X|GSVgsYhdXO29JVG{vDn0yPm&pIkJNz< z5=5R75bK}yn%TgIWBR(sQL{0_z0v>um~l4;()PTT`)7&+;Y$|XPTwko%q?8oh&&(?&(nkvh#^yzX&IVL!>NyC-(<}C*bmX-yy^GR=^uw#o#paQ$OPVb8- zS%F<@Rm|;sN5EG-`did&g0l?k7CX7v$+L}}%a?R6l4mDBGpR<`WZ0&GzaLUQ$*>cN z1)^q;8?<8azQxFxAs&LwTwAS)q&=7s4+5F$9C6t^Q+p&tsilm((M zrc9<>qE0}H`6%RF9=Y(*eH5lvr zzukeqIgm2?OnRBh1@r#?pd(5GnA>{0=@2>nqEWuVYN{^#SE5HSDg*pMxBD@W14fsC_nrIr*}0R%)RLX!3dQ-S3Fttmd{d^#NHn{o28E zR0WbCrB#(ZD+Q2}lc0}G%@{0>ZF|CZv5J2;l0*?rJA^2EM$ZlOjLi`^S zG>74YTealTTBBI#vR?iVj2><77Ec9EBZniiJGGynKoUF>uAgT zOhB~G=&_Wa5_oCj2W?^rGzG`GU$WtX{w-o6`9_seLqCP*+w_SWIp*(B-Swj-q1 zO!;1limY+UP@WJ~TN`2Zm)0)$@SVbTCVjUnkNzUX2kB(p2 z)iicfhkfD5d-7WGI0-4)&~f_W-sJeeakxL{uUGBnaY(N)JcC?p=x$T73B#ccgAn~X ztLnt-K@e<8%`CATgo{?(_)lai6rVnwxGz@(S6Bfw^EwfDSH8S^T6+L88`q&i8y#8~ zqiE5KA_+**bsIhNsvF7FLw!Q%UKL+urX+&sN~eOOWSaIph9~KrCXK<;(}=K%#0FBI ztc)a|`~5e!Xtdmxg_Y3R%zuqZC7g8~P!U=9cUjYX)-BhGpb!l z6%P4Yw=X>uaA8~FHP^qSWDdv8ht!jX%o%H1QluyD<{ms+Iv-?u8Z5#`u1R5qF! z9IPevuWxxRx@l)YJ0G)2^6h{Kexe_C{@8^J{N85^iSRTohX{gqD`-yZ1%Jrf(CSssYm(run5&L?Xf+~#qwuccrZ&< z#SDp=IM(k{X1!=77p#7LsYDv~3>rmmLtYvQ^^VBHK3uihp)kQGiw`;Jt?X>HURRqo znm`Ggx-Nzu^uS(EmGw0}B;q8=7`;pT|Dp;FZD!ZVy7%8-2qCsUV%oe{2r}NK=d4M# z>}2Y)`erzAV;S#8Oq38f6T&iN>VVTvPNwgQA-UhoJ0!mCIO&{{M~Chw^C9G(`3zd_ zfUDxPP^tL_0={+Vyq-oW>e|{$)KH7Zt0-)bD+U%5Srj%ecndn^V2@=q(su|*C!^$C zmy6mRSQLeg4M=g0(JWoLJ1=J^ia}<jRvcja)O^;>s!~57CmvV2e;Vq1Xf>Wn2Iw6(3pL;8y}6OhRsZTNQ6v44LiC{=A6YVTWPM|NsusYp zlTppRj|I@BI=E=~8UZD1qV!SuTm~h}+Y7yzYcwly%p^&5t^~5zm3dzGl0bchiB`e( z5%_|p=2~Gll(HQTCy)rw^QIxkc?{Ln9sWi?ck-bruz!$^WHq(vL{`j-b>#${k5eDl zZYMxbW@W}rMKTF{qB4St=J{gHiKVZPlR{+L@a;47YaS!$z{>kX=yrHxImy%lnSMA6xW!PcmK zei&x(Ir#haCuDz1vBijNFBZEXQ+(Nu%uG&k+R$&1Lxu)bwrz(7nj1!wnW`jz|5G5~Q(4O=%_s+QV!xeOHK?bYk^WBASw-L~55%l)t zWzr`4zuY>MDuhq5VQNu`gym<`=EZKZ?2lsKVz0Hb?A{K61qyIx(j6;kZwvPI!zyL3 z*72r(XrwBX<>v|^_p)a=Dssl@$%jgB(jW4nv}k_8LD-_ZB{s#dAMhCS9ZJTZtCZccEitnqKG5xe6hB$KDLYcERaQh93Cw8-uW&@qDV{ z*&r-=?f>YrHVHy?AsHyyg@H+P&P1Hi6GFT`LGGmsW8vCQ#qm+zq$90+x|bVGhKv zFAYh6mHyy#|K>r+51a@|$sL3RJ0Jd=a*zOrw1&1RbeyJ5xyn9;!WX`weX}S!HtjV7 zImq7C%01o0`p1*I1gxlga@65BDXW=`*3Qog>_xlkcDhLw*l8;IgQ^W&csE&+px(uW zf8+;uemXCJ5A)M+p(0lnCT-9;8+CyXESb(y)b5I7F19Y4*ZPt13On>M5|f`;5;yMD zwTOVoml-3-(T!n~IX-o^ZaojYmcO>1*~NqXqUQ@+G$oLP#-wih@z9?Peo&;lv#RET z9G?SO1gvfF6{(`R40Gyq?W1_q>Q1LVJ1~9^aom~AcNEWIBOt)|aKx7xQhR=o#w?Xp z9|n&6hYeTEhoQM+@rFfSWOuqxnieIj^QA0FyQu2qru>-pQr_eydq zOD~}>9(4M%BA3>Zv~mCqemZQ0U2vlW-#S#0H1|18AY8 Ad;kCd diff --git a/NuRadioMC/test/SignalProp/reference_C0_MooresBay.pkl b/NuRadioMC/test/SignalProp/reference_C0_MooresBay.pkl index cfb6df141ff069f116d9fcba611e74fc25549c00..4e37801a1f3887f31360e0ee656194da2196bb28 100644 GIT binary patch literal 80162 zcmb@vX*`wR*FSEa6KOD%DO6O3C`#5z=6MQ5NajqTG9_h5r3|T5M3g8YL`ssO5Go;s zWXPF0$2|An_wW8cIv$+w>3jF!XtrCiO#k~YafAOEzre8F zCj)}qcl(|34e>q^6m%jiEs@VT$o*u1e{e|9nUf)DH`5Z?|KE#giJbm!|NF|#G-IZ? zw8PA$pjqETg|M&!jUB~zero&$w?x^N!@g7qT+{l~aTgUHJyY$8_Tj;7 z>J@!eXT*cyD6Yq_tYyVaSk8VuInIJHJZEeqx`qgsddr)4ZYM&*r+a31cjADrYUP%P zHICu-G0$JxwzvZiUO&Z#WAyOw&8a#1o-z((#b%5z+b~|=I=$|rTXaa^v}q>H{sajK zuRs6HYRAJRqj!IuD0qh37b>_#s3VjB-Mfe{UgZ%W^ll?DQ+^WsYo)|hHco9{INkaPi(Loa`r*MQN?Ot43LcVtkNp{Zg9WW7zDSK}#^r@?Mx6CG4iAak0ZJa? z1nAL{@jU(+3;DZFh++@n;A71W-^Z1cAjapoUpspek}dk~H$+Xqv4Z158lDrY+UvFJ z>;=}cF-Q>JHQ^RC21;7mMH>f+aNFs5G0Qd*99@^8{#kJzc4RU644BVDN7JWY!gaI2 z4Zmd7hGtjQSH0fu*{x;*ylxt}wmeLLDu)=0w0JBmFl%m9f5muz!`owuY6S4G=WF%o zFL}o0gLWa>+znC3VWz=VeZx|I%``L+w^+WH6TrMUo|xLLCxFR`-}LZH)dKjY%Hyx9 zFGAR3$L?NFG0f&Yd!Cl-i(x|C$wPfvf*9eC(SK*&31adtObC|Aks+TdVzKQo86

  • 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 <$Mx2io7$mLE)?3AGd_ zK;ED1)5i`F;2QH9t3L?;n*5o=z8t2#{t9>sPj7~BSe7%8CxZ+HmyLM&)r}ySb-JN zwg>EWOVD|ikG&qh+TK6^RpGBV2OeJNq-SA~U9>mmtD_Fehi>L@`iSc>Ds;4Wm~N9o zaU3kNI!E;B+Y1z~blohpujOYNKD+NsfVZcf79AvF;lSDlJlm8Q@2|zD`d5+*csReV zaO31o#53ER>(}c#366DDc||6Zfct#KKfsC#%JJ9qc{J&tpKo5G960b72dC10k)p*= zUIrBC%JL8k+*i(?%Kyf={6!o!)hy>HL*h}#VM&ya?|k`-Y4w8AJBj z3#;5x_GysZ-k)&;@v6l+7R-Dj>EmIY+f9^L)*$&P!X0KMqkMnX`$)zEcu?7WzsV(gPi-#YN;v9BKGOi!emfd_G z1|d1VvN2u{;Rm@=ubV5MVZqVx24QrB@%d;^>S&tRK>VE4=HZhFzy4LDnwX00xzy-3 zD~-LA(4g~)NyCc*hc0ZsbKQ#me5eT(-n2(~Uof0fhxu*saAoJ#z!SUiU}9eBm5K6K z(dsvPW!uw_p0%R9(#ID31? z3{*#iW#H?^V5IK4`UK*+_X=A1TfAbyd{HdhXZ?@`vu>L~$lCYI!1E;I#=zL>_{+Qp ze|B~uJ>t82y@-S{5X1h ze<8qC;p*#Oe-Y31GTD_d3nA;8Dd*R&_D@HU%cd zrfRq`bG8~BL8Gjgu(`;Hv=6KK0{b4`bC-!l`N4O6xhs^(_%e5XU65FvAm)96Us;P;k&A0PX`6;)MVCA`h6WiuR52Ltz+VQ6?3wXKmd?cZKO=T@2aHNbQ{8FpRYS}7SH&6 ze@ITg)p-;7Q++k_EQ=W*FWUCWpLJ~X-A97Kr0rRJ$ZtD=d44U^7z^*$C~fPzi|#pa z-St`j;WS9My4jz6Jq~-yo39w3I-?}ztHQq6B-6iU}-PKP}kKu}zZk{$uI})jg0c0MzS)UoI?J~F_!Pga*^HH@if+4UTzTxRIUxfI%r>ym`l0OJ_RxcD*U@- zR^z+T=ek@TAbq+i*EhXw zJ*IAah{tMU?}ph%fbXZy&bt<2A*G@0@XRRV`_Y(B?Zd#$BnX`UU=f7QMc0fnw?2D~ z?y<0G3gi6E`1rZ*dl?@(iie>wGh81!XV9BJde5I-*8NgICcrwv{>~YcH}dh9lLxkM zL+dYax>OnEk)ZecRnJp@{?bK$#i18_m|IaC;>7Up?r0q>tnCfonsW&YS4;dZ3LcmQ z+pYxG$1;;J)i3{=)I^24FTB-erK|OqbD4&hbsrIUjvQ0kG)n{ztt26#dMqe}R;KE) zGd_MZ!TU@PBRrxf+4CeB;Sq$r6?l`ASnw%K3HpQL+*kF7&i~M~;h#K>?q^C^u)n8< z@)2~~tYv+M_*_15_4_3MVL$2f8SU~hB|+bb{_t|dQy~gJCaqP)f`EnI)~7~{w@*(= zA%9I32|APy5C*zP(E4L%7$4%_ici)ss+OutvdIjNN;dULo+|h`qY{N_>Z$o$y zPq}c$ZpPd9%jlHA4rLtV7-qk$Jca{#;Vat}Stua+N!U5{&p4%(T3tfNHpH8+S1U+L@!-IlmKNM*#N~w&VRY-+edQe3r{QZ;$iop!=>}cuSoknM$1mDx|>T8uA%lg zs%J%%2p7lJzZh#`!yMqMksQxp!>C@p`$}i+Ea31z`#n*dfuDznYXMFWb9V1?*T)q> zjONh~3gM@CFq(;ace3yBV4jF-=RM%W!-aff&tjBk&(w~sY;NZSn9L_O+!LOFt0PL6 zl+7t1bYH0?azFk4UVXXeYKa8}(!Wh#TZ{5QErw`|wZ_ds(et_QM%i<4vFWL(9+KlL z&FOC&j?C)=8Qwx7PFI_iv*B9ZoigYhX|6N^~>&0&BLvcWCeczs3|(g%kSFI+`3e5rB)2Q1fQ#qGkW$e!MLq72=e;JRM7Z5ZW0>rr`@ zwFmL8>9tR+!KAxK7~yqWV>k@di178bJ9bnb&C8JgsSRBRHJph6 zix)huZAI}_H(J9N5{@9=fcK(`W;o;Ri~DjD&#@Eb7Z6@ZcxRg#zCnEqw)2XRC(wNz9YWMm4unh3Bz`?C8#D*HKSsN4P<*4~ z*n#1`4Kr~5aE`N(>T0~5$1=fJG;Dm*l6Zu*hhiFkIJvASL8 z{?$Wom%iiHFy6k6H(WxAD+sT5x?LKehl8lc4mOJZ6rie)?D^wJ0Zm(1FW(C!=y{~E zcOsX*e`~}~)ay?b6}V%z6n(u#g;BBA?)4}R__t+d-ZOiI%k*v@dTzN4GRihBvS*jU z^N^FpMa(=Lj+yDexy`Q{-`}y4rjp42*?PI9{XE*=I)ao9D$dM9N^&&5^zl4I6?H76 zY7oJ}$2{kK4iUE0%3y65*f73#6V7ZLV#C}W?=E(@wS;ii)J^e?OVIs-)IFm}LjJp3 z_ud$jV1`-oVB{slLsh=muUf$P_*DgeU6%Pufb754n_^LZbq{st^`O+HBp9@gFuzhKZIDQ0%iEz}M+%K8N=-fPF zSbN!)Z35cw{I-4mX&eszsI?nI=Mj4H9NUwz*Xa_{qai1coEIU$X`!2P)CeXFn~J*K z*$gJkr!aib{a+MFIJYMCstRw6t=Nq3?vk~ zf30D~>@R63YUAf zl+VVrNgUaigB2RN2!D30y>p6J6X}=KVwMRj#@lyp`{dAj#IM*@Q@$fC0}C&4N*wBZ zYf#gQ^geU%7wdY-a}+Y9ssf#(5dne-_;GmXr|!ymHxf zu$6@fPUn~2bj6_k_w~C(u3Y-^K|8<7EUNbj2)7wytEm2a74g<^?Bk;qV{n^XvhH{K z7<@YB6c>r&miGmFmKP&EMEiT%a=JrhNxcXeu-j9@)z!%0oik|ki-Oj(gUW~qvRi52 zr&m^g*LUvhZ32i5?6_3%0_EMvoVrU!@nCKB`HH*U8L#iUm{g%4;@|HP(+@Pb!uWX6 zwztmzhu!IE#}Q=xs%XnFhft~bgmSUAlqSKxF63pbK1PCxrQ4tL)z3)uIK zLz*kKZ@cmsSRC5c(Zff7{oXjZN1^&H0lr?e8oD@x^2lJhviBlfEYV$8I^`uEUYj{n z8&F=zv+)$oR*`8aHyF4UZGrqL{ift>bpH}<`=1`PNV$aUm#_<;q9oGrV0d)qdnn?m zDCbrtI3V6T?fdk~Dcsd|(wyj?vf!?q#;qjSeB)roq$M6m!`-cq5ucyl?`fZJ?yQTw zri%7S*LI%mD2{>lIiux!5B(n${~1w@vq_j^zD1v?|t~m zG|hzcbAGp;)@zh!fc80~WeWauQuPCLzjIxX#1jKiLR$Ws#B%l}2r{#pFpymW0}Iw2 zSI~W8dTqW&WXIL=%sLyb{R{Erb-W{lHV>hE*YOh-C!bG2Ecd##kquMmo>KXay7g3e zWq^%6yG$SNbW9WqJZ(t^9=Fe%r~zc~xKaDT4C$|JvW|(HQ651?=c9Ijg`!xAgYUB$ z;_e7PY?4R{llzJGq37wr?kI05qxCt>-8$hYg7RDZl0Nbq@#`4|FD(< z`)6AM{tx?`@2Jm6J-SEH*42B;9pxK-b&+j@ z2=YVCJ7f*1{sUfeu|{o9b_Lxh%(m^%NnysvpSJ(@FIAcb(ET&j?901XPBAXOwDo!H zsCg|qfN)dy*sc?kjGw1y>tj0;r5=`t?%k?+$b1Ur2hQm1d@H$xh3r822Wx@x`6YcL z2Uwp$e3z==3wx1YkM?_vmVY}Jv}qzfiJV1#xFm|NW%T#7@1K5o$BMOs1rypQZqk;^ zf{_@jVUzfS?0e(byY7cpKqgi1`D0T-jP!e>Xp);C=HpjP)sYT?zOCHkx71MNA8wL%+fzM2ACLGcTG?9S zgM-W=CK(A7&lI2Qj5*MY1@*4yY0CeguL?yA-)w9rf$SaqrDr4(Y$RKXYElRgAD;xK zD1SX|f9RD(b!RK~gpon+Z7Pcx%F{JrU!wNm<1~crp_(lILU~#(6|9!Fp}1w81kXqT z`ucuQD%-K^0*Y%EQ^l5}eB4aOxu|xjSf~qHE5?TWNfTx+SI?iD1HquFpw63f(6o3y z;$`V1TrRY`%ldh>J)PodxjXngx<3VOX}(8#s!|8H&s-nz^};_&;gLS1*FW0luXnQQ z{xm^x$^Bd2cz6<#okg@aMR>=_tIS2m|A8->(OUiKW(N_To;=OTOhNY`G0$eBq#oe^ zDB=S1VaDYY;G!_P z&zH7;wB;8ZU)Dt&Aj0(EdMztkBAhT0d2)@41+O=$`+x6eeEi5Uf@;?hzq2a7qOjZn z@u=;sr1;VO;tQv`UUZ;)cb!_F#|vF0K+ebKH=2v+_aFN??3%bb$`^U;(7k?Z#B)^C zC)CIz9J=B7=dCu3w{OmF^Tm8gJZz3pj1WP*4T|}Jj6*y);NNAjR}9%nwBtjsywt7v z*vSnKO}e@~*r@-0|H!wE|B{LJH8Xb?)y^z*FPhTun-54%M90=2{eV|2MPH zEqkADtY;Q5T+Mr%#;2im>*lXEYgXgM=O0EJtZzg2v5XeHF(43ue>UOACK4W4)zXt> z*3ch++Wxcg>$P65cnOk3Sy`En zA3y2OsXGhvm+_P2hgBP%wJ4B!qDHSX-YSsxT{b@BZ6Qb6()T2bx=@a!S`znyz8n2~ zgIwtm_?;tqAEN6X)4`num`^;Hv(O~!>c7tyXXeojKkZQ;>f6M9ZS+qneKN7!j`&@V z;k^>CQKzTINQFBDzwISO@oVw z|1)ban)UVt;*M3TKQu=YpQj(*J(9{Pjr^QNlJ5&KuIMmlUyKv3w^Wk)OFR4Xc~)TP`Vox3$vt>&*M_)xqVXfT&J!=Oa4W`R9+~a%`4<20^W{UsBOWpI zCwWgD52ap1os!Vm{IfOt;DWjBlS2zoPu=x|(Vhq@wrz)s_n$AMElF!dl`qX+k!P|}I3vdCvZ^uEnz6P;DaFS`ESiz`gb z$053(=(_oBUn}(@%qP=cmUBu8;~rkd8@N*u4hz#sE$g*)ALi_poC zTyFTbMIt2hZ-y#$CZqpM_@Kr^zrrE7DR{Lx{p%38J#3HK6x9p+zuo@E zf0h`J6nt{Px<3cwGgFE(K8O<|nh!+RhYx9PYDB-+RhnDU_OO4iFILuoJ#Bu`_@SA>3+ZjE!o9cDp#0r zLSCDG*_aBhbLZ~7g8USEx25)LrH;V^{sgi_Ir65vS$q8C90E`4uF71+nf8!g^R6=o zZqwjMe_Jf?2O69oj?wT$9>eFK7O#kkN8DEBF6{;QyeU}tr!R`w-gshK^XVY+0nBSW z);DV-4PJZ~msZxoe8-QROc`tT=VRl&y>mwp-_x9WYT_;0&qV!AbUi;zHuW{eeV14~ zdR(;-@mtT;7aYd;+v@u*m)ByRHqq}{ufOg|-l{Iw1+%NW)*W4q{+Fe84l;$PH#Yy{ z8%M;$vEENqPTg26vIq0`J6@hE_US;}@+vp(&~v@8CW6)yi#m5tb?18B3da2>L1l3a z=HnC9H=cQ_Zoy^bMGrlHP6X#y*Ro%gbUcp;?$!2f#kdmD?^&-e4bm5{ucN}x~R|N){kdrZ*huf6PsqXQZtX897rAqdGv( zvj^iIQrE{^_UBTe>w9(QFVs1XxKXgaU6lRt(5l|C$k%WLuIqZ9X+U1^p_|f&$ziC2 z8995AW>waLq$01Vn zmgk7`VXCM%f8!*%in#El=5dmgwo6aSTMlA8YRiYdJA+W#<~bbFE<%d!zpu-~D@r&=^vb=@!*|m69t^4&9Q0{A+00uWBA3_6)Q(!<(G@b_3ff09e*C+qZ|T7!Y58ys<~l z`zT<%>q^J`T3d{>v;Lm7{G;;ELe8iC@JLR=QZ1|>&h(|NiN<`Fp5mnU%E(*yJ??!p zO^}1Mu0vN-T%Lnuck#yX%ddzR`rFQ+@C4wXzHNo7I%o<9RNq z$h3S1gSfv~pI3T#$9a>RgK+F>w94VPgYfNWW9{=Av|F@xD85WW-La{L#JoB#($w?1 z(08x6NHg5kbK@8KX0{=gTz{2A6auOFtiseQk>4O!S9dW?XWN}cg&YDKge~j z7j!F z!iY+8YFPEZk4JV|y}KU9Rc{XM3Dpe6eVTu@O{*@RKR5!Hs%~N5KCqPB6%@!n4tad9 zQWkC*hofyb1REcYz^1D=_>%iZK(&i>NzGk=q<*B-?Wl+XAMsTWsb`_}d;EW>=Ol0{+*CB>Q0VXlvLCKTqy zQXyfrLU9Jp8=~hEU60uL;E`A>4O~aZIv$|i(K|7FamW=4w2UNM-u#RF-C1ICF0|{Y z&&icAe`t3Pyr0CTK1qQHQiM^4&TYok5mw_Sy9#{T&FJ3M%C&I)xPuAEj>D(wYxr)-lW z4ML}xxDNSlR&d90z69&Kzcce4_#)HX0#cdth(H zt4Q?Yx0T+m--&tFx3;N-$R+iHzLi5Q2l7_u+$cYog?y{5?O`o{zwqR-2KNx0D__|( zUv&r?1V8x)VScSfg!3Br`IzUl<;<$d_nf4i#cB5{pK_8utlF1*O@9QWiXKngah_@a zWdvUSKKBU&&ONVBllsH}ojjVYKjzzud=sAz>t=sER&wpnk-~VumQQ?p!m!^A-$mB! zLc40)=BDpXVN6i&IN;QQydys!rZ=VJ67Q$w@>WL{y~p@=N|8+@`YA^awJI2zBd^)- zxpfnI$lLtBt#1JHjBRQ+Z`@Q*+<(djldC5G!*8h6%+^7i4r~9iTh1xzE@^jSz{~k> zY{&6j>6F5=VNU)4=Jnk=Ir3=$oF}&>3mf!+P1-lb-QvXO^`+2dCfz`W{rPKhYIG@( zw3jx~q0EHUu1g=NBY%1B#oKB5sMjnZ7dO8Mbm?ZA=)We|OPjd=S?fFEsqn5UrW*`(75VP&=!W^PH2vpj(xG7W zB2U9J$mitv;Zjt`2ncWOF6@{dfup-EC+^K1hG0LPsEO4x^9LmuTcJgk4pzI0Oonuk zN1M5I_Y=&YbiS#n)G4II{k1&j9l7vAz#c zxyqpWs2cKb)vRj}C`CQ%68Y$PPc?){YfY!!pB@q-eRu4Ba$?muoRDGOvPd6?-(K%- z9gCSuntZHk*yuf%Bq;WtS3g9I)ZB#Iu_&P8*i2INeZZ`wmp@){_pkuwmaC7hq@XG64Q}mfpl0k zu_xX^lm<7d{uq=YzZp?`Sg+q}kzaSj9_I;m;L%|7_BM8$ak}2 zbIqDDbp{Np&&{t!oTIn9KBRwS|NXxOl5EV8&+<{7MW}ZK`{T(vJWmvx&T1Z7)v<3ymFJ00LF6Nh0^yl{Sx`_>A~@Cq|n->_NQ3+SPZK)dnFi zU!l#tb0MQ(|7YiN?$lA(Fm=l0=2RafX6Vgc@?)mG!rH$3t3S-nu|?g+4GxW0&>mvF z&Tg4$HqUYl^-V{vJ%7&W(G842DV~^LLL`Iu;Igqr!X$-ok(A6=9HiDzvv>D=IY>A1 z5^V~8$dHl~9Qlrx$&mEJ4!+_WmLSQsSWIn}o`U`)1gldb*C{c6FM(`Q!yK;GS+ z;gP6p)Cp)0<$ZK<7$i8JyjpM<@h)dLiaqvWK8>&mKbHw{|2@br^!SAP6shHPY8dymUY*Z%6yqu(6$eUA74|};{2686`@JAPrgI_Ya4*CNn2es=F>}8usMeKE zMqJphL)UJMJfwoHe)KWAQXhyuUdHb|vAx#9e7(xEpd0Gj z80m)R@V_O;&J(yE^hD;l_BPO9v*VUs2dYOP<4$&#Ue^flU43}@Eb0g>kkpH?elT-< zt43?zwxj=#Yrt-#3jKc>6FDb-YcW7_pU}cdYxeDp#mn+!z$Caf(SceE4FpMfaHgw}<4K6QyW zavpI>QG;jPL@;lkFL=|>0`!wy&Q3TLG|mKXq3Y)xWa4ir*wI2@6DP_OESnFqo zq)VA%p4Q5kcg~+*BmeG#t!^(dFYG~D>-)(&#O-0N?{*y=GQ&9S{4cLg1MEKHCT5K?TvwXUdwtgzSCjuRg@D(0h`~F z0UIB)-+#}QehJ%P-r@S?_WA<&-qg|i@1Ixn0R6?15S#lwaQjww)I;QL8h3oM_3-}? z|MB=b;1g>=2h$qGCS7|v+%%5mN{` zqqx1D0&5Sd9_Yq(Jm90bcRFzbaoQq(QcETvbwIwhY|{`_^we%Kbep+fiB!KCWnz4* z_EF8|-8po48j#hu9Q_d%KL=kv31q+jq-m4;+f`BDiSf$H8Fl@Hedk?~c+&$)Pbksp zvBc*|*8bQcIz4PvkNG2eo;MiuV1DgRj)AwRTkE!c&s(Tq-(I6J+`^lWQb4(CK2LK3 z^2}3A>V<}wu=~%lKkC1jkh;G?u?BJNV{hcw*zyp6KOCApjX!H3FJ{8#WAbQMrmt-F z`@v6vvucg)FL1rEz7J73CV!Rk$~Sa)?L%&BqobaZ?)zD%Tl>Mw=ttt0-hMcBX8W4Y zYF!|RT)FgT`Tl z`p^9E$$ky_E{J-DD@9EBRoU;q9iA>drQKAheLIJCa0%j@0@WmEWB$G>mtvnGKh;$~an7@mh!<}B)cf`9%=x$YV8Y_a`4ouWc-p-h`)gB_ zkF&yF^k?^-qdvXB{{C`}@7JIT@_=sV|K0s(1Lj>ObQWDf{P+o%y!Pjf?AOPrHgMjC z_(UIX!%r(kx?%Eg*~1GVLl9nb_3c#R5NMCOtX++Ky1lQr=0tT6+e5$3w&&0hr{d%s zxb_cH$a`lv|hbB%%dTy@0l z?2z|5ae4A+!~j@MS{{9uJ^)utXj5wN7iiEbl@}%wi!w^ zW{ILMcJx;6730WveZVZ^gkcZJ@3JWNk|BOypO3B52hk4QdX4Y)k{Sw3-0^?r#@h#% zZXBST?(GHp;;NvS<-M>qPGH|bshRr|>-%P>E|AZ|_+|a{j~@kAs2~4n;Gwtz1-6}L zP8V!ufBr?U8u1Op{fgeYnf#lJ0sN0QUKl(;hTqPgPs&C9#d=#9xTR`484ivQiq>Bz zL!M-J(4NIiNM5xfB?9B#`yXr=tT*e1b>ZI(^#2FGjEv=j?|1l9;AOP=asSi=i^2PA$e`4Ds^&N5ceC5RKh8IU3^9-C*L)yM}U-5$d`fKt;8lEB_l&)p(_Xdo2 z(-`riX|{;>;otW-*O&>1n>M<1b>V)|E#|)#;}}HmFO#Dm)}%ZP453ZB?T*8s_48+r z2IlXNE$gbP$m|3CiZf@f<#3Z6^asN4-QXtuDx6L>HQ^#H5H%J*sLDlRtv~jXx#N8q z#0imOz8NA8nDsilWkD6^CnM-@F%4jPCZ%w(r z&D_6iM1LulIuC($;(})}VMCzfcHj8-1RdA0UY@r-1CCj5R5f|PMG~11NR+z4MdJM? zpc_^^4nVm_@5pcB4*scC; zHfj9VxU3k52&vg>0a&aTAWaC4zV(n6m@ytxeu3l_n`vOYhkPsTAnMN)KC*DZyg~g> z-xFNVvcI3cnNPpw7vBXU_VML(#BpWwuA82fPX$MpIbF|?hwhWrrBwx`n8!4?=J3z< zVYoH=_LH&CAiVzF_1pW_On%Xeaoc!pSpVpH?*Aj6$K6}p_e`1&F7mlf#u~))i?zR4%YO0M zr$*%&;7q-B^xAp`2!Efi%k^Kq3#21AY-7KEelvB=%f6_Spk#kt;V}auF8sK&DSHrJ z=vC4t%Ll>1NWvyW67w9zKCgNf@XZ?tDG`Geuet^*};|0;-tx8r=@Ol1W8A2Y_}gV5F|O9iuhhb zzj)-;;}UBP@xPqiOXan_aKuEpKn(3>A?xYPc@?PRmYTlM9(5I1+rwH8*0}x31J~7t z*wd{Ru87ZOFwXm|#r!(o_^xkw{$;(NsBHIR)~Wrycs}ECORqxRRM$|MfJDkD=F`n> z1)ebwJ!SHIG4cSDR$NGlPnvmtX05+{&f1lhd}AQ}CoV*5!x#*$Uc$`~?uWwWz$1TZ z`(Rm}-a6@7d?f18mJb!bc}csz*2pYUokjAxxNYSRk(qisPnSA!Y@tvfa&mfhA^JDM zG`M8TW5|&6q~ph@x9rcCD4+A(6x0trrfu@@72-B7{hVW{s@o5zYg8`2Slkcur{}J2 z_h7)EL+T`r7^!O@I#axr07d3;JRI4&8=!fqqyn@4rAXjsdY! zI}?_c6W14KCB$uP$bik0YFk7-8E|CTZOY?4gRsW-dciNRL8!1gqI(u~Z5*7mzbr{7 z-VY>IlX8yBqg}<}KYxuG4T2Ku@<(>}!93%&A3ZR>ctWCMq8sy!b(QyXXJQVfT3GY?3- zhkD?=&&+}%Q2)qU^=Ccey?(v?{Y9pQxP5(!Ubj`_x}kAobFCeola#i6`xU>H0o$ZP zG-OW^|DN@IeV)Gb^*l|1!J&6!b;+2o5g$34dzT46!i^0i@%!}nI8Rh6;&rUQ4PLMP zANXAI)b2h|s3(KTK+||D;-#9Rk9wsde}t(?Q__ zcV8p=BQ483=-XnDzpW=uQZcm`Zt8OVc8}_X?+3@dnV2sz_o%4u4dg>)eLvQ+=6rX# zy?QPL4Jeq0tSRMD#o7wMwSULRrelMFIv!!e?4pageL9E#L$oSiKiv&3EHVib2;y9yoUO<>zO@iFWBF&mX7{8WK~QC zqyFoiYtb%U)OC@O@TUj9D|p$Nzv}_32(INfP*22A)cbw_^4PPshqcUAt0;R6^H$|I zkzpOJjG$NkA%xq;Op#OmA`9#-6bPAN^ooMh--O5(u zEOGx3)kkV>_<9gf56xn1WE}a`+e=R--$Z<3l;XiF{VD8^@3E{^oK6#nW1UrKwpJH; z;&isg>wiZ4ZC&|SS`~T$U%%cjkF3mQN(U zu8so3Rzb>lm=v&N7`^FxhJ48PW1lW!u-`t-rp6>0)Q43!R?M14-gTn>A-c}Isw8tL z6z!Mk>IQwxcPZGcAnCUX;~)EXYi}}TzkN~O6sdtnJ#eh))*4gHvp87ff8*;DQ%Bt>&m<7U?X@=3c>9O6v7|73iOj-*3Jz*YAw9`raKXn7i#21@y*aMVItYz}t?;H|29LOoTlRDSU-~mS>*V z?;-qBYQriZwpE$b*!67T+fe{qW7 zQ7;c4WC1$5*?CVD>6^-z-8S;jXCcxYHD?;c=(KW44}4A1f-^nS!KE&Ry)OB{I$ zb+$5g#iPD!g=kBFk4?$nDpzLxd;dLdO}7q0KQ7mevkr-0{(XF3cBbd0VZJKY z_9}0?Sp{qw`uc4_;2BfrHCt-b(^+g!MCHMIUV@%RW^n|+I-BVXUflQ7Afe`#|H45%AYN+&P#x54&Cw;T}>P}|xk@(1E6=E0o zNE<)f3Dr6BkyzX3^z_}%1$aJd>wDSE^@0IropH9=h*NwWpTISZ_CD+VL}l~l>gC$u z3=o>Q7)g1E`4yfgD;3n}ploj;--LP7M89Xfp5nbdrB9y<*F!nvKD?#E^D~`irdLb> zDKIT$=>gQUO(=A=Ufu;7rRTZBkpI+8t<8fu!A}x$?{i$(!B5(rK$}?P#zAV=;o9>q zh=UaLJmQzEFakp4;aN_myEZutI`6shp z%z!%?`BzVf?-G22`4z<%>XmT6(Q$6(;Q5R1iTqY|&!aYok7WeL3a;vgHy!k+Z9}MM zCJ?aL6!Rol`-iA3WU;vUIOeZ5%nu0OZqELAvey4`UY5(^LFC_P`r@us)&*WSwpZ0` z9fH*Rb4-^bzADUc@Z(L+UWmvN-9Pt#;G?+yVbRMlv{S+yw0VVdx**!<$|x22$O~N_ ziAdid?tj+yxqs2x`O}jMo!o-K+wb9bDWl z7fxlCpUpR=P~qf zh~MS3kKG|_M~4@mMQ0UaoNE`457nxH{qb;R`b;PwE-ZR(UW*{|rLntSS?>?d7C-g{ z@s|$Eue8RmL;sqV0k24559F^XRd%`41MZd;Axks5;L|f_*DXQB>#c>u;fIw08Av}5 z_NXEbZZo&^c^f&@^;&Jp?40U?&uS#!njN@LJbx>cc!Bu+6;8NpY?NfcvN=PS7HTlS zz^o?CL>tFNxkz2%FXDqv3Uyq!XM(8j6VJh?Y-B@PS4Igcf z8J$IZP%iDMNbFWBsCAhy2=QQlzjD)%^ogybgX6ESpYsv-k@VBltXmWL$nwH_E+XER zbv_W4)5mKL%r{27yv|nj#90&lp7lCc%C92d1>K;#ZW&iU z&W~UBIFw)=4RXgV#3cSA|DaZ(RJjg+m(bPUw%P~dVxA<%1$Qzi7gcJ1yutqazWH^r z?gXxnmd^A71N6(Lim3Q6{LV>wnHyAf7W2&=?kn?^EE)!>2Wb`8PYy$+XqW9-Cs7iQ z*b%wImqkgb+WU7)D+`b|OL}mu;t(L^#_jVRM*M=ktoF(qkr;ousXS4I{%9T202lKP z6%Gw8$XvW{0%8vA-2ORW0{p%QeYHf~NIn;5Rnw!H`1^Q00bK#~-|phqH4H|(*;(L^ z?VW8@IOl(RYV0KY<57ES;nnkdP_Nrzx!%dM?Ejv1eESykJ9}b$Iyb<2nDY+uJ#ZKK z(a;`DVai6lawlH@to3o!nqKJrL4}P^#pL;Vk(V})_r@dkXXz%^L2H?d6z8e*~e25eNRc-Rnx{r8#C~~s9yby=!`MbSX zAMwBrGTgZyYX?9guP^049U+}Zlkq-swB zpOA_9y62?zcZ&W+zHZsNm2xjJ?sSFR7-Oozg!p%sZ~n-RLYAO3r_t(B$T)a&{R!mX zDA!tTwRG-GerDGB{4U?`;-YKFAJ*gJq>K4e4;X=K<$fy0qzGEcYk@glX(1y>XSHNwX+oM z`(5XG-7lbyz*n`c620M6kWgLcF8G-J`iH7C&M8(hAmO9j&%T`;v z!HVz7k=)LxzjOaZro&&Xw|#22lTy!Mo&u*}HxuI@v&uT9sijPqH&w8%0dY^>(p~C` zzR3Tr+OTge>S+>>$0N(N=#O|p4ZT*H)D3Ar=r(fUJfuy3*6z06&qMO)od^mP8UX&1 z>lOWb2SE2|tXrJ41W8qE%V$|t36lI=3&rt3ev;!^dy4#Sev+A{&65B0Ml(AE1D&5S zV71hC`F`~8S}r=({1LyO-mx3gtwo0*J7r+|29+T&X)XHVsM8M~t9&LL=gnL%B|93N zit{KyS8g+U^##wZdOsXB>`=Femn%ffm;Lb_d*c%LF^2-4&y5#L+~y$de{m z7aZFB7y7?3ZTseWAwQg0>@Ck~vg8vy_Fq!-Vbk__7&Mjf$8xH{~;?f?Do*H-FTe+ z{pGHSf6?3l#0j+LE?X-~gCBRf?W^0#kf?6*C0ddF_T}$Q*x|m1f%y}wt_YuJz?J5m z(hAFI&@e&T;BLYGegz&eDReg~?7o=Q?0yM(X&sIyS$a@F;q2&6!Q1S&??U0h0usi1 zJU+;gPJE<7nsxJqs~Eo>scEgfv6ubvy-6*%*!OIKn z@VA0OD-FrO?Y+}T(SiN(4bILDj>hkG8U2?3MKTq5&XBsS!>}F$hq)X7!aqb_YM31^ z(gjY+xdIxP&puJ7Wv2Fp0e3#l%_Bjwk;8eJ%TwcudQYXWd$1X?_RdU#bL3t|Bj-U3~RD65@Y|`iu2? z!OzX)%BF7cJ~%kcjk+AXBL~JVXyQ3@aP$1b|3m%=Yke|VD^BU+{<5Eg^N~KTw;u`->a@R~0)1#d}R&lI6E# zxi!+fB>mkL0a=Nhq<2MYXKMz{)U(#PS6AyI)dl74>$)CkcY%8IoIl?#(xC6g{%&97 zfna?;Q8~*nt8TRj@^0v?uyk8Pg|UkbMyKR^p{Kj_eEMuW2d}<2czibv9Jz$9Q!WtK zuj%=WlA6{H5#3+hz98Q34)e?QjwME~l62}*4FEkyZ`Dj3M&u(>4B%ZHC?Pc1k z37+Plf@j;SYn$h>zdy0oKPGl4%h+#U`XKYM$YDBUX?rp_E@Pf;q{HH#A}T~#xrhF4W4}KQmK20v(PBU|M@#g; z76v>F)-(|^ME_1mOHZXM`}5o4YJg<|;;FmN8U8vxn*z^d8)fe6kwNURTm2{GX=NQh zqO#t~i%<2@kJu|Dd4B|XwTSK~x}JUh>A5js%onQ3e5Im{y4HU-^NTFNd}{9U&@K!1 z>mN$juGov?@viZ*u+}X)F#L8{eS6Xm-XC{VBqa1hL&|*j>MdO`Z}mMV<{9Gs<%czQ zTNv_)h{afPxgcNSGP##=4XFQQU;D?=T8{nkrN7udsBeeB!mkWOTy-$M=&JAynuIS@j|!o49`W@GBSjTM@si&~iW<{SOzi=d|aUGU0Bb_`(!j zCRlU{?WiI#fP7?U3Eu(Y^9adsj?DJwG|-xmG}u#11Ad{66Hot8p!?8*>Tm(#_OOn3 zE_YD!4#ZX59raQ>h`d))K7+B=731)wyS&Nk&p6yRE$WS6^h4jW_e(FKABOe!tYxlM z&Hned(&6l#B9GjosB0K7;(Qu$d-a_U&!5FSGxaU2CNBsN!SnNfj*iL>LC~eNqFu~E z7(4di*w@LKc;HHPm#&yZjPH+GEL@4WOxEYITVD3zt<6XD+n7%{^fK@KdwuyjLPz%= zBEyfI()`9WGE{{~b3JkGftytck`bt%>R_^Xc{~Rl3XeEDaV#O;5BW1(cngbA58{P> zO>Wb_w{K`7yw)1^W$z^)ZJZ@Y{CuMRJhfwsEjJDG*QYdjoRulC^iKJy19(1fqqRS- z%4dJSI&ASImh)&2L?zM!O3hK<&b1*%(hSe*MWT-3M~K%yYkNP&nLfE1Nr5y+m!2B* zv#BrOzHN1n48^ORg~o87Wxb!MJS^NCVDts`VD&;nR4~8oqp41l{|D4v6r79_?_z&^ znl2eAx_O~LsPn8|#|@mc@W~jWwTDMsZy53+nR+hmQ~1~o zQ%c*N+>$WQ-SjnM4%)>;{mP>AN}^o+Yo3x`T0lqTjP# zA1RG!yW&WNk~4e1gkXK7c@_rmRwG}zRH3T);yz$1Qn}P7x5YI~Vey|XXe-EDAOEfkmdaG0v=Cr`y_~B3 z+!e&%3)c3{<5<;x%@q08+c!S8cP8#{*59+1qaGcZbLKh?BwJ`niDjrC@NgxNtZCiwbx78*F~1u`hK5^bw+umO0O;)L9|AGo z+!I?)F(D^7-Sgva;`)Am$hv`_47AJl&a{^BD$6CBTR?uQ_+H^s>JPKeg9O;3cE=+1}N0*PD=}7KznSp zs+j}Em0i{TWc|hYRqvUJM>XcH@@Hs?SD@c>*4@&po8Rz}_^Fd7K3DljrgBB%y$utP zo!PUt6Lrv*>L`79N|Pkz9NzPOEsqq*r8%VJCWw)^qbyfS+li5eRjjrLqTki2b4RJk zhku{X(IO*$Cmy37*6H7lN05i8Pi}fJ){g>;9Iihu*5El}@WPsRsNa-sl{Kd#7wt1X z^OBgHey}5bIFj>z=K5ta`^v)VDWLMYqj6pz1vW}2t$K}q@nh2kxgRkO!rI?N<+~N@ z^}>dwfrz9b@2b zm9w=6C>=otUAQisS6_@#swbY0NlyiN8fci0-RP5j2zeiZ&s%Ohv$h{{UOg@^T!#9W zp2-T!@H>3L>1?P6#xsc8_iSWBChal}ZgOPKQcd~y_wA;Z9yhV?h0q``MzMA;1ocyQ z+4wV|@w0d5$WA73wSCs|7MX%;4MydsS5JZ4u5a3IN|Vs&ca477a;CoD5AEHRF%3BX zet$Cm-cN_7hrW*{p3@=wzTolr|DnHF-+xu$n^sGlZ)u?u4`(A!=5MDr+R8R$*pYl? zpUGeNi&w^d2oBtU>uvTJBkC{sg<0EIsiSeYkb(R(iEp-S{oDo3inf^#jHvL3^X4o! z^y{vsUD3Ehn`(Yd6vV_+powmF^02*DA3Ve@I zpJh$t(uZjOm2-OUsh67h{qX3_D$*IGgYA)_qCFU2?Q*@7Q*xRLd2X(@CNHTFQC^V! zVA&81+C;Bm8V*55RFv+E7X#3>p1gZb-Aw<)T)Ec3Pf-k5Zl)%9GM51ZanH7p5QlF} zpG#`Na}sO+5S3|7D|+VIP(W+tSMJJS3OH?w%3O)|i}3uSLO!%#jI@9AsGaWtTbIY@ zxowI4#Zh;{ir%*&U-3P<-Q&@JAKxnKxJveVI;7JxoFy@TA!E+{lQpRKX>)gMVwNKD zdSHEj;YEz;NPRs2j{GiDK%Txwv$PF^FOnf_G~sP%F8lL&VX)1;Mk)oIcf6DqL_QSO z=doK(eJ!spmraJ=^tnS}$d6`v?j?7|${y$l|Fr!a>im#QAhyAWFVlaR9inaJzhJ`l?>ksUnM2Wh*>p6Z$cqlEnsFU$PlI}DpegteEv8-}OLLoR(Q6e69y z?qzzYQ;4+fMc^Sh4Sv$juQO6uRTFDa6Ou|0tm@WPf~;?xbCBy4VAWMrBS{(Erux z?L20V`+$krkX`vt3Vf>Kn-rn=xFVhx`=m&cBowo(j$A@9cZi*JzBmDRzI)djI>bH*-t&Q{mm0 zfEU%i?Ds!wed5WUgXCP)O%W_Vw*_%EyE+2|x1#Q#dS*pQ;$rsSH~HjVCq1;QLZ!{b z9^<%f-1(c*fpJmefOCnQf6;%=*X~VU3!}q`{_L+K59lDMVRC<~6Y`mq2TOm&{gw57 zh{^$3ca|tz!u*tU<9qZ(8U*%qHp-yg(zxt+b-6VA^?3x+I-E^#AN9JK-1ZmoEY|kk z{vM~##P_7MT#^-Np+oDX@;^h#12EAYwRr?}%=GJwWL3F)K_NN!;{b!$9@@llWIOF@ zH>j=YnDrQW0E5*kroTQ#9;Xv4XBjlIKOe6dURonDLWbsv_V$+>keBP+c1Iu7L+35n z|79`qwMh1Oe2r-O&kwLwFmIB0e!h8klI!c%ZfNWB%qv;h4G%4MUu(nmB?&0L6#0wx z8LOWc?F?qXBKgXYr-<)-d56Q7vv&Ygb|w{A^9{l}kBs7HH9e5InjU9$k9a?b9%zf) zdlYdw-JR!BEm2ov+-Hc1-@9mudT)t6?C+-vAHpx=2M*HI7PiD8-aJ6DeXkgrg8EgL#l_TQk*|c!dz@ve|k^EhdTguk&-QU+Y&g;Y=F8|C($j9Mc~P zSK5j3nFAY(cfCZMdSc_jx1nQjGV!%ud&U@Ot@CqMKukxrs^1Q zYW8)X_e{(iD!cQcK!pl#_l!OLvW2+6Sl@r;tYcQD#+X+td{Dsd9O?%gyft_n@tN7G zw@s7q9HD>JF7r9!&KGT5W!gEbAG$lc2YL?mft{IRQ~&mv{5ij`+Rv{tpn<;F7v%?t zP;1E0J_j7vl`9{lRWoxFO2BNfq&?GM^;OO#Z#TA+vQQ zlgP^@_ja|5PR+m9XM8+kcjgMzr*jyi+{E^kp1GRy4&%T^VFp1=#67b6zK{C?=X;@F ze9Xf1S5pPz7!IylR7XbqS>R9grAqAY|KHW_2Wz4Kt2Ll1+Z_4eFDpuW`i}HKgK|mf z@YfzFnzViYN2LqKxI*e`5qCk<-l;k3OVyF*@cH3eOkLFXOaJ{gZ#nvVhsGX#lNe^d zef|&Z-&OikVXpi8Fx}^fbCOb*4-F#2>Ra0^&*6K^J~H90*6fD>%Z*eWxqj&9{J6_g z0QuOzJT=Jao5>%U^UUa@8?Jw<8yG2}zgc}@v+Fjr|M=e&MOKTj-@cJij-pkwF&}5^ z%gpe=Nzct#L$A&p=m?25eo ztiNY1`-JnR^&_9N{I*ohe1!qvu8lX_+Cc_Si>F0v5O>#B+Fjh&Fpd7jrOFG&@xSnv z@eh_muw=!XtgKTr{o`w=e9UWekl$8NX`?ab8zeCj6W-9t5WeiRe4aY{{Wn|mgt%LN2dniyY<5Je#L{Z>V5FdCzhh5f+igpqJn?4pjqT%VtX~= z*2||?P*jgbpur?NzmY5Pxr3`!9z}LyUX{afGk*S~g<*SFkTB z-(@`&)Mx4Ryt;^aNM+`WXB7>AYV5Xxga(WQGpn!13lD(n5}sSuN;A*w2H}p&ym?`9x*zbag3L%&W*MHSyp>oiL*NiLRIQN>9cj zzR_lDRCB{AIxOESe(x*VgH`i2CEmNUKfm9!oR1IJKzq!GbT`7Bcs>xdZ>5ex{IkPU z*thkjq`+ldzp@-Jj_*SLphYQZXU?4|L)2m}o)-hCBW~kI7d?*gp01IbdXen6SNAE$ zUQ>+QuijPrGU*$1=n-{EUoVR{Q~RMJGDv zT^dI|@s~n2B8!Nh$Mx;oqf+EA;qw|c>cx7GD@0TB9x!1tuG;qg!^iO7}9Q*9p2mjaFm4`#UcX5;@RH{)T60VR^x+KY&khMgXvQ@a^ zQKU$vD{pBcYYej9*VTQsxUyB2o>q|-S+a~m6lRPWjA0C-_uS`s{~CY%@;vYScjmV| z-|z3cobx^Bd_HGUUN$|#atz{?xu5$n9=`hd;$U~3`Sy?C_?lPZv*c7GsRYcw z{Iy~8(heTtX9jdGZ9sh@ct4RG-YdSjUXcYdq}Vi_T`UkIrD>8xm;jY7!45y6e+1ue z;1das$V=m7sPW@|2*%0%goLcZuzpd_oQMME*$CcGByW@oDN46xfQRN9=jWG@7nmQC zxF7AR!slws_kP6lxwDGzMLd^RiC3F1{Ruu98_ymuksl*4dZby={M`tQzi8;(-iP&Q zzOpv8&thE-x0$w6k{qZVnNzDACAQaYMI8}Seu4bEU;EFuej=X#ME!NU7o{)99D>zh zS@sWqVF4qOW?yrQ31?o%{0Qo2!kAM$;kZk zFNt3`Anl2KN{TkR_K0uUelhd6SJqSDB;iUqjsBnJe2ZB#KQ6@YQFbk`nIFFsY_FC@ zVEI|h%W*q@(As1O^K-tLhe{xRBWs)Ot2)dZ61<;Cwy3C_aFJ&~bEA}T9gg#n-rcd= z&_C&@-4z^!{zXqk~7j-u+W(m&Xpa>z82OH~X}= z=F^ge&%Y|)Y-uvqZ%I6w8bNx2^>uuBgVdcYxU9D4o)*?`BkG^vbpvvyiauu;dguq2 zM|~KEn8@!K#a8(d2(fCM$U?Hz@OJh$u`3J zHg6`hX&S`qqpl}Bo`L7dw3ZAnDK75I7C+uuVxIPr?o!n$^ydhEA0oMa#(%|&+$qTX za)1}pHU%o5DBEf1SEmJ?xPSc-@X?7S#Ic!O>U5@jSs6B$$2cj#Q>qoed=&z7hKpKaS z=5Fg!hZ$gYLnI~YAlh$c`p4QxLgbvy%(mY*3XzZfB|H!pJPFxRHybn3kxyIT_wMSy zAbb%6t_;}cX<H&6({$u&7MR`9lu<@pW>L!hZM;W(sLp+veY=eh>ypUcC#xqRElti>``i5X zRY+PXtwMd?apUauHRiXiLf$KHmi2ubkh%Eb1)_nho8lOyqGt zUwf0|UN!*_5^s~z-(g*>YWwoVXF0H|SamMno!H(myQULCK^~xSOZAp;F5-V_No7=A z&o!O9Nlr5hZ|||Y^fHYL=oi=Pp1V=WhOUOffR4k6zp73MiOa@w?1<_0;7~p+Y6_EG zlE#NQaso-dXA<6X6&;`am_PsWgk@e&wlX0+zPH^#VhENNes0ZKGY-4_6Zmmk#^K7r zS2-D>Sl{bje87dH#QoLPyw1+KI0Dvc7mQu?MqrxVmE@8-438T!%gC6&>P<^>H_XI3 zG>@WHc0ZX0yQ>O*pH-%zF-5M3zIS@w_@AfEyx*ISd6(HILkE;>7Ovl} ztldhfRYbeOvHD0T^7^!o`aihoGzOotjc+NNjzOfld2JW^?`4MiwWvSgzi%mWk3Zao z`nz*&@QSh#xVFxeDQY$h6P|vno7XQ~zvZzfMN{{UL!EJ|e0InUR@A>25m%Gw#4E2uDAYasw$$&A{ zK|hgA9LSyFHk;sns%vHP@-6bwndMFu#`zQL%m0W=aP5%CQZtqAru%=$e`(zAy3qvj zJ#$awer=H+f?~s@-~Epd!l=B>fjfv(6I|~^@)w5HIYq?rto$Tq9*cH@^z*-a4p`D5 zpnHX#p69~nOWpo5)w77}uq$VLI)wh5N^Z)GwF~M?CNH=Kaacs{5xl-8n|`eYdH)*i zR=g`tXFR15sB44zzO8ZuW^@$r+a{fdfPQmsF$_GCf zZ0(<5LGCVfYXf06h*9_^>sncmUmd6w(?dKz1mEYp$)_-ujPq9BWlIA3n*wjs!s-LY zk-vV^rKzjqFym`25pse9=^gib2Wo5KUpzwl*Q&boNbn1m`%L30cClb6OS?PHfG~VW4*&1sIaIx!7=54PFeol`0-KL(OSY+_zC{HZ%=OO^dT== z`z9IxFX;dO>Nl)-7x7_+t_LKKVx8lS>w7cp*E3#3>B5uDlg9(XV;(-2{X*688YsCriA>ReWXJs zE~AKxRSVH5rg6bJuRxBMJqC9+l!7{CzQ5_PIzQP1{SXH7j~+y$eoOht%;GuFL2sY4 zyWP2kuiqzB-%9Ea4wM#cF|6p}ztLZz0c&HWf`$KIi~r|8 ze^?$QT<^oeU+w+bMt5*<(IZ}iFux4%JD+FtXs=Ldfr@Hn&x9a6EkS zmiGZ1!|f|nd@~Yfj0dj2dz2QG@Gu+q_(GOC4hCB0EiTzJUSA(3G|I`11j`$C9Nl0@ zf{wQ*SdLNfpffrC>wX)a;r3D0J6^weN`UW44(mI^2oU{^>Z9W3$%Ke=rG|RX4n!luv?>X`rC?@d@||IvI7*6RX-Q ze4LE)3>t%9wu7Opug2i}laJ*r3MAk#i7OQyBtpyGGOc#Czo2-Z$#1~=FSz<+ev8%4 z0yp%_YYxq>s;{1~J$Y%E0H-O`qMJ-{pSZ149M^zIZNc#7BZ}J zNX&mUfP*!i&OR~~jIR&pVB+~poCNqvT1@{={_p*LUFWQSorvnuW%nIx#ls!#Yj60g z@Q@wY6vK0u@%jTVhO@FM5a3HxU*c9i0xZgXt8E#=!rm(fUQ-GfpWkL}FLR7M9-gTr zB-YK~K%(osS@97nXva@CRGgqf!7(}Q1NTYrNd-GA9!^>%Z?y9(gPTm<%Zvjf(a5tq z_u_zK-09{1QY`2g-8-R?$awo$u57^ze!|0v*}}aCpW$JK9C-PSG7k9Dq|JD3|6zVx zEuXlEli;v%xTl`I0JZWLqRaDnmu(aK+4LuW?hFA|8pr`kx? zkf1)TYq9Mw4yJbf(X;GgyuZp0{>x0Ycvv6EQ^l0e_A+CFP*r5PVo}9tM zZ?#IV+Au0Cm`fG$B~oE5rJC==4+2zUzuBd}pg$fPmKXLJuuOmmX7YTm>;x#+Cr!H8 zV=7yiisyIxm=YmvLWR0VmbmJD+WrbuDexptlEGq0;0$aV z0}=gA?z+aZ^ycJFP1C{_6InsK4o* z6u|@V{-sXNp?bdMf4Cfmg&lRx#nlHHmp{r?igEWa74oHg*jfc9KucbV`9>ZUET1z; z)qSOcXOQ~wgvAwTNy|R8Ak2he9dCP+T(bhQnHkwEq?J|uk8VGbnR9{wVOz?bFW3^G zKgDD>&oU0~_ogWZ^)fDhHFpo{N;r_ zSpp7Xo?$CXTX8TpAwJUk9SdxHpZD%~%=q~ECDyo)*b$+dB5heMM+B=+--T<2Cm}nC zY1ZfOBp9#?wC>`efY40+qK*t@)p*g$3+CyMTrD{~JYG7tvz7C|uQ#Q}xJ!MZSeTv+ z`o7K-3pjJ$W}N>xY)R4J+?6yA*;;qiF(xF~JlldL%h9(tPUISLhil*=eq2(lWj!8p zE`_si*^YyN6IsJI|KYr~J!psUsZks}FlUi{T80Bd-O!n3lhQB`YNPxh$wp$ zY0F803+$V_rM8km&vUF?k(0i?aK9+|EW14!%G}OL{n|u^8S$UW-S4O2&EBrO^dHj@ zx7jdox|{-hTV6{Jx6_xGMfZkiax@N%UA8yX+Tmb3vHDrE8U@;wdWWol0;=5ah!>Fk zd+%n#54~IT$HO&asC%#Y1PqaLcO2E406}j|%JChG@a~Rg#e3UD_?x~>Z@PXGN_=?+ z#r{mvm1kv*T@UN=I9OVV&E!JsEpi=?a90NwwjLV4uX>;H_2%w%%y2S}494A&>?1bF zPRs1szE5=q`u$v8*-U1@J+S57sVh`4JFz{>Du=%Pclpc3bqQW$VC50&S8#C*x(vXV zxt<7FeKSYz=Fr#gwCnes^yKtMv@RYoDOnpWF|MCz>kDYM3p2Mz`y|^lval}w`J;WG zw#>CH7oTK9g6+oF_w(&QxI}`1nvo6>Mw1iYVZ|BmZvpE` z30{b`^&@~@!!-wCgiCN+4@7LSV7$G$4PrbgvpBHXB&s6$>%Y(Ms3Ik`7TNP1DK{sN zj1%C6uvKA;DFN6dJJZ)G(YJqS=hwn0&+A1r2{zm!=9hbrpzNwsK(+u5+&3=S#xya$ z-cIEfH8WqCgk6I59Ki@*$riC@>E1U1RX>jX`gv*sa4UPVKU`$STp0g)@914-j18~) zis4Ttj9q|4#4v>kL)*T`$_hUYtByf~p{T-h>oFkNc{rTgL53~O@7tt==<83~`W|t; zk8$UtK-Yq0DTgWrFq%UFGqxn4R7+eLxt*?TI1m6fk)(5mnh&Zr>cMaHU;M7o4@ZeCW9(ds+pcF z{q`Cf^Y_@H{XAb=?y@wJ8!qC{kJ18ExF={0avQ0zC**8yG?f77u}kZNKGUCX#gq-R zak&KGs?hb?n@s=rwBtov4$FTLS<*WLn_kx+;N+QwGnv+xs5mmj@5}Eo**^w1>M!5b z*~f}uV!OXm;>3z6-#%;AUcUsf`y}sQn_5~meka!CV^7v#VZ#|F=Z7&^sN~U?j=+t< zVq{F|0LM6pHSMkBDZs3$_b93_2nca9O*w#_nfzHvjxQdl7Z7P(S3o`FD zr^5UtyWeT&h|qQU-L5zX`ua=aT?=2Cc>ErGON)h9Au|1E0$X_zMe}A z3W5@Q#$dDUr7G3MF-Y{e(Uu`XhKjwKi}$JY?G@Vj_?>=FVrb74Z2t8%_=MjSq#kz- z-s(jGHkNR)H>ng5P=8fjo63you-n4xp3jU)?f!N2)c7)(d>UqcAhp^a@4S7(t#=IB zyDZmU%y%;0Kic+ved}WJWIrCtU1wz6x8cEYqZd<^4h}9)?~%-#Wn8~#9o*?teHaHP zzq*@@BRp5Tm$`Gp2o`uaOL9)UWV}8f-h{G~QaIQc7w;q4hy|y0){Z7e$Dx+%2q$yo zIM^sWePvyYhp@t$ik{2#&`~+*$m*YzpSD`#Ow|Pr)d4mok3@JI3@5rGEMrJ4P$nPl-Is zis9Hedb&%54MRJAggZ97vFGrxQd@g?${G(5^Cv4(W2w*>t9Q;kjS3MN0qZJ?h~T*t z*s6PpzJ9?Sx4*D#iHB;B*e4&Q@W5=rOp2PO!f>fH(@t*WkGL;9^iFXcjyc9;iQCe* zUv@<)NtdDX^j}vu|M8;)D0rqp$+0GYYNC}+2r#by1G07s3n>sm;*y%rH69`mDi-(f zMB-u0B+23GVaDap=RsJc{1_3g#fr*N+lkPY#l(Mxod~&qSPZ@YFy20gJ3>OKE#u&( zYIJarG7j<7bvwqkjzi_^9i4A&=#Lle{5pwNG&6mjgzj$Jk89>8!Rm=`!Z_N0T6(sn z=9%N6q5639UI8XdqI1v8iVPD*-{QwBv4&Z|T%DV8A+GlK2o;&^-O_@C#rntlurC;2 z|FrGmnaqM(3E{%L8{ghyQzjul);ni&lPRRIje_*x3M0rO)iZ0-&bwDjoUi3E)3b# zME(*$j3wo?pcx)g?^xC^C@{X>>auGVdeM0>>_hbcw+`d))AskV;n}Q>RTL2AOn9#H zn*y6>PVEo-L5326Pn^+L$R z<~g2oy-kMZiOWiF&_02urb^#v!NaZ5-Dw8@fFJkh&-JJT5a8gR8PY2|#^r;yzokXR zRzEuk5ESA#Ln!<2^~K$rzu5PM1end9{WE1GxDa6aPU;I5&gU6*ytu`<{bKiUr}6_< zgaW(-}9Ok^SUQbJ_uGI)Nh`* z|Kw`>FFcIbng{vs48}~Io1Ji=7;9JBXGDRMKBFmNjufce)U-y&h6p*z{Lyt=>93En zeGy!uEF?(ISf`>pN`#S=GmiHVuEU<8KeGnm*|g(LuY4~rN4B?n9AabM?<`*&hcBLI zHHY%XppM1<>$z6?`~}+jHKO+EQ;(6Le_O7#umK5Vy4}<;nRxg^9xE?9%lLZnS0$B^ z3h~g42|KTG1MxQO7X99maj@^=OjqY;#{1j0n?;W~gb3f)X4`GiCqnj3v3R>UEMVo6 z@Mrd6!DdfPb#z`Q+?$7*P75}mLjPCjZ#^>)w~iL?W=)v~-8W0J3STCmu*zj1PEjaXp&@|f)^ZS>qf+V-mHr7(*-5L zduBNJu068$%orB*$7*z&D;ZzE{ei+Q91_T{zona3%LWIx9#j23$Wwq{Nw$H17X{wd z$+x}eCjhgJIdx|xef`tL>r!s90S_Sqi|g>no~QUdbBjRu?BcPeoeD@UxP|0;jWQ`P z&<(13MfCCFTZ4VBbuM^NxzU=Mp^pc}xY>$vP8>v;;0DfN7?d6PgSx*=%XoCNRA_g20-tP#EV7`Wf5uPif4FSmCC3Ny|{Dldy_@WuHDRBZe z@%u9^_#+(egYvq&XI9tepsyxt@fGP2q4{?#6-4;G?gjPy1;pR$Jg>g<2;=>&i{szZ zvN!>O>9vpgwoC$bP2q!-Efh#Iy^pK6Me;k}A!HlIgxPKz5m}VPgsDq=V5HNv1SJHM zC#2=ocvJ44!F?@=Pvi2-%0qJs2Y1pwD0tOVp?m3%Wp6jajW_F#m5q-<^+A5kob~k2 z4?LXLH!8Uk!Mo5Q>VOduj5qwaDS`MfH#2l3rJgb_FZUY54?W+2gL0+5u8T;1J7)@H z%lBeo40GyOg(4b17WSN(15|M4Q5~@Jp@R7_>6nx;3P^vuuw9aMwf>rJ6`s3s9mz)# z`;L-BSWpq(U(&Y?;Tm3(p3|1&FnwR?)EcypTe#MoY2>88p9?yrtovbt$|RsbP)?di>dAY`dHZM?DyrtJtoYx1dSBsk4zY@`#w{e`_cN{ zJ68T9Wg1>}Td*(g;Ky_^RdIhk$d9qI5;4r3;J`#GNx1v3=forquD6}~iG}ao$9i0l z-%%s?U2Za3XD^3N8fhCcK7LO>TfO*+@bJDXdpmu0k)Za+Nkw-*97OPZVgF{x`1pw* zYB(<0j04_G`-s3o9Be*l^*cfd{k8W$L5kG|9`?SyXj3jfOW#b_!bPO|of${fg>r)+L)3-TG1doe%Dq{~J+*n)Q zFrWtqR6m~Tw%3gJH(7bT2p;W=+cjZ~$q?Z#GGT+Nh{uqeAV+mdVZ6RU{mobE&k%t! zGkVHoFA?(HHIC?!v2gkGhRThOI3U#?+j)6*3L@I(ww)20hSbELI=+(=5M3*D>onhL z|82M9`+JIr5BK@7gy4QdG6d9JkRC!jm+w+H^*ovA>l51X>)-OL=ZGdcZ^?G+?~Ho8yG%j~I_bkAGr5Hg+85_B`?`MEsJg96@R^xi~28`FO6o ze-3I&1zk@q&cW;3QL+t#Q$PvcaK~|FHJ_&Kn}nSM3mNJyw!0J}yk*x{2M$X~BFx{M z+P@XqnY8_(SKgcP(vf@z@d%4QT@v#r11a_POY@Owu&`mlO)X4={xP}V($N%n_%QCs z%1!$AnsZ9d+{X_@NRCSwJNTFg54wq)!psRE8o1y&`49T4I6LM*R4NW0YnYoo4#vT{ z9?3d(r2jt|pX2%$eIU1@cgTW;3env<*A`@{aFOM85*6`$_HKR7wguU3)}3_^TND>S zXZR@dQ_}@7Wj;RNb9x#&`NaKiA$>?Yo^10qXE*#r{_b10CkCtk`})1dG9QwePk`h) z*+W6s2%ynGviLKN@RK`_`Zj-Oyne^Ib32|qCBgN{n>(t|IcR(E%=JfjEc6POV7vZ- z4=j+#k6}mlMq%w>=fDmkBqZ$o(m$wW$DXHbflrb zX(O_8N$%`#N6BEiM7@!CoB$h)>_cY_8JA~`c6*~tbUx^}7ApOQ&PM_YwY$92DB$C> zL;dIz3S_x)EiN{b;Z{fHjkize9Hd4~?pz8P z2gktc=eA_9V*DoF9k+VUiV5!R2=XB>!*bN@XyS&|_=ZsAEvcHvNRIx9g${I2L)Sh< zDgE3@$XIzG)80D?3Gcie?H{sY=91R`=zPnHVcC#qS)a~=>32^%XZV~2Lo0uUb-ht~ zCRlL09g}ULh6RO7^&0-hV{lT7bz0qX3_klzn8}CX!DzX;Z_@$#@^iE&THo_0!Z*cJ zb`p{Qi1vGomNCCyM)G__JO;jznIBIG&}#g~)`^<{OEw%uS$O*Gq5a<67I*8Lh!@~q zv#g>PkMM^m?INoqRebRX z;egflH{+1rI}f|k zAf@g-;`2v6n`lCKw$PQqi@Z+}kF{XbB`}il_EmQaUU6?Hz?O22Wb0Q1n9kcy7!g46 zO-6g$6iAHkzxv*`#nBmvpZn~K4MhL<{$_VrTDze5t@+4!PAcNTgw8l_R=R;MVfrPbrg5(h{%=X}jPl*xe z@1>=^rD1HC=9JPL(ahEU!J6!L(<-Dt59Kd!|7iK&`+Ei$?$7VV-nQKa7{#T_aPku z^vFtN$%rxD-rQ7cm@zsUa* zzq>5Dmk4XaJ#6C32_Vw%`e!GSBYN-CJ`dmUYHdXn4p?_83S4l-K`LnnBqD!*acooq z@i*h^!)o_1uj5e?+|6KnP@+Nt>88)v;+ZL!+UCbp!#@q=_%!~52v@5)J}aJ6M_*q( zxOF-7#@0oUW!fs=9J~l^p`QaoFV4fzH}{u6+vdTkj9p?jj|Wqu>}kc`#)Bz5a-FrM zgBzn9#qQKQ&5fb$Z%23TkCXK{*kHSDS0cjK13nGev}I#qeP`1OE|~HDdTzSc+>dzm z-I+F@xBkQU)3)!FkM~$^5g9tRlD{-vC&MWj*`Z)$UqzXG5b*0{TwdJ9@oSGDyzY&c zW#!ocGH|_c5==+&DWid1Y`3QwmlqTfP@(+>;eVUmcjBXwJ)Y5f;uealdouXCk{jt+ z#}H9xA^TZy5WVUkergt^+^i&(!>542Ho8~$=IZmpl%2TvvCCsH+I+k}tY8cjWjDMX z|4ass0_DHuGCNV+m)U{Ox=+w~U5V>JS;pBB%+PKrRa53_Lhb-c0(AHn#B;HJzCW78&_iaZSiLfg(`*Ys5De$|`WcOEp3cTAC z;)1Kj;Hkr{){TfaM*BW(S@T9c1oDueZRp+CZ-|F*df%Eru?!sS{-9xHeTwn^mgzM7 z{)z1QZ+8@Rr4b&cxBJ??Qx_?S_cPZYnt|+ImOJ?QAu{ykI~M^L{r0^OP!o)=BEa!} z=}M1>1h~!mbHkf$IB?J|aC-I+e0k>xH`^b`AJA>z!=25H2i0z6PP;ZN;FY3WlaXGa z9UppSo{{Tsj`Wa$Ut#6$=_wS~`MBYgFW(^thE-9z3eI z0yj6oN`huRozu796QRb&Wvb=$9O!6V^iApZ)z{?R^Hxw>UtHo|R)w=4Vnk(~4^)Lz0OIm!Q6 z{5Z;r@%mh6G%P8IUpuSbg&9QtqP6eK&Obr?L(S~7IumySNP9N#X4*?% ze{IYDJ#){rtGw4DIIpZtBKCrW@)af1labi@Pv z`@UTJAMorgSNtYq$IqiU6kqYB!{#xJTOYp;sPPm5?s{Mg(nF ztFNwai6}1T&59s8ciEZAIUI3jeEsUi+&h$~hKI{Xil#O%AfC>`$Dt&h2{^g_CQqdG z1U$HW(r>YW0)_t9CscpYw_hmz`)_+9USt+Wl-l!uu=i;DPiC2xS3ime-q+^C-whZa zFWUNa*A4G;U%^6YntODkF%ERNoJkR0h?l)y+;}Ji#p7@fq?>;y!BEtodEx&c-?w<> zzP?Pu!}s;9-^;`Qd;6+x2>!4_@p($N-Z?i=T+@)3b;=1PDzJYkDVx!uLVb5lrc)1+ zqrdo~@c)62wCm-&cdqt-;k@7e*)iJu%}^TQCQ(5xTDpk0P4iD#`~7q23)8?-Csih2I1M-QT&#kTeDAvOTG~C0 z2nFj{a2bROV z`6xd3?ea0J(CZX<->oU|B8LJy$C-pi5gsw$eW<|dApP}`Y4_<&1LE`7d*4%B$Nk^s z<>c4XXT`+Py8Z0f%#CoE)`N2XtZd^jmiBomQg$4sv76%VI_Ke<(ML6$C$8SS!GjMA1z))!947eWVv)^)i5?<}y z|G4?pYJWiAnxuCfLpac44NGiC=a5ZngXFn5a8R{_-;T9~aeal$D{3t(C&Rr1vUOI7 zXV!e?ez5-oBIro&tA7&BxPRfYkouv>RxBL&`e<$-0ol3tIv*LIT>{xqNtcr6OK@?; zP%pd_@utk{>at!#XV zgYca5BzznW1p7ZJ^di50VeQk81y>mFua&_GNwtj>sK|^MBdJqRUYeVdBPecgZ^&Ka zHxl&ajb`~W#j(ccpLl@yOl`uu0mV<8XXct4LO45@k+JW)gY@NtwmzXF$x@BvF%Zc7 zV6Z4K4)f)&J`^UBKwgWD{PBO__t4h26FZZ2j0q2}cS_dWM0`;Khb^8*5(jZ(#p}9dE{Awy3u&iQy{K8DKnT))NQ0aZNzI#6rw48`{eZ26XE`|4X`iK24 z=(6)wg)B1kIBb5)=8pVGWvMy|_i#|Xoxt~K9}enBJwyxN>Exn>=TXX1-*eh^!Qh3s7qR3pj|zRS&g@6q>h*yajO3`_ccD(78U8c48P9okU|Ij1N z^4lah5?cA$$^r51*d;Sl)EU>WS1J<^up-=4p|~hr?;;LbwB!ljHL@aRA2zpsP-e)23>gku%R3RN#G5Jg)1Q0)d&C*V@=Az#My2@Lr4pI~?2|B%ruudhL^0`@_uy@t=8bcexvC)Birb z`p#_7SzN*rU~9N~?0yt~7btTv_*@RcJGEIJl*BS#|C_S5%z|bLECq#WlPDB0T(TT$ zLUxbq;Ly=EG88y6bdz;NZV8^{#2$(CHH3E&s|j^NaEI)|M#s2#4?&mhMI6ZAkvQ z3(xzsvQgk*=ELoR>nKq5vwCC`^2{e&Y0C>^;L9r) zn4e33euMUtGaR1cAZt$v6A9_R8}5-CgQclJ$#V4KRHuS!tdZ+4kui8I%1zMIrC*;% zj=+y~NdyQe?(DyN3iUToB~t_G`>Fa1x5oYleL_1Pf5%$B*P!^VHxpI1C*1%0`eT_wqcvz^6 zRr#Te@=m!YJw9-92C!YJoUapS;6c%Dt%~c&|HUpZvhCSw`{3-uIDKw}I|QV>wB4wS z1@C5x*Ng?iU)7>BultQb$PL{e!zf-w&8yvcH{w~+>n}tuES0ap!7y)4Kmdkudy2Mx zXfuTm*z;0F>)sLV+jzPut z4NuW}kCs=BXX=n)nxqQK*U=f_y|jk@ zc+-v-ZF$}ArH_>vcsR}5&r%xo-|M?zvnTNo0omUARd1mI}`zP@1`9Oq3GTDH}Pmb z?0r>Ot8viNjA>?mNP(lbJU?xGNr5MJMzgJL$nW5$zcQFhU!KCB?lW~kJcF|hie9a4 z$R5`yac&93ft-$Z0+$8j^C442_SkZL9L_K+Rt%y1AC(`ybZ{TZ;4HE-$p3&o-b~xy z7T>lt;fNPy`1>A*ogx9c9?A-Tr69axTkTCH)Lz=((!)7_MFv|tTJk>Dhhdy5aV zEEN7~{39Pms!8+W0OH5y?s~ZC3*yJJ{YBU&!kzW-+t=Uhr9b|(?adHS*IK31c+OJ9lu<(2&3n)J46gOwD7XeaoxgSQuH>`fBXU`1-&v>uaPnBRu1=yYOH!uEtkgc!J z^|cwD(_c~}&*m|XHw^|%?#M^^{<0|n*=%lDFvSk-ejtSMXtAx8R@pud-(1Vv`<@ek zI@zM)jQEDM?V&B7FaGv^I1&f@`Pii#5uYKbaZpae9Sd1!hpv4?JT%(h(<}FQZrhqK zIsx|CTbR`LOaQ^@?|cOEqnj#ye(Q$vWu~v|Rja93hQD5J8cn~K;q~Lw3NLmnfEmZE zUGbsS_^wW(`Uh^L*KeP1#iTo;yr)N`ALtWNJO!T;Uo_7+)R}7RS4DYj<0<*C~;U3f!oiVDn0cW>XXL+kIL*h+^b;)Ogc_?EkG5$+@m z@~uPp|17#~y9pxGpjGjyURiTB|CHC0Kjj*V^D|d2SYSp)rAfeo*~2O%byOux1z7VE{RA> zil!65c_QeXaVPT+AhYV3Z^fnkYaWFyl|JQsw1zGy%1>u3#qC3Y3 zaMk^Y$$hlX6|g+vQ`n9J`6c@odx(tB?^>}siAfcNlgt)W$;_ktf5!|T7F(eF3K^C@ zz3!9XsM2o0qld-}y z*PQ<&gYxl7d0m830W!!eRyITpGe;T8IivCtL#i2niq0LvqxEq@2xpVS4{vfl ziv>bWoA1;C#@knXO2_q_58{naY%JfWMFIic&0`&7Q*h^{-J=rrX_(uhWgZYo0gI%P z%w)u~rq|xRZS8wm$rR|8bXQsCM|qK|_i!0(;(D28@mvZx>7L=c6 z=J3nS^{H4GzILNB?H~9ILMe?bdlpd~>B7&DTS_w^<`cec0`b~MYXy?=wPPr5^q%U0 zhb)*J*Jf9nH!K*BgA);gAC`bOH#>P?Y<2wQr!Uc}-;h4ZtF0B^XwLZhqLpv&hsmSr zvN%vRd73r%5BMByeOU);8g*w$;NG7hai^CAt;yl9U+AE`ZYxi=ZaT_%d*LA0MVSN? zSCE+G$oy;)-W_|Yo=3%lXIb>_{+oD+jPkGXsaS#2?pqTp`&U4hq&((Mn1$fAO_V6X z)&A*{q(+N_tYfgpCM4Zoehf0wE(SGyL;2Ty4y4G<(YFU^`}^_B@a*@7C18##3fs(q z_M2l)rUnTU;Kn6t<5NEYmHJO3rmDFy4OHAUd_OlP$zISey@3_ul>2Dn^yq57Kq|X_ zw(wm7=9@){;pQ3Wd6^|>Gcp6d8y{XRsiuOE zw8G8pC?1%$J+$TOHf+Z$+`w`J2iW z{p{6vhau_Do_Um?uh8E;v|t9^$6|eLG#B|jU*swc?YPN!f8X?&5I!N^xD!>9uWteWhODHgU z*t6UL@!4h8XPu1rLx#$XAB%j*uS+}rwB-s{iWf$K0Oe(5YfnA`%s;qqG&72Y{tKcD z?!}DvH|v7JfgofDd6L&YJ|#thjJvMq&_yp`s2?i-tdep02}&Hp|3Y@ftj5yiuu;bM zTiX79z7qO<2IYx-V;|RCh&jttsQN{fBipCLXM?Re8G``Ft>mm*%u#Yc19 zewHMVl^>QbFvG&;Z}MY;8jQCu@|xz@z&8^3uUvS>UqJ$^ZUz2YEjs+_ zP#3x%On{BxS;;uwM_WHEm-(tl?MfWd>R?pQL)d+nD&NJ2O$?f2=GrOspB98lZ`seg3f)xrNk9_Un<#nJ4x z@D~rnkg~^DnvlJr(DJsvasr-KU1*PLp8yu873URh3N#sZgi?+YS{4m)nDXC z3{#9fqsIH++vmb+Bvpd&4b}6;-C5}SaAx{t+kDifgZD_<0;Ljkwzm!j3J>GxN8W&I^Vl=q49vM}L=4La9rzSz)m zaSn=#=6;wxm;>E~w2Hc;R3H)hMU0VL(;L478=sOCKH}j}@})0Z3jX`}$(btLj^2O+ z-<7&N&j~EZJaOxDLcEQy_jT9Ys%2cBwRD~4rI3HiU>pCUZ4eQ{q|aQK>Oy{>QyZ^~ zzhGRR+p{H(>7As4)c)|34%eyhI*{l46w33!L>S*~iTrUf)Zd)uO$%`EmByiL`~qlM zX^4FCoreBH-vlSGtj2dSsYK|MziqJA}b#2wK^V0qRvHT8Rcaz_V_U4bqWh+Y_YdL-9Y&XpZP4d zB7a<+_Tj)=h!2D_GTSYO;u~oDM_V4d6zqR901szg8CZ_kptvTME$WAuwZylG5-Y0x0HEzc2Prm7Scy~PruTdg)Ci( z1DD=SK#fPeJzw|g^MdJcdY(lL$_wIsE@87L3F5gA=Y=Exci?0$i3{tkZcS$A{`7>#MPp=%=^v78!7$v9neSP|#1HxVWU4H*Y`|w%`I|XKR zZv?&fX`fTJ)`|SF!-I&+hg&B#k^hLjtne7Rr)lKQ=UT@fjL+|U`uj6A#snzYT4W}O zaQ7v*?BNc?ch44Hy61|{!L;9}SAIV7;bt3Z&t4k|%YD5#h_f59&pD5HtuxyVP9pvR zz4vLKYwf*e?Db|6nuUC==dqJe@hOzOv=;dtFX1;Uzjm-$G5ZYz%yes zhcov5uwlk5Pr8J1`7&c@>kEllNRmVGRs11IyCRs7zoOSxLoWgcB{!rNFFP>az6kw| zGXeX_us*Dd%%MVtmR#YhdS&Q-FD&^OABy{-{XV_&oZP!p>$JvzqL84ge0B_Y|Li7l zARKzsPkCYj-Pe&xI;bxnGzUgMN59*n_(s<~D#O3l%|Mhv&M{$))p+~JHGvV_S|U0> zzY9D%i{>}auqPGq?M|vDD5=FV-rt4$DLZxe@gUxr_INK9@$T~*+#Vjo!u}3f(;Y^P z%ggua@}AT#l)rb{z}c(<4|xfDdvN?H|EU|Z$v1QlE4}feeXc*4evY_|&TA_kuTC1H zyzsO2>VKROzHY^9rxr*7d7oLGiAN-e5XtlpI8WcdHL|Jg>6e>SsGeYT|5HH)v3BX= zXHMw8sJBuBA}B6+zf9Ojk?j&FsM|Nohb#eyQjc{k<}Vn;&2-{C|E_BP?|2zY8RYlu zI;+qgh4wkk4O*6EXa7RVjTn5%6ZAJUqUb{o%2VcC!iB){~%SyLHCOXSMw&AoRvn#%>yRseduU#Z5y- z3fITfcoYY_o}*x}4BeNI>(PZlXUifbW1z3YiIWfA)AyJ|3Z zUI_65X8%qYwxT!zuAKesJC~@i{n%5cXrT#MSI&|ag#0Y#(rdO^TGGcm&+6qEy*-2n zf>)N1xgy%vA51AV@gskQeIQ#Yx^Gh6!r%i}_&DtMNn?BWkiI-?tg&#@zmM)qy+1ZC zj@mh{HS+TKV=UAz>^Qb7obmBvZ|dEge2oaDZYCvH(0PmXY-oof1`9VPLv?Q>+=+I* z(|Y=TO57)plzSq zIOY9HA{Ig`6z>ucj?+BgB=9?P3~IY&h@)j=P{=1${v7F_eeCs@B2gSO?fbOli2O^@ zTAE~73{HLZQJf5dhqWyFDac-PGaV5}=T+L@(<^69T#qk%NdTG9q==AP1Tb~~zFpM| z2U{H2?vPPD7`^vtpR35#1esnze01LWqBZ}=zyFW_$md&P3Q#^3w+Q<~r>7Zj5AEmI zq!|^uIAFmzj=x%c2Nsfz{rQ}Jjf2Fk4*zE>bUBQmyJ8vM1HQDx|zdag$G9J=ukDGEswP)H;+G@@xV{uSI+s;;kr&F*eAb(q~D2 zfbL(SZJ)eYV9dsJJUrb|mwEx6UtDKmt{y>rca9tRKf@4jh4%OK${YKvpVZ5dU}h`k z@Fq@#XP2b3KS6wcMV`m^CT;1<8*TmPPkN1YlfEDSj%qwJBd0)o+FY*xI;rxOC3vZ+fUm|~Z$L^%+;MNJ){B}jW=l2BU zBuB?_3X`EIYwPI)1p4-A#mOJHjuEI}7)F`wNBfVM>i+KRtth@~pWld5i zC~sg$qd=1t(qD|uub`5Ij2FTWdki9}YUPL*^7!akFO;uTe^BJymLA5}+kASh<8Q>T zGZ%OEa2EgX@&_j-GBw{K`$;hV@<}9r0%FEH67uk1UofM{dYSS1r4w}6xA@@T6!Y)~ zKeS&cu8kXgSVMtZr_;utPF|z+ z5eufQk)X@k$$|;G6Ck|t&k}4gkH77;ZyBU_CgeY{T!Y#4!7PU4xdyYw-tUb=rvS#Y zs4AqNNf1L@-^+HMjzA1yw;8bJ4n&KBJY zL;hjf_i4)xTMgtlqIjlXhCFRA{LnZm^WIWN`s&&?+&(NZni zhVHXT(J-(?`RipZIX37~7}uvbtRAN%%Fi`tzwgD)a5AL2;CD8Bnuds-REvfFX^@#P z_lOjtz)S|gYEgl{e+!>G)?bS9abpHPID9*g;+*$z$g&}S(w;}A(+5+raOxOyQdH<1 ztPPq9>PnjfQnPgA>yk;hTzK#{Yy0Z+bo3+Ao)1VbC7i>mor(It`ye^w@JJs<$8OQK zHep;I`7bKI^FB_5%X}FoJr*dBVCMAmqa!Guq2|zGON4jO&L6$93ZF6$GX?Q1`YYSg zI?+9Aq3bR%8xSB@Gwl&!i}ryf-;ZfQ(>Rp{*LswRCuD3 zk|2ie^9`?Xv~xR1U;bVMC}HdziBNy_%DQv9L@1u*-t$`r2Ts~$c~_~7_xIWR54)2P zzjMTCcX8ecb2)>Dl!in_zfBCQL-9B`0WPCBp zb!jc+7ifA-s#Zqv#o1;Za`ueR@9+NRNO8o|5Iu&wkSBxm{>+`b`*_ejIZ@2JCI8`k zv__G@i;c#^#i-h+E}o3<-?Z}cY8tQ8bszZ`@&$k1Mf+T(zn;rybpBE~o?Fv^ZS#(4ohXAiHfA;+*#@a$KRn^4+c1zoEE7+VP?-OYBo3-#9W3`_clJ z&e~JJY~Y4q<}>x}ACKE>=FZ(-_nv#s^E{tVU$)8-IKO8eATO0B+)m_BJiSMnK#5j) za1GBjU+bFJ6l>!E!I40H%)_L#ZwW^H zpI4UM%qZgjQjR9QZ;3(OVz+0r<*yjur@bTEN(wQKSn5}l$SOvKh=7D!_V~W>tEjlK zAV1@d7#OcPJ_gj9&8#jL$H35y!|_VP5UePAoxFN*{(k??`S2-!>`%q6%pE5`Qy}MI z;PBU1F z{qKEOQx-=TWbIh(8_c*ca0eg|{XmC6Uh{mZqWFkNXXMd+5tyJQfi& z%*Rm`s_v{peo^}8%$BW}UwG~%PXe<#6Z7>&MCkaS*zXZTgAkV&+U#jG;4FV?rM##g zF1?TqSfk0QBFW-ayt9y5d>mMw~ z^G-V^?(1LVGYBnyEb$~7`a z=D~XIGXv19zcyMgmhpYR^H;g#S;U3?y1U(SDC^(nLwmbWidhu$O~~Bc)rfvD`uSqE zEb-?fMK>4y%~G#irsMy!V+0$@+KF&rnd^FAd|#NY?^#W45VFi zwv5k@*k0R5smKq;Rw&o94(+_`_RgEuB16!6;fSsQ>bGtF>N&izx)1Gt#rT>u#`uzO z|BAFV;mA{9@Qy-#M1z+%Ms328pJJ#qU?6M03T(r868-ovDvO8}FRAY% z!O)jFnlMy`ItkdL6rM*vKI^E{n>d<`Z;aQ8K7Qu zpA0xN1CHe-tZUMTpxsm}M7s;^GUCnC_V;-R?9-7|btOE6hU3YLV`A6|Q5)whhn~;Z z!{F^tIO>>9hRMzQ{rWKuvVT;G@KX?R-#LWNKd5_5-ycTh<&?W}0XpLlrQze(fV|+^ zRd?2J9O?xXz2iQ_D9n@H_PecpH9LWmKg;+#AkKol)}$O}U_;TN!ebuu^P@z0Er^_m zcT?n3=JUMO2a(==8Z8;qUXXe`sq55vGM3 zstohcE-DloO3h^@NGL@}v^294E`EDBBWr{@zLyO@4&EMt(~)VTp+5x(w}&2RaBvC| zX#B<7)?VZy?7TkH8vB@wU@CMbX-_}mUHZ1=-bY^Vz45jgmB^d8xHmF@fH)vV<4^y* z@TZpLO^gGmmnL7;kEH;YgIeMg=Kr4G1q zf!#-^;L*)-O_RG*pjHH1PJQfyhejJ(?`lxNA!lyMNG&J9vumwHKZTP}nN0j>KQjkz zW%fcBC0PiTd;UmF=d%)&xA;lTb+8gDoGwX*wv9vQ*sJ=r$`jylL`1XhryxNsXxG$r zb|C^~*>z3Xqr3#8`{_AHqj(AQ?b~lXlEjbmP#j@=Nj{VWW&U>O6Z2{Ce)G!EWaRPV zzj~zJ0^{mhN7w@8{)c#%?_}_fbx}hw_NGmY^#z`f9AmW#$WzxD`HT>U`7SlVpJRJ? zSqNKyX>1ghWg*BLZ=QHlKMwjexkZgr^YcUV)OYHX;{CibKY_~t@8^CUyi?h6$Y`DL z`<;!DGnh*C;9?=1edpnCx|D@LUw`-eTpvw5f6QJw4u@PB0E?q~+^NNw*XiaK=j%d- zGqiB&&^6PL6Jxn*@t$cYo$ws>y*CQpuD2YzOXk}fEvFTRQ#h$`{_^6vT?SO}47UC9 zuBi`7t`@|;zupHT#}5Ayvz`Fkbv3cpXD49Oj?h;JkH>lx#6|+l+D6t%rB4Rx(6f*GevnHVx+YXNxge{}Apec+ORj zvea-2c!M7BG(H^%y{p%`?hlT`=i!@XCwB1=LL;x7Sm%QJH3O>GwS>3{gGC%XQ!3o^ z=HvZnoqIIm8((}2I(+I1{w>k1I*N94(wP+#PmouEe*PGhM?{6fBQXxIRbH&$j=I*2 zKF{cR#KMQY!ODp5*707x`Tz;8*gSpc%SwZh$xSk%!Zd(A8LC}~gWP&&G{66Uz>m^A zBsp%K!g%9QjDoiw8D=j=B*Y{QK;d@NLnYY*V4&xJWA{=dfA&Jk+sfqbI8$qmfkeQ@&2%FuA;_ZP9?u0^BP{h&}( zbg(C~A2_WVvKtOI68{H&5VwbhFIF8v-OH`bB4g@k z7ezUTcLoi?tedf{eEblQ8vNvD-u3}+@(E*F9OL^3iwN5oi+m4k=8WFki}|aJ)&ryG z3%TrQ!^qROqG@8`veEx|57oc|h~PqPUUdug0~vjv{`rdIH`y|~h>-EDH&|pR=GE;z zc*6kgg~yH-O2<(5c?oB$t(5fu*g2*6R-G6CDWQ!?=XD1_+IjU$OhTUbdpE0|ENVnv zAg)c@dq$4``+6~0pv)yiLH&AlwxJ-5=SjjY!xlQskLTt;t1eu@d*z?r zB7;-0JrJe@&G&hce^>jx@;H(C_2<+c-s3ya3+At$IjqCHPVw~DYyoX}9~t)d+KKo9 z`tfE|mP>f3GA@TYOsy(xm7KjG71gkovYQAzb}2U1s?5*tiRGK`oiiN(_X_QW@}&b1 zF5p0LYv3c?(s*=(TZo^aGd=UP=iMaaevYU7L0+z;?1Pv1h~fnQLZPPq1rh|qBFkpt z1tCJ+`>S`}B?}QYl`W1;A&x;Z>*r0omyLr=^#Nu7x?#|NGo9xuFanM;+|kkH9E7*y zI}N`5<{)@f)LuIv&rVQ~7xcfYJKw(7n&^G*CqjX;-39yhC68I%$OzPT_kPrX!(4{3qP?uTYS*nV0 zK}CPngNU2ml5y1Y1>$b#>!Ypjs&+!Y4XJ|1l&pF(@H<(p_d{NIk2d>1Wq%PL^tU_y zHU|CnKV5b8b#=*blH2^E^t}Oic=}82e$2c6QTfI#6Zux_NR)aODvzT?Z2w#Lk|~!=>@OTO+UqRdV#0@5NkA*2nPke?hndhem+R$kH3;pL>M~5-*nEw0p<!Pi(&XVL3nSSo(gbNtINED&y#vKH=#Fy|k4__Z0|*PAr$pVw;O zz0KnJUaK%pA&HUDtnsR4CXCZ*C?5wF0grY>-m24 z2hi8I`PX@$Dw95lI;!4B+t3H<@yo(}RZ-8eov?hH2;=dmukZG#Tkqnx<=aM{6+rcKnrj7TDh#H?+F||J9!2J6m%GYPN4tckZUFex8L0xMQij#b?fse37f6nEFGaq4ZhRLgwo2KBT1nuUY zj42Q{Sh}?Fv^ZhJY0}F*UYuZJU$syxRERKeq%5E!Rfv!rI8gds0Qt8MwM^c@xH<3f z@yn+WM`Ua3v73(*b$lD%PVfj%BHs#Wd;NwtA0#k>^y`DeDQXRDmIIFf{Vh9jz5JpaAEijZ~jlOYsvtU|{p z>TLMaE^jYGelue9(t9?7%-b6&Yqc6eqsg%FqA0i>BtvvgRyzCZLFj&Za&9Lo%EDG7Hgvx39eJA5@n|ov}%`bGh8FD5$%7 zVebPY+y~U97g8~gmHzh`l`r4j%ISx8ALo)Eimb>-#(Lqs|DFUQ1bVQsE1Y7!zCw?! zTPN4|!rN^o>0`)uqxztKd&Vcce^nX1seZ_O|6No{ub#fv14(L~76!;?$*4b!o(mfs zXNy-ue0R%`KMM~TF51f{Yc0b2hKtFaRVxR;JDp$j(@XT{g=*>4BqyC4v-9m0`u3_FVQUUYduYkB z0KqH^=EsY^zUiiA~LT%aTORg~y!jjfKvwOuB5%hcCzkjPd1X173A4Hhp z-v?Xr_N*oWSNATtD8yxb)t6VzOrM4NU4o~YDrdoKx$2&yn{l6#YSgnhIDfwqupkV? zKB2<%m4{ENcTizkZj$|3@EC}&nk!qJZ-ZCi&J$0z82FW%Xa+XeGg zi=x!3uVH>;kLnt(6BtL4_EAn*hjHMykzZB>JQx69LR^to;Q%!O`N?qCv2XvT&iu55lbuWzoROK9H8KI%!5@Y_F}0 z-jJwsjta@Osq1|5sUWA#;yTdK1KO@mwkPp@Ffc$DS@k$X9(j_vxo;dCf3}66K^*}Z z(aqP)AI+cNBu?MyD)j$7lGXb76a9br@>$Dg%zGiw-s4o43iI|xOxV!mvLj@OeP;Ug z0s2eI9*oi6xshO@^ydCHGlE*J<3CquUejpH=#`z4aiTQasV z|NhlSHV6H{yvE_oKZ_*0NMKvE>50e-W)wpQxL-PxH`R@-)Z~33R8GOoPK$ulh2*QK;zuW~g&~ z{(g1#Wu38g76r<=iBmL;Z-pC}7UqPIfS_VFtcd;yM*X9IE_9RC*a3C?mhGrL{8I_} zeUz_7W!&ipS(|qkMcy%f|LN-^+gUVe_ai_5nF|x9b!507e(3{z!2HVv_9O36$Cm!{ zjLO^Ew7FW6Nbp2PJ*MRZ`bjP<>RkVa2D^%lzVeMCzNGe`wgpEYq^*yVuSJ|Yqxw`- zdpu;(j?DVAT(4#W86Md51a)xZ{r};)U$5|eVf20a=kH!yb+%I|Am4gLN%5_yTG9@{>T$0cMcGkOWgb8WHdMCDX z!h~^NIa!{K5F}-MFe%mlkZXPl~G|% zO{nk0|Db>VV&xNF+u~mEuu!u1kLiVka>L|H--dxUy*=Ek^lUf_D(SH-tO63@>r;X{R*9|yqyTl7aU#EEc!DCIZ5Hs2oN4EyqO z2RrJI#8{gd;Qq_4G~kpYM1mycvK^qy{Q7&o)!%%UqZbOJ1O4Plc<<7Pe{~-50ufvb zcQ3lkc)z3X|B}@myJ}|1AZIsKq0oW(;toan+)8Blz3j%7AL!Sn|2(7emlg%;v6VfL z$bD<5l#2H_nb+bAF>gqfW3OE$+Cy&xj>Nr0UaHv3cLX<<4MBN(Nnib$L6Gybn?4;g zfBhvV>8y%bg1m&(E|+Q?uZ~AQDKE|w;oA@HBXWnB-(Sq*yau|r_khs-FJo(v7gYGw zy5D(?h_8z)EDrw*{J4)zZ-ue|6{=3$KWKvZ#C_xwPtJ#qLR9V5_p{0Pm+bf`_7@Fm z)lRFcPcXKJBDbwH^{hfYb<0)HDTrHfeDtvOKYY{43B}s~@Cb~?pZ@utb==QaBaepz zi`A0CISPD>D|yb9It<$-gc2O{hvAKgxcYa@n-Pywcp9Y5xP3Qt-4Y|lkoRhKr|Lu- z^Xr4YeGio^??xR!UdJUvjh@I$+Y}I=GI4Df3}=i^RAk^^C;x$us4KiwOIgXli1GQv zo+I$OPYU&utjl=W|Kk0kZ=Zd6_(*vU1&mUOQ|31)kbSl7P9XAaCVboXol~3n{(nRm z;?Yx>*EqiAdi{IQb{v6#1&I zcgp2r{8A}(lJCxF`5k;Im-O| zyU3MWv@VheU#CtOSD6uE)uYhlYZ&K#{HrzCZUqg#6};8dLcWZ>e<-xN-HgwVu$`$n zifC^fO}6@E8HDkDt-!Rq$S+XpNu(k8t)J3 zvHY$U%`OO2Y8Fi$H#=FYRH)4Xt3>(+gQ2<4RIn{E^fiN#rlwsPJMlh<0)sj zY$BT!#-Nu^PvfWU7<3eFFaPj(5cYmPlClBw_wOe?2}!-qP7oZ{bB@SjC%k@Ix8Rr( z8)3Sr=Z5|+HUfS7ESGO?)j{0vogdtX9$=m*{c~o^`yU%7zj@pPiZg;Q$I;*7WNs*x ziTFvSB|=1wzu?od2M)@4G^YzUO2~&TjB!yT62y@h1+1_G2gwC$K)qA!fo`~+Bz}n+? z(vS7P`?uT4Yxg2QP2`4qPG^vBnPg{py+>v-TIiFv&WH#T$;w>3=tZfSF z#rHwHBck>l#*@d>cHhv)c(TFeQ{p0vDNvlOPh3i6y#KtdvALXsc}EEm8)U{!F;3%h zThr<_4J-mBImbStev~{(VpBygm=T;DdG9m6zb(IRa^tfK6?!u_b|kn`LAt_Fnn#=j zQa|?j)*3g{F|P7guE_64IN67%DYCj0cQt&rd5)X5a1 zTlqv_H;dcjgZq}1Lao4tAm;ZgdA=^TeTdUgDWYsCMSnBh^fO&dh%qwHG$kXyz5O3= z#2+wS0o@nQUo0Abi2jxl6=%VxsBfUcA2lkag?h&~s2LMh%(plBu$1DC2pYUiUr@vO zoCZCl$moQdCj+Zub7QNymbl0W_bbjL`tS7zaO*CgAB$XO{y5~M0e>!kYLf)qv z^<2v$>ry^rUZTuK&xw0Pu=v>izV9#aj%t?dPlah@F!?-TtI_!H>-l-`_45ZYf4ce1 z?gG_0%tK$G?D~O%by*D z315ScD;;0NOYq!hVdkdIOVE=QSiD7t3`gSBf+EmQ{zU8QOChwA_xkX^QrLpJ(eI9| zIEXq5QJsV=sSk|zzr$-Tw(oI5|EAE%LT`M(mkm|l0 zsHandn`^_zDEvcE9c`HZp^KBCnO317wt$PEuJ~?ghrj~D4cQ9rD3G8pO%smjTwKRzP^yAsp;?cNih5d&ikA~KZ#o17EwH( z96eaZvJ+^Kd+T+~H{^3!Y^5Kc_CMftyflx_wjo|>g-l$gTpba@e-UpdAr3}Tdd^Mk%UEJQ)&=SsWYDAL&fe?r@160CH@b(6Y1vsNJij zbshN-Wz|glX_zlT-#_|t_Efx-^5TBD%NDWt(B^)4?6%;@ms3>O&y$fFeUtHhm%cu& z08@TjyoX=XSlt?>fjXpT#R6pZB7f6E!CifJhy!{gabpB^J2Y}CZ;mf!>>n!Ia^jDv z4H+7j^yaL`eU<+Am@Nmr4tI$|f2qzybH%2=@YmD--oEmTCpl=B-g|9YCWQVpArKiz ze?^3|=UMLTj9`AhirV$DYYW<=>mISWnHCd4v`gC3prRiPKgbZ1y8FSvM=A3H^47O& zvaY-SKj?{=9#>9uAL)V8bbo1g%wtu!MP^$sfp&rWN{#^JL!j>uqcSa2BdvBZes9!_ zb59--oHn+u%hJJo-A^z3w;?}8OT6jmJ(oVjM+b8VBcBzc`d&tUj|KD}ydi5ZZu~#M z^Bb7g?%!~x2mJEv6lLuhpRbJC$2xmwatis?Yn~o%JO;>jSYZ?~ltKjCp0W4-+R-YB`E?PSV(x3zU|cnH`_qlc%P(zS;L)^i3{uMW z>?YffzyZvoNDi2P-#IFlD>Z@fo1KQ7t4G9vQnl3T?Cn(Tvv{efw?fln$?0hW^c{!)p#{55Q@b+|**fNmvo3 zm?aWF363WovI-)P`|Gg7J_Piq(tn@6?6L6nrZ&X!(|n~4N7?p(8rP~n4Z|Q|Se==67x65b<16!X=i6H@rBz?zVkmGSaQTtDh&ydJ zZgaN5yb2XvN!QH3&{JYrRbJS+IpLN4Bsj5XPRgVJ^+-zd zE*2IHz`MF-XHseqN6xW%WIsC%;##(cCm>FkQT^)t4OwlNmm;RPs8eR>-}n2uz$kH% z3Nj2{Q@OSoaYT%MpV4!zAd)Nv`Hel3G2DuX6E-}`t}aQ zv+?{9M%;n6fjeag?ZDnMmqL&q^lHsLs#PNM^KB4&35f1JP}%kKhy1=CFwbAO=lTc{ z*o@aj)uF$G{`VP`ZC}WS`65mrUgf3kb0g$4+7q~4p$zdL{SMaYXAoEExcP)S-tPx= zC;e_Hp`J~NyNdLWarnAd?R((t{QLlAE}bvRnIz~9mMy&d7x)kQ_Nu2Xu}l7ne8=po zEiR&8m;O1kwlW*Zkhnv*P9a6=XeNRE9|yvB=ZnR zUZp(L5^lmKpX@-ZuKD?rs#5uP_}nL;0N>w)XZZcMCdV5s$01O|_2;cyw$oqas0g?N7b zq?I4vlfffe>D=7fSs;X@hpsw03mRwoM52)Q^kMsJKXb)CxOAvPf9Wr7f~xB;TiP@? zK~YM1ZuxN*!Y?&8yNZh}gomFLh?4xs>whJts1?tjiP|;xLXtG7QoCtwv9GN#ja!ipC@ICe3JS8=042~GfPE1p{A$Soj#b?o@h7S(v9(1zvANPi2-nt zbssEU-UnkoGao{x7~d}|Hc8ni*r9%Ax?%6||AGFrM#G}Ynuk3QWc|RA5P^E-1q(Pn zdyye5?%LW4^h?u^H>0v?gH(pN1qJ3Z*Xa2mzayj1GkVV2e2e#NB^mgF>npBgB9G$k zF;Nv&#Mgaa?CXcTSd6|;|J==Kb&d@3)mtrC?VWg&`T3-;kE%JoOVb{8YZJ(v+=!>n zs@Y#c!h2!neygHZfKY`ur@^1mi{x3lpahSNrUe`LLnj0GOB$ zcpc_OewEhx4z4AP?KPvIRLhk%h$E!zooiM`o(AQ|ySUCH?#w_`(CqpUn40JR%B|~z z`#V-x-+#>5KED`n>3s;^hkE2$|Hw~}LCDZ6+P#Df*Vo6$N~bVCAGcEXUC8?nkG@Mb z&K&Q%zD2hM6p-K6bgbdJwEF;DSN*)t>Ll_2UMqTf9rGL*jUTzed5QNU)UWk>&sz|Q ze5JuQ6M2aLJLS?bJoy*?1Uud}yl#jq^*7I_6=5D2MMFU$nU@6Sb8QR9J~BVQ2d~oX zwxQqjd%mxR>kATm8@zJU4D;;SS1lG=S&q2sgL+T%`}#rOTR=;Yk8yvkOERN%_$UxJ z`)E!H{RbrJ(e&`XAy{d4ewegi7}yr9nGkNK!J%6#6Q1@nu8*6xHi?>m`SC=#tCENh zeQQ}u#Nau=X#DA)KRc&zK^N`jyZ3SrO=5m2%Z)pHhNy?*{z5eM%2U)G zS9=kVCeQ~N-)K=R|7Gy9~eAk-kmA$zV3#Thme{^kmivqN;5gx%m|zSUt}t;4Ig$&Oyw`kT^0MqIV8 z^;5N>9Om2ia{>F@Ag&LkOTupgWT+s{(IO&(`3H*vPAkAx=GXV6+sWVRXM4a)IZE+6 z*25+pt^Vmc5fo*%QqQ|E-`{tCg1?`{_o6v9K3^OCvDNJBUZ25y^T)3}T$cV|CFq~J z$z8I148$I#e~9!P1D)bK#%JsW2^>Oh(yn2Ggz8ti6g3teLfQCI9WezSLU;J+>gzEB zpk%SvZw&DZpI86nrrk!p7qv9DFX)f<+!&O(;_x)YAKh=S`IE~A~So_JG}2mQBe4;rvcd1Br!LC@;83G?%DTdrEu^9&huY_cQ#?U?^Q z{rXGWYCXw%8+GXS#2od(__RN-K}>-Q^7oA;o$vVzdvNk{jvUtj86qPig9kbghgCPI z!SS68Hm@V|y~>$yZg5iA?`~K0gdKKcz$PUG+k^zNQAw7+38`r%&$MMh$)Fsj3+wRwttNE z>;=*Lhs70d41=SUns!L$Fhnd^EcIK63Qe4yUQJsWpLesS{m%qD$)Fgp$3X4_8CISh zOPdKre@Cx(RLBv=`!W6eYJId6zkv9Xs9OK0@4`t?;-k9_d};7U_~swu%jmz~PJL!R zNQSfi{90Uy8>at0ec34TbD0+6f#pJLY<&@z*?2hnnfI1q5Xl`(`AyOg-P2e%^oxxW-|QE}eBGrhwk1FQi+tU;?}TIYH_$-0 zuu%LB#-UQy=e+BdoPbPTF;-pm35c>+*t<%62<|G`Y(9zn8}#j=FDu*1I%r@%UG4tN zkmV6%Ab;8Yx$F+=51t=v_w{6cy;QUgg`1l7f*3iYHCe3}#@%!7Rikdt!#F!?9mYrL zf1gqLy2{+QH~TTKJK*IvIc>)C$EdzrN=x0&qi%rSjP`+2wC~xEj=J$aM?ByabJ2ll z=IhVStL=6rqMxr_?52TrLjd18a_+vR-ASat{I+jq8^K%-&& zqh9l2N}3CB`=u!cA~Lq!aG&vKNj^g(&`~H@c~Bq1+Jqbyx3VY5j!fXUgE&40FLz z$V?eF+rDNL;}Fhcwo*fo)e~4{t2Y0Axif9Gv*0TURtH~pD9$Cp#{R=$LIETY(Hpbd zaDe&oJ010QWzA>w&mG~s^eGGZfo(j)TTuVEKFoTU=P&q%2lY1lRU=eo*{Gk3p2l-!w*?Wj$g!k?^kDMPG<_lUd>x{7J0BnGg5CH{|o&dy=}<% zdKlwG;Wsz@!ux)PQ^@|E9z?i%e=>N~l==OorESleErQ7Rb?`&6_%IoGPv?A#TSkIf z87rIWpUl_yPRT!#-@g}J7Ux*I*!4oDU!$(eo*sB9OOlXNWPZOAQ`q~%M3j9TO^48oN?dCoB8!}SiE5SN#tXAo%^7GfbpJ13$N8(KSYK#=e&ZiV*HlT zenKF9$)9 zyRcDybO9mo*y_MNi{|r7{jmOG>+6g0?z`uU%`gvJ>;6K$Wi~{p)Vt5Gti$|#a6Z+z z5KKfINVP^-9G=&XvYwJV(Ldz)ORC>IiuwAU)YL58fcfm=Dn`$u1yHX%E`^IQ*bA3B zJNK^p%GiHMKYrBRM&c)sFXOKJ;;S1M^@1_qm(}X4(eKn6ab+jsCg?xUsNBJuU3&5~ z1=xN)w&y}Wd-sm|3y*zUr;YnSVTU)~R{NQ^OVFWa85a0m1k$BZ0& zv}}m^@uF|<2d+YoCXAPfoZ1mVH0=Qu_3Voy&&Y6F@bxd^U!0dVuAO4$`zYY@nebg@ z6`l_(N6O^>AnzXp&^}BIfx6s8cmo#=Rycj}YnEYb?{*!g+_F7M0=3AwHHsF@k3W5X zX<_N|uYVyAfb};{{c;jCE*eWCApVE?wz%{v^2E`9o>BRi{m39Y>Tp!ctmypQM1?Cc z7Ry{Qf5fb^WA^+;#{LZY`tNFFWNYF3X7TCeDGl6TlmgVJ*saK*o)ho^krhn0ul(Vo z;F@d_=P#W# zcRu^2eGl)!jJ{9*Jd0R!GYsvt?);CD+30_!f6i>V+mc`Z2*&SrZD}7Bz4Y((Ij_HR zwl-k`S{HBHt@nKbl&=#+=Hv!IH#V=dW&Z&9osH(#6yqcazLCkR+{j5d<-d(}<3(12 zl~;yeX7YSJYcGdw1J6{EpHpIS!;!^(&=lWH3qan7FU~Hc=3wT}OCjHnCdW0&(7rCI zUR{6;0sVGoG8PVixXVL=m+SyM-f<K$Fw-7q=74d$0J2*Sj(y4Io z$iTKWMWgV>V6FNs)WhJqqjpB&4h_;;od!!#H;2*uWa-ak?MD5imzl0dhC?yWJENp! zBjz&&%RWA^(UJxy?;Y54V>=amG8F`FIWfKuMh5-dy!w`7!+eTiY{uOJhyK&$%$ZU(kP_zO2|WwOVwT2<{4>-`L;8{QbLc)QH>&vS)4NLov+nr$I6Mi%IA4 zzMwnNmE=o-9VvHpr|r>>`7I_T+w+FpPUFcX=V;ihr-kM0B;2VdBf>RsBWGk7wYI%eRING0)|i()Dl^ z#JQ)j4}5k)oT8IBHSBbby7wDLzg7)k`xUZ_;(He$knGo z`IfqJuA{wRSEzHKion>uZ;*5&*nLBO&8|`@v%DTyx%GWbG!ODCOO4FD=w`mZ&k0u) zjv>!gt%Sf`OT<|y=2hP||1br$)bb|Z?kTX`FgtLqcL)YoSFXB*ei-`kqA&Y~ah}aS zL4iD{`=JkvDNrzbE94C3m2qCEaz2GPzFy~;ne+UkkmuihVnXsiK3$KuR9P3ynr;IqvcN@Z}@yX2hkG_3*xAO;Sw{iW7)LDE&KMwtKX3K6qDfx}*i2qd? za6jZsgzB*ig4a+#_0Hq|ndeUZaQ*%85tfzM|BD}#5?L7Uhm&okU$dJq&SM?PRao@z z?X#PB(!79|0%Lk9b>@GeFH1ijVFhnE9TYH55xj6edk^Y>#PPhSdQAi^uNB@$|Kfhm zzUpm2sX;%SO^Lt3dZHinTITGd-TENUIQ6#ZZpQCFeftuHKhtW_ug2o1dG7w$}Lvpamrj0;qVvuh{7P}4~2+7U7A0^{~PVJ-VLAawukh<4sq@S z(i*7m_1=6-$G%DU8Frd&u@C06-Lo8D`*sw>ayj}e+ULjfW*(0}dH|K8x_aUxV)ucFF*!hD>F_TDJuL#i2e z?_Y#=ut>xihvWAc@281@R{!Yfdh^X{x>h58_zT(eT@HI75aI^!9oX~y=w-ubZ$`6Yb$7QKvMY{w4k1dzox4b-V5`xL%s>P zFuq?-kcKrIUsECB?SPYc4;2LTZnrLM9fj}_fylYw9~s zvET(i83g2SJxV}7R;*}6@i7t&>gs-Stw4Syb_=!ULB#Q?=c=(ac`_c~Uqhw~3FwdI zUeMfOg?^IpQ|fE=e-D6s<7}ki&;SJNT2Nn}O#z z`Vd}?`K!AmvsQgTf9H~~4;9Z|{+k7O|VP;MTAepveUGh4nDZsFjD zyhGZFw2+g}DR3mRv@5t4@lk`r6L$iU@Ai<%mI~Bw$}r7b^dWl$grs+s#%B$|0m4VO ztjhWCuT|&qW~o8sLz+x^A619>-G>EoK4IL$b*Mo7?O*uEXJkV|qgEi!??kUkH1c=X z?>OZ-{fi9WuC`9K;l3?4_PKnbWD0Hzh}v%IoC1*}m5*hSS1gu0U4rm#{`vOJA^uIH z3i6t*j1zk+!Fc^M8qdwI@9QK662aQ-XYca=beUS$?#(jphjha=2Lev^gU!)Hx8&<6 zz^`1W(}(W~qxvQagtDEH=i#-k9Ct$x>P1Tj7Zs?L zzZ%bFM)hToBsi5)df^U(&zHK@nYsCvAx7jgI(_HZ6YKfai1$CF38%-7HBa8;|v3jIxD za=+P8zm|SHm@SV6h#K2rzJk3*H^=W;)S+K)=#y8EddHi+kFX{&KYnMZCTXXViQpsO za%$2F^MC!CDyuMGXwKL;{P$HFa9wHFb6rP+LC+)boWS^e>t5gA^i=}m$rs8aD8?ix zr&?NkK|D-_=MH1t?Rc*~WYbc(0{LpU{a$A^$9Ozql=QZ$9t_y&ma2sM)nl> zyn2fHoYtOp5$IRX>rd69pzd!=qhI`a++WOk64V=p5YJ`oRnH>J*xxDs_?nF07}htf z`|flJ@*q@H_vWY|pZiPY>~_RsS;ozH8{Ha)^?jmpT+fkDaoWSWZZV!4Ar^8^|3CKM zvdLZLb{Jn(&DAVd8==61bvy@my+J*n8Q~Wtr^wKGFY(Ev)uS-FFHV!DGYWNkY&X4n zH4J^*h}Mg~&-YJU`7y=sncWNA2gspcVtXNM^$VR=yca2RpEMyLE}wpU7?o3}3OGMs z#&u`UJ|Mmiakg2K`CMqfIC<@Upp5p5{<|Z7>=ym7{Fe;tI)BFF_p2b#=J^B(#x_E6 zW&6L+@7buiqoSCH&4>GUk+w|J@1P*li)=@6phgCv_|s3_qS-%nenJGL$DU z8l6M^pEPf7)`!adpxaK3oyGlI=LWA{^(MyqYjVu?`po`mfHlqb;p=AL>&ZO65wAhu z6?9ziHhT~%UF*+Kg?R|PlW}(IH}Vjq6tcE0I=_HG3(u(8nlzvP#n0@smtZ{Rxixrh z_iCGkiB)!wIs(REj{v{w%8D_lOjo(kT*yZ_6X~n({F{$Z>w7~ij*pvQ71(Ajy1l7kIp^hKFj?4X!QkHg`@wgMefJtrr>^XF>tdh??fHeQ^#iwa6bt0v1v`OLw#4z zXZ13uH#und+uWvX7)~a{M^*ir|Nhnyidq|x|KQ`x>w$cT%i-U*)XIVvbu8``W=zTs z!9BM(y_F{YpdDqCJAIb%`)1kpYLFl8=Y<6hOP)O?L)_WKg3ZWJK_*L9*EKS~o>gRL zns*>h>f76qJFKqeI07JylJU>u8M$ATB zwt!7}@(L0dd|uCQj5>sjzEA&r(}^hI=Qxj&pG^;MMmtOH+~@nOIDT(p0(yR7oRt3a zjLJ&}7dMSRqQJ6mwXBg*s6#c@C0>vFs~XGchsO5IufN|HbJ8ivJ>dJqV71((9vCS* zRZ}j8el{_mW(l-o7`2D~`G)%R)OL(#IaZ$SblCOp^LsW|M3$$O0ufJrfQJ2!YvUq~ z-XDe;YV6)|)G*%(vGdKyi!6I1vO>PyTwd9nWu5zAq~(`eF6ruKj0G5B+=C2!HMj8R}+I8?QAn zUZ3qeqt8l|sZc*co~bjYLb&;Kp#Zjz-T2(K_P=P~j*;yVFA(2Z94@f<_vK#5V>unb zIxq~1`|stObB%!1W{-H&)P7hMrTgY(E#v)Q@ROZinh_Nsr91M_2`X5MIh+%*L){dy zfpHq1cl7IlQJJ%>=*L~en{#rrTuntjxA2EDt5tAcIdmg-uJJGUvs3$>e0|Z6_^0k! zdc$Af1L)gZ_2Afo-*|7cU%9H{_4xtNd{wZU7xN-m9<377L)`maQslJL)HJ9Yx{D_+ zoq%`R{vuv>Aa9008uK({31OL*$Zs1qJ^Dnam(#BtPEF z_)0ve^=o8yq*c;dkCedrfuRA08VXwc1TByh|bAF0QFpA1*h zc1GPYCraHmfwj!ozr|mgPq+S`C6Z8@N`XFsnr{dPwAA#$?qq@l)J*Q_g5ytGx_c2 zpARQt+tb*EMlvJNkYpNSv~_;GF=_LXz)D\-;2n*H7jvZ4?2z8YeF*;<{d{56cn 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 Date: Tue, 21 Dec 2021 18:07:27 +0000 Subject: [PATCH 022/418] fix wrong import --- NuRadioMC/test/SignalProp/T05unit_test_C0_SP.py | 1 - 1 file changed, 1 deletion(-) diff --git a/NuRadioMC/test/SignalProp/T05unit_test_C0_SP.py b/NuRadioMC/test/SignalProp/T05unit_test_C0_SP.py index 20434e709..2a507ef9e 100644 --- a/NuRadioMC/test/SignalProp/T05unit_test_C0_SP.py +++ b/NuRadioMC/test/SignalProp/T05unit_test_C0_SP.py @@ -7,7 +7,6 @@ import logging import pickle from numpy import testing -from keras.utils import io_utils logging.basicConfig(level=logging.INFO) logger = logging.getLogger('test_raytracing') From d44e07b1f4c395f37363d862aff9195c9f2b3eb4 Mon Sep 17 00:00:00 2001 From: Christian Glaser Date: Wed, 19 Jan 2022 21:04:43 +0000 Subject: [PATCH 023/418] add calculation of trigger time and cutting trace to correct length --- NuRadioReco/utilities/noise.py | 88 ++++++++++++++++++++-------------- 1 file changed, 53 insertions(+), 35 deletions(-) diff --git a/NuRadioReco/utilities/noise.py b/NuRadioReco/utilities/noise.py index c78d579ac..d35666e71 100644 --- a/NuRadioReco/utilities/noise.py +++ b/NuRadioReco/utilities/noise.py @@ -2,9 +2,11 @@ from NuRadioReco.modules import channelGenericNoiseAdder from NuRadioReco.utilities import units, fft from NuRadioReco.modules.trigger.highLowThreshold import get_high_low_triggers -from NuRadioReco.detector import detector +from NuRadioReco.detector import generic_detector as detector from scipy import constants import datetime +import scipy +import scipy.signal import copy import time @@ -31,10 +33,11 @@ def rolled_sum_roll(traces, rolling): # assume first trace always has no rolling sumtr = traces[0].copy() - for i in range(1,len(traces)): + for i in range(1, len(traces)): sumtr += np.roll(traces[i], rolling[i]) return sumtr + def rolling_indices(traces, rolling): """ pre calculates rolling index array for rolled sum via take @@ -53,6 +56,7 @@ def rolling_indices(traces, rolling): rolling_indices.append(np.roll(idx, roll)) return np.array(rolling_indices).astype(int) + def rolled_sum_take(traces, rolling_indices): """ calculates rolled sum via np.take @@ -72,10 +76,11 @@ def rolled_sum_take(traces, rolling_indices): # assume first trace always has no rolling sumtr = traces[0].copy() - for i in range(1,len(traces)): + for i in range(1, len(traces)): sumtr += np.take(traces[i], rolling_indices[i]) return sumtr + def rolled_sum_slicing(traces, rolling): """ calculates rolled sum via slicing @@ -95,7 +100,7 @@ def rolled_sum_slicing(traces, rolling): # assume first trace always has no rolling sumtr = traces[0].copy() - for i in range(1,len(traces)): + for i in range(1, len(traces)): r = rolling[i] if r > 0: sumtr[:-r] += traces[i][r:] @@ -108,8 +113,6 @@ def rolled_sum_slicing(traces, rolling): return sumtr - - class thermalNoiseGenerator(): def __init__(self, n_samples, sampling_rate, Vrms, threshold, time_coincidence, n_majority, time_coincidence_majority, @@ -215,7 +218,8 @@ class thermalNoiseGeneratorPhasedArray(): def __init__(self, detector_filename, station_id, triggered_channels, Vrms, threshold, ref_index, - noise_type="rayleigh"): + noise_type="rayleigh", log_level=logging.WARNING, + pre_trigger_time=100 * units.ns, trace_length=512 * units.ns): """ Efficient algorithms to generate thermal noise fluctuations that fulfill a phased array trigger @@ -239,16 +243,23 @@ def __init__(self, detector_filename, station_id, triggered_channels, the type of the noise, can be * "rayleigh" (default) * "noise" + pre_trigger_time: float + the time in the trace before the trigger happens + trace_length: float + the total trace length """ + logger.setLevel(log_level) self.debug = False self.max_amp = 0 self.upsampling = 2 - self.det = detector.Detector(json_filename=detector_filename) + self.det = detector.GenericDetector(json_filename=detector_filename) self.det.update(datetime.datetime(2018, 10, 1)) self.n_samples = self.det.get_number_of_samples(station_id, triggered_channels[0]) # assuming same settings for all channels self.sampling_rate = self.det.get_sampling_frequency(station_id, triggered_channels[0]) + self.pre_trigger_bins = int(pre_trigger_time * self.sampling_rate) + self.n_samples_trigger = int(trace_length * self.sampling_rate) det_channel = self.det.get_channel(station_id, triggered_channels[0]) self.adc_n_bits = det_channel["adc_nbits"] self.adc_noise_n_bits = det_channel["adc_noise_nbits"] @@ -280,7 +291,6 @@ def __init__(self, detector_filename, station_id, triggered_channels, roll = np.array(np.round(np.array(delays) * self.sampling_rate * self.upsampling)).astype(int) self.beam_time_delays[iBeam] = roll - print(self.beam_time_delays) self.Vrms = Vrms self.threshold = threshold self.noise_type = noise_type @@ -297,7 +307,7 @@ def __init__(self, detector_filename, station_id, triggered_channels, passband=[0 * units.MHz, 220 * units.MHz], filter_type='cheby1', order=7, rp=0.1) self.norm = np.trapz(np.abs(self.filt) ** 2, self.ff) self.amplitude = (self.max_freq - self.min_freq) ** 0.5 / self.norm ** 0.5 * self.Vrms - print(f"Vrms = {self.Vrms:.2f}, noise amplitude = {self.amplitude:.2f}, bandwidth = {self.norm/units.MHz:.0f}MHz") + print(f"Vrms = {self.Vrms:.3g}V, noise amplitude = {self.amplitude:.3g}V, bandwidth = {self.norm/units.MHz:.0f}MHz") print(f"frequency range {self.min_freq/units.MHz}MHz - {self.max_freq/units.MHz}MHz") self.adc_ref_voltage = self.Vrms * (2 ** (self.adc_n_bits - 1) - 1) / (2 ** (self.adc_noise_n_bits - 1) - 1) @@ -312,15 +322,14 @@ def __init__(self, detector_filename, station_id, triggered_channels, self.sampling_rate * self.upsampling, self.amplitude, self.noise_type) - def __generation(self): """ separated trace generation part for PA noise trigger """ for iCh in range(self.n_channels): - #spec = self.noise.bandlimited_noise(self.min_freq, self.max_freq, self.n_samples * self.upsampling, + # spec = self.noise.bandlimited_noise(self.min_freq, self.max_freq, self.n_samples * self.upsampling, # self.sampling_rate * self.upsampling, # self.amplitude, self.noise_type, time_domain=False) - + # function that does not re-calculate parameters in each simulated trace spec = self.noise.bandlimited_noise_from_precalculated_parameters(self.noise_type, time_domain=False) spec *= self.filt @@ -328,7 +337,6 @@ def __generation(self): self._traces[iCh] = perfect_floor_comparator(trace, self.adc_n_bits, self.adc_ref_voltage) - def __phasing(self): """ separated phasing part for PA noise trigger """ @@ -349,33 +357,37 @@ def __triggering(self): self.max_amp = 0 # take square over entire array - coh_sum_squared = self._phased_traces**2 + coh_sum_squared = self._phased_traces ** 2 # bin the data into windows of length self.step and normalise to step length - reduced_array = np.add.reduceat(coh_sum_squared.T,np.arange(0,np.shape(coh_sum_squared)[1],self.step)).T / self.step + reduced_array = np.add.reduceat(coh_sum_squared.T, np.arange(0, np.shape(coh_sum_squared)[1], self.step)).T / self.step sliding_windows = [] # self.window can extend over multiple steps, # assuming self.window being an integer multiple of self.step the reduction sums over subsequent steps - steps_per_window = self.window//self.step + steps_per_window = self.window // self.step # better extend the array in order to also trigger on sum of last/first (matching a previous implementation) - extended_reduced_array = np.column_stack([reduced_array, reduced_array[:,0:steps_per_window]]) + extended_reduced_array = np.column_stack([reduced_array, reduced_array[:, 0:steps_per_window]]) for offset in range(steps_per_window): # sum over steps_per_window adjacent steps window_sum = np.add.reduceat(extended_reduced_array.T, np.arange(offset, np.shape(extended_reduced_array)[1], steps_per_window)).T / steps_per_window sliding_windows.append(window_sum) - #self.max_amp = max(np.array(sliding_windows).max(), self.max_amp) + # self.max_amp = max(np.array(sliding_windows).max(), self.max_amp) self.max_amp = np.array(sliding_windows).max() # check if trigger condition is fulfilled anywhere if self.max_amp > self.threshold: - # check in which beam the trigger condition was fulfilled - sliding_windows = np.concatenate(sliding_windows, axis=1) - triggered_beams = np.amax(sliding_windows, axis=1) > self.threshold - for iBeam, is_triggered in enumerate(triggered_beams): - # print out each beam that has triggered - if is_triggered: - logger.info(f"triggered at beam {iBeam}") + sliding_windows = np.array(sliding_windows) + tmp = np.argwhere(sliding_windows > self.threshold) + triggered_step = tmp[0][0] + triggered_bin = tmp[0][2] * (self.window + triggered_step * steps_per_window) if(self.debug): + # check in which beam the trigger condition was fulfilled + sliding_windows = np.concatenate(sliding_windows, axis=1) + triggered_beams = np.amax(sliding_windows, axis=1) > self.threshold + for iBeam, is_triggered in enumerate(triggered_beams): + # print out each beam that has triggered + if is_triggered: + logger.info(f"triggered at beam {iBeam}") import matplotlib.pyplot as plt fig, ax = plt.subplots(5, 1, sharex=True) for iCh in range(self.n_channels): @@ -384,8 +396,8 @@ def __triggering(self): ax[4].plot(self._phased_traces[iBeam]) fig.tight_layout() plt.show() - return True - return False + return True, triggered_bin + return False, None def __triggering_strided(self): """ separated trigger part for PA noise trigger using np.lib.stride_tricks.as_strided """ @@ -398,7 +410,7 @@ def __triggering_strided(self): coh_sum_windowed = np.lib.stride_tricks.as_strided(coh_sum_squared, (num_frames, self.window), (coh_sum_squared.strides[0] * self.step, coh_sum_squared.strides[0])) squared_mean = np.sum(coh_sum_windowed, axis=1) / self.window - #self.max_amp = max(squared_mean.max(), self.max_amp) + # self.max_amp = max(squared_mean.max(), self.max_amp) self.max_amp = max(squared_mean.max(), self.max_amp) if True in (squared_mean > self.threshold): logger.info(f"triggered at beam {iBeam}") @@ -414,7 +426,6 @@ def __triggering_strided(self): return True return False - def generate_noise(self, phasing_mode="slice", trigger_mode="binned_sum", debug=False): """ generates noise traces for all channels that will cause a high/low majority logic trigger @@ -447,7 +458,7 @@ def generate_noise(self, phasing_mode="slice", trigger_mode="binned_sum", debug= while True: counter += 1 if(counter % 1000 == 0): - logger.info(f"{counter:d}, {self.max_amp:.2f}, threshold = {self.threshold:.2f}") + logger.info(f"{counter:d}, {self.max_amp:.2g}, threshold = {self.threshold:.2g}") # some printout for profiling logger.info(f"Time consumption: GENERATION: {dt_generation:.4f}, PHASING: {dt_phasing:.4f}, TRIGGER: {dt_triggering:.4f}") tstart = time.process_time() @@ -467,12 +478,12 @@ def generate_noise(self, phasing_mode="slice", trigger_mode="binned_sum", debug= logger.error(f"Requested phasing_mode {phasing_mode}. Only 'slice' and 'roll' are allowed") raise NotImplementedError(f"Requested phasing_mode {phasing_mode}. Only 'slice' and 'roll' are allowed") - # time profiling phasing + # time profiling phasing dt_phasing += time.process_time() - tstart tstart = time.process_time() if trigger_mode == "binned_sum": - is_triggered = self.__triggering() + is_triggered, triggered_bin = self.__triggering() elif trigger_mode == "stride": # more time consuming attempt to do triggering compared to taking binned sums is_triggered = self.__triggering_strided() @@ -484,7 +495,14 @@ def generate_noise(self, phasing_mode="slice", trigger_mode="binned_sum", debug= dt_triggering += time.process_time() - tstart if is_triggered: - return self._traces, self._phased_traces + triggered_bin = triggered_bin // 2 # the trace is cut in the downsampled version. Therefore, triggered bin is factor of two smaller. + i_low = triggered_bin - self.pre_trigger_bins + i_high = i_low + self.n_samples_trigger + if (i_low >= 0) and (i_high < self.n_samples): + # traces need to be downsampled + # resample and use axis -1 since trace might be either shape (N) for analytic trace or shape (3,N) for E-field + self._traces = scipy.signal.resample(self._traces, np.shape(self._traces)[-1] // self.upsampling, axis=-1) + return self._traces[:, i_low:i_high], self._phased_traces def generate_noise2(self, debug=False): """ @@ -499,7 +517,7 @@ def generate_noise2(self, debug=False): while True: counter += 1 if(counter % 1000 == 0): - print(f"{counter:d}, {max_amp:.2f}, threshold = {self.threshold:.2f}") + print(f"{counter:d}, {max_amp:.3g}, threshold = {self.threshold:.3g}") for iCh in range(self.n_channels): spec = self.noise.bandlimited_noise(self.min_freq, self.max_freq, self.n_samples * self.upsampling, self.sampling_rate * self.upsampling, From ec31b0360b60a0ee1dcb10ce0be6c254443b0c4a Mon Sep 17 00:00:00 2001 From: Christian Glaser Date: Thu, 20 Jan 2022 12:14:57 +0000 Subject: [PATCH 024/418] update changelog, change to Philox --- NuRadioReco/modules/channelGenericNoiseAdder.py | 8 ++++---- changelog.txt | 3 +++ 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/NuRadioReco/modules/channelGenericNoiseAdder.py b/NuRadioReco/modules/channelGenericNoiseAdder.py index e8a4acfd9..e5556c02a 100644 --- a/NuRadioReco/modules/channelGenericNoiseAdder.py +++ b/NuRadioReco/modules/channelGenericNoiseAdder.py @@ -2,7 +2,7 @@ from NuRadioReco.modules.base.module import register_run import numpy as np from NuRadioReco.utilities import units, fft -import numpy.random +from numpy.random import Generator, Philox import logging @@ -27,7 +27,7 @@ def add_random_phases(self, amps, n_samples_time_domain): """ amps = np.array(amps, dtype='complex') Np = (n_samples_time_domain - 1) // 2 - phases = self.__random_generator.rand(Np) * 2 * np.pi + phases = self.__random_generator.random(Np) * 2 * np.pi phases = np.cos(phases) + 1j * np.sin(phases) amps[1:Np + 1] *= phases # Note that the last entry of the index slice is f[Np] ! @@ -45,7 +45,7 @@ def fftnoise_fullfft(self, f): """ f = np.array(f, dtype='complex') Np = (len(f) - 1) // 2 - phases = self.__random_generator.rand(Np) * 2 * np.pi + phases = self.__random_generator.random(Np) * 2 * np.pi phases = np.cos(phases) + 1j * np.sin(phases) f[1:Np + 1] *= phases # Note that the last entry of the index slice is f[Np] ! f[-1:-1 - Np:-1] = np.conj(f[1:Np + 1]) @@ -308,7 +308,7 @@ def __init__(self): def begin(self, debug=False, seed=None): self.__debug = debug - self.__random_generator = np.random.RandomState(seed) + self.__random_generator = Generator(Philox(seed)) if debug: self.logger.setLevel(logging.DEBUG) diff --git a/changelog.txt b/changelog.txt index ccafe7d7e..3fbc11bed 100644 --- a/changelog.txt +++ b/changelog.txt @@ -2,6 +2,9 @@ Changelog - to keep track of all relevant changes please update the categories "new features" and "bugfixes" before a pull request merge! +version 2.1.6-dev +features: +- calculate trigger time and cut trace accordingly in the phased array noise generation utility class. version 2.1.5 bugfixes: From 7b36068212db20904ea4258f01789202e6fbb4c2 Mon Sep 17 00:00:00 2001 From: Christian Glaser Date: Thu, 12 May 2022 12:24:48 +0000 Subject: [PATCH 025/418] show that failed tests are due to change in random generator --- NuRadioReco/modules/channelGenericNoiseAdder.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/NuRadioReco/modules/channelGenericNoiseAdder.py b/NuRadioReco/modules/channelGenericNoiseAdder.py index e5556c02a..8f2f9bf57 100644 --- a/NuRadioReco/modules/channelGenericNoiseAdder.py +++ b/NuRadioReco/modules/channelGenericNoiseAdder.py @@ -3,6 +3,7 @@ import numpy as np from NuRadioReco.utilities import units, fft from numpy.random import Generator, Philox +import numpy.random import logging @@ -308,7 +309,8 @@ def __init__(self): def begin(self, debug=False, seed=None): self.__debug = debug - self.__random_generator = Generator(Philox(seed)) + self.__random_generator = np.random.RandomState(seed) + # self.__random_generator = Generator(Philox(seed)) if debug: self.logger.setLevel(logging.DEBUG) From 2c167acfb15ea3cf18d99937ec4510d82dd3ba62 Mon Sep 17 00:00:00 2001 From: Christian Glaser Date: Thu, 12 May 2022 13:53:35 +0000 Subject: [PATCH 026/418] change noise generator back to Philox --- NuRadioMC/test/SingleEvents/validate.sh | 4 ++-- NuRadioReco/modules/channelGenericNoiseAdder.py | 4 +--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/NuRadioMC/test/SingleEvents/validate.sh b/NuRadioMC/test/SingleEvents/validate.sh index 15b567380..920bf15af 100755 --- a/NuRadioMC/test/SingleEvents/validate.sh +++ b/NuRadioMC/test/SingleEvents/validate.sh @@ -1,5 +1,5 @@ #!/bin/bash -python T02RunSimulation.py 1e18_output_reference.hdf5 surface_station_1GHz.json config.yaml 1e18_output.hdf5 1e18_output.nur +python3 T02RunSimulation.py 1e18_output_reference.hdf5 surface_station_1GHz.json config.yaml 1e18_output.hdf5 1e18_output.nur -python T03validate.py 1e18_output.hdf5 1e18_output_reference.hdf5 +python3 T03validate.py 1e18_output.hdf5 1e18_output_reference.hdf5 diff --git a/NuRadioReco/modules/channelGenericNoiseAdder.py b/NuRadioReco/modules/channelGenericNoiseAdder.py index 8f2f9bf57..e5556c02a 100644 --- a/NuRadioReco/modules/channelGenericNoiseAdder.py +++ b/NuRadioReco/modules/channelGenericNoiseAdder.py @@ -3,7 +3,6 @@ import numpy as np from NuRadioReco.utilities import units, fft from numpy.random import Generator, Philox -import numpy.random import logging @@ -309,8 +308,7 @@ def __init__(self): def begin(self, debug=False, seed=None): self.__debug = debug - self.__random_generator = np.random.RandomState(seed) - # self.__random_generator = Generator(Philox(seed)) + self.__random_generator = Generator(Philox(seed)) if debug: self.logger.setLevel(logging.DEBUG) From a9d6002216ae4ae6324ae1f3a4a26423e9ad28f3 Mon Sep 17 00:00:00 2001 From: sjoerd-bouma Date: Mon, 11 Jul 2022 21:49:43 +0200 Subject: [PATCH 027/418] reduce number of events in iterator (maybe solves memory issues on online data browser?) --- NuRadioReco/modules/io/rno_g/readRNOGData.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/NuRadioReco/modules/io/rno_g/readRNOGData.py b/NuRadioReco/modules/io/rno_g/readRNOGData.py index 9126e8b03..c077811f5 100755 --- a/NuRadioReco/modules/io/rno_g/readRNOGData.py +++ b/NuRadioReco/modules/io/rno_g/readRNOGData.py @@ -70,12 +70,12 @@ def begin(self, input_files): def _set_iterators(self, cut=None): """ Set uproot iterators to loop over event trees - + Parameters ---------- cut: str cut string to apply (e.g. for initial event selection based on event_number, ... - e.g. "(event_number==1)" or "(run_number==1)&(event_number<10)" + e.g. "(event_number==1)" or "(run_number==1)&(event_number<10)" """ self.__id_current_event = -1 @@ -92,7 +92,7 @@ def _set_iterators(self, cut=None): # read_branches = ['run_number', 'event_number', 'station_number', 'radiant_data[24][2048]'] self._iterator_data = uproot.iterate(datadict, cut=cut,step_size=1, how=dict, library="np") - self.uproot_iterator_data = uproot.iterate(datadict, cut=cut, step_size=1000) + self.uproot_iterator_data = uproot.iterate(datadict, cut=cut, step_size=256) @register_run() def run(self, channels=np.arange(24), event_numbers=None, run_numbers=None, cut_string=None): @@ -115,7 +115,7 @@ def run(self, channels=np.arange(24), event_numbers=None, run_numbers=None, cut_ selection string for event pre-selection Cavieat: use only if event_numbers and run_numbers are not set """ - + # generate cut string based on passed event_numbers or run_numbers parameters if not run_numbers is None: event_cuts = "|".join(["(run_number==%i)" for run_number in run_numbers]) @@ -151,7 +151,7 @@ def run(self, channels=np.arange(24), event_numbers=None, run_numbers=None, cut_ if self.__id_current_event > 0: eta = (time.time() - self.__t) / self.__id_current_event * (self.n_events - self.__id_current_event) / 60. self.logger.warning("reading in event {}/{} ({:.0f}%) ETA: {:.1f} minutes".format(self.__id_current_event, self.n_events, 100 * progress, eta)) - + run_number = event["run_number"] evt_number = event["event_number"] station_id = event["station_number"] From 8eb627a70d190c5b73363e18786dbccc951d01fa Mon Sep 17 00:00:00 2001 From: sjoerd-bouma Date: Mon, 1 Aug 2022 19:32:25 +0200 Subject: [PATCH 028/418] Singleton metaclass no longer alters class signature --- NuRadioReco/utilities/metaclasses.py | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/NuRadioReco/utilities/metaclasses.py b/NuRadioReco/utilities/metaclasses.py index 63d1074de..fffefaeb0 100644 --- a/NuRadioReco/utilities/metaclasses.py +++ b/NuRadioReco/utilities/metaclasses.py @@ -1,21 +1,31 @@ class Singleton(type): """ Can be assigned to classes as a metaclass. - By default, only one instance of a Singleton can exist at a time, as the __call__ method is overwritten to + + By default, only one instance of a Singleton can exist at a time, + as the ``__call__`` method is overwritten to return the existing instance if one exists. """ _instances = {} - def __call__(cls, create_new=False, *args, **kwargs): + def __call__(cls, *args, **kwargs): """ - Overwrites the __call__ method to check if an instance of the class already exists - and returns that instance instead of creating a new one. + Overwrites the __call__ method + + Checks if an instance of the class already exists + and returns that instance instead of creating a new one, unless + ``create_new=True`` is specified. Parameters ---------- create_new: bool (default:False) - If set to true, a new instance will always be created, event if one already exists. + If set to true, a new instance will always be created, even if one already exists. """ + if 'create_new' in kwargs.keys(): + create_new = kwargs['create_new'] + kwargs.pop('create_new') # this kwarg should not be passed on to the class! + else: + create_new = False # the default if Singleton._instances.get(cls, None) is None or create_new: Singleton._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs) return Singleton._instances[cls] From 5847398c81c1eef477926a7e505ef853bb85a8d3 Mon Sep 17 00:00:00 2001 From: sjoerd-bouma Date: Thu, 11 Aug 2022 16:01:58 +0200 Subject: [PATCH 029/418] added block offset fitter for RNO-G --- .../modules/RNO_G/channelBlockOffsetFitter.py | 240 ++++++++++++++++++ 1 file changed, 240 insertions(+) create mode 100644 NuRadioReco/modules/RNO_G/channelBlockOffsetFitter.py diff --git a/NuRadioReco/modules/RNO_G/channelBlockOffsetFitter.py b/NuRadioReco/modules/RNO_G/channelBlockOffsetFitter.py new file mode 100644 index 000000000..67412e62f --- /dev/null +++ b/NuRadioReco/modules/RNO_G/channelBlockOffsetFitter.py @@ -0,0 +1,240 @@ +from NuRadioReco.utilities import units +from NuRadioReco.framework.base_trace import BaseTrace +# from iminuit import Minuit +import numpy as np +import scipy + +class channelBlockOffsets: + + def __init__(self, block_size=128, max_frequency=51*units.MHz): + """ + Initialize block offset fitter. + + Parameters: + ----------- + block_size: int (default: 128) + The size (in samples) of the blocks + max_frequency: float (default: 51 MHz) + The maximum frequency to include in the out-of-band + block offset fit + + """ + self.sampling_rate = None + self.block_size = block_size # the size (in samples) of the blocks + self._offset_guess = dict() + self._offset_fit = dict() + self._offset_inject = dict() + self._max_frequency = max_frequency + + def add_offsets(self, event, station, offsets=1*units.mV, channel_ids=None): + """ + Add (simulated or reconstructed) block offsets to an event. + + Parameters + ---------- + event: `NuRadioReco.framework.event.Event` | None + station: `NuRadioReco.framework.station.Station` + The station to add block offsets to + offsets: float | array | dict + offsets to add to the event. Default: 1 mV + + - if a float, add gaussian-distributed of amplitude `offsets` + to all channels specified; + - if an array, the length should be the same as the number + of blocks in a single trace, and the entries will be + interpreted as the amplitudes of the offsets; + - if a dict, the keys should be the channel ids, and each + value should contain either a float or an array to add to + each channel as specified above. + + channel_ids: list | None + either a list of channel ids to apply the offsets to, or + None to apply the offsets to all channels in the station + (default: None). + + """ + + if channel_ids is None: + channel_ids = station.get_channel_ids() + for channel_id in channel_ids: + channel = station.get_channel(channel_id) + if isinstance(offsets, dict): + add_offsets = offsets[channel_id] + elif len(np.atleast_1d(offsets)) == 1: + add_offsets = np.random.normal( + 0, offsets, (channel.get_number_of_samples() // self.block_size) + ) + else: + add_offsets = offsets + if channel_id in self._offset_inject.keys(): + self._offset_inject[channel_id] += add_offsets + else: + self._offset_inject[channel_id] = add_offsets + + channel.set_trace( + channel.get_trace() + np.repeat(add_offsets, self.block_size), + channel.get_sampling_rate() + ) + + def remove_offsets(self, event, station, offsets='fit', channel_ids=None): + """ + Remove block offsets from an event + + Fits and removes the block offsets from an event. + + Parameters + ---------- + event: `NuRadioReco.framework.event.Event` | None + station: `NuRadioReco.framework.station.Station` + The station to remove the block offsets from + offsets: str + How to remove the offsets. Options are: + + - 'fit': fit the offsets out of band + - 'guess': similar to 'fit', but just take + a first guess at the offsets from the out-of-band region + without actually performing the fit. + - 'injected': if offsets were injected using the `add_offsets` + method, this removes those offsets. Otherwise, this does nothing. + + Default: 'fit' + channel_ids: list | None + List of channel ids to remove offsets from. If None (default), + remove offsets from all channels in `station` + + """ + if offsets=='fit': + if not len(self._offset_fit): + self.fit_offsets(event, station, channel_ids) + offsets = self._offset_fit + elif offsets=='guess': + offsets = self._offset_guess + elif offsets=='injected': + if not len(self._offset_inject): + offsets = np.zeros(16) #TODO - ensure this works for different trace lengths + else: + offsets = self._offset_inject + + if isinstance(offsets, dict): + remove_offsets = {key: -offsets[key] for key in offsets.keys()} + else: + remove_offsets = -offsets + self.add_offsets(event, station, remove_offsets, channel_ids) + + def fit_offsets(self, event, station, channel_ids=None): + """ + Fit the block offsets using an out-of-band fit + + This function fits the block offsets present in a given + event / station using an out-of-band fit in frequency space. + + Parameters + ---------- + event: `NuRadioReco.framework.event.Event` | None + station: `NuRadioReco.framework.station.Station` + The station to fit the block offsets to + channel_ids: list | None + List of channel ids to fit block offsets for. If None (default), + fit offsets for all channels in `station` + + """ + block_size = self.block_size + if channel_ids is None: + channel_ids = station.get_channel_ids() + for channel_id in channel_ids: + channel = station.get_channel(channel_id) + trace = channel.get_trace() + + # we use the bandpass-filtered trace to get a first estimate of + # the block offsets, by simply averaging over each block. + filtered_trace = channel.get_filtered_trace([0, self._max_frequency], 'rectangular') + self.sampling_rate = channel.get_sampling_rate() + n_blocks = len(trace) // block_size + + # obtain guesses for block offsets + a_guess = np.array([ + np.mean(filtered_trace[i*block_size:(i+1)*block_size]) + for i in range(n_blocks) + ]) + self._offset_guess[channel_id] = a_guess + # we can get rid of one parameter through a global shift + a_guess = a_guess[:-1] - a_guess[-1] + frequencies = channel.get_frequencies() + spectrum = channel.get_frequency_spectrum() + + # we perform the fit out-of-band, in order to avoid + # distorting any actual signal + mask = (frequencies > 0) & (frequencies < self._max_frequency) + + frequencies_oob = frequencies[mask] + spectrum_oob = spectrum[mask] + + ns = self.block_size + dt = 1/self.sampling_rate + + # most of the terms in the fit depend only on the frequencies, + # sampling rate and number of blocks. We therefore calculate these + # only once, outside the fit function. + pre_factor_exponent = np.array([ + -2.j * np.pi * frequencies_oob * dt * ((j+.5) * ns - .5) + for j in range(len(a_guess)) + ]) + self._const_fft_term = ( + 1 / self.sampling_rate * np.sqrt(2) # NuRadio FFT normalization + * np.exp(pre_factor_exponent) + * np.sin(np.pi*frequencies_oob*ns*dt)[None] + / np.sin(np.pi*frequencies_oob*dt)[None] + ) + self._spectrum = spectrum_oob + res = scipy.optimize.fmin( + self._pedestal_fit, a_guess, disp=0) + ### Minuit seems a lot quicker than scipy - not sure why? + # m = Minuit(self._pedestal_fit_minuit, a_guess * nufft_conversion_factor) + # m.errordef = 1 + # m.errors = 0.01 * np.ones_like(a_guess) + # m.migrad(ncall=20000) + # res = m.values + block_offsets = np.zeros(len(res) + 1) + block_offsets[:-1] = res + # the fit is not sensitive to an overall shift, + # so we include the zero-meaning here + block_offsets += np.mean(trace) - np.mean(block_offsets) + + self._offset_fit[channel_id] = block_offsets + + def get_offsets(self, channel_id, offset_type='fit'): + """ + Return the block offsets for a given channel. + + Parameters + ---------- + channel_id: int + channel id that specifies the channel to return block offsets for + offset_type: str + Options: + + - 'fit': return the fitted block offsets + - 'guess': return the first guess for the block offsets + - 'injected': return the block offsets that were injected + using the `add_offsets` method. + + Returns + ------- + trace: `BaseTrace` + A `BaseTrace` object with the same length as the channel trace, + containing only the block offsets. + + """ + trace = BaseTrace() + if offset_type == 'fit': + trace.set_trace(np.repeat(self._offset_fit[channel_id], self.block_size), self.sampling_rate) + elif offset_type == 'guess': + trace.set_trace(np.repeat(self._offset_guess[channel_id], self.block_size), self.sampling_rate) + elif offset_type == 'injected': + trace.set_trace(np.repeat(self._offset_inject[channel_id], self.block_size), self.sampling_rate) + return trace + + def _pedestal_fit(self, a): + fit = np.sum(a[:, None] * self._const_fft_term, axis=0) + chi2 = np.sum(np.abs(fit-self._spectrum)**2) + return chi2 \ No newline at end of file From 27babda38d9ccfa66e5e1a0d8f2ba8b83065d9b9 Mon Sep 17 00:00:00 2001 From: sjoerd-bouma Date: Thu, 11 Aug 2022 16:36:35 +0200 Subject: [PATCH 030/418] fix docstrings --- .../modules/RNO_G/channelBlockOffsetFitter.py | 35 ++++++++++--------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/NuRadioReco/modules/RNO_G/channelBlockOffsetFitter.py b/NuRadioReco/modules/RNO_G/channelBlockOffsetFitter.py index 67412e62f..a4444b535 100644 --- a/NuRadioReco/modules/RNO_G/channelBlockOffsetFitter.py +++ b/NuRadioReco/modules/RNO_G/channelBlockOffsetFitter.py @@ -8,10 +8,13 @@ class channelBlockOffsets: def __init__(self, block_size=128, max_frequency=51*units.MHz): """ - Initialize block offset fitter. + Add or remove block offsets to channel traces - Parameters: - ----------- + This module adds, fits or removes 'block offsets' by fitting + them in a specified out-of-band region in frequency space. + + Parameters + ---------- block_size: int (default: 128) The size (in samples) of the blocks max_frequency: float (default: 51 MHz) @@ -32,13 +35,13 @@ def add_offsets(self, event, station, offsets=1*units.mV, channel_ids=None): Parameters ---------- - event: `NuRadioReco.framework.event.Event` | None - station: `NuRadioReco.framework.station.Station` + event: Event object | None + station: Station The station to add block offsets to offsets: float | array | dict offsets to add to the event. Default: 1 mV - - if a float, add gaussian-distributed of amplitude `offsets` + - if a float, add gaussian-distributed of amplitude ``offsets`` to all channels specified; - if an array, the length should be the same as the number of blocks in a single trace, and the entries will be @@ -84,8 +87,8 @@ def remove_offsets(self, event, station, offsets='fit', channel_ids=None): Parameters ---------- - event: `NuRadioReco.framework.event.Event` | None - station: `NuRadioReco.framework.station.Station` + event: NuRadioReco.framework.event.Event | None + station: NuRadioReco.framework.station.Station The station to remove the block offsets from offsets: str How to remove the offsets. Options are: @@ -94,13 +97,13 @@ def remove_offsets(self, event, station, offsets='fit', channel_ids=None): - 'guess': similar to 'fit', but just take a first guess at the offsets from the out-of-band region without actually performing the fit. - - 'injected': if offsets were injected using the `add_offsets` + - 'injected': if offsets were injected using the ``add_offsets`` method, this removes those offsets. Otherwise, this does nothing. Default: 'fit' channel_ids: list | None List of channel ids to remove offsets from. If None (default), - remove offsets from all channels in `station` + remove offsets from all channels in ``station`` """ if offsets=='fit': @@ -130,12 +133,12 @@ def fit_offsets(self, event, station, channel_ids=None): Parameters ---------- - event: `NuRadioReco.framework.event.Event` | None - station: `NuRadioReco.framework.station.Station` + event: NuRadioReco.framework.event.Event | None + station: NuRadioReco.framework.station.Station The station to fit the block offsets to channel_ids: list | None List of channel ids to fit block offsets for. If None (default), - fit offsets for all channels in `station` + fit offsets for all channels in ``station`` """ block_size = self.block_size @@ -216,12 +219,12 @@ def get_offsets(self, channel_id, offset_type='fit'): - 'fit': return the fitted block offsets - 'guess': return the first guess for the block offsets - 'injected': return the block offsets that were injected - using the `add_offsets` method. + using the ``add_offsets`` method. Returns ------- - trace: `BaseTrace` - A `BaseTrace` object with the same length as the channel trace, + trace: BaseTrace + A :class:`NuRadioReco.framework.base_trace.BaseTrace` object with the same length as the channel trace, containing only the block offsets. """ From 0dad153be4b49dfd1b69a287149d129e547325c3 Mon Sep 17 00:00:00 2001 From: Felix Schlueter Date: Tue, 6 Sep 2022 01:50:41 -0500 Subject: [PATCH 031/418] Update gitignore to cover output files created with run_all_tests.sh. The list is incomplete (my tests did not run through because I am missing some externals --- .gitignore | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.gitignore b/.gitignore index 4409f607b..0728357f4 100644 --- a/.gitignore +++ b/.gitignore @@ -123,3 +123,10 @@ venv.bak/ # ignore .nur files in NuRadioReco/examples/ # this should not apply for NuRadioReco/examples/example_data/ NuRadioReco/examples/*.nur + +# ignore test output (not include input files here!) +NuRadioMC/test/SingleEvents/1e18_output.nur +NuRadioMC/test/SingleEvents/1e18_output_ARZ.hdf5 +NuRadioMC/test/SingleEvents/1e18_output_noise.hdf5 +NuRadioMC/test/SingleEvents/MB_1e18_output.hdf5 +NuRadioMC/test/Veff/1e18eV/output.nur From ffeb64195c3822387fe7c3dc4503e4fb99b57f62 Mon Sep 17 00:00:00 2001 From: Felix Schlueter Date: Wed, 7 Sep 2022 05:28:19 -0500 Subject: [PATCH 032/418] Clean up output files of automatic testing after validation --- NuRadioMC/test/SingleEvents/test_build.sh | 3 +++ NuRadioMC/test/SingleEvents/validate.sh | 4 ++++ NuRadioMC/test/SingleEvents/validate_ARZ.sh | 5 ++++- NuRadioMC/test/SingleEvents/validate_MB.sh | 5 ++++- NuRadioMC/test/Veff/1e18eV/test_build.sh | 3 +++ 5 files changed, 18 insertions(+), 2 deletions(-) diff --git a/NuRadioMC/test/SingleEvents/test_build.sh b/NuRadioMC/test/SingleEvents/test_build.sh index ee61b8b43..391869b5e 100755 --- a/NuRadioMC/test/SingleEvents/test_build.sh +++ b/NuRadioMC/test/SingleEvents/test_build.sh @@ -6,3 +6,6 @@ python3 NuRadioMC/test/SingleEvents/T04validate_allmost_equal.py NuRadioMC/test/ python3 NuRadioMC/test/SingleEvents/T05validate_nur_file.py NuRadioMC/test/SingleEvents/1e18_output.nur NuRadioMC/test/SingleEvents/1e18_output_reference.nur python3 NuRadioMC/test/SingleEvents/T02RunSimulation.py NuRadioMC/test/SingleEvents/1e18_output_reference.hdf5 NuRadioMC/test/SingleEvents/surface_station_1GHz.json NuRadioMC/test/SingleEvents/config_noise.yaml NuRadioMC/test/SingleEvents/1e18_output_noise.hdf5 python3 NuRadioMC/test/SingleEvents/T04validate_allmost_equal.py NuRadioMC/test/SingleEvents/1e18_output_noise.hdf5 NuRadioMC/test/SingleEvents/1e18_output_noise_reference.hdf5 + +# cleanup +rm -v 1e18_output_noise.hdf5 1e18_output.hdf5 1e18_output.nur \ No newline at end of file diff --git a/NuRadioMC/test/SingleEvents/validate.sh b/NuRadioMC/test/SingleEvents/validate.sh index 15b567380..47c782218 100755 --- a/NuRadioMC/test/SingleEvents/validate.sh +++ b/NuRadioMC/test/SingleEvents/validate.sh @@ -3,3 +3,7 @@ python T02RunSimulation.py 1e18_output_reference.hdf5 surface_station_1GHz.json config.yaml 1e18_output.hdf5 1e18_output.nur python T03validate.py 1e18_output.hdf5 1e18_output_reference.hdf5 + + +# cleanup +rm -v 1e18_output.hdf5 \ No newline at end of file diff --git a/NuRadioMC/test/SingleEvents/validate_ARZ.sh b/NuRadioMC/test/SingleEvents/validate_ARZ.sh index 81d84bc13..9927bcc67 100755 --- a/NuRadioMC/test/SingleEvents/validate_ARZ.sh +++ b/NuRadioMC/test/SingleEvents/validate_ARZ.sh @@ -1,4 +1,7 @@ #!/bin/bash set -e NuRadioMC/test/SingleEvents/T02RunSimulation.py NuRadioMC/test/SingleEvents/1e18_output_ARZ_reference.hdf5 NuRadioMC/test/SingleEvents/surface_station_1GHz.json NuRadioMC/test/SingleEvents/config_ARZ.yaml NuRadioMC/test/SingleEvents/1e18_output_ARZ.hdf5 -NuRadioMC/test/SingleEvents/T04validate_allmost_equal.py NuRadioMC/test/SingleEvents/1e18_output_ARZ.hdf5 NuRadioMC/test/SingleEvents/1e18_output_ARZ_reference.hdf5 \ No newline at end of file +NuRadioMC/test/SingleEvents/T04validate_allmost_equal.py NuRadioMC/test/SingleEvents/1e18_output_ARZ.hdf5 NuRadioMC/test/SingleEvents/1e18_output_ARZ_reference.hdf5 + +# cleanup +rm -v 1e18_output_ARZ.hdf5 \ No newline at end of file diff --git a/NuRadioMC/test/SingleEvents/validate_MB.sh b/NuRadioMC/test/SingleEvents/validate_MB.sh index b5da1c0f1..9cee19dd5 100755 --- a/NuRadioMC/test/SingleEvents/validate_MB.sh +++ b/NuRadioMC/test/SingleEvents/validate_MB.sh @@ -3,4 +3,7 @@ set -e NuRadioMC/test/SingleEvents/T02RunSimulation.py NuRadioMC/test/SingleEvents/MB_1e18_reference.hdf5 NuRadioMC/test/SingleEvents/surface_station_1GHz.json NuRadioMC/test/SingleEvents/config_MB.yaml NuRadioMC/test/SingleEvents/MB_1e18_output.hdf5 -NuRadioMC/test/SingleEvents/T04validate_allmost_equal.py NuRadioMC/test/SingleEvents/MB_1e18_output.hdf5 NuRadioMC/test/SingleEvents/MB_1e18_reference.hdf5 \ No newline at end of file +NuRadioMC/test/SingleEvents/T04validate_allmost_equal.py NuRadioMC/test/SingleEvents/MB_1e18_output.hdf5 NuRadioMC/test/SingleEvents/MB_1e18_reference.hdf5 + +# cleanup +rm -v MB_1e18_output.hdf5 \ No newline at end of file diff --git a/NuRadioMC/test/Veff/1e18eV/test_build.sh b/NuRadioMC/test/Veff/1e18eV/test_build.sh index c5181a7d6..871783fc8 100755 --- a/NuRadioMC/test/Veff/1e18eV/test_build.sh +++ b/NuRadioMC/test/Veff/1e18eV/test_build.sh @@ -6,3 +6,6 @@ NuRadioMC/test/Veff/1e18eV/T01generate_event_list.py NuRadioMC/test/Veff/1e18eV/T02RunSimulation.py 1e18_full.hdf5 ../dipole_100m.json ../config.yaml output.hdf5 output.nur NuRadioMC/test/Veff/1e18eV/T03check_output.py + +# cleanup +rm -v output.nur \ No newline at end of file From 976c22f2a0e5eb5bd4ce5545838bb5bd71adddcb Mon Sep 17 00:00:00 2001 From: Felix Schlueter Date: Thu, 8 Sep 2022 11:15:13 +0200 Subject: [PATCH 033/418] Update shebang to use python3 --- NuRadioMC/SignalGen/ARZ/ARZ.py | 2 +- NuRadioMC/SignalGen/ARZ/tests/T01CompareWithFast.py | 2 +- NuRadioMC/SignalGen/ARZ/tests/T02TestARZ.py | 2 +- NuRadioMC/SignalGen/ARZ/tests/T04InterpolationFactors.py | 2 +- NuRadioMC/test/SignalGen/U01unit_test.py | 2 +- NuRadioMC/test/SignalProp/T04MooresBay.py | 2 +- NuRadioMC/test/SingleEvents/M01generate_event_list.py | 2 +- NuRadioMC/test/SingleEvents/T01generate_event_list.py | 2 +- NuRadioMC/test/SingleEvents/T02RunSimulation.py | 2 +- NuRadioMC/test/SingleEvents/T03validate.py | 2 +- NuRadioMC/test/SingleEvents/T04validate_allmost_equal.py | 2 +- NuRadioMC/test/SingleEvents/T05validate_nur_file.py | 2 +- NuRadioMC/test/Veff/1e18eV/T01generate_event_list.py | 2 +- NuRadioMC/test/Veff/1e18eV/T01generate_event_list_noise.py | 2 +- NuRadioMC/test/Veff/1e18eV/T02RunSimulation.py | 2 +- NuRadioMC/test/Veff/1e18eV/T03check_output.py | 2 +- NuRadioMC/test/Veff/1e18eV/T03check_output_noise.py | 2 +- .../test/atmospheric_Aeff/1e18eV/T01generate_event_list.py | 2 +- NuRadioMC/test/atmospheric_Aeff/1e18eV/T02RunSimulation.py | 2 +- NuRadioMC/test/atmospheric_Aeff/1e18eV/T03check_output.py | 2 +- NuRadioMC/test/emitter/T02RunSimulation.py | 2 +- NuRadioMC/test/examples/validate_radio_emitter_allmost_equal.py | 2 +- NuRadioReco/test/tiny_reconstruction/TinyReconstruction.py | 2 +- NuRadioReco/test/tiny_reconstruction/compareToReference.py | 2 +- NuRadioReco/test/trigger_tests/compare_to_reference.py | 2 +- NuRadioReco/test/trigger_tests/generate_events.py | 2 +- NuRadioReco/test/trigger_tests/trigger_tests.py | 2 +- 27 files changed, 27 insertions(+), 27 deletions(-) diff --git a/NuRadioMC/SignalGen/ARZ/ARZ.py b/NuRadioMC/SignalGen/ARZ/ARZ.py index 002fb6c01..e2d868f29 100644 --- a/NuRadioMC/SignalGen/ARZ/ARZ.py +++ b/NuRadioMC/SignalGen/ARZ/ARZ.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # -*- coding: utf-8 -*- import numpy as np from NuRadioReco.utilities import units, io_utilities diff --git a/NuRadioMC/SignalGen/ARZ/tests/T01CompareWithFast.py b/NuRadioMC/SignalGen/ARZ/tests/T01CompareWithFast.py index 4a3a45948..ab947ef03 100644 --- a/NuRadioMC/SignalGen/ARZ/tests/T01CompareWithFast.py +++ b/NuRadioMC/SignalGen/ARZ/tests/T01CompareWithFast.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # -*- coding: utf-8 -*- import numpy as np from NuRadioReco.utilities import units diff --git a/NuRadioMC/SignalGen/ARZ/tests/T02TestARZ.py b/NuRadioMC/SignalGen/ARZ/tests/T02TestARZ.py index b8913b6fb..8f7165a96 100644 --- a/NuRadioMC/SignalGen/ARZ/tests/T02TestARZ.py +++ b/NuRadioMC/SignalGen/ARZ/tests/T02TestARZ.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # -*- coding: utf-8 -*- import numpy as np from NuRadioReco.utilities import units diff --git a/NuRadioMC/SignalGen/ARZ/tests/T04InterpolationFactors.py b/NuRadioMC/SignalGen/ARZ/tests/T04InterpolationFactors.py index 58b201241..9648718e1 100644 --- a/NuRadioMC/SignalGen/ARZ/tests/T04InterpolationFactors.py +++ b/NuRadioMC/SignalGen/ARZ/tests/T04InterpolationFactors.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # -*- coding: utf-8 -*- import numpy as np from NuRadioReco.utilities import units diff --git a/NuRadioMC/test/SignalGen/U01unit_test.py b/NuRadioMC/test/SignalGen/U01unit_test.py index f77eb43fa..3fe051de1 100755 --- a/NuRadioMC/test/SignalGen/U01unit_test.py +++ b/NuRadioMC/test/SignalGen/U01unit_test.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 from NuRadioMC.SignalGen.askaryan import get_time_trace, get_frequency_spectrum from NuRadioReco.utilities import units from NuRadioReco.utilities import io_utilities diff --git a/NuRadioMC/test/SignalProp/T04MooresBay.py b/NuRadioMC/test/SignalProp/T04MooresBay.py index 2a4f6c66f..73c86052b 100644 --- a/NuRadioMC/test/SignalProp/T04MooresBay.py +++ b/NuRadioMC/test/SignalProp/T04MooresBay.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # -*- coding: utf-8 -*- from __future__ import division, print_function import numpy as np diff --git a/NuRadioMC/test/SingleEvents/M01generate_event_list.py b/NuRadioMC/test/SingleEvents/M01generate_event_list.py index 0370be073..056f630c5 100644 --- a/NuRadioMC/test/SingleEvents/M01generate_event_list.py +++ b/NuRadioMC/test/SingleEvents/M01generate_event_list.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 from __future__ import absolute_import, division, print_function from NuRadioReco.utilities import units from NuRadioMC.EvtGen.generator import generate_eventlist_cylinder diff --git a/NuRadioMC/test/SingleEvents/T01generate_event_list.py b/NuRadioMC/test/SingleEvents/T01generate_event_list.py index 61d71c333..618edad12 100644 --- a/NuRadioMC/test/SingleEvents/T01generate_event_list.py +++ b/NuRadioMC/test/SingleEvents/T01generate_event_list.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 from __future__ import absolute_import, division, print_function from NuRadioReco.utilities import units from NuRadioMC.EvtGen.generator import generate_eventlist_cylinder diff --git a/NuRadioMC/test/SingleEvents/T02RunSimulation.py b/NuRadioMC/test/SingleEvents/T02RunSimulation.py index 70ca92412..d353dd159 100755 --- a/NuRadioMC/test/SingleEvents/T02RunSimulation.py +++ b/NuRadioMC/test/SingleEvents/T02RunSimulation.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 from __future__ import absolute_import, division, print_function import argparse # import detector simulation modules diff --git a/NuRadioMC/test/SingleEvents/T03validate.py b/NuRadioMC/test/SingleEvents/T03validate.py index 008e9c06b..997f43dbb 100755 --- a/NuRadioMC/test/SingleEvents/T03validate.py +++ b/NuRadioMC/test/SingleEvents/T03validate.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 from __future__ import absolute_import, division, print_function import sys import h5py diff --git a/NuRadioMC/test/SingleEvents/T04validate_allmost_equal.py b/NuRadioMC/test/SingleEvents/T04validate_allmost_equal.py index 96dfc64c8..b5363c9d5 100755 --- a/NuRadioMC/test/SingleEvents/T04validate_allmost_equal.py +++ b/NuRadioMC/test/SingleEvents/T04validate_allmost_equal.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 from __future__ import absolute_import, division, print_function import sys import h5py diff --git a/NuRadioMC/test/SingleEvents/T05validate_nur_file.py b/NuRadioMC/test/SingleEvents/T05validate_nur_file.py index b30ca007c..a608cae4a 100755 --- a/NuRadioMC/test/SingleEvents/T05validate_nur_file.py +++ b/NuRadioMC/test/SingleEvents/T05validate_nur_file.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 import sys from numpy import testing import numpy as np diff --git a/NuRadioMC/test/Veff/1e18eV/T01generate_event_list.py b/NuRadioMC/test/Veff/1e18eV/T01generate_event_list.py index 8ac979209..0b7f887fe 100755 --- a/NuRadioMC/test/Veff/1e18eV/T01generate_event_list.py +++ b/NuRadioMC/test/Veff/1e18eV/T01generate_event_list.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 from __future__ import absolute_import, division, print_function import os from NuRadioReco.utilities import units diff --git a/NuRadioMC/test/Veff/1e18eV/T01generate_event_list_noise.py b/NuRadioMC/test/Veff/1e18eV/T01generate_event_list_noise.py index b52446cb9..1ce5f361c 100755 --- a/NuRadioMC/test/Veff/1e18eV/T01generate_event_list_noise.py +++ b/NuRadioMC/test/Veff/1e18eV/T01generate_event_list_noise.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 from __future__ import absolute_import, division, print_function import os from NuRadioReco.utilities import units diff --git a/NuRadioMC/test/Veff/1e18eV/T02RunSimulation.py b/NuRadioMC/test/Veff/1e18eV/T02RunSimulation.py index 0c8e5c057..0407a85a7 100755 --- a/NuRadioMC/test/Veff/1e18eV/T02RunSimulation.py +++ b/NuRadioMC/test/Veff/1e18eV/T02RunSimulation.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 from __future__ import absolute_import, division, print_function import argparse # import detector simulation modules diff --git a/NuRadioMC/test/Veff/1e18eV/T03check_output.py b/NuRadioMC/test/Veff/1e18eV/T03check_output.py index 5e08809ba..f514c8462 100755 --- a/NuRadioMC/test/Veff/1e18eV/T03check_output.py +++ b/NuRadioMC/test/Veff/1e18eV/T03check_output.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 import numpy as np import h5py from NuRadioReco.utilities import units diff --git a/NuRadioMC/test/Veff/1e18eV/T03check_output_noise.py b/NuRadioMC/test/Veff/1e18eV/T03check_output_noise.py index ee2311566..bc820f6ca 100755 --- a/NuRadioMC/test/Veff/1e18eV/T03check_output_noise.py +++ b/NuRadioMC/test/Veff/1e18eV/T03check_output_noise.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 import numpy as np import h5py from NuRadioReco.utilities import units diff --git a/NuRadioMC/test/atmospheric_Aeff/1e18eV/T01generate_event_list.py b/NuRadioMC/test/atmospheric_Aeff/1e18eV/T01generate_event_list.py index 76d8b4b34..4607e3eaa 100755 --- a/NuRadioMC/test/atmospheric_Aeff/1e18eV/T01generate_event_list.py +++ b/NuRadioMC/test/atmospheric_Aeff/1e18eV/T01generate_event_list.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 from __future__ import absolute_import, division, print_function import os from NuRadioReco.utilities import units diff --git a/NuRadioMC/test/atmospheric_Aeff/1e18eV/T02RunSimulation.py b/NuRadioMC/test/atmospheric_Aeff/1e18eV/T02RunSimulation.py index e6016e68f..0866d18e4 100755 --- a/NuRadioMC/test/atmospheric_Aeff/1e18eV/T02RunSimulation.py +++ b/NuRadioMC/test/atmospheric_Aeff/1e18eV/T02RunSimulation.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 from __future__ import absolute_import, division, print_function import argparse # import detector simulation modules diff --git a/NuRadioMC/test/atmospheric_Aeff/1e18eV/T03check_output.py b/NuRadioMC/test/atmospheric_Aeff/1e18eV/T03check_output.py index f0eb70dc8..e02b8e6fd 100755 --- a/NuRadioMC/test/atmospheric_Aeff/1e18eV/T03check_output.py +++ b/NuRadioMC/test/atmospheric_Aeff/1e18eV/T03check_output.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 import numpy as np import h5py from NuRadioReco.utilities import units diff --git a/NuRadioMC/test/emitter/T02RunSimulation.py b/NuRadioMC/test/emitter/T02RunSimulation.py index 66c60cb05..e6203ad6e 100755 --- a/NuRadioMC/test/emitter/T02RunSimulation.py +++ b/NuRadioMC/test/emitter/T02RunSimulation.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 from __future__ import absolute_import, division, print_function import argparse # import detector simulation modules diff --git a/NuRadioMC/test/examples/validate_radio_emitter_allmost_equal.py b/NuRadioMC/test/examples/validate_radio_emitter_allmost_equal.py index a989e3a91..5251a75d4 100755 --- a/NuRadioMC/test/examples/validate_radio_emitter_allmost_equal.py +++ b/NuRadioMC/test/examples/validate_radio_emitter_allmost_equal.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 from __future__ import absolute_import, division, print_function import sys import h5py diff --git a/NuRadioReco/test/tiny_reconstruction/TinyReconstruction.py b/NuRadioReco/test/tiny_reconstruction/TinyReconstruction.py index adab77d34..535f9a788 100755 --- a/NuRadioReco/test/tiny_reconstruction/TinyReconstruction.py +++ b/NuRadioReco/test/tiny_reconstruction/TinyReconstruction.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 import os import sys import datetime diff --git a/NuRadioReco/test/tiny_reconstruction/compareToReference.py b/NuRadioReco/test/tiny_reconstruction/compareToReference.py index 037ecfa6b..76c381542 100644 --- a/NuRadioReco/test/tiny_reconstruction/compareToReference.py +++ b/NuRadioReco/test/tiny_reconstruction/compareToReference.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 import json import NuRadioReco.modules.io.eventReader import argparse diff --git a/NuRadioReco/test/trigger_tests/compare_to_reference.py b/NuRadioReco/test/trigger_tests/compare_to_reference.py index 215b1aa37..c11d604bd 100644 --- a/NuRadioReco/test/trigger_tests/compare_to_reference.py +++ b/NuRadioReco/test/trigger_tests/compare_to_reference.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 import json import NuRadioReco.modules.io.eventReader import argparse diff --git a/NuRadioReco/test/trigger_tests/generate_events.py b/NuRadioReco/test/trigger_tests/generate_events.py index 17c272f63..9bee68905 100644 --- a/NuRadioReco/test/trigger_tests/generate_events.py +++ b/NuRadioReco/test/trigger_tests/generate_events.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 import NuRadioReco.modules.efieldToVoltageConverter import NuRadioReco.modules.trigger.simpleThreshold import NuRadioReco.modules.channelResampler diff --git a/NuRadioReco/test/trigger_tests/trigger_tests.py b/NuRadioReco/test/trigger_tests/trigger_tests.py index 8fc08d98c..efdbb50e6 100644 --- a/NuRadioReco/test/trigger_tests/trigger_tests.py +++ b/NuRadioReco/test/trigger_tests/trigger_tests.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 import NuRadioReco.detector.detector import NuRadioReco.modules.io.eventReader import NuRadioReco.modules.io.eventWriter From ee3e353900bbddc68df3f248c8448e89ff766099 Mon Sep 17 00:00:00 2001 From: Felix Schlueter Date: Thu, 8 Sep 2022 11:26:34 +0200 Subject: [PATCH 034/418] Add .vscode to .gitignore --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 0728357f4..4fede08b6 100644 --- a/.gitignore +++ b/.gitignore @@ -108,6 +108,9 @@ venv.bak/ # dolphin .directory +# VSCode +.vscode/ + # eclipse .project .pydevproject From b478e404de2a249c03f4234235d57036f018f4bb Mon Sep 17 00:00:00 2001 From: Felix Schlueter Date: Thu, 8 Sep 2022 11:35:46 +0200 Subject: [PATCH 035/418] Fix paths --- NuRadioMC/test/SingleEvents/test_build.sh | 2 +- NuRadioMC/test/SingleEvents/validate.sh | 2 +- NuRadioMC/test/SingleEvents/validate_ARZ.sh | 2 +- NuRadioMC/test/SingleEvents/validate_MB.sh | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/NuRadioMC/test/SingleEvents/test_build.sh b/NuRadioMC/test/SingleEvents/test_build.sh index 391869b5e..ae40adaf2 100755 --- a/NuRadioMC/test/SingleEvents/test_build.sh +++ b/NuRadioMC/test/SingleEvents/test_build.sh @@ -8,4 +8,4 @@ python3 NuRadioMC/test/SingleEvents/T02RunSimulation.py NuRadioMC/test/SingleEve python3 NuRadioMC/test/SingleEvents/T04validate_allmost_equal.py NuRadioMC/test/SingleEvents/1e18_output_noise.hdf5 NuRadioMC/test/SingleEvents/1e18_output_noise_reference.hdf5 # cleanup -rm -v 1e18_output_noise.hdf5 1e18_output.hdf5 1e18_output.nur \ No newline at end of file +rm -v NuRadioMC/test/SingleEvents/{1e18_output_noise.hdf5,1e18_output.hdf5,1e18_output.nur} \ No newline at end of file diff --git a/NuRadioMC/test/SingleEvents/validate.sh b/NuRadioMC/test/SingleEvents/validate.sh index 47c782218..5aa12b647 100755 --- a/NuRadioMC/test/SingleEvents/validate.sh +++ b/NuRadioMC/test/SingleEvents/validate.sh @@ -6,4 +6,4 @@ python T03validate.py 1e18_output.hdf5 1e18_output_reference.hdf5 # cleanup -rm -v 1e18_output.hdf5 \ No newline at end of file +rm -v NuRadioMC/test/SingleEvents/1e18_output.hdf5 \ No newline at end of file diff --git a/NuRadioMC/test/SingleEvents/validate_ARZ.sh b/NuRadioMC/test/SingleEvents/validate_ARZ.sh index 9927bcc67..c52e45c0b 100755 --- a/NuRadioMC/test/SingleEvents/validate_ARZ.sh +++ b/NuRadioMC/test/SingleEvents/validate_ARZ.sh @@ -4,4 +4,4 @@ NuRadioMC/test/SingleEvents/T02RunSimulation.py NuRadioMC/test/SingleEvents/1e18 NuRadioMC/test/SingleEvents/T04validate_allmost_equal.py NuRadioMC/test/SingleEvents/1e18_output_ARZ.hdf5 NuRadioMC/test/SingleEvents/1e18_output_ARZ_reference.hdf5 # cleanup -rm -v 1e18_output_ARZ.hdf5 \ No newline at end of file +rm -v NuRadioMC/test/SingleEvents/1e18_output_ARZ.hdf5 \ No newline at end of file diff --git a/NuRadioMC/test/SingleEvents/validate_MB.sh b/NuRadioMC/test/SingleEvents/validate_MB.sh index 9cee19dd5..0857eefe4 100755 --- a/NuRadioMC/test/SingleEvents/validate_MB.sh +++ b/NuRadioMC/test/SingleEvents/validate_MB.sh @@ -6,4 +6,4 @@ NuRadioMC/test/SingleEvents/T02RunSimulation.py NuRadioMC/test/SingleEvents/MB_1 NuRadioMC/test/SingleEvents/T04validate_allmost_equal.py NuRadioMC/test/SingleEvents/MB_1e18_output.hdf5 NuRadioMC/test/SingleEvents/MB_1e18_reference.hdf5 # cleanup -rm -v MB_1e18_output.hdf5 \ No newline at end of file +rm -v NuRadioMC/test/SingleEvents/MB_1e18_output.hdf5 \ No newline at end of file From ba9705bca2242355d426e34355818f94bfb681cf Mon Sep 17 00:00:00 2001 From: Felix Schlueter Date: Thu, 8 Sep 2022 13:56:47 +0200 Subject: [PATCH 036/418] fix paths --- NuRadioMC/test/Veff/1e18eV/test_build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NuRadioMC/test/Veff/1e18eV/test_build.sh b/NuRadioMC/test/Veff/1e18eV/test_build.sh index 871783fc8..086f2d3d0 100755 --- a/NuRadioMC/test/Veff/1e18eV/test_build.sh +++ b/NuRadioMC/test/Veff/1e18eV/test_build.sh @@ -8,4 +8,4 @@ NuRadioMC/test/Veff/1e18eV/T02RunSimulation.py 1e18_full.hdf5 ../dipole_100m.js NuRadioMC/test/Veff/1e18eV/T03check_output.py # cleanup -rm -v output.nur \ No newline at end of file +rm -v NuRadioMC/test/Veff/1e18eV/output.{nur,hdf5} \ No newline at end of file From a6191720d2cc360719c7af5dc9c37d649c00c5d5 Mon Sep 17 00:00:00 2001 From: Felix Schlueter Date: Thu, 8 Sep 2022 13:57:02 +0200 Subject: [PATCH 037/418] Add comment in top level gitignore --- .gitignore | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.gitignore b/.gitignore index 4fede08b6..138ccec0a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,8 @@ +############################################################# +# Keep in might that sub-directories might contain additional +# .gitignore files to exclude specific files. +############################################################# + # Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] From 59531693c47a5e9569d0b9f5357c08150b470b76 Mon Sep 17 00:00:00 2001 From: Felix Schlueter Date: Thu, 8 Sep 2022 17:30:10 +0200 Subject: [PATCH 038/418] add more clean ups. Changed outfile of one test (was not used anywhere) --- .../test/tiny_reconstruction/testTinyReconstruction.sh | 3 +++ NuRadioReco/test/trigger_tests/generate_events.py | 2 +- NuRadioReco/test/trigger_tests/run_trigger_test.sh | 5 +++++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/NuRadioReco/test/tiny_reconstruction/testTinyReconstruction.sh b/NuRadioReco/test/tiny_reconstruction/testTinyReconstruction.sh index 5534a8771..0ce1fc0c9 100755 --- a/NuRadioReco/test/tiny_reconstruction/testTinyReconstruction.sh +++ b/NuRadioReco/test/tiny_reconstruction/testTinyReconstruction.sh @@ -2,3 +2,6 @@ set -e cd NuRadioReco/test/tiny_reconstruction python3 TinyReconstruction.py python3 compareToReference.py MC_example_station_32.nur reference.json + +# clean up +rm -v MC_example_station_32.nur \ No newline at end of file diff --git a/NuRadioReco/test/trigger_tests/generate_events.py b/NuRadioReco/test/trigger_tests/generate_events.py index 9bee68905..fd7baf600 100644 --- a/NuRadioReco/test/trigger_tests/generate_events.py +++ b/NuRadioReco/test/trigger_tests/generate_events.py @@ -26,7 +26,7 @@ def _detector_simulation_trigger(self, evt, station, det): sim = mySimulation( inputfilename='NuRadioReco/test/trigger_tests/trigger_test_eventlist.hdf5', - outputfilename='input.hdf5', + outputfilename='NuRadioReco/test/trigger_tests/trigger_test_input.hdf5', detectorfile='NuRadioReco/test/trigger_tests/trigger_test_detector.json', outputfilenameNuRadioReco='NuRadioReco/test/trigger_tests/trigger_test_input.nur', config_file='NuRadioReco/test/trigger_tests/config.yaml', diff --git a/NuRadioReco/test/trigger_tests/run_trigger_test.sh b/NuRadioReco/test/trigger_tests/run_trigger_test.sh index 11fde7000..7e1d06674 100755 --- a/NuRadioReco/test/trigger_tests/run_trigger_test.sh +++ b/NuRadioReco/test/trigger_tests/run_trigger_test.sh @@ -4,3 +4,8 @@ set -e python3 NuRadioReco/test/trigger_tests/generate_events.py python3 NuRadioReco/test/trigger_tests/trigger_tests.py python3 NuRadioReco/test/trigger_tests/compare_to_reference.py + +# clean up +rm -v NuRadioReco/test/trigger_tests/trigger_test_input.hdf5 +rm -v NuRadioReco/test/trigger_tests/trigger_test_input.nur +rm -v NuRadioReco/test/trigger_tests/trigger_test_output.nur \ No newline at end of file From 216a63bc5e9b5235be7c4303d0f0a5be05e10b5e Mon Sep 17 00:00:00 2001 From: Felix Schlueter Date: Thu, 8 Sep 2022 17:51:21 +0200 Subject: [PATCH 039/418] add clean up --- NuRadioReco/test/test_examples.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/NuRadioReco/test/test_examples.sh b/NuRadioReco/test/test_examples.sh index b91dc3605..0fde08ab0 100755 --- a/NuRadioReco/test/test_examples.sh +++ b/NuRadioReco/test/test_examples.sh @@ -8,6 +8,7 @@ rm minimal_eventlist.hdf5 rm output_PA*hdf5 cd ../Noise_trigger_rate python3 T01MeasureNoiselevel.py --ntries 10 +rm -v *xupsampling.txt cd ../SNR_curves python3 T01generate_event_list.py python3 T02RunSNR.py --inputfilename 25.0deg_12/25.00_12_00_1.00e+18_1.26e+18/input/25.00_12_00_1.00e+18_1.26e+18.hdf5 --detectordescription ../Effective_volume/8antennas_100m_0.5GHz.json --config config.yaml --outputfilename output_file.hdf5 --outputSNR output_snr.json From 672ad6285c90f402e7f4d3e24b528bc082d384a3 Mon Sep 17 00:00:00 2001 From: Felix Schlueter Date: Fri, 9 Sep 2022 10:33:46 +0200 Subject: [PATCH 040/418] clean up gitignores. Make top level gitignore more general. remove redundant entries --- .gitignore | 12 +++++------- .../examples/03_station_coincidences/.gitignore | 2 -- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/.gitignore b/.gitignore index 138ccec0a..56271c45c 100644 --- a/.gitignore +++ b/.gitignore @@ -91,7 +91,6 @@ celerybeat-schedule # Environments .env .venv -env/ venv/ ENV/ env.bak/ @@ -132,9 +131,8 @@ venv.bak/ # this should not apply for NuRadioReco/examples/example_data/ NuRadioReco/examples/*.nur -# ignore test output (not include input files here!) -NuRadioMC/test/SingleEvents/1e18_output.nur -NuRadioMC/test/SingleEvents/1e18_output_ARZ.hdf5 -NuRadioMC/test/SingleEvents/1e18_output_noise.hdf5 -NuRadioMC/test/SingleEvents/MB_1e18_output.hdf5 -NuRadioMC/test/Veff/1e18eV/output.nur +# ignore test output (not include input or reference files here!) +*output*.nur +*output*.hdf5 +!*reference*.nur +!*reference*.hdf5 \ No newline at end of file diff --git a/NuRadioMC/examples/03_station_coincidences/.gitignore b/NuRadioMC/examples/03_station_coincidences/.gitignore index 4e32aa6bb..ea33cf0ad 100644 --- a/NuRadioMC/examples/03_station_coincidences/.gitignore +++ b/NuRadioMC/examples/03_station_coincidences/.gitignore @@ -1,4 +1,2 @@ -*.png -*.pdf det.json horizontal_spacing_detector.json From afc7bed014ac21c6fd5d3f184842f78e758280db Mon Sep 17 00:00:00 2001 From: sjoerd-bouma Date: Fri, 9 Sep 2022 15:18:09 +0200 Subject: [PATCH 041/418] add trigger times to HDF5 output --- NuRadioMC/simulation/simulation.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/NuRadioMC/simulation/simulation.py b/NuRadioMC/simulation/simulation.py index 572eddda0..5d85ef366 100644 --- a/NuRadioMC/simulation/simulation.py +++ b/NuRadioMC/simulation/simulation.py @@ -1204,6 +1204,7 @@ def _create_trigger_structures(self): # we first create this data structure if('multiple_triggers' not in self._mout): self._mout['multiple_triggers'] = np.zeros((self._n_showers, len(self._mout_attrs['trigger_names'])), dtype=np.bool) + self._mout['trigger_times'] = np.nan * np.zeros_like(self._mout['multiple_triggers'], dtype=float) # for station_id in self._station_ids: # sg = self._mout_groups[station_id] # sg['multiple_triggers'] = np.zeros((self._n_showers, len(self._mout_attrs['trigger_names'])), dtype=np.bool) @@ -1212,6 +1213,10 @@ def _create_trigger_structures(self): nx, ny = self._mout['multiple_triggers'].shape tmp[:, 0:ny] = self._mout['multiple_triggers'] self._mout['multiple_triggers'] = tmp + # repeat for trigger times + tmp_t = np.nan * np.zeros_like(tmp, dtype=float) + tmp_t[:, 0:ny] = self._mout['trigger_times'] + self._mout['trigger_times'] = tmp_t # for station_id in self._station_ids: # sg = self._mout_groups[station_id] # tmp = np.zeros((self._n_showers, len(self._mout_attrs['trigger_names'])), dtype=np.bool) @@ -1228,25 +1233,35 @@ def _save_triggers_to_hdf5(self, sg, local_shower_index, global_shower_index): n_showers = sg['launch_vectors'].shape[0] if('multiple_triggers' not in sg): sg['multiple_triggers'] = np.zeros((n_showers, len(self._mout_attrs['trigger_names'])), dtype=np.bool) + sg['trigger_times'] = np.nan * np.zeros_like(sg['multiple_triggers'], dtype=float) elif(extend_array): tmp = np.zeros((n_showers, len(self._mout_attrs['trigger_names'])), dtype=np.bool) nx, ny = sg['multiple_triggers'].shape tmp[:, 0:ny] = sg['multiple_triggers'] sg['multiple_triggers'] = tmp + # repeat for trigger times + tmp_t = np.nan * np.zeros_like(tmp, dtype=float) + tmp_t[:, :ny] = sg['trigger_times'] + sg['trigger_times'] = tmp_t self._output_event_group_ids[self._station_id].append(self._evt.get_run_number()) self._output_sub_event_ids[self._station_id].append(self._evt.get_id()) multiple_triggers = np.zeros(len(self._mout_attrs['trigger_names']), dtype=np.bool) + trigger_times = np.nan*np.zeros_like(multiple_triggers) for iT, trigger_name in enumerate(self._mout_attrs['trigger_names']): if(self._station.has_trigger(trigger_name)): multiple_triggers[iT] = self._station.get_trigger(trigger_name).has_triggered() + trigger_times[iT] = self._station.get_trigger(trigger_name).get_trigger_time() for iSh in local_shower_index: # now save trigger information per shower of the current station sg['multiple_triggers'][iSh][iT] = self._station.get_trigger(trigger_name).has_triggered() + sg['trigger_times'][iSh][iT] = trigger_times[iT] for iSh, iSh2 in zip(local_shower_index, global_shower_index): # now save trigger information per shower of the current station sg['triggered'][iSh] = np.any(sg['multiple_triggers'][iSh]) self._mout['triggered'][iSh2] |= sg['triggered'][iSh] self._mout['multiple_triggers'][iSh2] |= sg['multiple_triggers'][iSh] + self._mout['trigger_times'][iSh2] = sg['trigger_times'][iSh] self._output_multiple_triggers_station[self._station_id].append(multiple_triggers) + self._output_trigger_times_station[self._station_id].append(trigger_times) self._output_triggered_station[self._station_id].append(np.any(multiple_triggers)) def get_Vrms(self): @@ -1286,6 +1301,7 @@ def _create_meta_output_datastructures(self): self._output_event_group_ids = {} self._output_sub_event_ids = {} self._output_multiple_triggers_station = {} + self._output_trigger_times_station = {} self._output_maximum_amplitudes = {} self._output_maximum_amplitudes_envelope = {} @@ -1296,6 +1312,7 @@ def _create_meta_output_datastructures(self): self._output_sub_event_ids[station_id] = [] self._output_triggered_station[station_id] = [] self._output_multiple_triggers_station[station_id] = [] + self._output_trigger_times_station[station_id] = [] self._output_maximum_amplitudes[station_id] = [] self._output_maximum_amplitudes_envelope[station_id] = [] @@ -1438,6 +1455,11 @@ def _write_output_file(self, empty=False): for iE, values in enumerate(self._output_multiple_triggers_station[station_id]): tmp[iE] = values sg['multiple_triggers_per_event'] = tmp + tmp_t = np.nan * np.zeros_like(tmp, dtype=float) + for iE, values in enumerate(self._output_trigger_times_station[station_id]): + tmp_t[iE] = values + sg['trigger_times_per_event'] = tmp_t + # save meta arguments for (key, value) in iteritems(self._mout_attrs): From 973f14c1e0639a62e7d7fcd6cb196895630b92eb Mon Sep 17 00:00:00 2001 From: sjoerd-bouma Date: Wed, 14 Sep 2022 15:28:20 +0200 Subject: [PATCH 042/418] change trigger_time -> readout_time --- NuRadioReco/modules/io/rno_g/rnogDataReader.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NuRadioReco/modules/io/rno_g/rnogDataReader.py b/NuRadioReco/modules/io/rno_g/rnogDataReader.py index 430ad1848..3eb78892f 100644 --- a/NuRadioReco/modules/io/rno_g/rnogDataReader.py +++ b/NuRadioReco/modules/io/rno_g/rnogDataReader.py @@ -83,7 +83,7 @@ def get_event_i(self, i_event): station.set_is_neutrino() if 'header' in file: - unix_time = file['header']['trigger_time'].array(library='np', entry_start=i_event_in_file, entry_stop=(i_event_in_file+1))[0] + unix_time = file['header']['readout_time'].array(library='np', entry_start=i_event_in_file, entry_stop=(i_event_in_file+1))[0] event_time = astropy.time.Time(unix_time, format='unix') station.set_station_time(event_time) ### read in basic trigger data From 37c88eb4517741fd1427d4d609d16c03061e31aa Mon Sep 17 00:00:00 2001 From: Bob Oeyen Date: Mon, 20 Dec 2021 11:13:01 +0100 Subject: [PATCH 043/418] Able to add modules to radiopropa ice outside medium.py --- NuRadioMC/utilities/medium.py | 19 ++++++------ NuRadioMC/utilities/medium_base.py | 50 +++++++++++++++++++++++++----- 2 files changed, 52 insertions(+), 17 deletions(-) diff --git a/NuRadioMC/utilities/medium.py b/NuRadioMC/utilities/medium.py index 81b760ae1..f85bfadf1 100644 --- a/NuRadioMC/utilities/medium.py +++ b/NuRadioMC/utilities/medium.py @@ -247,22 +247,22 @@ def get_gradient_of_index_of_refraction(self, position): return self._scalarfield.getGradient(pos) * (1 / (units.meter/RP.meter)) - def get_ice_model_radiopropa(self): + def compute_default_ice_model_radiopropa(self): """ - Returns an object holding the radiopropa scalarfield and necessary radiopropa moduldes - that define the medium in radiopropa. It uses the parameters of the medium object to - contruct some modules, like a discontinuity object for the air boundary. Additional modules - can be added in this function + Computes a default object holding the radiopropa scalarfield and necessary radiopropa + moduldes that define the medium in radiopropa. It uses the parameters of the medium + object to contruct some modules, like a discontinuity object for the air boundary. + Additional modules can be added in this function Overwrites function of the mother class Returns ------- - ice: RadioPropaIceWrapper - object holding the radiopropa scalarfield and modules + ice_model_radiopropa: RadioPropaIceWrapper + object holding the radiopropa scalarfield and modules """ - ice = medium_base.RadioPropaIceWrapper(self, self._scalarfield) - return ice + self._ice_model_radiopropa = medium_base.RadioPropaIceWrapper(self, self._scalarfield) + return self._ice_model_radiopropa class greenland_perturbation(greenland_firn): def __init__(self): @@ -288,7 +288,6 @@ def __init__(self, z_bottom=None): delta_n = 0, ) - def get_ice_model(name): """ function to access the right ice model class by name of the class diff --git a/NuRadioMC/utilities/medium_base.py b/NuRadioMC/utilities/medium_base.py index 4e741a17e..5959efe33 100644 --- a/NuRadioMC/utilities/medium_base.py +++ b/NuRadioMC/utilities/medium_base.py @@ -37,6 +37,7 @@ def __init__(self, z_air_boundary=0*units.meter, z_bottom=None): self.reflection = None self.reflection_coefficient = None self.reflection_phase_shift = None + self._ice_model_radiopropa = None def add_reflective_bottom(self, refl_z, refl_coef, refl_phase_shift): """ @@ -126,21 +127,56 @@ def get_gradient_of_index_of_refraction(self, position): raise NotImplementedError('function not defined') - def get_ice_model_radiopropa(self): + def compute_default_ice_model_radiopropa(self): """ if radiopropa is installed this will a RadioPropaIceWrapper object which can then be used to insert in the radiopropa tracer """ - if radiopropa_is_imported: - # when implementing a new ice_model this part of the function should be ice model specific - # if the new ice_model cannot be used in RadioPropa, this function should throw an error - logger.error('function not defined') - raise NotImplementedError('function not defined') - else: + if not radiopropa_is_imported: logger.error('The radiopropa dependancy was not import and can therefore not be used. \nMore info on https://github.com/nu-radio/RadioPropa') raise ImportError('RadioPropa could not be imported') + # when implementing a new ice_model this part of the function should be ice model specific + # if the new ice_model cannot be used in RadioPropa, this function should throw an error + + def get_ice_model_radiopropa(self): + """ + Returns an object holding the radiopropa scalarfield and necessary radiopropa moduldes + that define the medium in radiopropa. + + Returns + ------- + ice: RadioPropaIceWrapper + object holding the radiopropa scalarfield and modules + """ + if not radiopropa_is_imported: + logger.error('The radiopropa dependancy was not import and can therefore not be used. \nMore info on https://github.com/nu-radio/RadioPropa') + raise ImportError('RadioPropa could not be imported') + + if self._ice_model_radiopropa is None: + self._ice_model_radiopropa = self.compute_default_ice_model_radiopropa() + + return self._ice_model_radiopropa + + def set_ice_model_radiopropa(self, ice_model_radiopropa): + """ + If radiopropa is installed, this function can be used + to set a specific RadioPropaIceWrapper object as the + ice model used for RadioPropa. + + Parameters: + ----------- + ice_model_radioprop: RadioPropaIceWrapper + object holding the radiopropa scalarfield and modules + + """ + if not radiopropa_is_imported: + logger.error('The radiopropa dependancy was not import and can therefore not be used. \nMore info on https://github.com/nu-radio/RadioPropa') + raise ImportError('RadioPropa could not be imported') + + self._ice_model_radiopropa = ice_model_radiopropa + class IceModelSimple(IceModel): """ From de8b06854c74df4d7ffe1b1dd3e0d828d59080a5 Mon Sep 17 00:00:00 2001 From: Bob Oeyen Date: Mon, 19 Sep 2022 17:02:51 +0200 Subject: [PATCH 044/418] Add notimplementederror --- NuRadioMC/utilities/medium_base.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/NuRadioMC/utilities/medium_base.py b/NuRadioMC/utilities/medium_base.py index 5959efe33..8b4fa45ed 100644 --- a/NuRadioMC/utilities/medium_base.py +++ b/NuRadioMC/utilities/medium_base.py @@ -139,6 +139,8 @@ def compute_default_ice_model_radiopropa(self): # when implementing a new ice_model this part of the function should be ice model specific # if the new ice_model cannot be used in RadioPropa, this function should throw an error + logger.error('function not defined') + raise NotImplementedError('function not defined') def get_ice_model_radiopropa(self): """ From 9316e59d15c92593cea014351dd4a04de0ba6f48 Mon Sep 17 00:00:00 2001 From: Bob Oeyen Date: Mon, 19 Sep 2022 17:07:06 +0200 Subject: [PATCH 045/418] add doc string --- NuRadioMC/utilities/medium_base.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/NuRadioMC/utilities/medium_base.py b/NuRadioMC/utilities/medium_base.py index 8b4fa45ed..20a92a4bf 100644 --- a/NuRadioMC/utilities/medium_base.py +++ b/NuRadioMC/utilities/medium_base.py @@ -129,9 +129,17 @@ def get_gradient_of_index_of_refraction(self, position): def compute_default_ice_model_radiopropa(self): """ - if radiopropa is installed this will a RadioPropaIceWrapper object - which can then be used to insert in the radiopropa tracer + Computes a default object holding the radiopropa scalarfield and necessary radiopropa + moduldes that define the medium in radiopropa. It uses the parameters of the medium + object to contruct some modules, like a discontinuity object for the air boundary. + Additional modules can be added in this function + + Overwrites function of the mother class + Returns + ------- + ice_model_radiopropa: RadioPropaIceWrapper + object holding the radiopropa scalarfield and modules """ if not radiopropa_is_imported: logger.error('The radiopropa dependancy was not import and can therefore not be used. \nMore info on https://github.com/nu-radio/RadioPropa') From 2131ba053d39489774947d5ba7f91bcf9aecbaac Mon Sep 17 00:00:00 2001 From: Bob Oeyen Date: Mon, 19 Sep 2022 17:14:14 +0200 Subject: [PATCH 046/418] Update changelog --- changelog.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/changelog.txt b/changelog.txt index f5b9c03bd..7952d76f2 100644 --- a/changelog.txt +++ b/changelog.txt @@ -5,11 +5,11 @@ please update the categories "new features" and "bugfixes" before a pull request version 2.2.0 new features: - add attenuation model from the 2021 measurements taken at Summit Station -- print warning for positive z in attenuation, and set attenuation length to -+inf for positive z +- print warning for positive z in attenuation, and set attenuation length to +inf for positive z - adding minimize mode to the radiopropa propagation module & more configurable settings in config file - add uniform ice model with 1.78 refractive index - update ARA detector description and add a file to Print ARA detector json file +- adding default RadioPropa ice model object to medium with the feature to set a personlised object as alternative bugfixes: From abc4aa81abc6bbb3a0865794a0775c36bf1f8061 Mon Sep 17 00:00:00 2001 From: Bob Oeyen Date: Tue, 20 Sep 2022 10:03:24 +0200 Subject: [PATCH 047/418] Adjust existing models --- NuRadioMC/utilities/medium.py | 25 +++++++++++++++++++------ NuRadioMC/utilities/medium_base.py | 27 ++++++++++++++------------- 2 files changed, 33 insertions(+), 19 deletions(-) diff --git a/NuRadioMC/utilities/medium.py b/NuRadioMC/utilities/medium.py index f85bfadf1..3a60b5476 100644 --- a/NuRadioMC/utilities/medium.py +++ b/NuRadioMC/utilities/medium.py @@ -251,8 +251,8 @@ def compute_default_ice_model_radiopropa(self): """ Computes a default object holding the radiopropa scalarfield and necessary radiopropa moduldes that define the medium in radiopropa. It uses the parameters of the medium - object to contruct some modules, like a discontinuity object for the air boundary. - Additional modules can be added in this function + object to contruct the scalar field (using the firn ice model implementation + in radiopropa) and some modules (like a discontinuity object for the air boundary). Overwrites function of the mother class @@ -261,15 +261,27 @@ def compute_default_ice_model_radiopropa(self): ice_model_radiopropa: RadioPropaIceWrapper object holding the radiopropa scalarfield and modules """ - self._ice_model_radiopropa = medium_base.RadioPropaIceWrapper(self, self._scalarfield) - return self._ice_model_radiopropa + return medium_base.RadioPropaIceWrapper(self, self._scalarfield) class greenland_perturbation(greenland_firn): def __init__(self): greenland_firn.__init__(self) - def get_ice_model_radiopropa(self,discontinuity=False): - ice = greenland_firn.get_ice_model_radiopropa(self,discontinuity=discontinuity) + def compute_default_ice_model_radiopropa(self,discontinuity=False): + """ + Computes a default object holding the radiopropa scalarfield and necessary radiopropa + moduldes that define the medium in radiopropa. It uses the parameters of the medium + object to contruct some modules using the default computation of the firn model. + An additional module for the perturbation layer is then added to the object. + + Overwrites function of the mother class + + Returns + ------- + ice_model_radiopropa: RadioPropaIceWrapper + object holding the radiopropa scalarfield and modules + """ + ice = greenland_firn.compute_default_ice_model_radiopropa(self) #fraction from ArXiv 1805.12576 table IV last row perturbation_horz = RP.PerturbationHorizontal(-100*RP.meter,2*RP.meter, fraction=1) ice.add_module('horizontal perturbation',perturbation_horz) @@ -288,6 +300,7 @@ def __init__(self, z_bottom=None): delta_n = 0, ) + def get_ice_model(name): """ function to access the right ice model class by name of the class diff --git a/NuRadioMC/utilities/medium_base.py b/NuRadioMC/utilities/medium_base.py index 20a92a4bf..e51f6f9a0 100644 --- a/NuRadioMC/utilities/medium_base.py +++ b/NuRadioMC/utilities/medium_base.py @@ -315,13 +315,13 @@ def get_gradient_of_index_of_refraction(self, position): gradient[2] = -self.delta_n / self.z_0 * np.exp((position[2] - self.z_shift) / self.z_0) return gradient - def get_ice_model_radiopropa(self): + def compute_default_ice_model_radiopropa(self): """ - If radiopropa is installed this will return an object holding the radiopropa - scalarfield and necessary radiopropa moduldes that define the medium in radiopropa. - It uses the parameters of the medium object to contruct the scalar field using the - simple ice model implementation in radiopropa and some modules, like a discontinuity - object for the air boundary + If radiopropa is installed this will compute and return a default object holding the + radiopropa scalarfield and necessary radiopropa moduldes that define the medium in + radiopropa. It uses the parameters of the medium object to contruct the scalar field + using the simple ice model implementation in radiopropa and some modules, like a + discontinuity object for the air boundary Overwrites function of the mother class @@ -330,17 +330,18 @@ def get_ice_model_radiopropa(self): ice: RadioPropaIceWrapper object holding the radiopropa scalarfield and modules """ - if radiopropa_is_imported: - scalar_field = RP.IceModel_Simple(z_surface=self.z_air_boundary*RP.meter/units.meter, - n_ice=self.n_ice, delta_n=self.delta_n, - z_0=self.z_0*RP.meter/units.meter, - z_shift=self.z_shift*RP.meter/units.meter) - return RadioPropaIceWrapper(self, scalar_field) - else: + if not radiopropa_is_imported: logger.error('The radiopropa dependency was not import and can therefore not be used.' +'\nMore info on https://github.com/nu-radio/RadioPropa') raise ImportError('RadioPropa could not be imported') + scalar_field = RP.IceModel_Simple(z_surface=self.z_air_boundary*RP.meter/units.meter, + n_ice=self.n_ice, delta_n=self.delta_n, + z_0=self.z_0*RP.meter/units.meter, + z_shift=self.z_shift*RP.meter/units.meter) + return RadioPropaIceWrapper(self, scalar_field) + + if radiopropa_is_imported: From d0b82b9b0a1417580612b4d6fba579a622e1069e Mon Sep 17 00:00:00 2001 From: Bob Oeyen Date: Tue, 20 Sep 2022 10:40:56 +0200 Subject: [PATCH 048/418] More clear documentation --- NuRadioMC/utilities/medium.py | 6 +++--- NuRadioMC/utilities/medium_base.py | 23 ++++++++++++++++------- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/NuRadioMC/utilities/medium.py b/NuRadioMC/utilities/medium.py index 3a60b5476..8d8e9bf89 100644 --- a/NuRadioMC/utilities/medium.py +++ b/NuRadioMC/utilities/medium.py @@ -247,7 +247,7 @@ def get_gradient_of_index_of_refraction(self, position): return self._scalarfield.getGradient(pos) * (1 / (units.meter/RP.meter)) - def compute_default_ice_model_radiopropa(self): + def _compute_default_ice_model_radiopropa(self): """ Computes a default object holding the radiopropa scalarfield and necessary radiopropa moduldes that define the medium in radiopropa. It uses the parameters of the medium @@ -267,7 +267,7 @@ class greenland_perturbation(greenland_firn): def __init__(self): greenland_firn.__init__(self) - def compute_default_ice_model_radiopropa(self,discontinuity=False): + def _compute_default_ice_model_radiopropa(self,discontinuity=False): """ Computes a default object holding the radiopropa scalarfield and necessary radiopropa moduldes that define the medium in radiopropa. It uses the parameters of the medium @@ -281,7 +281,7 @@ def compute_default_ice_model_radiopropa(self,discontinuity=False): ice_model_radiopropa: RadioPropaIceWrapper object holding the radiopropa scalarfield and modules """ - ice = greenland_firn.compute_default_ice_model_radiopropa(self) + ice = greenland_firn._compute_default_ice_model_radiopropa(self) #fraction from ArXiv 1805.12576 table IV last row perturbation_horz = RP.PerturbationHorizontal(-100*RP.meter,2*RP.meter, fraction=1) ice.add_module('horizontal perturbation',perturbation_horz) diff --git a/NuRadioMC/utilities/medium_base.py b/NuRadioMC/utilities/medium_base.py index e51f6f9a0..ad83b3bb5 100644 --- a/NuRadioMC/utilities/medium_base.py +++ b/NuRadioMC/utilities/medium_base.py @@ -127,14 +127,15 @@ def get_gradient_of_index_of_refraction(self, position): raise NotImplementedError('function not defined') - def compute_default_ice_model_radiopropa(self): + def _compute_default_ice_model_radiopropa(self): """ Computes a default object holding the radiopropa scalarfield and necessary radiopropa moduldes that define the medium in radiopropa. It uses the parameters of the medium object to contruct some modules, like a discontinuity object for the air boundary. Additional modules can be added in this function - - Overwrites function of the mother class + + This is the default and should always be overriden/implemented in new ice model! + Returns ------- @@ -153,7 +154,13 @@ def compute_default_ice_model_radiopropa(self): def get_ice_model_radiopropa(self): """ Returns an object holding the radiopropa scalarfield and necessary radiopropa moduldes - that define the medium in radiopropa. + that define the medium in radiopropa. If no specific model is set by the user it returns + the default implemented model using the '_compute_default_ice_model_radiopropa' function. + + This seperation allows having the posibility to set a more specific/adjusted radiopropa + ice model in case they need it, without losing the access to the default model. + + DO NOT OVERRIDE THIS FUNCTION Returns ------- @@ -165,7 +172,7 @@ def get_ice_model_radiopropa(self): raise ImportError('RadioPropa could not be imported') if self._ice_model_radiopropa is None: - self._ice_model_radiopropa = self.compute_default_ice_model_radiopropa() + self._ice_model_radiopropa = self._compute_default_ice_model_radiopropa() return self._ice_model_radiopropa @@ -175,6 +182,8 @@ def set_ice_model_radiopropa(self, ice_model_radiopropa): to set a specific RadioPropaIceWrapper object as the ice model used for RadioPropa. + DO NOT OVERRIDE THIS FUNCTION + Parameters: ----------- ice_model_radioprop: RadioPropaIceWrapper @@ -315,13 +324,13 @@ def get_gradient_of_index_of_refraction(self, position): gradient[2] = -self.delta_n / self.z_0 * np.exp((position[2] - self.z_shift) / self.z_0) return gradient - def compute_default_ice_model_radiopropa(self): + def _compute_default_ice_model_radiopropa(self): """ If radiopropa is installed this will compute and return a default object holding the radiopropa scalarfield and necessary radiopropa moduldes that define the medium in radiopropa. It uses the parameters of the medium object to contruct the scalar field using the simple ice model implementation in radiopropa and some modules, like a - discontinuity object for the air boundary + discontinuity object for the air boundary. Overwrites function of the mother class From 072cabb05923a11c6322fb8e17d5817bfd02a862 Mon Sep 17 00:00:00 2001 From: Bob Oeyen Date: Tue, 20 Sep 2022 11:02:07 +0200 Subject: [PATCH 049/418] Remove : because of doc string error --- NuRadioMC/utilities/medium_base.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/NuRadioMC/utilities/medium_base.py b/NuRadioMC/utilities/medium_base.py index ad83b3bb5..1811993b6 100644 --- a/NuRadioMC/utilities/medium_base.py +++ b/NuRadioMC/utilities/medium_base.py @@ -184,8 +184,8 @@ def set_ice_model_radiopropa(self, ice_model_radiopropa): DO NOT OVERRIDE THIS FUNCTION - Parameters: - ----------- + Parameters + ---------- ice_model_radioprop: RadioPropaIceWrapper object holding the radiopropa scalarfield and modules From 392b5ca9a5f934dfd64129635d5a23491c1fa745 Mon Sep 17 00:00:00 2001 From: sjoerd-bouma Date: Fri, 30 Sep 2022 18:57:16 +0200 Subject: [PATCH 050/418] sort ray tracing solutions by C0 --- NuRadioMC/SignalProp/CPPAnalyticRayTracing/wrapper.pyx | 4 ++-- NuRadioMC/SignalProp/analyticraytracing.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/NuRadioMC/SignalProp/CPPAnalyticRayTracing/wrapper.pyx b/NuRadioMC/SignalProp/CPPAnalyticRayTracing/wrapper.pyx index 9753e1668..05e332da8 100644 --- a/NuRadioMC/SignalProp/CPPAnalyticRayTracing/wrapper.pyx +++ b/NuRadioMC/SignalProp/CPPAnalyticRayTracing/wrapper.pyx @@ -13,7 +13,7 @@ cdef extern from "numpy/arrayobject.h": cdef extern from "analytic_raytracing.cpp": void find_solutions2(double * &, double * &, int * &, int & , double, double, double, double, double, double, double, int, int, double) double get_attenuation_along_path2(double, double, double, double, double, double, double, double, double, int) - + cpdef find_solutions(x1, x2, n_ice, delta_n, z_0, reflection, reflection_case, ice_reflection): cdef: @@ -49,7 +49,7 @@ cpdef find_solutions(x1, x2, n_ice, delta_n, z_0, reflection, reflection_case, i 'reflection': reflection, 'reflection_case': reflection_case}) - s = sorted(solutions, key=itemgetter('type')) + s = sorted(solutions, key=itemgetter('C0')) # print((time.time() - t) * 1000) return s diff --git a/NuRadioMC/SignalProp/analyticraytracing.py b/NuRadioMC/SignalProp/analyticraytracing.py index 2c1329489..bb01124be 100644 --- a/NuRadioMC/SignalProp/analyticraytracing.py +++ b/NuRadioMC/SignalProp/analyticraytracing.py @@ -1133,7 +1133,7 @@ def find_solutions(self, x1, x2, plot=False, reflection=0, reflection_case=1): import matplotlib.pyplot as plt plt.show() - return sorted(results, key=itemgetter('type')) + return sorted(results, key=itemgetter('C0')) def plot_result(self, x1, x2, C_0, ax): """ From 37cd0702908040fc19f5fcf3f0ddf20a664374b0 Mon Sep 17 00:00:00 2001 From: sjoerd-bouma Date: Sat, 22 Oct 2022 13:41:29 +0200 Subject: [PATCH 051/418] changed block offset fit function to standalone --- .../modules/RNO_G/channelBlockOffsetFitter.py | 178 ++++++++++++------ 1 file changed, 118 insertions(+), 60 deletions(-) diff --git a/NuRadioReco/modules/RNO_G/channelBlockOffsetFitter.py b/NuRadioReco/modules/RNO_G/channelBlockOffsetFitter.py index a4444b535..c873f9d96 100644 --- a/NuRadioReco/modules/RNO_G/channelBlockOffsetFitter.py +++ b/NuRadioReco/modules/RNO_G/channelBlockOffsetFitter.py @@ -1,4 +1,4 @@ -from NuRadioReco.utilities import units +from NuRadioReco.utilities import units, fft from NuRadioReco.framework.base_trace import BaseTrace # from iminuit import Minuit import numpy as np @@ -24,7 +24,6 @@ def __init__(self, block_size=128, max_frequency=51*units.MHz): """ self.sampling_rate = None self.block_size = block_size # the size (in samples) of the blocks - self._offset_guess = dict() self._offset_fit = dict() self._offset_inject = dict() self._max_frequency = max_frequency @@ -148,61 +147,10 @@ def fit_offsets(self, event, station, channel_ids=None): channel = station.get_channel(channel_id) trace = channel.get_trace() - # we use the bandpass-filtered trace to get a first estimate of - # the block offsets, by simply averaging over each block. - filtered_trace = channel.get_filtered_trace([0, self._max_frequency], 'rectangular') - self.sampling_rate = channel.get_sampling_rate() - n_blocks = len(trace) // block_size - - # obtain guesses for block offsets - a_guess = np.array([ - np.mean(filtered_trace[i*block_size:(i+1)*block_size]) - for i in range(n_blocks) - ]) - self._offset_guess[channel_id] = a_guess - # we can get rid of one parameter through a global shift - a_guess = a_guess[:-1] - a_guess[-1] - frequencies = channel.get_frequencies() - spectrum = channel.get_frequency_spectrum() - - # we perform the fit out-of-band, in order to avoid - # distorting any actual signal - mask = (frequencies > 0) & (frequencies < self._max_frequency) - - frequencies_oob = frequencies[mask] - spectrum_oob = spectrum[mask] - - ns = self.block_size - dt = 1/self.sampling_rate - - # most of the terms in the fit depend only on the frequencies, - # sampling rate and number of blocks. We therefore calculate these - # only once, outside the fit function. - pre_factor_exponent = np.array([ - -2.j * np.pi * frequencies_oob * dt * ((j+.5) * ns - .5) - for j in range(len(a_guess)) - ]) - self._const_fft_term = ( - 1 / self.sampling_rate * np.sqrt(2) # NuRadio FFT normalization - * np.exp(pre_factor_exponent) - * np.sin(np.pi*frequencies_oob*ns*dt)[None] - / np.sin(np.pi*frequencies_oob*dt)[None] + block_offsets = fit_block_offsets( + trace, block_size, + channel.get_sampling_rate(), self._max_frequency ) - self._spectrum = spectrum_oob - res = scipy.optimize.fmin( - self._pedestal_fit, a_guess, disp=0) - ### Minuit seems a lot quicker than scipy - not sure why? - # m = Minuit(self._pedestal_fit_minuit, a_guess * nufft_conversion_factor) - # m.errordef = 1 - # m.errors = 0.01 * np.ones_like(a_guess) - # m.migrad(ncall=20000) - # res = m.values - block_offsets = np.zeros(len(res) + 1) - block_offsets[:-1] = res - # the fit is not sensitive to an overall shift, - # so we include the zero-meaning here - block_offsets += np.mean(trace) - np.mean(block_offsets) - self._offset_fit[channel_id] = block_offsets def get_offsets(self, channel_id, offset_type='fit'): @@ -217,7 +165,6 @@ def get_offsets(self, channel_id, offset_type='fit'): Options: - 'fit': return the fitted block offsets - - 'guess': return the first guess for the block offsets - 'injected': return the block offsets that were injected using the ``add_offsets`` method. @@ -231,8 +178,6 @@ def get_offsets(self, channel_id, offset_type='fit'): trace = BaseTrace() if offset_type == 'fit': trace.set_trace(np.repeat(self._offset_fit[channel_id], self.block_size), self.sampling_rate) - elif offset_type == 'guess': - trace.set_trace(np.repeat(self._offset_guess[channel_id], self.block_size), self.sampling_rate) elif offset_type == 'injected': trace.set_trace(np.repeat(self._offset_inject[channel_id], self.block_size), self.sampling_rate) return trace @@ -240,4 +185,117 @@ def get_offsets(self, channel_id, offset_type='fit'): def _pedestal_fit(self, a): fit = np.sum(a[:, None] * self._const_fft_term, axis=0) chi2 = np.sum(np.abs(fit-self._spectrum)**2) - return chi2 \ No newline at end of file + return chi2 + +def fit_block_offsets( + trace, block_size=128, sampling_rate=3.2*units.GHz, + max_frequency=50*units.MHz, return_trace = False, + xtol=1e-6, maxiter=100000): + """ + Fit 'block' offsets for a voltage trace + + Fit block offsets ('rect'-shaped offsets from a baseline) + using a fit to the out-of-band spectrum of a voltage trace. + + Parameters + ---------- + trace: numpy Array + the voltage trace + block_size: int (default: 128) + the number of samples in one block + sampling_rate: float (default: 3.2 GHz) + the sampling rate of the trace + max_frequency: float (default: 50 MHz) + the fit to the block offsets is performed + in the frequency domain, in the band up to + max_frequency + return_trace: bool (default: False) + if True, return the tuple (offsets, output_trace) + where the output_trace is the input trace with + fitted block offsets removed + + Returns + ------- + block_offsets: numpy array + The fitted block offsets. + output_trace: numpy array or None + The input trace with the fitted block offsets removed. + Returned only if return_trace=True + + Other Parameters + ---------------- + xtol: float (default: 1e-6) + tolerance parameter passed on to scipy.optimize.fmin + maxiter: int (default: 100000) + maximum number of iterations for scipy.optimize.fmin + + """ + dt = 1. / sampling_rate + spectrum = fft.time2freq(trace, sampling_rate) + frequencies = np.fft.rfftfreq(len(trace), dt) + n_blocks = len(trace) // block_size + + mask = (frequencies > 0) & (frequencies < max_frequency) # a simple rectangular filter + frequencies_oob = frequencies[mask] + spectrum_oob = spectrum[mask] + + # we use the bandpass-filtered trace to get a first estimate of + # the block offsets, by simply averaging over each block. + filtered_trace_fft = np.copy(spectrum) + filtered_trace_fft[~mask] = 0 + filtered_trace = fft.freq2time(filtered_trace_fft, dt) + + # obtain guesses for block offsets + a_guess = np.array([ + np.mean(filtered_trace[i*block_size:(i+1)*block_size]) + for i in range(n_blocks) + ]) + # self._offset_guess[channel_id] = a_guess + # we can get rid of one parameter through a global shift + a_guess = a_guess[:-1] - a_guess[-1] + + # we perform the fit out-of-band, in order to avoid + # distorting any actual signal + + # most of the terms in the fit depend only on the frequencies, + # sampling rate and number of blocks. We therefore calculate these + # only once, outside the fit function. + pre_factor_exponent = np.array([ + -2.j * np.pi * frequencies_oob * dt * ((j+.5) * block_size - .5) + for j in range(len(a_guess)) + ]) + const_fft_term = ( + 1 / sampling_rate * np.sqrt(2) # NuRadio FFT normalization + * np.exp(pre_factor_exponent) + * np.sin(np.pi*frequencies_oob*block_size*dt)[None] + / np.sin(np.pi*frequencies_oob*dt)[None] + ) + + def pedestal_fit(self, a): + fit = np.sum(a[:, None] * const_fft_term, axis=0) + chi2 = np.sum(np.abs(fit-spectrum_oob)**2) + return chi2 + + # self._spectrum = spectrum_oob + res = scipy.optimize.fmin( + pedestal_fit, a_guess, disp=0, + xtol=xtol, maxiter=maxiter) + ### maybe TODO - include option to use Minuit, which seems a lot quicker? + # m = Minuit(self._pedestal_fit_minuit, a_guess * nufft_conversion_factor) + # m.errordef = 1 + # m.errors = 0.01 * np.ones_like(a_guess) + # m.migrad(ncall=20000) + # res = m.values + + block_offsets = np.zeros(len(res) + 1) + block_offsets[:-1] = res + + # the fit is not sensitive to an overall shift, + # so we include the zero-meaning here + block_offsets += np.mean(trace) - np.mean(block_offsets) + + if return_trace: + output_trace = trace - np.repeat(block_offsets, block_size) + return block_offsets, output_trace + + return block_offsets \ No newline at end of file From 0a180635847a69101a644fa46eefc62007cb201f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Sun, 23 Oct 2022 18:31:13 +0200 Subject: [PATCH 052/418] Fix bug: When generating a electron-cc interactions the produced electron had still the flavor of the neutrino (from which it was copied from). I also refactored the indexing to make it more readible. Thereby I change the index from idx_to_insert to idx_to_copy. This change in not affecting anything because the data was just copied but I thought it is somewhat more intuitive like this. --- NuRadioMC/EvtGen/generator.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/NuRadioMC/EvtGen/generator.py b/NuRadioMC/EvtGen/generator.py index 81cc28814..42bc2a218 100644 --- a/NuRadioMC/EvtGen/generator.py +++ b/NuRadioMC/EvtGen/generator.py @@ -1257,10 +1257,13 @@ def generate_eventlist_cylinder(filename, n_events, Emin, Emax, data_sets[key] = list(data_sets[key]) n_inserted = 0 for i in np.arange(n_events_batch, dtype=int)[em_shower_mask]: # loop over all events where an EM shower needs to be inserted + idx_to_copy = i + n_inserted + idx_to_insert = idx_to_copy + 1 for key in data_sets: - data_sets[key].insert(i + 1 + n_inserted, data_sets[key][i + n_inserted]) # copy event - data_sets['shower_energies'][i + 1 + n_inserted] = (1 - data_sets['inelasticity'][i + 1 + n_inserted]) * data_sets['energies'][i + 1 + n_inserted] - data_sets['shower_type'][i + 1 + n_inserted] = 'em' + data_sets[key].insert(idx_to_insert, data_sets[key][idx_to_copy]) # copy event + data_sets['shower_energies'][idx_to_insert] = (1 - data_sets['inelasticity'][idx_to_copy]) * data_sets['energies'][idx_to_copy] + data_sets['shower_type'][idx_to_insert] = 'em' + data_sets['flavors'][idx_to_insert] = data_sets['flavors'][idx_to_copy] - 1 * np.sign(data_sets['flavors'][idx_to_copy]) n_inserted += 1 logger.debug("converting to numpy arrays") From 5ec9450d5d73f78c03c4279642f4c3c8b71b7dc0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Sun, 23 Oct 2022 18:44:25 +0200 Subject: [PATCH 053/418] make the code a bit smarter --- NuRadioMC/EvtGen/generator.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/NuRadioMC/EvtGen/generator.py b/NuRadioMC/EvtGen/generator.py index 42bc2a218..b7536130d 100644 --- a/NuRadioMC/EvtGen/generator.py +++ b/NuRadioMC/EvtGen/generator.py @@ -1288,10 +1288,8 @@ def generate_eventlist_cylinder(filename, n_events, Emin, Emax, E_all_leptons = (1 - data_sets["inelasticity"]) * data_sets["energies"] lepton_codes = copy.copy(data_sets["flavors"]) - lepton_codes[lepton_codes == 14] = 13 - lepton_codes[lepton_codes == -14] = -13 - lepton_codes[lepton_codes == 16] = 15 - lepton_codes[lepton_codes == -16] = -15 + # convert neutrino flavors (makes only sense for cc interaction which is ensured with "mask_leptons") + lepton_codes = lepton_codes - 1 * np.sign(lepton_codes) if("fiducial_rmax" in attributes): mask_phi = mask_arrival_azimuth(data_sets, attributes['fiducial_rmax']) From 115cca21b08757e66833a95977bb08bea2a01ba8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Mon, 24 Oct 2022 12:34:36 +0200 Subject: [PATCH 054/418] Move exclusion of hdf5 files to top of ignorefile --- .gitignore | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/.gitignore b/.gitignore index 56271c45c..b0f30754a 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,13 @@ # .gitignore files to exclude specific files. ############################################################# +# Ignore test output - this will also make sure that you do not accidentally add large files to your commit +*output*.nur +*output*.hdf5 +# Exclude reference files from being ignored here +!*reference*.nur +!*reference*.hdf5 + # Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] @@ -129,10 +136,4 @@ venv.bak/ # ignore .nur files in NuRadioReco/examples/ # this should not apply for NuRadioReco/examples/example_data/ -NuRadioReco/examples/*.nur - -# ignore test output (not include input or reference files here!) -*output*.nur -*output*.hdf5 -!*reference*.nur -!*reference*.hdf5 \ No newline at end of file +NuRadioReco/examples/*.nur \ No newline at end of file From 9bc2e3f8518e4b6b4d48616340ad606117912f31 Mon Sep 17 00:00:00 2001 From: sjoerd-bouma Date: Mon, 24 Oct 2022 13:26:46 +0200 Subject: [PATCH 055/418] fixed bug (dt instead of sampling rate) --- NuRadioReco/modules/RNO_G/channelBlockOffsetFitter.py | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/NuRadioReco/modules/RNO_G/channelBlockOffsetFitter.py b/NuRadioReco/modules/RNO_G/channelBlockOffsetFitter.py index c873f9d96..eeb34e87d 100644 --- a/NuRadioReco/modules/RNO_G/channelBlockOffsetFitter.py +++ b/NuRadioReco/modules/RNO_G/channelBlockOffsetFitter.py @@ -93,9 +93,6 @@ def remove_offsets(self, event, station, offsets='fit', channel_ids=None): How to remove the offsets. Options are: - 'fit': fit the offsets out of band - - 'guess': similar to 'fit', but just take - a first guess at the offsets from the out-of-band region - without actually performing the fit. - 'injected': if offsets were injected using the ``add_offsets`` method, this removes those offsets. Otherwise, this does nothing. @@ -109,8 +106,6 @@ def remove_offsets(self, event, station, offsets='fit', channel_ids=None): if not len(self._offset_fit): self.fit_offsets(event, station, channel_ids) offsets = self._offset_fit - elif offsets=='guess': - offsets = self._offset_guess elif offsets=='injected': if not len(self._offset_inject): offsets = np.zeros(16) #TODO - ensure this works for different trace lengths @@ -243,7 +238,7 @@ def fit_block_offsets( # the block offsets, by simply averaging over each block. filtered_trace_fft = np.copy(spectrum) filtered_trace_fft[~mask] = 0 - filtered_trace = fft.freq2time(filtered_trace_fft, dt) + filtered_trace = fft.freq2time(filtered_trace_fft, sampling_rate) # obtain guesses for block offsets a_guess = np.array([ @@ -271,7 +266,7 @@ def fit_block_offsets( / np.sin(np.pi*frequencies_oob*dt)[None] ) - def pedestal_fit(self, a): + def pedestal_fit(a): fit = np.sum(a[:, None] * const_fft_term, axis=0) chi2 = np.sum(np.abs(fit-spectrum_oob)**2) return chi2 From a3d913f8768f4a781f30cc2c5fd588df12ec1e3c Mon Sep 17 00:00:00 2001 From: Jean-Marco Alameddine Date: Tue, 1 Nov 2022 11:04:36 +0100 Subject: [PATCH 056/418] Upgrade PROPOSAL interface to PROPOSAL version 7 --- NuRadioMC/EvtGen/NuRadioProposal.py | 473 +++++++++--------- NuRadioMC/EvtGen/config_PROPOSAL.json.sample | 253 +++------- .../config_PROPOSAL_greenland.json.sample | 253 +++------- .../EvtGen/config_PROPOSAL_infice.json.sample | 138 ++--- .../config_PROPOSAL_mooresbay.json.sample | 253 +++------- .../Introduction/pages/installation.rst | 2 +- pyproject.toml | 2 +- 7 files changed, 515 insertions(+), 859 deletions(-) diff --git a/NuRadioMC/EvtGen/NuRadioProposal.py b/NuRadioMC/EvtGen/NuRadioProposal.py index 69a8eea5c..619276072 100644 --- a/NuRadioMC/EvtGen/NuRadioProposal.py +++ b/NuRadioMC/EvtGen/NuRadioProposal.py @@ -24,9 +24,6 @@ - MuPair: a muon/antimuon pair - WeakInt: a weak interaction - Compton: Compton effect -The last secondaries obtained via the propagation belong to the Particle DynamicData -type, and represent the products of the decay. They are standard particles with -a PDG code. """ # Units definition in PROPOSAL @@ -88,69 +85,77 @@ def __str__(self): calculated by PROPOSAL, and although most of them correspond to actual particles - Brems is a bremsstrahlung photon, DeltaE is an ionised electron, and EPair is an electron-positron pair, it is useful to treat them as separate entities so that -we know they come from an interaction. PROPOSAL returns particles as decay products -only, in our case. +we know they come from an interaction. We have followed the PDG recommendation and used numbers between 80 and 89 for our own-defined particles, although we have needed also 90 and 91 (they are very rarely used). """ -proposal_interaction_names = { 1000000001: 'particle', - 1000000002: 'brems', - 1000000003: 'ionized_e', - 1000000004: 'e_pair', - 1000000005: 'nucl_int', - 1000000006: 'mu_pair', - 1000000007: 'hadrons', - 1000000008: 'cont_loss', - 1000000009: 'weak_int', - 1000000010: 'compton', - 1000000011: 'decay' } - -proposal_interaction_codes = { 1000000001: 80, - 1000000002: 81, - 1000000003: 82, - 1000000004: 83, - 1000000005: 85, - 1000000006: 87, - 1000000007: 84, - 1000000008: 88, - 1000000009: 89, - 1000000010: 90, - 1000000011: 91 } - - -def particle_code(particle): +proposal_interaction_names = { pp.particle.Interaction_Type.particle.value: 'particle', + pp.particle.Interaction_Type.brems.value: 'brems', + pp.particle.Interaction_Type.ioniz.value: 'ionized_e', + pp.particle.Interaction_Type.epair.value: 'e_pair', + pp.particle.Interaction_Type.photonuclear.value: 'nucl_int', + pp.particle.Interaction_Type.mupair.value: 'mu_pair', + pp.particle.Interaction_Type.hadrons.value: 'hadrons', + pp.particle.Interaction_Type.continuousenergyloss.value: 'cont_loss', + pp.particle.Interaction_Type.weakint.value: 'weak_int', + pp.particle.Interaction_Type.compton.value: 'compton', + pp.particle.Interaction_Type.decay.value: 'decay' } + +proposal_interaction_codes = { pp.particle.Interaction_Type.particle.value: 80, + pp.particle.Interaction_Type.brems.value: 81, + pp.particle.Interaction_Type.ioniz.value: 82, + pp.particle.Interaction_Type.epair.value: 83, + pp.particle.Interaction_Type.photonuclear.value: 85, + pp.particle.Interaction_Type.mupair.value: 87, + pp.particle.Interaction_Type.hadrons.value: 84, + pp.particle.Interaction_Type.continuousenergyloss.value: 88, + pp.particle.Interaction_Type.weakint.value: 89, + pp.particle.Interaction_Type.compton.value: 90, + pp.particle.Interaction_Type.decay.value: 91 } + + +def particle_code(pp_type): """ - If a particle object from PROPOSAL is passed as input, it returns the - corresponding PDG particle code. DynamicData objects are not considered - particles internally in PROPOSAL, so they are handled differently. + For an integer, corresponding to a proposal.particle.Interaction_Type or + proposal.particle.Particle_Type, it returns the corresponding PDG + particle code. Parameters ---------- - particle: particle object from PROPOSAL + pp_type: int, corresponding to a proposal.particle.Interaction_Type or + proposal.particle.Particle_Type Returns ------- integer with the PDG particle code. None if the argument is not a particle """ - particle_type = particle.type - if particle_type in proposal_interaction_codes: - return proposal_interaction_codes[particle_type] - elif particle_type in particle_names.particle_names: - return particle_type + if pp_type in proposal_interaction_codes: + return proposal_interaction_codes[pp_type] + elif pp_type in particle_names.particle_names: + return pp_type else: - print(particle_type) + print(pp_type) return None -def is_em_primary (particle): +def is_em_primary (pp_type): """ - Given a PROPOSAL particle object as an input, returns True if the particle - can be an electromagnetic shower primary and False otherwise + For an integer corresponding to a particle type or interaction type of + proposal, returns True if the object can be an electromagnetic shower primary + and False otherwise + + Parameters + ---------- + pp_type: int, corresponding to a pp.proposal.Interaction_Type or pp.proposal.Particle_Type + + Returns + ------- + bool, True if the particle can be an electromagnetic shower primary and False otherwise """ - code = particle_code(particle) + code = particle_code(pp_type) name = particle_names.particle_name(code) if name in particle_names.em_primary_names: @@ -159,12 +164,21 @@ def is_em_primary (particle): return False -def is_had_primary(particle): +def is_had_primary(pp_type): """ - Given a PROPOSAL particle object as an input, returns True if the particle - can be a hadronic shower primary and False otherwise + Given an integer corresponding to a particle type or interaction type of + proposal, returns True if the object can be a hadronic shower primary + and False otherwise + + Parameters + ---------- + pp_type: int, corresponding to a pp.proposal.Interaction_Type or pp.proposal.Particle_Type + + Returns + ------- + bool, True if the particle can be a hadronic shower primary and False otherwise """ - code = particle_code(particle) + code = particle_code(pp_type) name = particle_names.particle_name(code) if name in particle_names.had_primary_names: @@ -173,12 +187,20 @@ def is_had_primary(particle): return False -def is_shower_primary(particle): +def is_shower_primary(pp_type): """ - Given a PROPOSAL particle object, returns True if the particle can be - a shower primary and False otherwise + Given an integer corresponding to a particle type or interaction type of + proposal, returns True if the object can be a shower primary and False otherwise + + Parameters + ---------- + pp_type: int, corresponding to a pp.proposal.Interaction_Type or pp.proposal.Particle_Type + + Returns + ------- + bool, True if the particle can be a shower primary and False otherwise """ - code = particle_code(particle) + code = particle_code(pp_type) name = particle_names.particle_name(code) if name in particle_names.primary_names: @@ -187,34 +209,6 @@ def is_shower_primary(particle): return False -def check_path_to_tables(config_file_path): - """ - Checks if the paths for the PROPOSAL tables in the input config file are - existing directories. - """ - - with open(config_file_path, 'r') as f: - - config_file = json.load(f) - - path_to_tables = config_file['global']['interpolation']['path_to_tables'] - path_to_tables_readonly = config_file['global']['interpolation']['path_to_tables_readonly'] - - if not os.path.isdir(path_to_tables): - - error_msg = "'path_to_tables' in {} points to {}, which is a non-existing directory. ".format(config_file_path, - path_to_tables) - error_msg += "Please choose a valid path for the PROPOSAL config file in {}.".format(config_file_path) - raise ValueError(error_msg) - - if not os.path.isdir(path_to_tables_readonly): - - error_msg = "'path_to_tables_readonly' in {} points to {}, which is a non-existing directory. ".format(config_file_path, - path_to_tables_readonly) - error_msg += "Please choose a valid path for the PROPOSAL config file in {}.".format(config_file_path) - raise ValueError(error_msg) - - @six.add_metaclass(Singleton) class ProposalFunctions(object): """ @@ -223,27 +217,39 @@ class ProposalFunctions(object): not be used from the outside to avoid mismatching units. """ - def __init__(self, config_file='SouthPole', log_level=logging.INFO): + def __init__(self, config_file='SouthPole', log_level=logging.INFO, tables_path="/tmp", seed=12): """ Parameters ---------- config_file: string or path The user can specify the path to their own config file or choose among the three available options: - -'SouthPole', a config file for the South Pole (spherical Earth) - -'MooresBay', a config file for Moore's Bay (spherical Earth) + -'SouthPole', a config file for the South Pole (spherical Earth). It + consists of a 2.7 km deep layer of ice, bedrock below and air above. + -'MooresBay', a config file for Moore's Bay (spherical Earth). It + consists of a 576 m deep ice layer with a 2234 m deep water layer below, + and bedrock below that. -'InfIce', a config file with a medium of infinite ice - -'Greenland', a config file for Summit Station, Greenland (spherical Earth) - IMPORTANT: If these options are used, the code is more efficient if the - user requests their own "path_to_tables" and "path_to_tables_readonly", - pointing them to a writable directory + -'Greenland', a config file for Summit Station, Greenland (spherical Earth), + same as SouthPole but with a 3 km deep ice layer. + log_level: logging level + tables_path: path + Path to PROPOSAL tables. Should be set to a path where PROPOSAL tables exist, or + where PROPOSAL tables can be saved. This avoids that PROPOSAL has to regenerate + tables (which can take several minutes) every time the script is executed + seed: int + Seed to be used by PROPOSAL + """ self.__logger = logging.getLogger("proposal") self.__logger.setLevel(log_level) self.__logger.info("initializing proposal interface class") + pp.RandomGenerator.get().set_seed(seed) # set global seed for PROPOSAL + self.__propagators = {} self.__config_file = config_file + self.__tables_path = tables_path def __get_propagator(self, particle_code=13): @@ -254,20 +260,6 @@ def __get_propagator(self, ---------- particle_code: integer Particle code for the muon- (13), muon+ (-13), tau- (15), or tau+ (-15) - config_file: string or path - The user can specify the path to their own config file or choose among - the three available options: - -'SouthPole', a config file for the South Pole (spherical Earth). It - consists of a 2.7 km deep layer of ice, bedrock below and air above. - -'MooresBay', a config file for Moore's Bay (spherical Earth). It - consists of a 576 m deep ice layer with a 2234 m deep water layer below, - and bedrock below that. - -'InfIce', a config file with a medium of infinite ice - -'Greenland', a config file for Summit Station, Greenland (spherical Earth), - same as SouthPole but with a 3 km deep ice layer. - IMPORTANT: If these options are used, the code is more efficient if the - user requests their own "path_to_tables" and "path_to_tables_readonly", - pointing them to a writable directory Returns ------- @@ -276,21 +268,6 @@ def __get_propagator(self, """ if(particle_code not in self.__propagators): self.__logger.info(f"initializing propagator for particle code {particle_code}") - mu_def_builder = pp.particle.ParticleDefBuilder() - if (particle_code == 13): - mu_def_builder.SetParticleDef(pp.particle.MuMinusDef()) - elif (particle_code == -13): - mu_def_builder.SetParticleDef(pp.particle.MuPlusDef()) - elif (particle_code == 15): - mu_def_builder.SetParticleDef(pp.particle.TauMinusDef()) - elif (particle_code == -15): - mu_def_builder.SetParticleDef(pp.particle.TauPlusDef()) - else: - error_str = "The propagation of this particle via PROPOSAL is not currently supported.\n" - error_str += "Please choose between -/+muon (13/-13) and -/+tau (15/-15)" - raise NotImplementedError(error_str) - - mu_def = mu_def_builder.build() if (self.__config_file == 'SouthPole'): config_file_full_path = os.path.join(os.path.dirname(__file__), 'config_PROPOSAL.json') @@ -305,21 +282,33 @@ def __get_propagator(self, else: raise ValueError("Proposal config file is not valid. Please provide a valid option.") - if not os.path.exists(config_file_full_path): + # TODO: What is this {}.sample, and what does it have to do with interpoation tables? + #if not os.path.exists(config_file_full_path): error_message = "Proposal config file does not exist.\n" error_message += "Please provide valid paths for the interpolation tables " error_message += "in file {}.sample ".format(config_file_full_path) error_message += "and copy the file to {}.".format(os.path.basename(config_file_full_path)) raise ValueError(error_message) - check_path_to_tables(config_file_full_path) + pp.InterpolationSettings.tables_path = self.__tables_path - self.__propagators[particle_code] = pp.Propagator(particle_def=mu_def, config_file=config_file_full_path) + # upper energy lim for proposal tables, in PROPOSAL units (MeV) + pp.InterpolationSettings.upper_energy_lim = 1e14 * pp_MeV + + try: + p_def = pp.particle.get_ParticleDef_for_type(particle_code) + except: + error_str = "The propagation of this particle via PROPOSAL is not currently supported.\n" + error_str += "Please choose between -/+muon (13/-13) and -/+tau (15/-15)" + raise NotImplementedError(error_str) + + self.__propagators[particle_code] = pp.Propagator(particle_def=p_def, path_to_config_file=config_file_full_path) return self.__propagators[particle_code] def __produces_shower(self, - particle, + pp_type, + energy, min_energy_loss=1 * pp_PeV): """ Returns True if the input particle or interaction can be a shower primary @@ -327,8 +316,10 @@ def __produces_shower(self, Parameters ---------- - particle: PROPOSAL particle or DynamicData (interaction) - Input particle + pp_type: int + int corresponding to a pp.proposal.Interaction_Type or pp.proposal.Particle_Type + energy: float + Energy of particle or interaction, in PROPOSAL units (MeV) min_energy_loss: float Threshold above which a particle shower is considered detectable or relevant, in PROPOSAL units (MeV) @@ -338,46 +329,20 @@ def __produces_shower(self, bool True if particle produces shower, False otherwise """ - energy_threshold = self.__secondary_energy(particle) > min_energy_loss - if not energy_threshold: + if (energy < min_energy_loss): return False - shower_inducing = is_shower_primary(particle) + return is_shower_primary(pp_type) - return shower_inducing - def __secondary_energy(self, sec): - """ - Retrieves the energy of the secondary particle - - Parameters - ---------- - sec: Particle - Secondary particle issued by Proposal - - Returns - ------- - energy: float - Energy in MeV - """ - - # Checking if the secondary type is greater than 1000000000, which means - # that the secondary is an interaction particle. - if (sec.type > 1000000000): - energy = (sec.parent_particle_energy - sec.energy) * pp_MeV - # Else, the secondary is a particle issued upon decay. - else: - energy = sec.energy * pp_MeV - - return energy - - def __shower_properties(self, particle): + def __shower_properties(self, pp_type): """ Calculates shower properties for the shower created by the input particle Parameters ---------- - particle: PROPOSAL particle or DynamicData + pp_type: int + int corresponding to a pp.proposal.Interaction_Type or pp.proposal.Particle_Type Returns ------- @@ -388,15 +353,15 @@ def __shower_properties(self, particle): name: string Name of the shower primary """ - if not is_shower_primary(particle): + if not is_shower_primary(pp_type): return None, None, None - code = particle_code(particle) + code = particle_code(pp_type) - if is_em_primary(particle): + if is_em_primary(pp_type): shower_type = 'em' - if is_had_primary(particle): + if is_had_primary(pp_type): shower_type = 'had' name = particle_names.particle_name(code) @@ -431,30 +396,25 @@ def __propagate_particle(self, Returns ------- - secondaries: array of PROPOSAL particles - Secondaries created by the propagation + secondaries: proposal.particle.Secondaries + object containing all information about secondary particles produced + during propagation """ x, y, z = lepton_position px, py, pz = lepton_direction - if (lepton_code == 13): - particle_def = pp.particle.MuMinusDef() - elif (lepton_code == -13): - particle_def = pp.particle.MuPlusDef() - elif (lepton_code == 15): - particle_def = pp.particle.TauMinusDef() - elif (lepton_code == -15): - particle_def = pp.particle.TauPlusDef() - - initial_condition = pp.particle.DynamicData(particle_def.particle_type) - initial_condition.position = pp.Vector3D(x, y, z) - initial_condition.direction = pp.Vector3D(px, py, pz) + initial_condition = pp.particle.ParticleState() + initial_condition.type = lepton_code + initial_condition.position = pp.Cartesian3D(x, y, z) + initial_condition.direction = pp.Cartesian3D(px, py, pz) initial_condition.energy = energy_lepton initial_condition.propagated_distance = 0 + initial_condition.direction.normalize() # ensure that direction is normalized + secondaries = self.__get_propagator(lepton_code).propagate(initial_condition, - propagation_length, - minimal_energy=low).particles + max_distance = propagation_length, + min_energy=low) return secondaries def __filter_secondaries(self, @@ -467,8 +427,8 @@ def __filter_secondaries(self, Parameters ---------- - secondaries: array of PROPOSAL particles - Array with secondary particles + secondaries: array of proposal.particle.StochasticLoss objects + Array of all stochastic losses produced by PROPOSAL min_energy_loss: float Threshold for shower production, in PROPOSAL units (MeV) lepton_position: tuple (float, float, float) @@ -485,23 +445,66 @@ def __filter_secondaries(self, for sec in secondaries: - # Decays contain only one shower-inducing particle - # Muons and neutrinos resulting from decays are ignored - if self.__produces_shower(sec, min_energy_loss): + if self.__produces_shower(sec.type, sec.energy, min_energy_loss): distance = ((sec.position.x - lepton_position[0]) * units.cm) ** 2 distance += ((sec.position.y - lepton_position[1]) * units.cm) ** 2 distance += ((sec.position.z - lepton_position[2]) * units.cm) ** 2 distance = np.sqrt(distance) - energy = self.__secondary_energy(sec) * units.MeV + energy = sec.energy * units.MeV - shower_type, code, name = self.__shower_properties(sec) + shower_type, code, name = self.__shower_properties(sec.type) shower_inducing_prods.append(SecondaryProperties(distance, energy, shower_type, code, name)) return shower_inducing_prods + def __group_decay_products(self, + decay_products, + min_energy_loss, + lepton_position): + """ + group remaining shower-inducing decay products so that they create a single shower + + Parameters + ---------- + decay_products: list of proposal.particle.ParticleState + List of decay particles that we want to group + min_energy_loss: float + Threshold for shower production, in PROPOSAL units (MeV) + lepton_position: (float, float, float) tuple + Original lepton positions in proposal units (cm) + + Returns + ------- + None or SecondaryProperties + If energy of grouped decay particles is above min_energy_loss, SecondaryProperties object, + containing information about the grouped decay particles is returned. + Otherwise, None is returned. + """ + + # TODO: At the moment, all decay_products in primary_names are grouped and identified + # as a 'Hadronic Decay bundle', even electromagnetic decay products such as + # electrons. Is that ok? Should they be negleceted? Or grouped separately? + + sum_decay_particle_energy = 0 + + for decay_particle in decay_products: + if(is_shower_primary(decay_particle.type)): + sum_decay_particle_energy += decay_particle.energy + + if (sum_decay_particle_energy > min_energy_loss): + # all decay_particles have the same position, so we can just look at the first in list + distance = ((decay_products[0].position.x - lepton_position[0]) * units.cm) ** 2 + distance += ((decay_products[0].position.y - lepton_position[1]) * units.cm) ** 2 + distance += ((decay_products[0].position.z - lepton_position[2]) * units.cm) ** 2 + distance = np.sqrt(distance) + return SecondaryProperties(distance, sum_decay_particle_energy * units.MeV, + 'had', 86, particle_names.particle_name(86)) + return None + + def get_secondaries_array(self, energy_leptons_nu, lepton_codes, @@ -561,10 +564,6 @@ def get_secondaries_array(self, if lepton_directions is None: lepton_directions = [(0, 0, -1)] * len(energy_leptons) - if propagate_decay_muons: - - decay_muons_array = [] - secondaries_array = [] for energy_lepton, lepton_code, lepton_position, lepton_direction in zip(energy_leptons, @@ -574,64 +573,51 @@ def get_secondaries_array(self, lepton_position, lepton_direction, propagation_length, low=low) - shower_inducing_prods = self.__filter_secondaries(secondaries, min_energy_loss, lepton_position) + shower_inducing_prods = self.__filter_secondaries(secondaries.stochastic_losses(), + min_energy_loss, lepton_position) - # Checking if there is a muon in the products - if propagate_decay_muons: - - decay_muons_array.append([None, None, None, None]) + decay_products = secondaries.decay_products() # array of decay particles - for sec in secondaries: - - if (sec.type not in proposal_interaction_codes) or (sec.type not in particle_names.particle_names): - continue + # Checking if there is a muon in the decay products + if propagate_decay_muons: - if (sec.particle_def == pp.particle.MuMinusDef()) or (sec.particle_def == pp.particle.MuPlusDef()): + repropagated_muon_indices = [] # indices of muons that will be further propagated - if sec.particle_def == pp.particle.MuMinusDef(): - mu_code = 13 - elif sec.particle_def == pp.particle.MuPlusDef(): - mu_code = -13 + for i, decay_particle in enumerate(decay_products): - mu_energy = sec.energy + if (abs(decay_particle.type) == 13): + mu_energy = decay_particle.energy if (mu_energy <= low): continue - mu_position = (sec.position.x, sec.position.y, sec.position.z) - mu_direction = lepton_direction # We reuse the primary lepton direction - # At these energies the muon direction is the same - decay_muons_array[-1] = [mu_energy, mu_code, mu_position, mu_direction] - # I store the properties of each muon in an array because they cannot be - # propagated while we are looping the secondaries array. Doing that can - # create a segmentation fault because the results of the new propagation - # are written into the secondaries array (!) - - # group shower-inducing decay products so that they create a single shower - min_distance = 0.1 * units.m - while(len(shower_inducing_prods) > 1 and - np.abs(shower_inducing_prods[-1].distance - shower_inducing_prods[-2].distance) < min_distance): - - last_decay_prod = shower_inducing_prods.pop(-1) - shower_inducing_prods[-1].energy += last_decay_prod.energy - shower_inducing_prods[-1].code = 86 - shower_inducing_prods[-1].name = particle_names.particle_name(86) + mu_position = (decay_particle.position.x, decay_particle.position.y, decay_particle.position.z) + mu_direction = (decay_particle.direction.x, decay_particle.direction.y, decay_particle.direction.z) - secondaries_array.append(shower_inducing_prods) + muon_secondaries = self.__propagate_particle(mu_energy, decay_particle.type, + mu_position, mu_direction, + propagation_length, low=low) - # Propagating the decay muons - if propagate_decay_muons: + shower_inducing_muon_secondaries = self.__filter_secondaries(muon_secondaries.stochastic_losses(), + min_energy_loss, lepton_position) - for shower_inducing_prods, decay_muon, lepton_position in zip(secondaries_array, - decay_muons_array, lepton_positions): + shower_inducing_prods.extend(shower_inducing_muon_secondaries) - if decay_muon[0] is None: - continue - mu_energy, mu_code, mu_position, mu_direction = decay_muon - mu_secondaries = self.__propagate_particle(mu_energy, mu_code, mu_position, mu_direction, - propagation_length, low=low) + # TODO: Are we interested in muon decay products here? (i.e. the electron/positron?) + + # We have already handled the muon, remove it to avoid double counting. + # However, we can't remove the muon in-place from the decay_products list, + # therefore just save indices and pop items after loop + repropagated_muon_indices.append(i) + + # remove muons that have already been propagated further + for i in repropagated_muon_indices: + decay_products.pop(i) - mu_shower_inducing_prods = self.__filter_secondaries(mu_secondaries, min_energy_loss, lepton_position) + grouped_decay_products = self.__group_decay_products(decay_products, min_energy_loss, lepton_position) - shower_inducing_prods += mu_shower_inducing_prods + if (grouped_decay_products is not None): + shower_inducing_prods.append(grouped_decay_products) + + secondaries_array.append(shower_inducing_prods) return secondaries_array @@ -693,21 +679,24 @@ def get_decays(self, secondaries = self.__propagate_particle(energy_lepton, lepton_code, lepton_position, lepton_direction, propagation_length, low=low) - decay_particles = np.array([p for p in secondaries if p.type not in proposal_interaction_codes]) + + decay_particles = secondaries.decay_products() decay_energies = np.array([p.energy for p in decay_particles]) decay_energy = np.sum(decay_energies) * units.MeV - try: - # If Proposal fails and there is no decay (sometimes it happens), - # the particle is propagated again - decay_distance = ((decay_particles[0].position.x - lepton_position[0]) * units.cm) ** 2 - decay_distance += ((decay_particles[0].position.y - lepton_position[1]) * units.cm) ** 2 - decay_distance += ((decay_particles[0].position.z - lepton_position[2]) * units.cm) ** 2 - decay_distance = np.sqrt(decay_distance) - - decay_prop = (decay_distance, decay_energy) - decays_array.append(decay_prop) - except: + # TODO: Is it physical to repeat the propagation until a decay (before the energy of low) happened? + if (len(decay_particle) == 0): decay_prop = (None, None) + continue + + # all decay particles have the same position, so we can just use the position of the first one + decay_distance = ((decay_particles[0].position.x - lepton_position[0]) * units.cm) ** 2 + decay_distance += ((decay_particles[0].position.y - lepton_position[1]) * units.cm) ** 2 + decay_distance += ((decay_particles[0].position.z - lepton_position[2]) * units.cm) ** 2 + decay_distance = np.sqrt(decay_distance) + + # TODO: Note that this includes ALL decay particles, including invisible ones like neutrinos + decay_prop = (decay_distance, decay_energy) + decays_array.append(decay_prop) return np.array(decays_array) diff --git a/NuRadioMC/EvtGen/config_PROPOSAL.json.sample b/NuRadioMC/EvtGen/config_PROPOSAL.json.sample index b271f9d9f..068bd3a77 100644 --- a/NuRadioMC/EvtGen/config_PROPOSAL.json.sample +++ b/NuRadioMC/EvtGen/config_PROPOSAL.json.sample @@ -1,205 +1,112 @@ { "global": { - "seed" : 12, - "continous_loss_output" : false, - "only_loss_inside_detector" : false, - - "interpolation": - { - "do_interpolation" : true, - "path_to_tables" : "Please provide here a valid system path", - "path_to_tables_readonly" : "Please provide here a valid system path", - "do_binary_tables" : false, - "just_use_readonly_path" : false, - "max_node_energy" : 1e14, - "nodes_cross_section" : 100, - "nodes_continous_randomization" : 200, - "nodes_propagate" : 1000 - }, - + "do_interpolation" : true, "exact_time" : true, - "stopping_decay" : true, - "scattering" : "NoScattering", - - "brems_multiplier" : 1, - "photo_multiplier" : 1, - "ioniz_multiplier" : 1, - "epair_multiplier" : 1, - "ioniz": "IonizBetheBlochRossi", - "epair": "EpairKelnerKokoulinPetrukhin", - "brems" : "BremsKelnerKokoulinPetrukhin", - "photo" : "PhotoAbramowiczLevinLevyMaor97", - "annihilation": "none", - "compton" : "none", - "photopair": "none", - "mupair": "none", - "weak": "none", - "lpm" : true, - "photo_hard_component" : true, - "photo_shadow" : "ShadowButkevichMikhailov", - - "cuts_infront": + "scattering": { - "e_cut": 1e8, - "v_cut": -1, - "cont_rand": true + "multiple_scattering" : "NoScattering" }, - "cuts_inside": - { - "e_cut": 1e8, - "v_cut": -1, - "cont_rand": false + "CrossSections" : { + "brems": { + "parametrization": "KelnerKokoulinPetrukhin", + "multiplier" : 1.0, + "lpm": true + }, + "epair": { + "parametrization": "KelnerKokoulinPetrukhin", + "multiplier" : 1.0, + "lpm": true + }, + "ioniz": { + "parametrization": "BetheBlochRossi", + "multiplier" : 1.0 + }, + "photo": { + "parametrization": "AbramowiczLevinLevyMaor97", + "multiplier" : 1.0, + "shadow": "ButkevichMikheyev" + } }, - "cuts_behind": + "cuts": { "e_cut": 1e8, - "v_cut": -1, - "cont_rand": false - }, - "medium": "air", - "geometry": - { - "shape": "sphere", - "origin": [0, 0, -6374134], - "outer_radius": 1000000000, - "inner_radius": 6374134 + "v_cut": 1, + "cont_rand": true } }, - "sectors": [ { - "hierarchy": 1, "medium": "air", - "density_correction": 0.673, + "geometries": [ + { + "hierarchy": 0, + "shape": "sphere", + "origin": [0, 0, -637413400], + "outer_radius": 1e20, + "inner_radius": 637413400 - "geometry": - { - "shape": "sphere", - "origin": [0, 0, -6374134], - "outer_radius": 1000000000, - "inner_radius": 6374134 - }, - "cuts_inside": - { - "e_cut": 1e8, - "v_cut": -1, - "cont_rand": false - }, - "cuts_infront": - { - "e_cut": 1e8, - "v_cut": -1, - "cont_rand": true - }, - "cuts_behind": + } + ], + "density_distribution": { - "e_cut": 1e8, - "v_cut": -1, - "cont_rand": false + "type": "homogeneous", + "mass_density" : 0.000810965 } }, { - "hierarchy": 1, "medium": "ice", - "density_correction": 0.832, + "geometries": [ + { + "hierarchy": 1, + "shape": "sphere", + "origin": [0, 0, -637413400], + "outer_radius": 637413400, + "inner_radius": 637393400 - "geometry": + } + ], + "density_distribution": { - "shape": "sphere", - "origin": [0, 0, -6374134], - "outer_radius": 6374134, - "inner_radius": 6373934 - }, - "cuts_inside": - { - "e_cut": 1e8, - "v_cut": -1, - "cont_rand": false - }, - "cuts_infront": - { - "e_cut": 1e8, - "v_cut": -1, - "cont_rand": true - }, - "cuts_behind": - { - "e_cut": 1e8, - "v_cut": -1, - "cont_rand": false + "type": "homogeneous", + "mass_density" : 0.762944 } - }, + }, { - "hierarchy": 1, "medium": "ice", - "density_correction": 1.005, + "geometries": [ + { + "hierarchy": 2, + "shape": "sphere", + "origin": [0, 0, -637413400], + "outer_radius": 637393400, + "inner_radius": 637132400 - "geometry": - { - "shape": "sphere", - "origin": [0, 0, -6374134], - "outer_radius": 6373934, - "inner_radius": 6371324 - }, - "cuts_inside": + } + ], + "density_distribution": { - "e_cut": 1e8, - "v_cut": -1, - "cont_rand": false - }, - "cuts_infront": - { - "e_cut": 1e8, - "v_cut": -1, - "cont_rand": true - }, - "cuts_behind": - { - "e_cut": 1e8, - "v_cut": -1, - "cont_rand": false + "type": "homogeneous", + "mass_density" : 0.921585 } - }, + }, { - "hierarchy": 1, - "medium": "standardrock", - "density_correction": 1.0, + "medium": "StandardRock", + "geometries": [ + { + "hierarchy": 3, + "shape": "sphere", + "origin": [0, 0, -637413400], + "outer_radius": 637132400, + "inner_radius": 0 - "geometry": - { - "shape": "sphere", - "origin": [0, 0, -6374134], - "outer_radius": 6371324, - "inner_radius": 0 - }, - "cuts_inside": - { - "e_cut": 1e8, - "v_cut": -1, - "cont_rand": false - }, - "cuts_infront": + } + ], + "density_distribution": { - "e_cut": 1e8, - "v_cut": -1, - "cont_rand": true - }, - "cuts_behind": - { - "e_cut": 1e8, - "v_cut": -1, - "cont_rand": false + "type": "homogeneous", + "mass_density" : 2.65 } - } - ], - - "detector": - { - "shape": "cylinder", - "origin" : [0, 0, 0], - "outer_radius": 1e20, - "inner_radius": 0, - "height": 1e20 - } -} + } + ] +} \ No newline at end of file diff --git a/NuRadioMC/EvtGen/config_PROPOSAL_greenland.json.sample b/NuRadioMC/EvtGen/config_PROPOSAL_greenland.json.sample index 9b1f6567d..05c9ccf4e 100644 --- a/NuRadioMC/EvtGen/config_PROPOSAL_greenland.json.sample +++ b/NuRadioMC/EvtGen/config_PROPOSAL_greenland.json.sample @@ -1,205 +1,112 @@ { "global": { - "seed" : 12, - "continous_loss_output" : false, - "only_loss_inside_detector" : false, - - "interpolation": - { - "do_interpolation" : true, - "path_to_tables" : "Please provide here a valid system path", - "path_to_tables_readonly" : "Please provide here a valid system path", - "do_binary_tables" : false, - "just_use_readonly_path" : false, - "max_node_energy" : 1e14, - "nodes_cross_section" : 100, - "nodes_continous_randomization" : 200, - "nodes_propagate" : 1000 - }, - + "do_interpolation" : true, "exact_time" : true, - "stopping_decay" : true, - "scattering" : "NoScattering", - - "brems_multiplier" : 1, - "photo_multiplier" : 1, - "ioniz_multiplier" : 1, - "epair_multiplier" : 1, - "ioniz": "IonizBetheBlochRossi", - "epair": "EpairKelnerKokoulinPetrukhin", - "brems" : "BremsKelnerKokoulinPetrukhin", - "photo" : "PhotoAbramowiczLevinLevyMaor97", - "annihilation": "none", - "compton" : "none", - "photopair": "none", - "mupair": "none", - "weak": "none", - "lpm" : true, - "photo_hard_component" : true, - "photo_shadow" : "ShadowButkevichMikhailov", - - "cuts_infront": + "scattering": { - "e_cut": 1e8, - "v_cut": -1, - "cont_rand": true + "multiple_scattering" : "NoScattering" }, - "cuts_inside": - { - "e_cut": 1e8, - "v_cut": -1, - "cont_rand": false + "CrossSections" : { + "brems": { + "parametrization": "KelnerKokoulinPetrukhin", + "multiplier" : 1.0, + "lpm": true + }, + "epair": { + "parametrization": "KelnerKokoulinPetrukhin", + "multiplier" : 1.0, + "lpm": true + }, + "ioniz": { + "parametrization": "BetheBlochRossi", + "multiplier" : 1.0 + }, + "photo": { + "parametrization": "AbramowiczLevinLevyMaor97", + "multiplier" : 1.0, + "shadow": "ButkevichMikheyev" + } }, - "cuts_behind": + "cuts": { "e_cut": 1e8, - "v_cut": -1, - "cont_rand": false - }, - "medium": "air", - "geometry": - { - "shape": "sphere", - "origin": [0, 0, -6374134], - "outer_radius": 1000000000, - "inner_radius": 6374134 + "v_cut": 1, + "cont_rand": true } }, - "sectors": [ { - "hierarchy": 1, "medium": "air", - "density_correction": 0.673, + "geometries": [ + { + "hierarchy": 0, + "shape": "sphere", + "origin": [0, 0, -637413400], + "outer_radius": 1e20, + "inner_radius": 637413400 - "geometry": - { - "shape": "sphere", - "origin": [0, 0, -6374134], - "outer_radius": 1000000000, - "inner_radius": 6374134 - }, - "cuts_inside": - { - "e_cut": 1e8, - "v_cut": -1, - "cont_rand": false - }, - "cuts_infront": - { - "e_cut": 1e8, - "v_cut": -1, - "cont_rand": true - }, - "cuts_behind": + } + ], + "density_distribution": { - "e_cut": 1e8, - "v_cut": -1, - "cont_rand": false + "type": "homogeneous", + "mass_density" : 0.000810965 } }, { - "hierarchy": 1, "medium": "ice", - "density_correction": 0.832, + "geometries": [ + { + "hierarchy": 1, + "shape": "sphere", + "origin": [0, 0, -637413400], + "outer_radius": 637413400, + "inner_radius": 637393400 - "geometry": + } + ], + "density_distribution": { - "shape": "sphere", - "origin": [0, 0, -6374134], - "outer_radius": 6374134, - "inner_radius": 6373934 - }, - "cuts_inside": - { - "e_cut": 1e8, - "v_cut": -1, - "cont_rand": false - }, - "cuts_infront": - { - "e_cut": 1e8, - "v_cut": -1, - "cont_rand": true - }, - "cuts_behind": - { - "e_cut": 1e8, - "v_cut": -1, - "cont_rand": false + "type": "homogeneous", + "mass_density" : 0.762944 } - }, + }, { - "hierarchy": 1, "medium": "ice", - "density_correction": 1.005, + "geometries": [ + { + "hierarchy": 2, + "shape": "sphere", + "origin": [0, 0, -637413400], + "outer_radius": 637393400, + "inner_radius": 637102400 - "geometry": - { - "shape": "sphere", - "origin": [0, 0, -6374134], - "outer_radius": 6373934, - "inner_radius": 6371024 - }, - "cuts_inside": + } + ], + "density_distribution": { - "e_cut": 1e8, - "v_cut": -1, - "cont_rand": false - }, - "cuts_infront": - { - "e_cut": 1e8, - "v_cut": -1, - "cont_rand": true - }, - "cuts_behind": - { - "e_cut": 1e8, - "v_cut": -1, - "cont_rand": false + "type": "homogeneous", + "mass_density" : 0.921585 } - }, + }, { - "hierarchy": 1, - "medium": "standardrock", - "density_correction": 1.0, + "medium": "StandardRock", + "geometries": [ + { + "hierarchy": 3, + "shape": "sphere", + "origin": [0, 0, -637413400], + "outer_radius": 637102400, + "inner_radius": 0 - "geometry": - { - "shape": "sphere", - "origin": [0, 0, -6374134], - "outer_radius": 6371024, - "inner_radius": 0 - }, - "cuts_inside": - { - "e_cut": 1e8, - "v_cut": -1, - "cont_rand": false - }, - "cuts_infront": + } + ], + "density_distribution": { - "e_cut": 1e8, - "v_cut": -1, - "cont_rand": true - }, - "cuts_behind": - { - "e_cut": 1e8, - "v_cut": -1, - "cont_rand": false + "type": "homogeneous", + "mass_density" : 2.65 } - } - ], - - "detector": - { - "shape": "cylinder", - "origin" : [0, 0, 0], - "outer_radius": 1e20, - "inner_radius": 0, - "height": 1e20 - } -} + } + ] +} \ No newline at end of file diff --git a/NuRadioMC/EvtGen/config_PROPOSAL_infice.json.sample b/NuRadioMC/EvtGen/config_PROPOSAL_infice.json.sample index cd959923e..81c78bc13 100644 --- a/NuRadioMC/EvtGen/config_PROPOSAL_infice.json.sample +++ b/NuRadioMC/EvtGen/config_PROPOSAL_infice.json.sample @@ -1,112 +1,58 @@ { "global": { - "seed" : 12, - "continous_loss_output" : false, - "only_loss_inside_detector" : false, - - "interpolation": - { - "do_interpolation" : true, - "path_to_tables" : "Please provide here a valid system path", - "path_to_tables_readonly" : "Please provide here a valid system path", - "do_binary_tables" : false, - "just_use_readonly_path" : false, - "max_node_energy" : 1e14, - "nodes_cross_section" : 100, - "nodes_continous_randomization" : 200, - "nodes_propagate" : 1000 - }, - + "do_interpolation" : true, "exact_time" : true, - "stopping_decay" : true, - "scattering" : "NoScattering", - - "brems_multiplier" : 1, - "photo_multiplier" : 1, - "ioniz_multiplier" : 1, - "epair_multiplier" : 1, - "ioniz": "IonizBetheBlochRossi", - "epair": "EpairKelnerKokoulinPetrukhin", - "brems" : "BremsKelnerKokoulinPetrukhin", - "photo" : "PhotoAbramowiczLevinLevyMaor97", - "annihilation": "none", - "compton" : "none", - "photopair": "none", - "mupair": "none", - "weak": "none", - "lpm" : true, - "photo_hard_component" : true, - "photo_shadow" : "ShadowButkevichMikhailov", - - "cuts_infront": + "scattering": { - "e_cut": 1e8, - "v_cut": -1, - "cont_rand": true + "multiple_scattering" : "NoScattering" }, - "cuts_inside": - { - "e_cut": 1e8, - "v_cut": -1, - "cont_rand": false + "CrossSections" : { + "brems": { + "parametrization": "KelnerKokoulinPetrukhin", + "multiplier" : 1.0, + "lpm": true + }, + "epair": { + "parametrization": "KelnerKokoulinPetrukhin", + "multiplier" : 1.0, + "lpm": true + }, + "ioniz": { + "parametrization": "BetheBlochRossi", + "multiplier" : 1.0 + }, + "photo": { + "parametrization": "AbramowiczLevinLevyMaor97", + "multiplier" : 1.0, + "shadow": "ButkevichMikheyev" + } }, - "cuts_behind": + "cuts": { "e_cut": 1e8, - "v_cut": -1, - "cont_rand": false - }, - "medium": "air", - "geometry": - { - "shape": "sphere", - "origin": [0, 0, -6374134], - "outer_radius": 1000000000, - "inner_radius": 6374134 + "v_cut": 1, + "cont_rand": true } }, - - "sectors": [ + "sectors": [ { - "hierarchy": 1, "medium": "ice", - "density_correction": 1.005, + "geometries": [ + { + "hierarchy": 0, + "shape": "sphere", + "origin": [0, 0, -637413400], + "outer_radius": 1e20, + "inner_radius": 0 - "geometry": + } + ], + "density_distribution": { - "shape": "sphere", - "origin": [0, 0, -6374134], - "outer_radius": 1e20, - "inner_radius": 0 - }, - "cuts_inside": - { - "e_cut": 1e8, - "v_cut": -1, - "cont_rand": false - }, - "cuts_infront": - { - "e_cut": 1e8, - "v_cut": -1, - "cont_rand": true - }, - "cuts_behind": - { - "e_cut": 1e8, - "v_cut": -1, - "cont_rand": false + "type": "homogeneous", + "mass_density" : 0.921585 } - } - ], - - "detector": - { - "shape": "cylinder", - "origin" : [0, 0, 0], - "outer_radius": 1e20, - "inner_radius": 0, - "height": 1e20 - } -} + } + ] +} \ No newline at end of file diff --git a/NuRadioMC/EvtGen/config_PROPOSAL_mooresbay.json.sample b/NuRadioMC/EvtGen/config_PROPOSAL_mooresbay.json.sample index ed1e4b479..fc1671767 100644 --- a/NuRadioMC/EvtGen/config_PROPOSAL_mooresbay.json.sample +++ b/NuRadioMC/EvtGen/config_PROPOSAL_mooresbay.json.sample @@ -1,205 +1,112 @@ { "global": { - "seed" : 12, - "continous_loss_output" : false, - "only_loss_inside_detector" : false, - - "interpolation": - { - "do_interpolation" : true, - "path_to_tables" : "Please provide here a valid system path", - "path_to_tables_readonly" : "Please provide here a valid system path", - "do_binary_tables" : false, - "just_use_readonly_path" : false, - "max_node_energy" : 1e14, - "nodes_cross_section" : 100, - "nodes_continous_randomization" : 200, - "nodes_propagate" : 1000 - }, - + "do_interpolation" : true, "exact_time" : true, - "stopping_decay" : true, - "scattering" : "NoScattering", - - "brems_multiplier" : 1, - "photo_multiplier" : 1, - "ioniz_multiplier" : 1, - "epair_multiplier" : 1, - "ioniz": "IonizBetheBlochRossi", - "epair": "EpairKelnerKokoulinPetrukhin", - "brems" : "BremsKelnerKokoulinPetrukhin", - "photo" : "PhotoAbramowiczLevinLevyMaor97", - "annihilation": "none", - "compton" : "none", - "photopair": "none", - "mupair": "none", - "weak": "none", - "lpm" : true, - "photo_hard_component" : true, - "photo_shadow" : "ShadowButkevichMikhailov", - - "cuts_infront": + "scattering": { - "e_cut": 1e8, - "v_cut": -1, - "cont_rand": true + "multiple_scattering" : "NoScattering" }, - "cuts_inside": - { - "e_cut": 1e8, - "v_cut": -1, - "cont_rand": false + "CrossSections" : { + "brems": { + "parametrization": "KelnerKokoulinPetrukhin", + "multiplier" : 1.0, + "lpm": true + }, + "epair": { + "parametrization": "KelnerKokoulinPetrukhin", + "multiplier" : 1.0, + "lpm": true + }, + "ioniz": { + "parametrization": "BetheBlochRossi", + "multiplier" : 1.0 + }, + "photo": { + "parametrization": "AbramowiczLevinLevyMaor97", + "multiplier" : 1.0, + "shadow": "ButkevichMikheyev" + } }, - "cuts_behind": + "cuts": { "e_cut": 1e8, - "v_cut": -1, - "cont_rand": false - }, - "medium": "air", - "geometry": - { - "shape": "sphere", - "origin": [0, 0, -6374134], - "outer_radius": 1000000000, - "inner_radius": 6374134 + "v_cut": 1, + "cont_rand": true } }, - "sectors": [ { - "hierarchy": 1, "medium": "air", - "density_correction": 0.673, + "geometries": [ + { + "hierarchy": 0, + "shape": "sphere", + "origin": [0, 0, -637413400], + "outer_radius": 1e20, + "inner_radius": 637413400 - "geometry": - { - "shape": "sphere", - "origin": [0, 0, -6374134], - "outer_radius": 1000000000, - "inner_radius": 6374134 - }, - "cuts_inside": - { - "e_cut": 1e8, - "v_cut": -1, - "cont_rand": false - }, - "cuts_infront": - { - "e_cut": 1e8, - "v_cut": -1, - "cont_rand": true - }, - "cuts_behind": + } + ], + "density_distribution": { - "e_cut": 1e8, - "v_cut": -1, - "cont_rand": false + "type": "homogeneous", + "mass_density" : 0.000810965 } }, { - "hierarchy": 1, "medium": "ice", - "density_correction": 0.832, + "geometries": [ + { + "hierarchy": 1, + "shape": "sphere", + "origin": [0, 0, -637413400], + "outer_radius": 637413400, + "inner_radius": 637355800 - "geometry": + } + ], + "density_distribution": { - "shape": "sphere", - "origin": [0, 0, -6374134], - "outer_radius": 6374134, - "inner_radius": 6373558 - }, - "cuts_inside": - { - "e_cut": 1e8, - "v_cut": -1, - "cont_rand": false - }, - "cuts_infront": - { - "e_cut": 1e8, - "v_cut": -1, - "cont_rand": true - }, - "cuts_behind": - { - "e_cut": 1e8, - "v_cut": -1, - "cont_rand": false + "type": "homogeneous", + "mass_density" : 0.762944 } - }, + }, { - "hierarchy": 1, "medium": "water", - "density_correction": 1.00, + "geometries": [ + { + "hierarchy": 2, + "shape": "sphere", + "origin": [0, 0, -637413400], + "outer_radius": 637355800, + "inner_radius": 637132400 - "geometry": - { - "shape": "sphere", - "origin": [0, 0, -6374134], - "outer_radius": 6373558, - "inner_radius": 6371324 - }, - "cuts_inside": + } + ], + "density_distribution": { - "e_cut": 1e8, - "v_cut": -1, - "cont_rand": false - }, - "cuts_infront": - { - "e_cut": 1e8, - "v_cut": -1, - "cont_rand": true - }, - "cuts_behind": - { - "e_cut": 1e8, - "v_cut": -1, - "cont_rand": false + "type": "homogeneous", + "mass_density" : 1.0 } - }, + }, { - "hierarchy": 1, - "medium": "standardrock", - "density_correction": 1.0, + "medium": "StandardRock", + "geometries": [ + { + "hierarchy": 3, + "shape": "sphere", + "origin": [0, 0, -637413400], + "outer_radius": 637132400, + "inner_radius": 0 - "geometry": - { - "shape": "sphere", - "origin": [0, 0, -6374134], - "outer_radius": 6371324, - "inner_radius": 0 - }, - "cuts_inside": - { - "e_cut": 1e8, - "v_cut": -1, - "cont_rand": false - }, - "cuts_infront": + } + ], + "density_distribution": { - "e_cut": 1e8, - "v_cut": -1, - "cont_rand": true - }, - "cuts_behind": - { - "e_cut": 1e8, - "v_cut": -1, - "cont_rand": false + "type": "homogeneous", + "mass_density" : 2.65 } - } - ], - - "detector": - { - "shape": "cylinder", - "origin" : [0, 0, 0], - "outer_radius": 1e20, - "inner_radius": 0, - "height": 1e20 - } -} + } + ] +} \ No newline at end of file diff --git a/documentation/source/Introduction/pages/installation.rst b/documentation/source/Introduction/pages/installation.rst index 122f68593..f7d1c9ba5 100644 --- a/documentation/source/Introduction/pages/installation.rst +++ b/documentation/source/Introduction/pages/installation.rst @@ -189,7 +189,7 @@ These packages are recommended to be able to use all of NuRadioMC/NuRadioReco's .. code-block:: bash - pip install proposal==6.1.6 + pip install proposal - To use the channelGalacticNoiseAdder, you need the `PyGDSM `_ package. diff --git a/pyproject.toml b/pyproject.toml index 54a4d0efd..50e381ac6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -46,7 +46,7 @@ numba = "*" Sphinx = "*" sphinx-rtd-theme = "*" numpydoc = "1.1.0" -proposal = "6.1.6" +proposal = ">=7.0.0" pygdsm = {git = "https://github.com/telegraphic/pygdsm"} nifty5 = {git = "https://gitlab.mpcdf.mpg.de/ift/nifty.git", branch="NIFTy_5"} pypocketfft = {git = "https://gitlab.mpcdf.mpg.de/mtr/pypocketfft"} From 548a79933c6cda684adfcc7e31002e484664c272 Mon Sep 17 00:00:00 2001 From: Jean-Marco Alameddine Date: Tue, 1 Nov 2022 11:26:26 +0100 Subject: [PATCH 057/418] correct wrong # sign --- NuRadioMC/EvtGen/NuRadioProposal.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NuRadioMC/EvtGen/NuRadioProposal.py b/NuRadioMC/EvtGen/NuRadioProposal.py index 619276072..5a2b9d717 100644 --- a/NuRadioMC/EvtGen/NuRadioProposal.py +++ b/NuRadioMC/EvtGen/NuRadioProposal.py @@ -283,7 +283,7 @@ def __get_propagator(self, raise ValueError("Proposal config file is not valid. Please provide a valid option.") # TODO: What is this {}.sample, and what does it have to do with interpoation tables? - #if not os.path.exists(config_file_full_path): + if not os.path.exists(config_file_full_path): error_message = "Proposal config file does not exist.\n" error_message += "Please provide valid paths for the interpolation tables " error_message += "in file {}.sample ".format(config_file_full_path) From 871a625519eb43f21bbfb527271008edb621ece2 Mon Sep 17 00:00:00 2001 From: Jean-Marco Alameddine Date: Tue, 1 Nov 2022 11:47:23 +0100 Subject: [PATCH 058/418] make proposal.InterpolationSettings.upper_energy_lim an adjustable parameter --- NuRadioMC/EvtGen/NuRadioProposal.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/NuRadioMC/EvtGen/NuRadioProposal.py b/NuRadioMC/EvtGen/NuRadioProposal.py index 5a2b9d717..197e88fc4 100644 --- a/NuRadioMC/EvtGen/NuRadioProposal.py +++ b/NuRadioMC/EvtGen/NuRadioProposal.py @@ -217,7 +217,7 @@ class ProposalFunctions(object): not be used from the outside to avoid mismatching units. """ - def __init__(self, config_file='SouthPole', log_level=logging.INFO, tables_path="/tmp", seed=12): + def __init__(self, config_file='SouthPole', log_level=logging.INFO, tables_path="/tmp", seed=12, upper_energy_limit=1e14*units.MeV): """ Parameters ---------- @@ -239,6 +239,10 @@ def __init__(self, config_file='SouthPole', log_level=logging.INFO, tables_path= tables (which can take several minutes) every time the script is executed seed: int Seed to be used by PROPOSAL + upper_energy_limit: float + upper_energy_limit of tables that will be created by PROPOSAL, in NuRadioMC units (eV). + There will be an error if primaries with energies above this energy will be injected. + Note that PROPOSAL will have to regenerate tables for a new values of upper_energy_limit """ self.__logger = logging.getLogger("proposal") @@ -250,6 +254,7 @@ def __init__(self, config_file='SouthPole', log_level=logging.INFO, tables_path= self.__propagators = {} self.__config_file = config_file self.__tables_path = tables_path + self.__upper_energy_limit = upper_energy_limit * pp_eV # convert to PROPOSAL units def __get_propagator(self, particle_code=13): @@ -293,7 +298,7 @@ def __get_propagator(self, pp.InterpolationSettings.tables_path = self.__tables_path # upper energy lim for proposal tables, in PROPOSAL units (MeV) - pp.InterpolationSettings.upper_energy_lim = 1e14 * pp_MeV + pp.InterpolationSettings.upper_energy_lim = self.__upper_energy_limit try: p_def = pp.particle.get_ParticleDef_for_type(particle_code) @@ -403,6 +408,10 @@ def __propagate_particle(self, x, y, z = lepton_position px, py, pz = lepton_direction + if (energy_lepton > self.__upper_energy_limit): + raise ValueError("Initial lepton energy higher than upper_energy_limit of PROPOSAL. Adjust upper_energy_limit when" + " initialzing EvtGen.NuRadioProposal.ProposalFunctions.") + initial_condition = pp.particle.ParticleState() initial_condition.type = lepton_code initial_condition.position = pp.Cartesian3D(x, y, z) From ff70bb3f5e8f7243f80666228083159d9b19c07b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Tue, 1 Nov 2022 16:26:01 +0100 Subject: [PATCH 059/418] Refactoring code. Potentially fixed a small bug --- NuRadioMC/utilities/Veff.py | 380 +++++++++++++++++++----------------- 1 file changed, 205 insertions(+), 175 deletions(-) diff --git a/NuRadioMC/utilities/Veff.py b/NuRadioMC/utilities/Veff.py index 4c97d8c55..4a7b9a6d3 100644 --- a/NuRadioMC/utilities/Veff.py +++ b/NuRadioMC/utilities/Veff.py @@ -150,20 +150,42 @@ def get_Veff_water_equivalent(Veff, density_medium=0.917 * units.g / units.cm ** return Veff * density_medium / density_water -def get_Veff_Aeff_single(filename, trigger_names, trigger_names_dict, trigger_combinations, deposited, station, veff_aeff="veff", bounds_theta=[0, np.pi]): +def get_veff_output(volume, counts, all_events): + v_eff = volume * counts / all_events + fc_low, fc_high = FC_limits(counts) + + if counts: + v_eff_error = v_eff / np.sqrt(counts) + else: + v_eff_error = 0 + + v_eff_low = volume * fc_low / all_events + v_eff_high = volume * fc_high / all_events + + return [v_eff, v_eff_error, counts, v_eff_low, v_eff_high] + + +def get_Veff_Aeff_single( + filename, trigger_names, trigger_names_dict, trigger_combinations, + deposited, station, veff_aeff="veff", bounds_theta=[0, np.pi]): """ - calculates the effective volume or effective area from surface muons from a single NuRadioMC hdf5 file + Calculates the effective volume or effective area from surface muons from + a single NuRadioMC hdf5 file - the effective volume is NOT normalized to a water equivalent. It is also NOT multiplied with the solid angle (typically 4pi). + The effective volume is NOT normalized to a water equivalent. It is also NOT + multiplied with the solid angle (typically 4pi). Parameters ---------- filename: string filename of the hdf5 file + trigger_names: list of strings list of the trigger names contained in the file + trigger_names_dict: dict map from trigger name to index + trigger_combinations: dict, optional keys are the names of triggers to calculate. Values are dicts again: @@ -188,6 +210,7 @@ def get_Veff_Aeff_single(filename, trigger_names, trigger_names_dict, trigger_co station: int the station that should be considered + veff_aeff: string specifiy if the effective volume or the effective area for surface muons is calculated can be @@ -201,12 +224,14 @@ def get_Veff_Aeff_single(filename, trigger_names, trigger_names_dict, trigger_co bounds_theta should be a (two-item) list, but will care only about the min/max values Returns - ---------- + ------- + list of dictionaries Each file is one entry. The dictionary keys store all relevant properties """ if(veff_aeff not in ["veff", "aeff_surface_muons"]): raise AttributeError(f"the paramter `veff_aeff` needs to be one of either `veff` or `aeff_surface_muons`") + logger.warning(f"processing file {filename}") fin = h5py.File(filename, 'r') n_events = fin.attrs['n_events'] @@ -214,20 +239,15 @@ def get_Veff_Aeff_single(filename, trigger_names, trigger_names_dict, trigger_co out = {} Emin = fin.attrs['Emin'] Emax = fin.attrs['Emax'] - E = 10 ** (0.5 * (np.log10(Emin) + np.log10(Emax))) - out['energy'] = E + out['energy'] = 10 ** (0.5 * (np.log10(Emin) + np.log10(Emax))) out['energy_min'] = Emin out['energy_max'] = Emax # calculate effective - thetamin = 0 - thetamax = np.pi - phimin = 0 - phimax = 2 * np.pi - if('thetamin' in fin.attrs): - thetamin = fin.attrs['thetamin'] - if('thetamax' in fin.attrs): - thetamax = fin.attrs['thetamax'] + phimin = fin.attrs['phimin'] + phimax = fin.attrs['phimax'] + thetamin = fin.attrs['thetamin'] + thetamax = fin.attrs['thetamax'] theta_width_file = abs(np.cos(thetamin) - np.cos(thetamax)) # restrict the theta range, if requested @@ -237,19 +257,16 @@ def get_Veff_Aeff_single(filename, trigger_names, trigger_names_dict, trigger_co if max(bounds_theta) < thetamax: logger.info("restricting thetamax from {} to {}".format(thetamax, max(bounds_theta))) thetamax = max(bounds_theta) + # The restriction assumes isotropic event generation in cos(theta) band theta_fraction = abs(np.cos(thetamin) - np.cos(thetamax)) / theta_width_file if theta_fraction < 1: # adjust n_events to account for solid angle fraction in the requested theta range n_events *= theta_fraction - if('phimin' in fin.attrs): - phimin = fin.attrs['phimin'] - if('phimax' in fin.attrs): - phimax = fin.attrs['phimax'] - if(veff_aeff == "veff"): + if veff_aeff == "veff": volume_proj_area = fin.attrs['volume'] - elif(veff_aeff == "aeff_surface_muons"): + elif veff_aeff == "aeff_surface_muons": area = fin.attrs['area'] # The used area must be the projected area, perpendicular to the incoming # flux, which leaves us with the following correction. Remember that the @@ -258,9 +275,7 @@ def get_Veff_Aeff_single(filename, trigger_names, trigger_names_dict, trigger_co else: raise AttributeError(f"attributes do neither contain volume nor area") - Vrms = np.nan - if 'Vrms' in fin.attrs: - Vrms = fin.attrs['Vrms'] + Vrms = fin.attrs['Vrms'] # Solid angle needed for the effective volume calculations out['domega'] = np.abs(phimax - phimin) * np.abs(np.cos(thetamin) - np.cos(thetamax)) @@ -270,28 +285,35 @@ def get_Veff_Aeff_single(filename, trigger_names, trigger_names_dict, trigger_co out[veff_aeff] = {} out['n_triggered_weighted'] = {} out['SNRs'] = {} + + fc_low_0, fc_high_0 = FC_limits(0) + v_eff_low_0 = volume_proj_area * fc_low_0 / n_events + v_eff_high_0 = volume_proj_area * fc_high_0 / n_events - if('weights' not in fin.keys()): + if 'weights' not in fin.keys(): logger.warning(f"file {filename} is empty") - FC_low, FC_high = FC_limits(0) - Veff_low = volume_proj_area * FC_low / n_events - Veff_high = volume_proj_area * FC_high / n_events for iT, trigger_name in enumerate(trigger_names): - out[veff_aeff][trigger_name] = [0, 0, 0, Veff_low, Veff_high] + out[veff_aeff][trigger_name] = [0, 0, 0, v_eff_low_0, v_eff_high_0] for trigger_name, values in iteritems(trigger_combinations): - out[veff_aeff][trigger_name] = [0, 0, 0, Veff_low, Veff_high] + out[veff_aeff][trigger_name] = [0, 0, 0, v_eff_low_0, v_eff_high_0] + return out triggered = np.array(fin['triggered']) - if('trigger_names' in fin.attrs): - if(np.any(trigger_names != fin.attrs['trigger_names'])): - if(triggered.size == 0 and fin.attrs['trigger_names'].size == 0): - logger.warning("file {} has no triggering events. Using trigger names from another file".format(filename)) + if 'trigger_names' in fin.attrs: + if np.any(trigger_names != fin.attrs['trigger_names']): + if triggered.size == 0 and fin.attrs['trigger_names'].size == 0: + logger.warning("file {} has no triggering events. " + "Using trigger names from another file".format(filename)) else: - logger.error("file {} has inconsistent trigger names: {}\ncurrent trigger names {}".format(filename, fin.attrs['trigger_names'], trigger_names)) - raise AttributeError("file {} has inconsistent trigger names: {}\ncurrent trigger names {}".format(filename, fin.attrs['trigger_names'], trigger_names)) + error_msg = ("file {} has inconsistent trigger names: " + "{}\ncurrent trigger names {}").format( + filename, fin.attrs['trigger_names'], trigger_names) + logger.error(error_msg) + raise AttributeError(error_msg) else: - logger.warning(f"file {filename} has no triggering events. Using trigger names from a different file: {trigger_names}") + logger.warning(f"file {filename} has no triggering events. " + "Using trigger names from a different file: {trigger_names}") weights = np.array(fin['weights']) # if theta range is restricted, select events in that range @@ -301,151 +323,156 @@ def get_Veff_Aeff_single(filename, trigger_names, trigger_names_dict, trigger_co # multiply events with mask, events outside are zero-weighted weights *= mask_theta - if(triggered.size == 0): - FC_low, FC_high = FC_limits(0) - Veff_low = volume_proj_area * FC_low / n_events - Veff_high = volume_proj_area * FC_high / n_events - for iT, trigger_name in enumerate(trigger_names): - out[veff_aeff][trigger_name] = [0, 0, 0, Veff_low, Veff_high] - for trigger_name, values in iteritems(trigger_combinations): - out[veff_aeff][trigger_name] = [0, 0, 0, Veff_low, Veff_high] - else: + if triggered.size == 0: for iT, trigger_name in enumerate(trigger_names): - triggered = np.array(fin['multiple_triggers'][:, iT], dtype=np.bool) - triggered = remove_duplicate_triggers(triggered, fin['event_group_ids']) - Veff = volume_proj_area * np.sum(weights[triggered]) / n_events - Veff_error = 0 - if(np.sum(weights[triggered]) > 0): - Veff_error = Veff / np.sum(weights[triggered]) ** 0.5 - FC_low, FC_high = FC_limits(np.sum(weights[triggered])) - Veff_low = volume_proj_area * FC_low / n_events - Veff_high = volume_proj_area * FC_high / n_events - out[veff_aeff][trigger_name] = [Veff, Veff_error, np.sum(weights[triggered]), Veff_low, Veff_high] - + out[veff_aeff][trigger_name] = [0, 0, 0, v_eff_low_0, v_eff_high_0] for trigger_name, values in iteritems(trigger_combinations): - indiv_triggers = values['triggers'] - triggered = np.zeros_like(fin['multiple_triggers'][:, 0], dtype=np.bool) + out[veff_aeff][trigger_name] = [0, 0, 0, v_eff_low_0, v_eff_high_0] + + return out + + for iT, trigger_name in enumerate(trigger_names): + triggered = np.array(fin['multiple_triggers'][:, iT], dtype=np.bool) + triggered = remove_duplicate_triggers(triggered, fin['event_group_ids']) + out[veff_aeff][trigger_name] = get_veff_output(volume_proj_area, np.sum(weights[triggered]), n_events) + + for trigger_name, values in iteritems(trigger_combinations): + indiv_triggers = values['triggers'] + triggered = np.zeros_like(fin['multiple_triggers'][:, 0], dtype=np.bool) + + if isinstance(indiv_triggers, str): + triggered = triggered | \ + np.array(fin['multiple_triggers'][:, trigger_names_dict[indiv_triggers]], dtype=np.bool) + else: + for indiv_trigger in indiv_triggers: + triggered = triggered | \ + np.array(fin['multiple_triggers'][:, trigger_names_dict[indiv_trigger]], dtype=np.bool) + + if 'triggerAND' in values: + triggered = triggered & \ + np.array(fin['multiple_triggers'][:, trigger_names_dict[values['triggerAND']]], dtype=np.bool) + + if 'notriggers' in values: + indiv_triggers = values['notriggers'] if(isinstance(indiv_triggers, str)): - triggered = triggered | np.array(fin['multiple_triggers'][:, trigger_names_dict[indiv_triggers]], dtype=np.bool) + triggered = triggered & \ + ~np.array(fin['multiple_triggers'][:, trigger_names_dict[indiv_triggers]], dtype=np.bool) else: for indiv_trigger in indiv_triggers: - triggered = triggered | np.array(fin['multiple_triggers'][:, trigger_names_dict[indiv_trigger]], dtype=np.bool) - if 'triggerAND' in values: - triggered = triggered & np.array(fin['multiple_triggers'][:, trigger_names_dict[values['triggerAND']]], dtype=np.bool) - if 'notriggers' in values: - indiv_triggers = values['notriggers'] - if(isinstance(indiv_triggers, str)): - triggered = triggered & ~np.array(fin['multiple_triggers'][:, trigger_names_dict[indiv_triggers]], dtype=np.bool) - else: - for indiv_trigger in indiv_triggers: - triggered = triggered & ~np.array(fin['multiple_triggers'][:, trigger_names_dict[indiv_trigger]], dtype=np.bool) - if('min_sigma' in values.keys()): - if(isinstance(values['min_sigma'], list)): - if(trigger_name not in out['SNR']): - out['SNR'][trigger_name] = {} - masks = np.zeros_like(triggered) - for iS in range(len(values['min_sigma'])): - As = np.max(np.nan_to_num(fin['max_amp_ray_solution']), axis=-1) # we use the this quantity because it is always computed before noise is added! - As_sorted = np.sort(As[:, values['channels'][iS]], axis=1) - # the smallest of the three largest amplitudes - max_amplitude = As_sorted[:, -values['n_channels'][iS]] - mask = np.sum(As[:, values['channels'][iS]] >= (values['min_sigma'][iS] * Vrms), axis=1) >= values['n_channels'][iS] - masks = masks | mask - out['SNR'][trigger_name][iS] = max_amplitude[mask] / Vrms - triggered = triggered & masks - else: + triggered = triggered & \ + ~np.array(fin['multiple_triggers'][:, trigger_names_dict[indiv_trigger]], dtype=np.bool) + + if 'min_sigma' in values.keys(): + if isinstance(values['min_sigma'], list): + if trigger_name not in out['SNR']: + out['SNR'][trigger_name] = {} + + masks = np.zeros_like(triggered) + for iS in range(len(values['min_sigma'])): As = np.max(np.nan_to_num(fin['max_amp_ray_solution']), axis=-1) # we use the this quantity because it is always computed before noise is added! + As_sorted = np.sort(As[:, values['channels'][iS]], axis=1) + # the smallest of the three largest amplitudes + max_amplitude = As_sorted[:, -values['n_channels'][iS]] + mask = np.sum( + As[:, values['channels'][iS]] >= (values['min_sigma'][iS] * Vrms), axis=1) >= values['n_channels'][iS] + masks = masks | mask + out['SNR'][trigger_name][iS] = max_amplitude[mask] / Vrms + + triggered = triggered & masks + else: + As = np.max(np.nan_to_num(fin['max_amp_ray_solution']), axis=-1) # we use the this quantity because it is always computed before noise is added! - As_sorted = np.sort(As[:, values['channels']], axis=1) - max_amplitude = As_sorted[:, -values['n_channels']] # the smallest of the three largest amplitudes - - mask = np.sum(As[:, values['channels']] >= (values['min_sigma'] * Vrms), axis=1) >= values['n_channels'] - out['SNR'][trigger_name] = As_sorted[mask] / Vrms - triggered = triggered & mask - if('ray_solution' in values.keys()): - As = np.array(fin['max_amp_ray_solution']) - max_amps = np.argmax(As[:, values['ray_channel']], axis=-1) - sol = np.array(fin['ray_tracing_solution_type']) - mask = np.array([sol[i, values['ray_channel'], max_amps[i]] == values['ray_solution'] for i in range(len(max_amps))], dtype=np.bool) + As_sorted = np.sort(As[:, values['channels']], axis=1) + max_amplitude = As_sorted[:, -values['n_channels']] # the smallest of the three largest amplitudes + + mask = np.sum(As[:, values['channels']] >= (values['min_sigma'] * Vrms), axis=1) >= values['n_channels'] + out['SNR'][trigger_name] = As_sorted[mask] / Vrms triggered = triggered & mask + + if 'ray_solution' in values.keys(): + As = np.array(fin['max_amp_ray_solution']) + max_amps = np.argmax(As[:, values['ray_channel']], axis=-1) + sol = np.array(fin['ray_tracing_solution_type']) + mask = np.array([sol[i, values['ray_channel'], max_amps[i]] == values['ray_solution'] for i in range(len(max_amps))], dtype=np.bool) + triggered = triggered & mask + + if 'n_reflections' in values.keys(): + if(np.sum(triggered)): + As = np.array(fin[f'station_{station:d}/max_amp_ray_solution']) + # find the ray tracing solution that produces the largest amplitude + max_amps = np.argmax(np.argmax(As[:,:], axis=-1), axis=-1) + # advanced indexing: selects the ray tracing solution per event with the highest amplitude + triggered = triggered & (np.array(fin[f'station_{station:d}/ray_tracing_reflection'])[..., max_amps, 0][:, 0] == values['n_reflections']) + + triggered = remove_duplicate_triggers(triggered, fin['event_group_ids']) + + v_eff, v_eff_err, count, v_eff_low, v_eff_high = \ + get_veff_output(volume_proj_area, np.sum(weights[triggered]), n_events) + + if 'efficiency' in values.keys() and v_eff > 0: + get_efficiency = values['efficiency']['func'] + channel_ids = values['efficiency']['channel_ids'] + gids = np.array(fin['event_group_ids']) + ugids = np.unique(np.array(fin['event_group_ids'])) + + # calculate the group event ids that triggered + ugids_triggered_index = [] + ugids_triggered = [] + for i_ugid, ugid in enumerate(ugids): + mask = ugid == gids + if(np.any(triggered[mask])): + ugids_triggered_index.append(i_ugid) + ugids_triggered.append(ugid) + ugids_triggered = np.array(ugids_triggered) + ugids_triggered_index = np.array(ugids_triggered_index) + + n_unique_gids = len(ugids_triggered) + sorter = np.argsort(ugids_triggered) + max_amplitudes = np.zeros(n_unique_gids) + for key in fin.keys(): + if key.startswith("station_"): + if 'event_group_ids' not in fin[key]: + continue # the station might have no triggers + + sgids = np.array(fin[key]['event_group_ids']) + usgids = np.unique(sgids) + usgids, comm1, comm2 = np.intersect1d(usgids, ugids_triggered, assume_unique=True, return_indices=True) # select only the gids that triggered + common_mask = np.isin(sgids, usgids) + sgids = sgids[common_mask] # also reduce gids array to the event groups that triggered + + if(len(usgids) == 0): # skip stations that don't have any trigger for this trigger combination + continue + + usgids_index = sorter[np.searchsorted(ugids_triggered, usgids, sorter=sorter)] + # each station might have multiple triggeres per event group id. We need to select the one + # event with the largest amplitude. Let's first check if one event group created more than one event + max_amps_per_event_channel = np.nan_to_num(np.array(fin[key]['maximum_amplitudes_envelope'])[common_mask]) + max_amps_per_event = np.amax(max_amps_per_event_channel[:, channel_ids], axis=1) # select the maximum amplitude of all considered channels + + if len(sgids) != len(usgids): + # at least one event group created more than one event. Let's calculate it the slow but correct way + for sgid in np.unique(sgids): # loop over all event groups which triggered this station + + if(sgid not in usgids): + continue + + mask_gid = sgid == sgids # select all event that are part of this event group + index = np.squeeze(np.argwhere(ugids_triggered == sgid)) + max_amplitudes[index] = max(max_amplitudes[index], max_amps_per_event[mask_gid].max()) + else: + max_amplitudes[usgids_index] = np.maximum(max_amplitudes[usgids_index], max_amps_per_event) + + if 'scale' in values['efficiency']: + max_amplitudes *= values['efficiency']['scale'] + if "Vrms" in values['efficiency']: + Vrms = values['efficiency']['Vrms'] + + e = get_efficiency(max_amplitudes / Vrms) # we calculated the maximum amplitudes for all gids, now we select only those that triggered + v_eff, v_eff_err, count, v_eff_low, v_eff_high = \ + get_veff_output(volume_proj_area, np.sum(weights[triggered] * e), n_events) + + out[veff_aeff][trigger_name] = [v_eff, v_eff_err, count, v_eff_low, v_eff_high] - if('n_reflections' in values.keys()): - if(np.sum(triggered)): - As = np.array(fin[f'station_{station:d}/max_amp_ray_solution']) - # find the ray tracing solution that produces the largest amplitude - max_amps = np.argmax(np.argmax(As[:,:], axis=-1), axis=-1) - # advanced indexing: selects the ray tracing solution per event with the highest amplitude - triggered = triggered & (np.array(fin[f'station_{station:d}/ray_tracing_reflection'])[..., max_amps, 0][:, 0] == values['n_reflections']) - - triggered = remove_duplicate_triggers(triggered, fin['event_group_ids']) - Veff = volume_proj_area * np.sum(weights[triggered]) / n_events - Vefferror = 0 - if(np.sum(weights[triggered]) > 0): - Vefferror = Veff / np.sum(weights[triggered]) ** 0.5 - FC_low, FC_high = FC_limits(np.sum(weights[triggered])) - Veff_low = volume_proj_area * FC_low / n_events - Veff_high = volume_proj_area * FC_high / n_events - - if('efficiency' in values.keys() and Veff > 0): - get_efficiency = values['efficiency']['func'] - channel_ids = values['efficiency']['channel_ids'] - gids = np.array(fin['event_group_ids']) - ugids = np.unique(np.array(fin['event_group_ids'])) - - # calculate the group event ids that triggered - ugids_triggered_index = [] - ugids_triggered = [] - for i_ugid, ugid in enumerate(ugids): - mask = ugid == gids - if(np.any(triggered[mask])): - ugids_triggered_index.append(i_ugid) - ugids_triggered.append(ugid) - ugids_triggered = np.array(ugids_triggered) - ugids_triggered_index = np.array(ugids_triggered_index) - - n_unique_gids = len(ugids_triggered) - sorter = np.argsort(ugids_triggered) - max_amplitudes = np.zeros(n_unique_gids) - for key in fin.keys(): - if(key.startswith("station_")): - if('event_group_ids' not in fin[key]): - continue # the station might have no triggers - sgids = np.array(fin[key]['event_group_ids']) - usgids = np.unique(sgids) - usgids, comm1, comm2 = np.intersect1d(usgids, ugids_triggered, assume_unique=True, return_indices=True) # select only the gids that triggered - common_mask = np.isin(sgids, usgids) - sgids = sgids[common_mask] # also reduce gids array to the event groups that triggered - if(len(usgids) == 0): # skip stations that don't have any trigger for this trigger combination - continue - usgids_index = sorter[np.searchsorted(ugids_triggered, usgids, sorter=sorter)] - # each station might have multiple triggeres per event group id. We need to select the one - # event with the largest amplitude. Let's first check if one event group created more than one event - max_amps_per_event_channel = np.nan_to_num(np.array(fin[key]['maximum_amplitudes_envelope'])[common_mask]) - max_amps_per_event = np.amax(max_amps_per_event_channel[:, channel_ids], axis=1) # select the maximum amplitude of all considered channels - if(len(sgids) != len(usgids)): - # at least one event group created more than one event. Let's calculate it the slow but correct way - for sgid in np.unique(sgids): # loop over all event groups which triggered this station - if(sgid not in usgids): - continue - mask_gid = sgid == sgids # select all event that are part of this event group - index = np.squeeze(np.argwhere(ugids_triggered == sgid)) - max_amplitudes[index] = max(max_amplitudes[index], max_amps_per_event[mask_gid].max()) - else: - max_amplitudes[usgids_index] = np.maximum(max_amplitudes[usgids_index], max_amps_per_event) - if('scale' in values['efficiency']): - max_amplitudes *= values['efficiency']['scale'] - if("Vrms" in values['efficiency']): - Vrms = values['efficiency']['Vrms'] - e = get_efficiency(max_amplitudes / Vrms) # we calculated the maximum amplitudes for all gids, now we select only those that triggered - Veff = volume_proj_area * np.sum(weights[triggered] * e) / n_events - Vefferror = 0 - if(np.sum(weights[triggered]) > 0): - Vefferror = Veff / np.sum(weights[triggered] * e) ** 0.5 - FC_low, FC_high = FC_limits(np.sum(weights[triggered] * e)) - Veff_low = volume_proj_area * FC_low / n_events - Veff_high = volume_proj_area * FC_high / n_events - - out[veff_aeff][trigger_name] = [Veff, Vefferror, np.sum(weights[triggered]), Veff_low, Veff_high] return out @@ -519,12 +546,15 @@ def get_Veff_Aeff(folder, prev_deposited = None deposited = False - if(os.path.isfile(folder)): + if os.path.isfile(folder): filenames = [folder] else: - if(len(glob.glob(os.path.join(folder, '*.hdf5'))) == 0): + filenames = glob.glob(os.path.join(folder, '*.hdf5')) + if len(filenames) == 0: raise FileNotFoundError(f"couldnt find any hdf5 file in folder {folder}") - filenames = sorted(glob.glob(os.path.join(folder, '*.hdf5'))) + + filenames = sorted(filenames) + for iF, filename in enumerate(filenames): fin = h5py.File(filename, 'r') if 'deposited' in fin.attrs: From 5e5e466722ff2b1fdd01179e67674571991f51d5 Mon Sep 17 00:00:00 2001 From: sjoerd-bouma Date: Fri, 4 Nov 2022 15:48:22 +0100 Subject: [PATCH 060/418] sort simulated electric fields in plot --- .../apps/simulation_plots/sim_electric_field_spectrum.py | 5 ++++- .../apps/simulation_plots/sim_electric_field_trace.py | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/NuRadioReco/eventbrowser/apps/simulation_plots/sim_electric_field_spectrum.py b/NuRadioReco/eventbrowser/apps/simulation_plots/sim_electric_field_spectrum.py index c535a20d7..f19ea72cd 100644 --- a/NuRadioReco/eventbrowser/apps/simulation_plots/sim_electric_field_spectrum.py +++ b/NuRadioReco/eventbrowser/apps/simulation_plots/sim_electric_field_spectrum.py @@ -54,7 +54,10 @@ def update_sim_spectrum_plot(i_event, filename, signal_types, station_id, juser_ if sim_station is None: return {} fig = plotly.subplots.make_subplots(rows=1, cols=1) - for i_electric_field, electric_field in enumerate(sim_station.get_electric_fields()): + efields = list(sim_station.get_electric_fields()) + efield_ids = [efield.get_unique_identifier() for efield in efields] + efields_sorted = [k[1] for k in sorted(zip(efield_ids, efields))] + for i_electric_field, electric_field in enumerate(efields_sorted): if electric_field.get_parameter(efp.ray_path_type) in signal_types: for polarization in range(1, 3): fig.append_trace( diff --git a/NuRadioReco/eventbrowser/apps/simulation_plots/sim_electric_field_trace.py b/NuRadioReco/eventbrowser/apps/simulation_plots/sim_electric_field_trace.py index 892591a8b..8f3a81a98 100644 --- a/NuRadioReco/eventbrowser/apps/simulation_plots/sim_electric_field_trace.py +++ b/NuRadioReco/eventbrowser/apps/simulation_plots/sim_electric_field_trace.py @@ -54,7 +54,10 @@ def update_sim_trace_plot(i_event, filename, signal_types, station_id, juser_id) if sim_station is None: return {} fig = plotly.subplots.make_subplots(rows=1, cols=1) - for i_electric_field, electric_field in enumerate(sim_station.get_electric_fields()): + efields = list(sim_station.get_electric_fields()) + efield_ids = [efield.get_unique_identifier() for efield in efields] + efields_sorted = [k[1] for k in sorted(zip(efield_ids, efields))] + for i_electric_field, electric_field in enumerate(efields_sorted): if electric_field.get_parameter(efp.ray_path_type) in signal_types: for polarization in range(1, 3): fig.append_trace( From 1c38812655db92ce882ca4c7ab08ee5b3972014a Mon Sep 17 00:00:00 2001 From: Jean-Marco Alameddine Date: Fri, 4 Nov 2022 17:08:10 +0100 Subject: [PATCH 061/418] fix invalid removing of already propagated muons from decay products list in NuRadioProposal --- NuRadioMC/EvtGen/NuRadioProposal.py | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/NuRadioMC/EvtGen/NuRadioProposal.py b/NuRadioMC/EvtGen/NuRadioProposal.py index 197e88fc4..5f5204cc4 100644 --- a/NuRadioMC/EvtGen/NuRadioProposal.py +++ b/NuRadioMC/EvtGen/NuRadioProposal.py @@ -590,9 +590,7 @@ def get_secondaries_array(self, # Checking if there is a muon in the decay products if propagate_decay_muons: - repropagated_muon_indices = [] # indices of muons that will be further propagated - - for i, decay_particle in enumerate(decay_products): + for decay_particle in list(decay_products): if (abs(decay_particle.type) == 13): mu_energy = decay_particle.energy @@ -610,16 +608,8 @@ def get_secondaries_array(self, shower_inducing_prods.extend(shower_inducing_muon_secondaries) - # TODO: Are we interested in muon decay products here? (i.e. the electron/positron?) - # We have already handled the muon, remove it to avoid double counting. - # However, we can't remove the muon in-place from the decay_products list, - # therefore just save indices and pop items after loop - repropagated_muon_indices.append(i) - - # remove muons that have already been propagated further - for i in repropagated_muon_indices: - decay_products.pop(i) + decay_products.remove(decay_particle) grouped_decay_products = self.__group_decay_products(decay_products, min_energy_loss, lepton_position) From 160e59df5dd1296dc37a6bc62b5d417e8196a59c Mon Sep 17 00:00:00 2001 From: Jean-Marco Alameddine Date: Mon, 7 Nov 2022 11:18:55 +0100 Subject: [PATCH 062/418] remove .sample prefix from PROPOSAL config files --- .../EvtGen/{config_PROPOSAL.json.sample => config_PROPOSAL.json} | 0 ...POSAL_greenland.json.sample => config_PROPOSAL_greenland.json} | 0 ...ig_PROPOSAL_infice.json.sample => config_PROPOSAL_infice.json} | 0 ...POSAL_mooresbay.json.sample => config_PROPOSAL_mooresbay.json} | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename NuRadioMC/EvtGen/{config_PROPOSAL.json.sample => config_PROPOSAL.json} (100%) rename NuRadioMC/EvtGen/{config_PROPOSAL_greenland.json.sample => config_PROPOSAL_greenland.json} (100%) rename NuRadioMC/EvtGen/{config_PROPOSAL_infice.json.sample => config_PROPOSAL_infice.json} (100%) rename NuRadioMC/EvtGen/{config_PROPOSAL_mooresbay.json.sample => config_PROPOSAL_mooresbay.json} (100%) diff --git a/NuRadioMC/EvtGen/config_PROPOSAL.json.sample b/NuRadioMC/EvtGen/config_PROPOSAL.json similarity index 100% rename from NuRadioMC/EvtGen/config_PROPOSAL.json.sample rename to NuRadioMC/EvtGen/config_PROPOSAL.json diff --git a/NuRadioMC/EvtGen/config_PROPOSAL_greenland.json.sample b/NuRadioMC/EvtGen/config_PROPOSAL_greenland.json similarity index 100% rename from NuRadioMC/EvtGen/config_PROPOSAL_greenland.json.sample rename to NuRadioMC/EvtGen/config_PROPOSAL_greenland.json diff --git a/NuRadioMC/EvtGen/config_PROPOSAL_infice.json.sample b/NuRadioMC/EvtGen/config_PROPOSAL_infice.json similarity index 100% rename from NuRadioMC/EvtGen/config_PROPOSAL_infice.json.sample rename to NuRadioMC/EvtGen/config_PROPOSAL_infice.json diff --git a/NuRadioMC/EvtGen/config_PROPOSAL_mooresbay.json.sample b/NuRadioMC/EvtGen/config_PROPOSAL_mooresbay.json similarity index 100% rename from NuRadioMC/EvtGen/config_PROPOSAL_mooresbay.json.sample rename to NuRadioMC/EvtGen/config_PROPOSAL_mooresbay.json From ae7e21485fd0e4c9cebf1bb7a88d3dd9000937d0 Mon Sep 17 00:00:00 2001 From: Jean-Marco Alameddine Date: Mon, 7 Nov 2022 11:25:12 +0100 Subject: [PATCH 063/418] adapt error_message for missing tables and remove todo --- NuRadioMC/EvtGen/NuRadioProposal.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/NuRadioMC/EvtGen/NuRadioProposal.py b/NuRadioMC/EvtGen/NuRadioProposal.py index 5f5204cc4..ca10c7f84 100644 --- a/NuRadioMC/EvtGen/NuRadioProposal.py +++ b/NuRadioMC/EvtGen/NuRadioProposal.py @@ -287,12 +287,10 @@ def __get_propagator(self, else: raise ValueError("Proposal config file is not valid. Please provide a valid option.") - # TODO: What is this {}.sample, and what does it have to do with interpoation tables? if not os.path.exists(config_file_full_path): - error_message = "Proposal config file does not exist.\n" - error_message += "Please provide valid paths for the interpolation tables " - error_message += "in file {}.sample ".format(config_file_full_path) - error_message += "and copy the file to {}.".format(os.path.basename(config_file_full_path)) + error_message = "Unable to find proposal config file.\n" + error_message += "Make sure that json configuration file under " + error_message += "path {} exists.".format(config_file_full_path) raise ValueError(error_message) pp.InterpolationSettings.tables_path = self.__tables_path From 720637694a78f15de88b033b65800a0ea87e0da5 Mon Sep 17 00:00:00 2001 From: Jean-Marco Alameddine Date: Tue, 22 Nov 2022 18:04:46 +0100 Subject: [PATCH 064/418] specify proposal 7 for installation --- documentation/source/Introduction/pages/installation.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/source/Introduction/pages/installation.rst b/documentation/source/Introduction/pages/installation.rst index f7d1c9ba5..f54d94656 100644 --- a/documentation/source/Introduction/pages/installation.rst +++ b/documentation/source/Introduction/pages/installation.rst @@ -189,7 +189,7 @@ These packages are recommended to be able to use all of NuRadioMC/NuRadioReco's .. code-block:: bash - pip install proposal + pip install proposal==7.* - To use the channelGalacticNoiseAdder, you need the `PyGDSM `_ package. From 8f85b3c3e8f73076198afcbd0517b213e86c7224 Mon Sep 17 00:00:00 2001 From: Bob Oeyen Date: Mon, 5 Dec 2022 10:45:25 -0600 Subject: [PATCH 065/418] Incorporate positions array for average and gradient --- NuRadioMC/utilities/medium_base.py | 41 +++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 12 deletions(-) diff --git a/NuRadioMC/utilities/medium_base.py b/NuRadioMC/utilities/medium_base.py index 4e741a17e..eba9eb1e1 100644 --- a/NuRadioMC/utilities/medium_base.py +++ b/NuRadioMC/utilities/medium_base.py @@ -233,21 +233,29 @@ def get_average_index_of_refraction(self, position1, position2): n_average: float averaged index of refraction between the two points """ - zmax = max(position1[2], position2[2]) - zmin = min(position1[2], position2[2]) def exp_average(z_max, z_min): return (self.n_ice - self.delta_n * self.z_0 / (z_max - z_min) * (np.exp((z_max-self.z_shift) / self.z_0) - np.exp((z_min-self.z_shift) / self.z_0))) - if ((zmax - self.z_air_boundary) <=0): - return exp_average(zmax, zmin) - elif ((zmin - self.z_air_boundary) <=0): - n1 = exp_average(self.z_air_boundary, zmin) - n2 = 1 - return (n1 * (self.z_air_boundary - zmin) + n2 * (zmax - self.z_air_boundary)) / (zmax - zmin) + if (isinstance(position1, list) or position1.ndim == 1) and (isinstance(position2, list) or position2.ndim == 1): + zmax = max(position1[2], position2[2]) + zmin = min(position1[2], position2[2]) + if ((zmax - self.z_air_boundary) <=0): + return exp_average(zmax, zmin) + elif ((zmin - self.z_air_boundary) <=0): + n1 = exp_average(self.z_air_boundary, zmin) + n2 = 1 + return (n1 * (self.z_air_boundary - zmin) + n2 * (zmax - self.z_air_boundary)) / (zmax - zmin) + else: + return 1 else: - return 1 + if all((position1[:,2] - self.z_air_boundary) <= 0) and all((position2[:,2] - self.z_air_boundary) <= 0): + return exp_average(position1[:,2], position2[:,2]) + elif all((position1[:,2] - self.z_air_boundary) > 0) and all((position2[:,2] - self.z_air_boundary) > 0): + return np.ones_like(position1[:,2]) + else: + raise NotImplementedError('function cannot handle averages accros boundary when using arrays of positions.') def get_gradient_of_index_of_refraction(self, position): """ @@ -264,9 +272,18 @@ def get_gradient_of_index_of_refraction(self, position): n_nabla: (3,) np.array gradient of index of refraction at the point """ - gradient = np.array([0., 0., 0.]) - if (position[2] - self.z_air_boundary) <=0: - gradient[2] = -self.delta_n / self.z_0 * np.exp((position[2] - self.z_shift) / self.z_0) + def gradient_z(z): + return -self.delta_n / self.z_0 * np.exp((z - self.z_shift) / self.z_0) + + if (isinstance(position, list) or position.ndim == 1): + gradient = np.array([0,0,0]) + if (position1[2] - self.z_air_boundary) <= 0: + gradient[2] = gradient_z(position[2]) + else: + gradient = gradient_z(position[:,2]) + gradient[position[:, 2] >= 0] = 0 + gradient = np.stack((np.zeros_like(gradient),np.zeros_like(gradient),gradient),axis=1) + return gradient def get_ice_model_radiopropa(self): From 6c00433d4235211d2ef34899c9fc965b7c01bc61 Mon Sep 17 00:00:00 2001 From: Bob Oeyen Date: Mon, 5 Dec 2022 10:50:21 -0600 Subject: [PATCH 066/418] adjust doc strings --- NuRadioMC/utilities/medium_base.py | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/NuRadioMC/utilities/medium_base.py b/NuRadioMC/utilities/medium_base.py index eba9eb1e1..1c6f0e313 100644 --- a/NuRadioMC/utilities/medium_base.py +++ b/NuRadioMC/utilities/medium_base.py @@ -196,14 +196,14 @@ def get_index_of_refraction(self, position): Parameters ---------- - position: 1D or 2D numpy array + position: 1D (3,) or 2D (n,3) numpy array Either one position or an array of positions for which the indices of refraction are returned Returns ------- - n: float + n: float or 1D numpy array (n,) index of refraction """ if isinstance(position, list) or position.ndim == 1: @@ -223,14 +223,18 @@ def get_average_index_of_refraction(self, position1, position2): Parameters ---------- - position1: 3dim np.array - point - position2: 3dim np.array - point + position1: 1D (3,) or 2D (n,3) numpy array + Either one position or an array + of positions for which the indices + of average refraction are returned + position2: 1D (3,) or 2D (n,3) numpy array + Either one position or an array + of positions for which the indices + of average refraction are returned Returns ------- - n_average: float + n_average: float of 1D numpy array (n,) averaged index of refraction between the two points """ @@ -264,12 +268,14 @@ def get_gradient_of_index_of_refraction(self, position): Parameters ---------- - position: 3dim np.array - point + position: 1D or 2D numpy array + Either one position or an array + of positions for which the gradient + of index of refraction is returned Returns ------- - n_nabla: (3,) np.array + n_nabla: 1D (3,) or 2D (n,3) numpy array gradient of index of refraction at the point """ def gradient_z(z): From 5f944774a60c837259ab42f5799ed31704d2aadb Mon Sep 17 00:00:00 2001 From: Bob Oeyen Date: Mon, 5 Dec 2022 10:52:40 -0600 Subject: [PATCH 067/418] adjust changelog --- changelog.txt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/changelog.txt b/changelog.txt index f5b9c03bd..eaac557d1 100644 --- a/changelog.txt +++ b/changelog.txt @@ -5,11 +5,12 @@ please update the categories "new features" and "bugfixes" before a pull request version 2.2.0 new features: - add attenuation model from the 2021 measurements taken at Summit Station -- print warning for positive z in attenuation, and set attenuation length to -+inf for positive z +- print warning for positive z in attenuation, and set attenuation length to +inf for positive z - adding minimize mode to the radiopropa propagation module & more configurable settings in config file - add uniform ice model with 1.78 refractive index - update ARA detector description and add a file to Print ARA detector json file +- add positions array funcionality to simple ice model in average and gradient functions + bugfixes: @@ -24,11 +25,10 @@ secondary interactions. With this bug, the initial interaction needs to be idenf This bug does not effect any effective volume calculation. new features: -- add hvsp1, update idl1 model for emitter simulation (from KU lab measurements) and remove -hvsp2(no longer in use for experiment) +- add hvsp1, update idl1 model for emitter simulation (from KU lab measurements) and remove hvsp2(no longer in use for experiment) - add CalPulser data for emitter simulation + version 2.1.5 -new features: bugfixes: - the phased array trigger module did not calculate the trigger time. From 275d2adc6cef91835163b2911b37141b51873869 Mon Sep 17 00:00:00 2001 From: Bob Oeyen Date: Mon, 5 Dec 2022 12:01:26 -0600 Subject: [PATCH 068/418] fix typo --- NuRadioMC/utilities/medium_base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NuRadioMC/utilities/medium_base.py b/NuRadioMC/utilities/medium_base.py index 1c6f0e313..c0614c9a4 100644 --- a/NuRadioMC/utilities/medium_base.py +++ b/NuRadioMC/utilities/medium_base.py @@ -283,7 +283,7 @@ def gradient_z(z): if (isinstance(position, list) or position.ndim == 1): gradient = np.array([0,0,0]) - if (position1[2] - self.z_air_boundary) <= 0: + if (position[2] - self.z_air_boundary) <= 0: gradient[2] = gradient_z(position[2]) else: gradient = gradient_z(position[:,2]) From 4b239da7f5ccc44536a39b76faf1e066ab2456a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Thu, 12 Jan 2023 13:54:52 +0100 Subject: [PATCH 069/418] ignore all hdf5 and nur files by default (except if they contain reference in their name --- .gitignore | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index b0f30754a..5692ed345 100644 --- a/.gitignore +++ b/.gitignore @@ -3,9 +3,9 @@ # .gitignore files to exclude specific files. ############################################################# -# Ignore test output - this will also make sure that you do not accidentally add large files to your commit -*output*.nur -*output*.hdf5 +# Ignore all nur and hdf5 files. This will also make sure that you do not accidentally add large files to your commit. Execeptions, such as (!*reference*.hdf5) have to be added explicitly. +*.nur +*.hdf5 # Exclude reference files from being ignored here !*reference*.nur !*reference*.hdf5 @@ -136,4 +136,4 @@ venv.bak/ # ignore .nur files in NuRadioReco/examples/ # this should not apply for NuRadioReco/examples/example_data/ -NuRadioReco/examples/*.nur \ No newline at end of file +NuRadioReco/examples/*.nur From 97c80b78dec026dffc39def6e4640d746c7f3c1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Mon, 16 Jan 2023 12:12:23 +0100 Subject: [PATCH 070/418] Improve layout of the HDF5 documentation. Changed wrongly labeled shapes for several items. Extended description following the recently discussed changes. --- .../source/NuRadioMC/pages/HDF5_structure.rst | 223 +++++++----------- 1 file changed, 85 insertions(+), 138 deletions(-) diff --git a/documentation/source/NuRadioMC/pages/HDF5_structure.rst b/documentation/source/NuRadioMC/pages/HDF5_structure.rst index 6290e6dda..43edd8d33 100644 --- a/documentation/source/NuRadioMC/pages/HDF5_structure.rst +++ b/documentation/source/NuRadioMC/pages/HDF5_structure.rst @@ -51,81 +51,61 @@ ____________________ The top-level attributes can be accessed using ``f.attrs``. These contain: -* ``Emax``, ``Emin`` - - maximum and minimum energy simulated -* ``NuRadioMC_EvtGen_version``, ``NuRadioMC_EvtGen_version_hash`` -* ``NuRadioMC_version``, ``NuRadioMC_version_hash`` -* ``Tnoise`` - - (explicit) noise temperature used in simulation -* ``Vrms`` -* ``area`` -* ``bandwidth`` -* ``config`` - - the (yaml-style) config file used for the simulation -* ``deposited`` -* ``detector`` - - the (json-format) detector description used for the simulation -* ``dt`` - - the time resolution, i.e. the inverse of the sampling rate used for the simulation. - This is not necessarily the same as the sampling rate of the simulated channels! -* ``fiducial_rmax``, ``fiducial_rmin``, ``fiducial_zmax``, ``fiducial_zmin`` - - Specify the simulated fiducial volume -* ``flavors`` - - a list of particle flavors that were simulated, using the PDG convention. -* ``n_events`` - - total number of events simulated (including those that did not trigger) -* ``n_samples`` -* ``phimax``, ``phimin`` -* ``rmax``, ``rmin`` -* ``start_event_id`` - - ``event_id`` of the first event in the file -* ``thetamax``, ``thetamin`` -* ``trigger_names`` - - list of the names of the different triggers simulated -* ``volume`` -* ``zmax``, ``zmin`` + .. _hdf5-attrs-table: + + .. csv-table:: HDF5 attributes + :header: "Key", "Description" + :delim: | + + ``NuRadioMC_EvtGen_version`` ``NuRadioMC_EvtGen_version_hash`` ``NuRadioMC_version`` ``NuRadioMC_version_hash`` | Hashes + ``Emin`` ``Emax`` | Define energy range for neutrino energies + ``phimax`` ``phimin`` | Define azimuth range for incoming neutrino directions + ``thetamax`` ``thetamin`` | Define zenith range for incoming neutrino directions + ``flavors`` | A list of particle flavors that were simulated, using the PDG convention. + ``n_events`` | Total number of generated/simulated events(including those that did not trigger) + ``fiducial_rmax`` ``fiducial_rmin`` ``fiducial_zmax`` ``fiducial_zmin`` or ``fiducial_xmax`` ``fiducial_xmin`` ``fiducial_ymax`` ``fiducial_ymin`` ``fiducial_zmax`` ``fiducial_zmin`` | Specify the simulated cylindrical/quadratic fiducial volume. An event has to produce an interaction within this volume. However, in case of a muon or tau CC interaction the first interaction can occur outside + ``rmax`` ``rmin`` ``zmax`` ``zmin`` or ``xmax`` ``xmin`` ``ymax`` ``ymin`` ``zmax`` ``zmin`` | Specify the cylindrical/quadratic volume in which neutrino interactions are generated + ``volume`` | Volume of the above specified volume + ``area`` | Surface area of the above specified volume + ``start_event_id`` | ``event_id`` of the first event in the file + ``trigger_names`` | List of the names of the different triggers simulated + ``Tnoise`` | (explicit) noise temperature used in simulation + ``Vrms`` | + ``bandwidth`` | + ``n_samples`` | + ``config`` | The (yaml-style) config file used for the simulation + ``deposited`` | + ``detector`` | The (json-format) detector description used for the simulation + ``dt`` | The time resolution, i.e. the inverse of the sampling rate used for the simulation. This is not necessarily the same as the sampling rate of the simulated channels! HDF5 file contents -__________________ -The HDF5 file contains the following items. Listed are the ``key`` and the ``shape`` of -each HDF5 dataset, where ``n_events`` is the number of events in the file, ``n_showers`` -is the number of showers (which may be larger than the number of events), and ``n_triggers`` -is the number of different triggers simulated. - -* ``azimuths``: (``n_events``,) -* ``energies``: (``n_events``,) -* ``event_group_ids``: (``n_events``,) -* ``flavors``: (``n_events``,) -* ``inelasticity``: (``n_events``,) -* ``interaction_type``: (``n_events``,) -* ``multiple_triggers``: (``n_events``, ``n_triggers``) -* ``n_interaction``: (``n_events``,) -* ``shower_energies``: (``n_showers``,) -* ``shower_ids``: (``n_showers``,) -* ``shower_realization_ARZ``: (``n_showers``,) - - Which realization from the ARZ shower library was used for each shower (only if ARZ - was used for signal generation). -* ``shower_type``: (``n_showers``,) -* ``triggered``: (``n_events``,) - - boolean; ``True`` if the event triggered on any trigger, ``False`` otherwise -* ``vertex_times``: (``n_events``,) -* ``weights``: (``n_events``,) -* ``xx``: (``n_events``,) -* ``yy``: (``n_events``,) -* ``zeniths``: (``n_events``,) -* ``zz``: (``n_events``,) +------------------ +The HDF5 file contains the following items. Listed are the ``key`` and the ``shape`` of each HDF5 dataset, where ``n_events`` is the number of events stored in the file and ``n_showers`` +is the number of showers (which may be larger than the number of events), and ``n_triggers`` is the number of different triggers simulated. Each "row" correspond to a particle shower which can produce radio emission. + + .. _hdf5-items-table: + + .. csv-table:: HDF5 items + :header: "Key", "Shape", "Description" + :delim: | + + ``event_group_ids`` | (``n_showers``,) | Specifies the event id to which the corresponding shower belongs (``n_events = len(unique(event_group_ids)))``) + ``xx`` ``yy`` ``zz`` | (``n_showers``,) | Specifying coordinates of interaction vertices + ``vertex_times`` | (``n_showers``,) | Time at the interaction vertex. The neutrino interaction (= first interaction) is defined as time 0 + ``azimuths`` ``zeniths`` | (``n_showers``,) | Angle Specifying the neutrino incoming direction (``azimuths = 0`` points east) + ``energies`` | (``n_showers``,) | Energy of the parent particle of a shower. This is typically the energy of the neutrino (for showers produced at the first interaction: all flavor NC, electron CC interactions) or the energy of a muon or tau lepton when those are producing secondary energy losses + ``shower_energies`` | (``n_showers``,) | Energy of the shower which is used to determine the radio emission + ``flavors`` | (``n_showers``,) | Same as above (the parent of an electromagnetic cascade in an electron CC interaction is the neutrino) + ``inelasticity`` | (``n_showers``,) | Inelasticity of the first interaction + ``interaction_type`` | (``n_showers``,) | Interaction type producing the shower (for the first interaction that can be "nc" or "cc") + ``multiple_triggers`` | (``n_showers``, ``n_triggers``) | Information which exact trigger fired each shower. The different triggers are specified in the attributes (``f.attrs["triggers"]``). The order of ``f.attrs["triggers"]`` matches that in ``multiple_triggers`` + ``triggered`` | (``n_showers``,) | boolean; ``True`` if any trigger fired for this shower, ``False`` otherwise + ``n_interaction`` | (``n_showers``,) | Hierarchical counter for the number of showers per event (also accounts for showers which did not trigger and might not be saved) + ``shower_ids`` | (``n_showers``,) | Hierarchical counter for the number of triggered showers + ``shower_realization_ARZ`` | (``n_showers``,) | Which realization from the ARZ shower library was used for each shower (only if ARZ was used for signal generation). + ``shower_type`` | (``n_showers``,) | Type of the shower (so far we only have "em" and "had") + ``weights`` | (``n_showers``,) | Weight for the probability that the neutrino reached the interaction vertex taking into account the attenuation from the earth (Does not include interaction probability in the volume) + Station data ____________ @@ -134,68 +114,35 @@ The station contains more detailed information for each event that triggered it: ``n_events`` and ``n_shower`` refer to the number of events and showers that triggered the station. The ``event_group_id`` is the same as in the global dictionary. Therefore you can check for one event with an ``event_group_id`` which stations contain the same ``event_group_id`` and retrieve the information, which -station triggered, with which amplitude, etc. The same approach works for ``shower_id``. - -* ``event_group_ids``: (``n_events``) -* ``event_group_id_per_shower'``: (``n_shower``) - - event group ids of the triggered events -* ``event_ids``: (``n_events``) -* ``event_id_per_shower``: (``n_shower``) - - the event ids of each event. These are unique only within each separate event group, - and start from 0. -* ``focusing_factor``: (``n_showers``, ``n_channels``, ``n_ray_tracing_solutions``) -* ``launch_vectors``: (``n_showers``, ``n_channels``, ``n_ray_tracing_solutions``, 3) - - 3D (Cartesian) coordinates of the launch vector of each ray tracing solution, - per shower and channel. -* ``max_amp_shower_and_ray``: (``n_showers``, ``n_channels``, ``n_ray_tracing_solutions``) - - Maximum amplitude per shower, channel and ray tracing solution. -* ``maximum_amplitudes``: (``n_events``, ``n_channels``) - - Maximum amplitude per event and channel -* ``maximum_amplitudes_envelope``: (``n_events``, ``n_channels``) - - Maximum amplitude of the hilbert envelope for each event and channel -* ``multiple_triggers``: (``n_showers``, ``n_triggers``) - - a boolean array that specifies if a shower contributed to an event that fulfills a certain trigger. - The index of the trigger can be translated to the trigger name via the attribute ``trigger_names``. -* ``multiple_triggers_per_event``: (``n_events``, ``n_triggers``) - - a boolean array that specifies if each event fulfilled a certain trigger. - The index of the trigger can be translated to the trigger name via the attribute ``trigger_names``. -* ``polarization``: (``n_shower``, ``n_channels``, ``n_ray_tracing_solutions``, 3) - - 3D (Cartesian) coordinates of the polarization vector -* ``ray_tracing_C0``: (``n_showers``, ``n_channels``, ``n_ray_tracing_solutions``) - - One of two parameters specifying the **analytic** ray tracing solution. - Can be used to retrieve the solutions without having to re-run the ray tracer. -* ``ray_tracing_C1``: (``n_showers``, ``n_channels``, ``n_ray_tracing_solutions``) - - One of two parameters specifying the **analytic** ray tracing solution. - Can be used to retrieve the solutions without having to re-run the ray tracer. -* ``ray_tracing_reflection``: (``n_showers``, ``n_channels``, ``n_ray_tracing_solutions``) -* ``ray_tracing_reflection_case``: (``n_showers``, ``n_channels``, ``n_ray_tracing_solutions``) -* ``ray_tracing_solution_type``: (``n_showers``, ``n_channels``, ``n_ray_tracing_solutions``) -* ``receive_vectors``: (``n_showers``, ``n_channels``, ``n_ray_tracing_solutions``, 3) - - 3D (Cartesian) coordinates of the receive vector of each ray tracing solution, - per shower and channel. -* ``shower_id``: (``n_showers``,) -* ``time_shower_and_ray``: (``n_showers``, ``n_channels``, ``n_ray_tracing_solutions``) -* ``travel_distances``: (``n_showers``, ``n_channels``, ``n_ray_tracing_solutions``) - - The distance travelled by each ray tracing solution to a specific channel -* ``travel_times``: (``n_showers``, ``n_channels``, ``n_ray_tracing_solutions``) - - The time travelled by each ray tracing solution to a specific channel -* ``triggered``: (``n_showers``,) - - Whether or not each shower contributed to an event that satisfied any trigger condition -* ``triggered_per_event``: (``n_events``,) - - Whether or not each event fulfilled any trigger condition. +station triggered, with which amplitude, etc. The same approach works for ``shower_id``. + + .. _hdf5-station-table: + + .. csv-table:: HDF5 station items + :header: "Key", "Shape", "Description" + :delim: | + + ``event_group_ids`` | (``n_events``,) | event group ids of the triggered events + ``event_group_id_per_shower`` | (``n_shower``) | + ``event_ids`` | (``n_events``,) | the event ids of each event. These are unique only within each separate event group, and start from 0. + ``event_id_per_shower`` | (``n_shower``) | + ``focusing_factor`` | (``n_showers``, ``n_channels``, ``n_ray_tracing_solutions``) | + ``launch_vectors`` | (``n_showers``, ``n_channels``, ``n_ray_tracing_solutions``, ``3``) | 3D (Cartesian) coordinates of the launch vector of each ray tracing solution, per shower and channel. + ``max_amp_shower_and_ray`` | (``n_showers``, ``n_channels``, ``n_ray_tracing_solutions``) | Maximum amplitude per shower, channel and ray tracing solution. + ``maximum_amplitudes`` | (``n_events``, ``n_channels``) | Maximum amplitude per event and channel + ``maximum_amplitudes_envelope`` | (``n_events``, ``n_channels``) | Maximum amplitude of the hilbert envelope for each event and channel + ``multiple_triggers`` | (``n_showers``, ``n_triggers``) | A boolean array that specifies if a shower contributed to an event that fulfills a certain trigger. The index of the trigger can be translated to the trigger name via the attribute ``trigger_names``. + ``multiple_triggers_per_event`` | (``n_events``, ``n_triggers``) | A boolean array that specifies if each event fulfilled a certain trigger. The index of the trigger can be translated to the trigger name via the attribute ``trigger_names``. + ``polarization`` | (``n_shower``, ``n_channels``, ``n_ray_tracing_solutions``, ``3``) | 3D (Cartesian) coordinates of the polarization vector + ``ray_tracing_C0`` | (``n_showers``, ``n_channels``, ``n_ray_tracing_solutions``) | One of two parameters specifying the **analytic** ray tracing solution. Can be used to retrieve the solutions without having to re-run the ray tracer. + ``ray_tracing_C1`` | (``n_showers``, ``n_channels``, ``n_ray_tracing_solutions``) | One of two parameters specifying the **analytic** ray tracing solution. Can be used to retrieve the solutions without having to re-run the ray tracer. + ``ray_tracing_reflection`` | (``n_showers``, ``n_channels``, ``n_ray_tracing_solutions``) | + ``ray_tracing_reflection_case`` | (``n_showers``, ``n_channels``, ``n_ray_tracing_solutions``) | + ``ray_tracing_solution_type`` | (``n_showers``, ``n_channels``, ``n_ray_tracing_solutions``) | + ``receive_vectors`` | (``n_showers``, ``n_channels``, ``n_ray_tracing_solutions``, ``3``) | 3D (Cartesian) coordinates of the receive vector of each ray tracing solution, per shower and channel. + ``shower_id`` | (``n_showers``,) | + ``time_shower_and_ray`` | (``n_showers``, ``n_channels``, ``n_ray_tracing_solutions``) | + ``travel_distances`` | (``n_showers``, ``n_channels``, ``n_ray_tracing_solutions``) | The distance travelled by each ray tracing solution to a specific channel + ``travel_times`` | (``n_showers``, ``n_channels``, ``n_ray_tracing_solutions``) | The time travelled by each ray tracing solution to a specific channel + ``triggered`` | (``n_showers``,) | Whether each shower contributed to an event that satisfied any trigger condition + ``triggered_per_event`` | (``n_events``,) | Whether each event fulfilled any trigger condition. From 0fa45364f4864c9dd799fbd5251bfb7922bd8061 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Mon, 16 Jan 2023 12:46:35 +0100 Subject: [PATCH 071/418] Revert changes to the flavor for electron CC interaction, this is a convention. Some more refactoring --- NuRadioMC/EvtGen/generator.py | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/NuRadioMC/EvtGen/generator.py b/NuRadioMC/EvtGen/generator.py index b7536130d..e88dc253c 100644 --- a/NuRadioMC/EvtGen/generator.py +++ b/NuRadioMC/EvtGen/generator.py @@ -1253,18 +1253,20 @@ def generate_eventlist_cylinder(filename, n_events, Emin, Emax, # now add EM showers if appropriate em_shower_mask = (data_sets["interaction_type"] == "cc") & (np.abs(data_sets['flavors']) == 12) - for key in data_sets: # transform datatype to list so that inserting elements is faster + # transform datatype to list so that inserting elements is faster + for key in data_sets: data_sets[key] = list(data_sets[key]) - n_inserted = 0 - for i in np.arange(n_events_batch, dtype=int)[em_shower_mask]: # loop over all events where an EM shower needs to be inserted + + # loop over all events where an EM shower needs to be inserted + # Create a shower for each CC electron interaction. The primary of this shower is still the neutrino + for n_inserted, i in enumerate(np.arange(n_events_batch, dtype=int)[em_shower_mask]): idx_to_copy = i + n_inserted idx_to_insert = idx_to_copy + 1 for key in data_sets: data_sets[key].insert(idx_to_insert, data_sets[key][idx_to_copy]) # copy event - data_sets['shower_energies'][idx_to_insert] = (1 - data_sets['inelasticity'][idx_to_copy]) * data_sets['energies'][idx_to_copy] + data_sets['shower_energies'][idx_to_insert] = \ + (1 - data_sets['inelasticity'][idx_to_copy]) * data_sets['energies'][idx_to_copy] data_sets['shower_type'][idx_to_insert] = 'em' - data_sets['flavors'][idx_to_insert] = data_sets['flavors'][idx_to_copy] - 1 * np.sign(data_sets['flavors'][idx_to_copy]) - n_inserted += 1 logger.debug("converting to numpy arrays") # make all arrays numpy arrays @@ -1296,11 +1298,10 @@ def generate_eventlist_cylinder(filename, n_events, Emin, Emax, mask_leptons = mask_leptons & mask_phi # TODO: combine with `get_intersection_volume_neutrino` function - lepton_positions = [ (x, y, z) for x, y, z in zip(data_sets["xx"], data_sets["yy"], data_sets["zz"]) ] - lepton_positions = np.array(lepton_positions) - lepton_directions = [ (-np.sin(theta) * np.cos(phi), -np.sin(theta) * np.sin(phi), -np.cos(theta)) - for theta, phi in zip(data_sets["zeniths"], data_sets["azimuths"])] - lepton_directions = np.array(lepton_directions) + lepton_positions = np.array([data_sets["xx"], data_sets["yy"], data_sets["zz"]]).T + lepton_directions = np.array([ + [-np.sin(theta) * np.cos(phi), -np.sin(theta) * np.sin(phi), -np.cos(theta)] + for theta, phi in zip(data_sets["zeniths"], data_sets["azimuths"])]) for iE, event_id in enumerate(data_sets["event_group_ids"]): first_inserted = False From 2eb5817387e95f30c18452f5c09fb99628f74827 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Mon, 16 Jan 2023 12:51:58 +0100 Subject: [PATCH 072/418] Make code easier to understand --- NuRadioMC/EvtGen/generator.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/NuRadioMC/EvtGen/generator.py b/NuRadioMC/EvtGen/generator.py index e88dc253c..662add91a 100644 --- a/NuRadioMC/EvtGen/generator.py +++ b/NuRadioMC/EvtGen/generator.py @@ -1259,8 +1259,8 @@ def generate_eventlist_cylinder(filename, n_events, Emin, Emax, # loop over all events where an EM shower needs to be inserted # Create a shower for each CC electron interaction. The primary of this shower is still the neutrino - for n_inserted, i in enumerate(np.arange(n_events_batch, dtype=int)[em_shower_mask]): - idx_to_copy = i + n_inserted + for n_inserted, orig_idx in enumerate(np.arange(n_events_batch, dtype=int)[em_shower_mask]): + idx_to_copy = orig_idx + n_inserted # orig idx in array with already inserted entries idx_to_insert = idx_to_copy + 1 for key in data_sets: data_sets[key].insert(idx_to_insert, data_sets[key][idx_to_copy]) # copy event From c43d8e95996e9de8f26dd96b90670a2fd3b4d50c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Mon, 16 Jan 2023 14:59:59 +0100 Subject: [PATCH 073/418] Refractoring --- NuRadioMC/EvtGen/generator.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/NuRadioMC/EvtGen/generator.py b/NuRadioMC/EvtGen/generator.py index 662add91a..ff308a919 100644 --- a/NuRadioMC/EvtGen/generator.py +++ b/NuRadioMC/EvtGen/generator.py @@ -1310,28 +1310,28 @@ def generate_eventlist_cylinder(filename, n_events, Emin, Emax, y_nu = data_sets['yy'][iE] z_nu = data_sets['zz'][iE] # Appending event if it interacts within the fiducial volume - if(is_in_fiducial_volume(attributes, np.array([x_nu, y_nu, z_nu]))): + if is_in_fiducial_volume(attributes, np.array([x_nu, y_nu, z_nu])): for key in iterkeys(data_sets): data_sets_fiducial[key].append(data_sets[key][iE]) first_inserted = True if mask_leptons[iE]: - geometry_selection = get_intersection_volume_neutrino(attributes, - [data_sets['xx'][iE], data_sets['yy'][iE], data_sets['zz'][iE]], - lepton_directions[iE]) + geometry_selection = get_intersection_volume_neutrino( + attributes, [x_nu, y_nu, z_nu], lepton_directions[iE]) + if geometry_selection: - products_array = proposal_functions.get_secondaries_array(np.array([E_all_leptons[iE]]), - np.array([lepton_codes[iE]]), - np.array([lepton_positions[iE]]), - np.array([lepton_directions[iE]]), + products_array = proposal_functions.get_secondaries_array( + np.array([E_all_leptons[iE]]), np.array([lepton_codes[iE]]), + np.array([lepton_positions[iE]]), np.array([lepton_directions[iE]]), **proposal_kwargs) + products = products_array[0] n_interaction = 2 for product in products: x, y, z, vertex_time = get_product_position_time(data_sets, product, iE) - if(is_in_fiducial_volume(attributes, np.array([x, y, z]))): + if is_in_fiducial_volume(attributes, np.array([x, y, z])): # the energy loss or particle is in our fiducial volume @@ -1389,7 +1389,7 @@ def generate_eventlist_cylinder(filename, n_events, Emin, Emax, uegids, uegids_inverse = np.unique(egids, return_inverse=True) data_sets_fiducial['event_group_ids'] = uegids_inverse + start_event_id - if(write_events): + if write_events: write_events_to_hdf5(filename, data_sets_fiducial, attributes, n_events_per_file=n_events_per_file, start_file_id=start_file_id) logger.status(f"finished in {pretty_time_delta(time.time() - t_start)}") else: From 141bfaf00f88d9913cc0d19802cbe980df966283 Mon Sep 17 00:00:00 2001 From: sjoerd-bouma Date: Wed, 18 Jan 2023 15:43:21 +0100 Subject: [PATCH 074/418] updated tests to include trigger_times --- .../1e18_output_ARZ_reference.hdf5 | Bin 81696 -> 91720 bytes .../1e18_output_noise_reference.hdf5 | Bin 95840 -> 98224 bytes .../SingleEvents/1e18_output_reference.hdf5 | Bin 95840 -> 98224 bytes .../test/SingleEvents/MB_1e18_reference.hdf5 | Bin 352120 -> 354720 bytes NuRadioMC/test/SingleEvents/T03validate.py | 3 ++- .../SingleEvents/T04validate_allmost_equal.py | 2 ++ .../radio_emitter_output_reference.hdf5 | Bin 66576 -> 69528 bytes .../test_radio_emitting_pulser_example.sh | 4 ++-- .../validate_radio_emitter_allmost_equal.py | 2 ++ 9 files changed, 8 insertions(+), 3 deletions(-) diff --git a/NuRadioMC/test/SingleEvents/1e18_output_ARZ_reference.hdf5 b/NuRadioMC/test/SingleEvents/1e18_output_ARZ_reference.hdf5 index 000774c19615fd7d1a9027b78edda5373e8236e1..13cb484e8f24da9bb49a197394a6427a613ce850 100644 GIT binary patch delta 14673 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 delta 13120 zcmeHuc{o+y_y0ZDculz~bEae{ndh?iC5facqBNK)G*U^Ep-F}cr@BPOlp&>5sMv@Q zab@gA<}qWFMEs8EUGF}>?;oG%`Tq5Ley2zKyw+NK@3q!BYn{FArL=-AZi+Qjfh+~X zmaeBb=#hS28F-n1ysj$iEQ*_LNF&R!pLbGo*nw{r^UvXA?OBW)vPx#s=BHrz$O2A0 zgUrcIn`Mx)`7!(hc@YbP1;abYOIT>^7|zWS&pJKowUeH&hlP?=xx+>!xcufur1204 zcVOitTk_7(<9^LFFKjdq&lgh1Q`y{q_Qvz;&)_%MPt1Z07C$_K!*~&+dA7rhA^gO@ znd{=)pA9K4bDYB-!w0x3a7*4+Uz_KxC#O!3V18GABXSMaIoOY$Pa^OWAjLXbP~5Cp*6Po(7u(@y)UNZ$Xabg}6-rx8SV9RWX%< zHsCfI9!CD#T$b1_SQKkeH%kaBJp*u&xX-LwIayZJ_00VnSOd z!#D4G!BkYmtB2DV%spx#=#kP3Vg`$1%1^LD7p0w^Oer>~j@gX)wX?#@R~>d-GG&E0 zhAH?aFa7W#LW~M4bw#d?@lxTesU#BbIIsVS2W?>CxzkU~bE(i$rf2<~!cI`#t$B6r z2`XIp?O4QN<_LIpS9iY4vk_3N&Y!U)bqJ)&Jm0o_YzTam^Z3DENQLbzRq0~S+JTGf z&BRa31mOM)9M{V~w1a!wb};(F$-eOP`Or3jx@pjQ(&UXlHVy7YEKO;z#o+l*3po~Y z_k*f0Y-!G+lOXr}^T8s*DymT1#W>3!V3S{g+6Dy#GP7Rl+e+jE*(ukD2iOXM?eIav zQ|k(Vb6oWTuc%>=Amh^>xs342nnO*u-VB4j&YV*IAPkm&-lAQ4SoA&cu>P}u|s_ee=C757Y0?j%7GuUoSA{v>$HuB!O_gK6;AZTWs~8fnId zQob*edo?EIHDGK3HQ0ls31eBppE>%g!?(xx={|K=gHw7sDUZmDp-#ir497b;JKMAO9cwC(|6N(*CJav5)1DNsB*Sv$rJ)~N zG3c^{>?0`t1z4yqQ?9We04~X|s`$5j1~qCU3VG*7!2wghPU#a1q38k)wc{=e;rQ-# z;ddhzLX1BxnuVaBAKP=^c@+cr_AFo(Y$C&g7mXopA1Z;>r{NNFAsH4J^EAllhrt)H zeO<_C|L!kfX{N@Zp#7hKgqmUAQiD$bSLM^i9ohrwjt~nVe5M=De|I+U`1RfCA9r9u z6vq77kXIns^KpiNl%DIt*_Tma?wypXpS>}i!;FI28{IiDY{2GwtOcVMS(8$6OZD!!8}eDmx=&r{D|!UbAh3C3726!X&27<24| zxTU19;Mc-#{LF!uP&9vZT?DBYnmEgb$-Ck{lA@Uzl71K^*EvM|aaSc=fa^&ID1Oy) zTCb7T4)0q?QMGgn;3fa!$@B4jFm{_-Wo=SBEC|24%21;KKEnH?OH{0l8Z=MdX@_#T zQ%_cT6u{)%gFV%RG<$M*1np8gEcS~t%e5bTGP0vuw)7yaTZ4S4`2h^U z^^|lJFMI6U9PieH9Nw0_>inJog%gHY+a7m8H^1c`SM7U{PYqmc|ani;7ik5QjA z1e>vMuSeXP`mzynZAc%lUQSnx*0{L!rg1&ewyZrEAkl_KYl9~z5_)0f`Fr(ugX>XI zhL83N%{H_e4^!@;aGuEY&NJ^u&ocd0ji5U&%KYT z+TP?it;|$yDU8fG`kOwY(@(ba`8Q@<_>D989k_pe3>D^Mcp}qL=GTXkg@`!;;^!A8 z6Zc|2F)sH`pNK*Q++l?<^(oK!EmO<-&}Qk^P4gC;Cwb>PCgTay*Y zVu;bB&pM21sQ2?_qq6a7nnMe6wUN7E!m?`$Gh?P+S)icLU4r0_W+V~=__04EqK-q=n z@J_Tm^SEgiCQ$#*9LxVQjD~kbzOOivg7W5P8m(Q=q6o;FO>aIMf@1+eF41SR&^X=x z&D}Z%8u7e#K`w=$Yw35MJeq|b;W-vMiX7iReyq!%ZJ<+IpBPM9%QVBN@(XEeR&+yeoNC#kSgN8|V^Yz8PMw>7)yrfMUg4+f zD$5n2HQM=6dASY9o{}wjU2_mBWQtgouxw$q5tWwzQH|Cenp9g++Kn8~g|%1HJ5lXH zWzAlnb|fC8II?MBE8<^%edq?^o_wztu?`j0=vectY|x2lRmT_j7bPOUV9qF+v^z-p-s^0s(P1=l_3{}@{Uhk=!XssAcb-ABtp4aP zRl`W_w2^#uMk3lT;d@Yw>n>8e+%%amIE?u56k^m|g_l*uBg4qgYrV#vl@PTq5mQKi z_zV_xAFk*ndQTnAAb-F1L*f%p;n+!! zFxxl7h=fbq3W;nG)GA+>+$?YINV+5B-v?L0qcGYGORU+(W$Y6(o&1- zkT%3PJyY7?UVPM6MK5LD6R)6)y=d5@a%H3TOL&U+?vBlGI?%b7$8PcY^&-8Hq6)$I zTC_0c%Km`*HW(vS77>547cIcI*r`yxBGgzTbY8-+G!xl@4;?50kF?XV+R;msZkk_* z3JpH4;?Zb_%gjo5x=Qq-cJ}6e?$ssm)9N!F!n-@sxGn_``_hAAQrLqx(d!V4VcR7p zTRUt|RRXIQ_ae!AYhUFw5IW(~TjYf|8awSDAdm~Q&3Jf2Cpt{u6y3|$i*N^t5eFNo z0;ROB$MAi8vHCrZ=Lo+i@h~W37%~0Aw$}#aK(lSQPOEAvl0BFf=vXm~goSs(=yB%+rUF1m^;n1$WQXdf zcG}+xWqnf@;@^AFko+@}QZW5K$$V3ND-_w^W--4aem?%|6pz6u>eB>B>O=(N{0HRs277isd(Vfe;*7C1ym4SjQUh`a$ z>_vQ9t?7rZGtt<*p;x&T`DnN8jldO^14tYf*{-AbJcR^5A8v(Ip$A*13F!duEg4KD zCJH`lQJU3XfIJc%7d>enK&ANc?UH7_7i3x+WC~IEV4$Qga{yVpv@lbaFi}TqSM#%b zt#Dnv)_Y5-n2n=EB2-v~v{=iKExU5a$~Diila-mu+ZWTzXf$kiuFo2Zu?k#O>VZxN`7Vr57D^TGb z+Q!o?-RR=&M8^jUyWx)bIuDEd3UpQNyN#&i0IGO8?@G=H6P|n0^2)Wi0@caK2$0C# zNJ4*gUbav-q~C~kx{*_X26WlZe3l(R`AJ`WN9Qq_aQN&2jGkA4LZVzE4|8>+3p=IG zEE4aAA*bOZG0_S%FG=j4&B_53ep=-9JAgvg3I$)i&V+)iOS`oEE6~*7IQ0`pHwt&$9}q9u4Mncw0#3?O zVPCD*`sS6R=Zk&0*~|yf8PO95HNBXy^SFB4sfO~IPeVS|j!QcWZTZ$0#j$N;3F1lE z=etj<3bnOtdA9!K5IRwlk!X7ZNBhnAdARMWkZJ+llbcv-PxGIkXdEv=qC-P!-+QZ& zL~VryWB(9(KBaQ|hWl|C8|Y+kczG3y#>1Q?sYh2#j%7BUfG~Nu_~F`0#D^C+Pg5-= zl%>CaFNbTU*PpZ=9z-d4wTqAKV-+0=a{Di*wum#=MUI<-90c-)i)ETQKze8ucM2dkBg@^4`qRS&i=5DIQs1QViR< zzWbOP4#9^ylNnnEtI;8xx<^Q42h7vBo?HyCy7}|!6I`mUW`#bZ8oAlcdF6tUfyNS&Lz;6J*n1*=yi|u$CizH&>7fNekOnK-V&dgd)udt9>m@p7bZ7#75N zzZJ#30?(f9?Z}fcgZb_$Bf>8SXl!(m))K`=A48^uBYnWIz5EeAMrIhCs_i!MWTVwb6%HH|7(yX|%|_KKFNo)3E^AAxgPnMpyQHrP zEbvfS^#Z0ZYPQ44bCH<5a(m)q_ZIwc{ci;kW8&xfwG!=3W<>5FW)Zt=%bI?z!nkIUg7ZH+$4jOoSuP=&Kgd zwq@pcHelF3JnYCpEE~s;>R@|uy`#2ROlBDIKL+qVFBOaz7da-+`W;X<;l{_J*_P6d zOef-9$I2xtofjY3w=I$8z5nC+2J1wc_<5g3Py0lgoK1UdiWOezeTH@IGnFN{^>HO0 z7xuoca+d^}(7mcPc*t?%d0W3eTUBnGK=a>e9uwi3fbTpm{U1U+e+uE-PTa+&aLP$} ziq3Go#mcKuv^AM}ClMxX<5;@USU8gQ>P~ykMfOOV`xIQSxIl#@?yO%ZJ>E^>Mg z#=!kg>rn1kH9B0)kEgxB3r=sqYBQ-m8!%s4RF`{r**F+(!%yYD9|a;G)lO_!IRR>} zyY2s$FbeqD*^>e$$ALydl=<4%AAwEHs|Sk}CP2IqY2)6HqhL%ZD(B%6GUVns!YQ$N z3h-Uf&Ka-7V5s}zH-|EQ0QOgoOW4IR=-%~XW%=DnaQfK2UA9LsXyZ0+@@~x!U+{2K zpwfpW)j*W|PCNMn6Bwnr_777VK=Tjf_if=dfIOfb>)F!?0@Q4S>ym3heZ!j{MGNae z&c1^6Ho*))bM4qv|3ets4h|VTI3@_4-uvJ6cp?lF-AEe~eHOx?Hj~Ml8N%>JrcA-g z^$X#f^V_%aeiep%HL{N<%zOnQZ9(b1f(@*22iGJ1d#8s0V^rq$DaRfVz_1J9D6R!P zOKzpt=dr?}?+WE?*Megjw=h9xpY*kD3zM#C#zcKBm*7yCdh z8=TZ-k1m>Ehxr#^$$dH-G`6vyXP?UsITlT z0=L*fhO3X`Psi0*q2YZ#^PXJtKj(|YuZVwM3fF@DdoQ*C&+_kHtem-(=n=y^{o0#~#TU_l^6*r+e~UeQ$f((EI6`O%^MLeB^|oDiycCU*q%^2l{w;2Q?-63!Kf_m6<%X%#ZH zJBC4EYIC#Bg9fmPV$rmFZ!ws^x?s8bNFsQ*Fj3;6=2f5$mnurOG=MlI>y+9z#enhV zQ*!6VTfn!Ked8L_YoPeyg6J2_m*A;$T5PeQZ!rkjy2A0JOEK^dOE^?7Rt%O3y;G|o z=(1eG!&ZvLV6r9DX_v)Ia7-o7W4(Pb_~dTpvw=#5CtWV+@byoE+VgBh^{Mgps0Q5Ckupctk)iAQfXCjxQY2_` z)^(eq7zqw{eJb{6p9CGX{d)f9)8PH~mRsq|Ccu@P{fN|nL8*5|Z;|6PQ2Sole8!*` zXipnM8<|G{?qYj(D{B%QxbWqh)$2n*ab5mx}@7Ce9HyZ1ym@SMK;z-oIT7|kD9ym2!QM32try_Q@A^1aM7>U^$& zo&HX$c?~bXx@5a+rSVrmEZhF8HV=n@z2UKg2bGyXJIv?Yv^oi>dV~p#?uz1QV>f%ALz}Bf&MzSb17|A7~A=;J%yD0_+b&YgxsIy$518UE8>AT0z{X z^B&B%1r+V~)3W~X9x!ibEl7IP3O7qNl zF^x8lqw@jV0WElYY>ZPjc>(mi^|48}PZOGK@#Af=6@VHleX$+i)uGBZiJSLx_~E^b z*EJ>X8qm?>#24vifteVh`BHX?b>&6~z_`7~l)Wh*fvl0!s(q&gVCN!m?2*+7sFBb= z?9#*!cYUloA$w&IglS)pQ5xWfMnjABJvWa4loBdt?6n9oJ9Kvj*(`(>SHw@y`bNO{ zyk!$Qaor$PYV5hjqDAmXefHgX?-#%)dMrM9M5x>{cK2B)-s20Zf*vr;?~-7u0h$&y z`~lv}7%1DnA6Di^rlWp+nXe@KCAt8Q+0$C~PYiH_E4j01K_6Ib zvG>(WE8jZM_rekx?J$Vr{G6+tdeGMFhPpeO)`iqTEBynnwg-jX+z*;U`qM!D#|dJSYfj z=c(ic^-v+zAmZtWvmkuvXfSnqoC@Q*FMY)J3&NDxzE@nORJi=rwcu4vmqD8S#SbAO z31Ct5>M8CYwIFpoms8|ZAvjc|@G|4$6>zm|G24}o2_Svf=Qv~KI#4NEIOY3g*9*{7 zLNk`U!T?{IHtF2ss{m?i(;Xet7+_$HNnr%20CtIrdsQw~0^Jk%eAnhO5c;Bhq;GR2 zc$(-^9(lhEEX|A5iicUCXvMb&p3OC2|F^vyskhjm*$ys)8>hd3-ZoWTS?L@gyRu(= zu|o}bQgwdfb~hVjJLd*3U0VDVeAOK-xS%)&a*MFNq1!)!2D=Gn(B?5fVS8uc>Hi7% zJ?&?)(Eb9Nk7x(b(?)@;fAHhIlrP|}EY1u7#BxdGqCBg2zTXYp_+m6`i`dKkc<056 zMG~)zDPD>dv`NSQWrvA2>BaK%R&o_I4au!;=J@Ntv#ixHWj$^kq{LGeQ+y2PFQ?fj zP)^_>LB>2K_nGQ~q;i__1W6HZ3X=UPF@OG?1W&Lr&vHS-$Wy;0wguNx1iE%@-~dH5 zg-pE=Vwv;?r(QmYeZc)M>tNM*&ShK7J(GIH2IFBT3D13yG6a8~_lJgZ;+Bn4T&{Cu zRqdbTR)Q@2R*J$oN4BF^Z@?re$-jyP@c2ea;?UC)_tOd@Thf1@q4IZL#7*lrl1bcn zbp70Utb@Rze`Fc4zh!@($0q+9Gcx{-EpvWj;(V4EhZA>*;KZ)sZV@Vkoskjp*brV2 z5sL}nj*(RoL->n;39BAx^5_l6CW9V$z(3rgW^)gmO*+T4e5VNaQ`8Jzl*Y=Y=K-4 zJugvc7PwyY222MJjFzW#>B{CJok4ghGbcI=Q#4eFtvzw97a9jUKh(a^3(M>m7jyXZ zLMuBPSW$?(DJrvRYG2dk(127z?#Oh$$xMA!D%COmnuj)NLaBpU0 z>;{ae_~?sM!M@=l@$%%)mAFxS3?_rO#aBu2@bcVx{3wFW!Wqgkm8HCU9{SPD@GXh*6z|AR-=~(lX@~H@#5MEmvK9*CYj@LH1>Ab0 zQeE(!iPHa;;Q3Pm-*(HIlDI@H?`FqgS_GbRYXdfjQ~mF*m&b*s(W( zwige)ql3ZBf;)FGmd?bT_}-M|EEcES@u-v~+$PGmo%Kz}Vg2h`ygcO^tD{Y@Or}ff zK8(9Ayz~6wTc6;%2e$aTv?V;S+5TJg`OlE%ReTlaxobSnGBJ%TwD>dh+h@6}iuE(z zk|zBhLVW)g!r$NBiW%X0>1(*9Glr(T(mul&2E>EYm$S(5p3Hof{uoolb|!Afzy2LQ zkj)&M~!FCJnRVc%gO9(jKc_fsZk#rjQOAZyQ7oI7JV z_Xzdf%K&0n+2ja(RfYx2+GgoYJY%~6IU@9DIP$;XBy-|3x7XJa0njKYg*&|9#Az?2 zxP<3IQuxJB$qYi$Qk}Rx@G~?SWxvCRztazw;&&$=QZT>tTsa^SQ49h0%pE1C$Yd!l zTpXVb*_k?@WV|ulh#dNx`0!N*7u^&PZy%%9k1{tcsg;wYSk-^huF61wNlk-Zy#lKJ0q;@K~VYQ?v%6hFS%%)^IIu!+nn zn_nM+U+i$gF5@3M=Je;+Zx#4ev5~=9ealWcay zXmWLfeIi>8biD;2cT3D2_GKNQY}kgwt)3`b{1UcfNBTBmf70$^b>rbQNZXWAd&rCo z$HPnNy2ScH)*^#Txyh4Y*SS@xrkTB9@ZJr#D32e&cdbZLAF){8sjhfxXJUCFFDx)cZKH$GHZB-d3(Vs-(zpL8MQ<&=?7J_LXjz ztn32^Ui5D+lkW%83q!Y-(0W1ZhZS$0ZtU{~DSL7pRESlccW>EVv9*M@9DzoI`^iv~ z+u4(1N`}S7*S7~|egT)gc}GOP4}n#utKF@?eg^TQwn-1(j)EWA6EOOOAiU7@be*fa zAY?RGWYpLT!mB!~TD3U z&d&_*+D+!tEuO`GTAAct2QvOqAK(uC`Mg0yb=0rAMvT5)2Q#OuI$*5-)H;&sT|2Q2 z|3DV{W1T-BE8V~Wv;Bw5hM#6XO3vo{U38eCi}jOf^ZrG6i1&x9vM?57_$3y}+5AAm zFXF1KoLr>2tYW7|R7PW#^amR-A@$#;%$ndZ+mJ?P3b}}Dt`F(AiS%%NO!;R8B#WKw z?`h~#23RAV6JX!ynyWEkx~d-L&eHma08Z3c|C5wRdb0ydvEwq-^%VX&hb9v#3gQkQ zDAc(U@n6#iv1GXudoL{O;C#%A%rUDQneH!wNn$KN8@;*ObJDMJQFT3SJ!e%-9o5}V zTFy@D>Q0VYE~>lLbe(tWYHMlfIqRrtX{c*!=(5q{MKB$VovtQ`31J+w4d>5>t}2LS z(^Z8qPK-*I7Q%$+oI;oaohFEJ(shLh7iJ4#{DiF!2o@$nZ<}dEegFN$EoB8syXk$xF*;NXE>Go+TY~&GgmYO8iO(rVO zRkMU?*gnkn*NY`ch|N5#UwEc!_D{UvFFaGN_a}e;UwGyN^Cy4aUwG!p5PaW%CY*V8 ze|BL13(q{QKlw9j=RYy!FU<89=Kc%w{KN$Hm&LqUmyEF3-yV@C1ZL_IfAQu1!b|?b zi~qv1e_=@i|EaLlUwr9V{M#cke+dZvg=h8}e-0?}7hm)*JX28lr$OR>;Y9={b{4-a zmLTFNI4gfO7J<>@Y_L%JHw(<2?7D>BWQxtLWQgQ3n=8EKeg`o=n=9CPI7rFFm@}8K zz|7xKWX}Q;V;O;PVlhQ;HN&K4s-nrQN(54;{zcuY=ky8A3&wiHV|DdQY{aYsc4+@cgE)e@X{<)Om zsy?G$@^(VCe0@TBZ;ct{73R1XHD|bt?F1u2i@3#!r5SldCv5bY&btv dlpeGb+xSnqR?NETfZZYggO_GmIAas!{{y3)$({fJ diff --git a/NuRadioMC/test/SingleEvents/1e18_output_noise_reference.hdf5 b/NuRadioMC/test/SingleEvents/1e18_output_noise_reference.hdf5 index 438bb90070cc038914669801d06b6b5cd384eaa7..e68a3ff164ca27b2282b981e8f210011e98d8933 100644 GIT binary patch delta 16904 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 diff --git a/NuRadioMC/test/SingleEvents/1e18_output_reference.hdf5 b/NuRadioMC/test/SingleEvents/1e18_output_reference.hdf5 index f695d29432b911a180c8764fdc066e37b6a2d8ab..4a940f9c11e040ae721a2b1118d12e4ca4d02a6e 100644 GIT binary patch delta 17068 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 Qi5vEWJo~WU6C+dp4}*3QmH+?% delta 15233 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%0A4ko=Jxkl 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℞%;Pr>CKa9t|ReaHpgxka$Ihc*n3=lFf1Qf-P>` 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 diff --git a/NuRadioMC/test/SingleEvents/T03validate.py b/NuRadioMC/test/SingleEvents/T03validate.py index 008e9c06b..d83e36ef6 100755 --- a/NuRadioMC/test/SingleEvents/T03validate.py +++ b/NuRadioMC/test/SingleEvents/T03validate.py @@ -120,7 +120,8 @@ error = -1 keys2 = [ - u'travel_times'] + u'travel_times', + u'trigger_times'] for key in keys2: try: testing.assert_allclose(np.array(fin1['station_101'][key]), np.array(fin2['station_101'][key]), rtol=1e-9, atol=10 * units.ps) diff --git a/NuRadioMC/test/SingleEvents/T04validate_allmost_equal.py b/NuRadioMC/test/SingleEvents/T04validate_allmost_equal.py index 96dfc64c8..c142cc5bf 100755 --- a/NuRadioMC/test/SingleEvents/T04validate_allmost_equal.py +++ b/NuRadioMC/test/SingleEvents/T04validate_allmost_equal.py @@ -169,6 +169,7 @@ def test_almost_equal_keys(keys, fin1=fin1, fin2=fin2, error=error): error = test_equal_station_keys(keys, fin1=fin1, fin2=fin2, error=error) keys = [ + u'trigger_times', u'weights'] error = test_almost_equal_keys(keys, fin1=fin1, fin2=fin2, error=error) @@ -180,6 +181,7 @@ def test_almost_equal_keys(keys, fin1=fin1, fin2=fin2, error=error): u'launch_vectors', u'receive_vectors', u'travel_times', + u'trigger_times', u'travel_distances', u'ray_tracing_C1', ] diff --git a/NuRadioMC/test/examples/radio_emitter_output_reference.hdf5 b/NuRadioMC/test/examples/radio_emitter_output_reference.hdf5 index 2a45edb2cd75d612819a6aaf0755c997c1ef4aa0..9802bb32d73ee0d4c0ba6b2bc3277f03dd02d9cd 100644 GIT binary patch literal 69528 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 k`>>m^v{g*-&6Cudw9J659S#jSpWb4 literal 66576 zcmeGl30MUkAQ&y`g?%xevsLjdGluG&6~Gx-p;<6 z(W6VZ+OADp34FP@5LF3x=9d3?$X)JLotPv(&gYNjZrEIcn9jvlJF_=VL{kFiHRjUY zIsER8*o5m``oR8OyAnhdg2&H?TsGldmAzZdC3xRrZ%D4<19#bY2;UG6P6%EO3iRmO zF$DJ{ljEzQ+&G6gu{Ul61-wfDuQejv2p7VnHz~AoojD?uHpum1ayp9EnT!PC?gDJi zkc47>d3LGB#PAQB%SWAv>J0y~KNvsD$xd9od^tX>0{IwcJrddK@vBAnJ*>iFtOlt# z-`UxjsoI6ZSH+31*psiC3F~vo7&!Wq3pzrV$nDbLEaU+_^Mex1ewMqaH5Wp z$2iHOo#~${WD0eeSQ};VN~JD0*nOQ=rci5ERJ#-)Po;7`Hg2!BBZV56>~{0>)v45n zM<(ys4CD)wz{Q)#`U+ z(YhZ~s2+Qx<*Pcap^n_o%^X~!9lsL^YpBFkpD#V}W(pPW+4dK=MyXVjL9M@O zqDY|*iuT`K*CUl$Vs)OR*qTDsZR9DNH8+*&{DyDKFY{BV-)419{Ps*LrHpBRta1Ak z>c0bW`=3cmr8YKeAe9+XsO_@Z1=mlfQhoaRub6o-g<8M**S&38uAz3XdVlMLnqN^3 zN4m-nXxC6e|Ap}v`2W?N|Am6Hyb_a#D=TaO07oveQ24P`G+x6lUfnK^wdJDlh5CTw zrvMaz>pH@?_Ypi*mZYRhwJXum_^`XwK32`K4s%Q*nn6c%HBx0_~>@*&1#-h zT)GfcP72tsyU%muN=<&Y{VBd4U^QWorA)=VwBp03r~e0X`ah4E?PqcQU;S(eV27Pu zcUL8N`xY5%2VfT+&5e_HoLz=p^avM^liOw3Mfv$pyl$6K$)bV{Qtuq#xH&A79~`1IRwG_<;+j6^-NaZeU?!?U^;9J{Lkon`os;Z@}>Qa#$amO`Ppqh`$P?@%FMT?e`(Q}sEC#Omu91S z;{!ii@N=G}?cEOlojE$$VyUa^+N9e~v}mgQtZ)q_9JvHU*d<82G3WupTH zm&1*K|LVdEi9bF}LIcl!hj#qB1Ksw>ijibmE&bmMKN37L5v{-X=9t5g+2|V=?a0Ve zd6qrtKm4<#XPjm7-N20(wr@k8eho+U-)pt3h;0AGKYgMt%Vuxf=O2-czPK#yeE#n| z%RK9{(Hfj+xV-B5{XURWa zGo@ZsvgPi~f+XFZ3>12^8u{92tL4_G1wPg>b1YqMNKT7SWuu4|%MR2B{6`lxx)f7? zK01H6!RsqS(@{0ew7r{5R*R`++6TLw6Va$#>cEga+2~howOJSb$+N66We&bMB+imw zx4)(J@HJ>dr`*eFA6qTm-G3vRSC6)A+DS*Q-kFW=?XQ{s!=XIO)>$8ay5c<}T2HEztwhy)soxrR@H<>TJ-jzoi(iUvJo1+^QUSD^DNVj{MN1hhslzVbPWV&o!2}6xnG1<$==zujN^ix4V4t^IRj^uJFs6bYwlEt~H&J zJQ(`hvE_fSf38JuwuyY0b}1X((GGTc@2@<|;7R|S$MSyGQFYZr*@!%pI&@xco@M4lmFQsI`RHW(EqkT^u1BqwXsDj?R?Ec| zyZ5zfn1}*4znwjQQ#O({y)$YAjMwP+y&tw39A|lNh4a}V12WK&R-c>Oqp{|NfOp#Q%*`hNwsf3)Y8=+D*u zQGw|ps~GfP-*h;^hAn(KvVS>Be{y@6iZv(|R>{;~+#WWRNq<&9#rfk!(SzvC^^qs_ zt4@#p0zL36s~iN2xbzS&2LN2MnhU+(Egg=R24tJk z;dtS)sD9~i{CnM@b4rJ+EV`tAycNPPURuG>)YvO*bM7tgaMO9dC2`l~HOHE5NA8)U5|=2fXe>4S)V056Sw`0y#yc?Y^A9rOJ~l@$$7JCT0)>NvDxdhLE4e+7Gd;}JVo zUCl#=!II{0g%~YuTYT8w_}T_Et>3avgLhfc&986ly1hkfSvdRfI&oAs8ZcziyLDi^ z^a=0Wxo${C$!)uarBB>|QZys){Q0vLRV9z>jl^7J@Fjk$DbGfOW`+4Lg7G>&W75p7 zb>>^@Z=AS1z3)cUCg;7cT`yXZrT)OEO9_bQ;IHpgn{V-%@0Hf+udQgT zb=?lnC@bpI`=gAQs)-iQAJ{>Q^s z0Q{nHbAI^e;W#wE&mXtEzRN}e{|o#t@V_Ac1^F+?e?k8d^dCY05%hmS|9^G#e|DXI zo7+t)gaSP<1q412_(0$TVIBx_K#&8191!GyAO{3FAjknh4!nGFV0el```z+MRGr`; za$W8eYR!K(51By3Qae`ekcBpkr)C?Dzt(D8ES1uh99gGVJk@sEo4cAHjHP@c_tw52 z8&6%na7*p_gM2M9_CoerLU;wjg|3K z`&9AX?ofXD7-i0&U*oBy6Y5aO%1P8uP2=``aDEDvd8@&_=FYKHizNfV3a{a)Io6jM?dKoAa_C^h+T_-gKF z+waKkW>5Wd-tcp>lOGP6mZiKS+q`S@yF%ME2v9bAl>2TM2Zas!( zNaZ(8?R^#|N!RB6ZeDvkUHaA!J_}baPLg_QXAJ2Ol`j2v%BJs3W0R!Q2VWe0pGcS9 zTK3D~W!;mcLjQ&F7x@3xo&US`*Zy?r+bgNK#a-Op!qTX?^dU1JrmUp8NS94Kax9IS z@_Ow7%Lc5Xu8C3-eIwGTd`(mNUq7v)b{y+m&(Ar7Ix#Wq&YAWrsr8Bn)7)dzsoP3j z8^zX@)Xb&3-&lP)om%9Ie0VFA9_HZ+%q+e@|*mhMtA$KqE@f}_T)Pq)2Xu?5AP28aTR4~ z`A5qUzok?6>L2`Qqt{9*`0CVL(|~lU*Os&sCpWF6`v2By!OSh`)Rikgb$BOq74?26 z{ir?tGN_^GQpjt6tfDgVSKL-)Wl%!@h4B~o|J9xU73g~o6>DR&eNw|jU;Otio=iLJ z{m}CMaQKf;`1q55-$Tq~`ya= zfgX>1KZM;n;Y;8TAOd_(70poN1=EB7o@zbU7~(_zrsOb_OO6~>az3AWp1YYlnolV? zyv-$lsVF(0Pi@S89!d}s`IM4F37_1Wzj?l47j^EiOL19fholwZ_0JU)U$fJso|CiC z8|vJcqvx)mMbz*vA3?qw5g6uw@CusQpihGF<17??_NeUFeOJ)D;KS9_x-7J@_E4AQ z-E+_$x37+!g7~=_2i2!UIcUkE1MQnY{H)TVb$%lUdHPIRI$xWGmYWDb%LQI=P>Z@BBsZ%_s zQL_%ui(T|-3}p(rKX3bk1nR<%jhZeP8biJ3I{b9~?$fA%#cOwd@=grZzt)k(1Fh32 z#lug<-?+z6t(sp{>c35*4p=T`{o$5Kt(oCbd*l8jN;P+P{@k|`sVi-VHQSe&L^YH@ zY`Duiky^ZNL&L_&N!0gsmWF2gBvSba?UKUO3DndUtL}~%8$%RXJFZ1jLjQ&F7x@3xo&T)1S+>W2 z0S;3@pp(D{0w275^MK`Q;a8x5KmmaQuO0;iy@nlgfer#4Fa-oYcvbkI0=<8o%F?`| zy>Bde{{z2Cfqyy5$DiIgTq=C9AY6~05BTEugEVGZ#h>fL_n!}|z)3s!)nEC~i_&rZ zWa-Qxho9p8jN`LjXjpu{JZ*X`tW@;i2ZK8gism;l8P)o6a6FWTk82fXol-52Vh(YF zodpJ3No%5LTSBB>t1xKBD@+#f~Xj15u%#l+})e(wl zxgsJ`&ef;TspJMl3_;+6#S)){INZO)-&dER4xznTbh1n#p|V=}9FN)%6*(>kD_o~zL|KJrKy76vPWuvk0n^7+^J=ehb{ zw!n=zz@0PZ%A9K!3LG>}qcZWk%<7Q{eCpzhBK&F*eh=|sVsP>DkKgykhsr}MzRowE zMlUL4Phex)_!z$w3+uv#&{^gZ;w&8mdIhK*;dV-upYX6*{7|?HmjMHFYC7Q!)dny{*_&wdvTH%nJ+sj|J$$k#C+L| z8ZB| zxVv3gE8U(wWYA3CwNjz}SDXHzM-;u-=~cG*#h1B$L1l&9bafmQU(b}h-sSZhex1k1 z|BwCt$!x1C)_#9}e{CE`GODd(+Tol?PC<4bSvuTwUXh+%I-G>ZH>q^EOb$*xw{*B3 zT(&zqtfd1##oXe2Rn|J$ld&5#215$&8nz#>U34M3b?h~uE2ItVKL`g*hU4?6;}RK| zN6knj*b~$&*mL?VP7iiK?7ypl?lTuZ&-nP$vnx&I=<{OjO7)nNqM@stAR)PPH{6Kx zPE{e<2}Z0T;YlcTCR(Rc$RqVe4PHa@>tKiLGG~@+3gr_^Py09;GGc?pt0i?X8?F3f zw==b{^DM2kJDr*I;e*Zv5e+D+fnv`uhu+CN7`1y@lMm?3db6*QQ7Kh3@8_G(|L0o| z%DL^d*H0Pf%yq**zy86Z|S&pq?TvEHHXxpd}+3pvRf0lziT^J;Ct&!n#p z&-}G&zki+74XBu$R$`aK?_~aX7_PMN%$~~4pRNJ?`^fbMHQ*20d?0GKH9Yf*w|rC_ z;2-IGCu|AepZ%GxetZvgCg1)wQ~LE>8t2Ty=czJp&rOJ!*W?~>MRxayDaOgAEvTX$Du*4={*5zNp!99KAB9AEr6^5N+P9v$8a zzbJcAA%Cto@d?vB;tCtse%%NO*UuWvIpza(dJQ%aIqavcB-~^gsKWA?PA){5bmGeM z^x)ff_WZm*-*E`y*K(?^%>alwk-I2ZhTJGQV<#%K=CyttR zAgMrBC*t1LP8|wlQ%=tDiq5zr8+EScUK;#ZOg8LYmrS?L)G&5sY_`O!? z()qO~4pQf*N#{>dzr8a&L;CK{L)Gfm$dEc8|GlbvNV>EiN}pP*QMy#9|J9~{_s)HL zVU`T(!m=dKo((t-Rcpf4TKzb=k5LmIp^*0gJ28{PKNlUq4d&rEa~*NEGmCJ7D+!l} zTt$Z|zy#|NOiq~S#il9M3Z0JD8gUwv!a#aI5@nJUDka!vAzf$IYT3d#9bXm71}_LHPbp}48V#-0VQB!4BaYPtH2;7p#$SM7_Mmp zV4>v^w8CgM&=Fu{b_|Zq)DCjNHm%f0aK$|a=*=cI8KT$HfUF4W=<(&!9N5k~sHAKytqV7)p+o+~NR3NB24`UKN0?0#8{&GL>VvN8s2-|M^(Z{@{F&de7CGY|Vn(Z-Rphg$dMPZ^R2K#tJH^t(1-r|AY z-oebDeV0{qStxuZP`)%2@PdhXS;Ne5vA5VJ3P4WS?mfiNwn8akoBFSSSn%*IKB%Cj zmrpK;?FS5(e8zIYPbBd#TP(B#@!=aJ5!-PzZl6tj*aU;GAQ+g(9mDs}LNM45Ls_%> zMGFR=8Xi7^T;OSewW0FL1)mon7uxxNz99Coe}+9WrNVJ4gFna+VJ*QkfXA~?8GP*oZ>5n8eu8A+8RKzO2EP{|8CVm8J*O2D4A{g_ zx?aJG1xb*|-`oC)hOyaHfeNQEkoL0-tO6C=#$ay{sx)%JUyut=A{YE$fLy>P2C;uh z4|tpH0IwuC8$&sk5+E7u`L<%qg-RzD><6LJh=l+_EIf%=2zUWvfweIBmdnBr7--Lt zkEj)_!Vn~ecM_FLVW@P1!Tu#%r4bB)f?%jLf`PFx_?BupU=#*yVUYNg3dczXKao#> zJ?jc80}U_w*;nJ`d|O#;eZy`FU|(0-D|nSgG)M%|@Fb$4*vo4?p`P*E%JT1GDC5-y zD;EL+MSelgTVuexbe`tk1&4bHUi=OQd)=4NdlMe=ChR5Wl+n9RIHkO%;CQf=@Zj3IP(4Ux59S>{%}! zUI}?1u53FT`DdbsSlHpn(*nYmX~ROf_Bi^0hG1v969hszZ3uRBdu0Dov0WvVM?(;{ zHa?L+sOb9?>{ZrB))m}7g#eMi-}5#uz8d<0y^yUu;y~EY_(bC1<=CDOAQG3jBU&&Z z*gyR7S5uGiMU>cnb6MpP2*N(bClUxR#l{3lpvd3H{#hn07@o$0!G0fDjL+=HIr8A=heMCc9tttDg$lAuq6`=YJppxs%5uvo9WCRs~mOvx9 z0$c-Q*S^q7d-E~Q1{V${@D1T0w}^)a=5zg$yNdDX^ahjKF(Q7n0D;GVkYevWF$QqS z#C)S~#C{;)oj+~A$Fd9@_Mh6@>CSw15q}gm4k2xK6Pde-t`ixDR)zj@sxba?R3_H% zN4fm%5a;2XU#f^dU>Bm?{(w1uCA{C?!gjb4Zs51a<`aa2v-gkA`#l-Mx=DjFd^=db zK}x+YOcPEJZ#X$IK9I2gBeo1UO0(S)#3XQda^xbD#N@jXAzXj3KP?xckGa1>rP259 z44$_Q*wF$DS|(oXkBrBQeXkVaZB#N|xmsZa7i(p;7kfeD@v^>J*#2#F53r8-jVlgict2Hk<$LxiS9zPCshe!Wylvz4WaHY2#^dgT>$taK*paN!ltpK|7a@sFQUW3G)nBE%!sRK2cPTt2Z;Q9{lFIh z6Zi2K`H6kSzCM_`I2%6m4f6Hz4aEIwhn<=E_yz@m>i`KRVbLn(MmVyA{Y)0O2y!Dd zIyud9mF*}GcGw_?IpJd*4X*FNtrG48E@7ZmdfZ>`^b%Wd8J}FRD&o+Aq6nIui8kO- z5W5=jF(K@EADs6tO;{MTfevuxjs(Gd#a<;u?*)6_WG@;6Shfg8wq5!E7{vhR*97ynkCCkyzvn^OBpM z;PI8cf_%fo65mk2(10+pztS&AsZjd*1ccJyPfz0Q=N~2!)4o35KK|HOEWUU@fT0>7 z030hLk!y5etk*OqpRcbhxatga+4yRd6V9caa5XtNzJB9aGfbMo)1U0qYdL^-bCAv{ zN1#o!7muHN2oMsEK&~xFg;q;K?K)V5YG@+~%^)>85}eYIoYO?owum6jI`CsidTK

    _n?X$I^kkS;5v4a2W|QDf5+=Ed1We3CL_!x<^+KFRG5nv@dYC2XhV1msSmTIlb$NQIaEtyYWRt;mS6~{NoWW| z7tEbz131<+!2|);hZCdVQB8UpG0DQcNDxFA*@)IkWos|8wNBZ3B;fHEwGR-r4-|2< zfC5D;EQ*Mch~W8JjG2ozM5Tcv zy4e0i>Y-J5P=Tq(slk&dsWCy5B4`qG8^_@KNM>wl48+I^TY11*MBTx)2Z_ky-2A*M zhYxIkr0`W3SkaUkQw-^en;XWDUeRW73}I4(SP9ny4+9<8-l-KTgI=dmGW-o)a;?kB zRsOj^gBk`b!KK1E0sI5VmLl8;6c8vNP(Yx-)1-jC-CRv8R9Flc4({< z7urK>GWJwht>KdyjeJ`j*;9Ej??&|C?C$Q2eH;t|W-aSj7%z^>Y!7~p@a@6RmcsVb zW!eMpMhyJA4j;1Vs6Dp!at4tD+yZPUpYfO>dp=GzVjEX3I=^%TN4V_i|CSDSoy%Ty zyL31gZopRGDIJdF;IyRpVZFx`0q6mUTVANFRx*W8Ne?RGd-vI!ZEaAdM+`^96 z7x?!J{JB-`99%T7060L)+XG47;OPL4;wmB^H~`?1dvI{x4@-v&;ovCtwW&kk$A2z8 zE?@PjRDAXL^mx+!2T|puOSHqWdmb6jj~-tL^nd{^d`|DL6!hSEkb7H1a4(r?SfVgj zvGeA+bbhZF9Js=yaQ3re=iJ-UxpM*WD??m>Psi^tnFEtJynMP^p$(H4IoO>~XWpw8 zDR1Z9$A-6PI%EI0!(Vh)E6(Ea+tRs0%qmhIZqS<}!Kajw;NE=VTjq-9rguyX8y`QO S4f*Gen!jO_h2N)4f&T%gHbQj( diff --git a/NuRadioMC/test/examples/test_radio_emitting_pulser_example.sh b/NuRadioMC/test/examples/test_radio_emitting_pulser_example.sh index 2e24afa80..582f7b17b 100755 --- a/NuRadioMC/test/examples/test_radio_emitting_pulser_example.sh +++ b/NuRadioMC/test/examples/test_radio_emitting_pulser_example.sh @@ -2,7 +2,7 @@ set -e python NuRadioMC/examples/05_pulser_calibration_measurement/radioEmitting_pulser_calibration/A01generate_pulser_events.py python NuRadioMC/examples/05_pulser_calibration_measurement/radioEmitting_pulser_calibration/runARA02.py emitter_event_list.hdf5 NuRadioMC/examples/05_pulser_calibration_measurement/radioEmitting_pulser_calibration/ARA02Alt.json NuRadioMC/examples/05_pulser_calibration_measurement/radioEmitting_pulser_calibration/config.yaml output.hdf5 output.nur -python NuRadioMC/test/examples/validate_radio_emitter_allmost_equal.py output.hdf5 NuRadioMC/test/examples/radio_emitter_output_reference.hdf5 +python NuRadioMC/test/examples/validate_radio_emitter_allmost_equal.py output.hdf5 NuRadioMC/test/examples/radio_emitter_output_reference.hdf5 rm emitter_event_list.hdf5 -rm output.hdf5 +# rm output.hdf5 rm output.nur diff --git a/NuRadioMC/test/examples/validate_radio_emitter_allmost_equal.py b/NuRadioMC/test/examples/validate_radio_emitter_allmost_equal.py index a989e3a91..1e7fbb94e 100755 --- a/NuRadioMC/test/examples/validate_radio_emitter_allmost_equal.py +++ b/NuRadioMC/test/examples/validate_radio_emitter_allmost_equal.py @@ -111,6 +111,7 @@ def test_almost_equal_keys(keys, fin1=fin1, fin2=fin2, error=error): error = test_equal_station_keys(keys, fin1=fin1, fin2=fin2, error=error) keys = [ + u'trigger_times', u'weights'] error = test_almost_equal_keys(keys, fin1=fin1, fin2=fin2, error=error) @@ -123,6 +124,7 @@ def test_almost_equal_keys(keys, fin1=fin1, fin2=fin2, error=error): u'receive_vectors', u'travel_times', u'travel_distances', + u'trigger_times', u'ray_tracing_C1'] From f3cdeb52da242c229e3e0ae2df09bdc3c027160d Mon Sep 17 00:00:00 2001 From: sjoerd-bouma Date: Wed, 18 Jan 2023 17:56:08 +0100 Subject: [PATCH 075/418] enable word wrap in tables --- documentation/source/custom_scripts/styling.css | 3 +++ 1 file changed, 3 insertions(+) diff --git a/documentation/source/custom_scripts/styling.css b/documentation/source/custom_scripts/styling.css index 51c1f678f..b1cc36c4f 100644 --- a/documentation/source/custom_scripts/styling.css +++ b/documentation/source/custom_scripts/styling.css @@ -2,3 +2,6 @@ .wy-menu-vertical { word-wrap: break-word; } +.wy-table-responsive table td, .wy-table-responsive table th { + white-space: normal; +} \ No newline at end of file From 04685fcb288ea1ee4abe4d2e6d66cdf399c380ff Mon Sep 17 00:00:00 2001 From: sjoerd-bouma Date: Wed, 18 Jan 2023 18:12:04 +0100 Subject: [PATCH 076/418] fixed minor typo [ci skip] --- .../source/NuRadioMC/pages/HDF5_structure.rst | 47 ++++++++++--------- 1 file changed, 25 insertions(+), 22 deletions(-) diff --git a/documentation/source/NuRadioMC/pages/HDF5_structure.rst b/documentation/source/NuRadioMC/pages/HDF5_structure.rst index 43edd8d33..25cd9c788 100644 --- a/documentation/source/NuRadioMC/pages/HDF5_structure.rst +++ b/documentation/source/NuRadioMC/pages/HDF5_structure.rst @@ -52,41 +52,43 @@ ____________________ The top-level attributes can be accessed using ``f.attrs``. These contain: .. _hdf5-attrs-table: - - .. csv-table:: HDF5 attributes + + .. csv-table:: HDF5 attributes :header: "Key", "Description" + :widths: auto :delim: | - + ``NuRadioMC_EvtGen_version`` ``NuRadioMC_EvtGen_version_hash`` ``NuRadioMC_version`` ``NuRadioMC_version_hash`` | Hashes ``Emin`` ``Emax`` | Define energy range for neutrino energies ``phimax`` ``phimin`` | Define azimuth range for incoming neutrino directions ``thetamax`` ``thetamin`` | Define zenith range for incoming neutrino directions ``flavors`` | A list of particle flavors that were simulated, using the PDG convention. ``n_events`` | Total number of generated/simulated events(including those that did not trigger) - ``fiducial_rmax`` ``fiducial_rmin`` ``fiducial_zmax`` ``fiducial_zmin`` or ``fiducial_xmax`` ``fiducial_xmin`` ``fiducial_ymax`` ``fiducial_ymin`` ``fiducial_zmax`` ``fiducial_zmin`` | Specify the simulated cylindrical/quadratic fiducial volume. An event has to produce an interaction within this volume. However, in case of a muon or tau CC interaction the first interaction can occur outside - ``rmax`` ``rmin`` ``zmax`` ``zmin`` or ``xmax`` ``xmin`` ``ymax`` ``ymin`` ``zmax`` ``zmin`` | Specify the cylindrical/quadratic volume in which neutrino interactions are generated + ``fiducial_rmax`` ``fiducial_rmin`` ``fiducial_zmax`` ``fiducial_zmin`` or ``fiducial_xmax`` ``fiducial_xmin`` ``fiducial_ymax`` ``fiducial_ymin`` ``fiducial_zmax`` ``fiducial_zmin`` | Specify the simulated cylindrical/quadratic fiducial volume. An event has to produce an interaction within this volume. However, in case of a muon or tau CC interaction the first interaction can occur outside + ``rmax`` ``rmin`` ``zmax`` ``zmin`` or ``xmax`` ``xmin`` ``ymax`` ``ymin`` ``zmax`` ``zmin`` | Specify the cylindrical/quadratic volume in which neutrino interactions are generated ``volume`` | Volume of the above specified volume ``area`` | Surface area of the above specified volume ``start_event_id`` | ``event_id`` of the first event in the file ``trigger_names`` | List of the names of the different triggers simulated ``Tnoise`` | (explicit) noise temperature used in simulation - ``Vrms`` | - ``bandwidth`` | + ``Vrms`` | + ``bandwidth`` | ``n_samples`` | ``config`` | The (yaml-style) config file used for the simulation - ``deposited`` | + ``deposited`` | ``detector`` | The (json-format) detector description used for the simulation ``dt`` | The time resolution, i.e. the inverse of the sampling rate used for the simulation. This is not necessarily the same as the sampling rate of the simulated channels! HDF5 file contents ------------------- +__________________ The HDF5 file contains the following items. Listed are the ``key`` and the ``shape`` of each HDF5 dataset, where ``n_events`` is the number of events stored in the file and ``n_showers`` is the number of showers (which may be larger than the number of events), and ``n_triggers`` is the number of different triggers simulated. Each "row" correspond to a particle shower which can produce radio emission. .. _hdf5-items-table: - - .. csv-table:: HDF5 items + + .. csv-table:: HDF5 items :header: "Key", "Shape", "Description" + :widths: auto :delim: | ``event_group_ids`` | (``n_showers``,) | Specifies the event id to which the corresponding shower belongs (``n_events = len(unique(event_group_ids)))``) @@ -95,7 +97,7 @@ is the number of showers (which may be larger than the number of events), and `` ``azimuths`` ``zeniths`` | (``n_showers``,) | Angle Specifying the neutrino incoming direction (``azimuths = 0`` points east) ``energies`` | (``n_showers``,) | Energy of the parent particle of a shower. This is typically the energy of the neutrino (for showers produced at the first interaction: all flavor NC, electron CC interactions) or the energy of a muon or tau lepton when those are producing secondary energy losses ``shower_energies`` | (``n_showers``,) | Energy of the shower which is used to determine the radio emission - ``flavors`` | (``n_showers``,) | Same as above (the parent of an electromagnetic cascade in an electron CC interaction is the neutrino) + ``flavors`` | (``n_showers``,) | Same as above (the parent of an electromagnetic cascade in an electron CC interaction is the neutrino) ``inelasticity`` | (``n_showers``,) | Inelasticity of the first interaction ``interaction_type`` | (``n_showers``,) | Interaction type producing the shower (for the first interaction that can be "nc" or "cc") ``multiple_triggers`` | (``n_showers``, ``n_triggers``) | Information which exact trigger fired each shower. The different triggers are specified in the attributes (``f.attrs["triggers"]``). The order of ``f.attrs["triggers"]`` matches that in ``multiple_triggers`` @@ -111,37 +113,38 @@ Station data ____________ In addition, the HDF5 file contains a key for each station in the simulation. The station contains more detailed information for each event that triggered it: -``n_events`` and ``n_shower`` refer to the number of events and showers that triggered the station. +``n_events`` and ``n_showers`` refer to the number of events and showers that triggered the station. The ``event_group_id`` is the same as in the global dictionary. Therefore you can check for one event with an ``event_group_id`` which stations contain the same ``event_group_id`` and retrieve the information, which -station triggered, with which amplitude, etc. The same approach works for ``shower_id``. +station triggered, with which amplitude, etc. The same approach works for ``shower_id``. .. _hdf5-station-table: - .. csv-table:: HDF5 station items + .. csv-table:: HDF5 station items :header: "Key", "Shape", "Description" + :widths: auto :delim: | ``event_group_ids`` | (``n_events``,) | event group ids of the triggered events - ``event_group_id_per_shower`` | (``n_shower``) | - ``event_ids`` | (``n_events``,) | the event ids of each event. These are unique only within each separate event group, and start from 0. - ``event_id_per_shower`` | (``n_shower``) | + ``event_group_id_per_shower`` | (``n_showers``) | + ``event_ids`` | (``n_events``,) | the event ids of each event. These are unique only within each separate event group, and start from 0. + ``event_id_per_shower`` | (``n_showers``) | ``focusing_factor`` | (``n_showers``, ``n_channels``, ``n_ray_tracing_solutions``) | ``launch_vectors`` | (``n_showers``, ``n_channels``, ``n_ray_tracing_solutions``, ``3``) | 3D (Cartesian) coordinates of the launch vector of each ray tracing solution, per shower and channel. ``max_amp_shower_and_ray`` | (``n_showers``, ``n_channels``, ``n_ray_tracing_solutions``) | Maximum amplitude per shower, channel and ray tracing solution. ``maximum_amplitudes`` | (``n_events``, ``n_channels``) | Maximum amplitude per event and channel ``maximum_amplitudes_envelope`` | (``n_events``, ``n_channels``) | Maximum amplitude of the hilbert envelope for each event and channel ``multiple_triggers`` | (``n_showers``, ``n_triggers``) | A boolean array that specifies if a shower contributed to an event that fulfills a certain trigger. The index of the trigger can be translated to the trigger name via the attribute ``trigger_names``. - ``multiple_triggers_per_event`` | (``n_events``, ``n_triggers``) | A boolean array that specifies if each event fulfilled a certain trigger. The index of the trigger can be translated to the trigger name via the attribute ``trigger_names``. - ``polarization`` | (``n_shower``, ``n_channels``, ``n_ray_tracing_solutions``, ``3``) | 3D (Cartesian) coordinates of the polarization vector + ``multiple_triggers_per_event`` | (``n_events``, ``n_triggers``) | A boolean array that specifies if each event fulfilled a certain trigger. The index of the trigger can be translated to the trigger name via the attribute ``trigger_names``. + ``polarization`` | (``n_showers``, ``n_channels``, ``n_ray_tracing_solutions``, ``3``) | 3D (Cartesian) coordinates of the polarization vector ``ray_tracing_C0`` | (``n_showers``, ``n_channels``, ``n_ray_tracing_solutions``) | One of two parameters specifying the **analytic** ray tracing solution. Can be used to retrieve the solutions without having to re-run the ray tracer. ``ray_tracing_C1`` | (``n_showers``, ``n_channels``, ``n_ray_tracing_solutions``) | One of two parameters specifying the **analytic** ray tracing solution. Can be used to retrieve the solutions without having to re-run the ray tracer. ``ray_tracing_reflection`` | (``n_showers``, ``n_channels``, ``n_ray_tracing_solutions``) | ``ray_tracing_reflection_case`` | (``n_showers``, ``n_channels``, ``n_ray_tracing_solutions``) | ``ray_tracing_solution_type`` | (``n_showers``, ``n_channels``, ``n_ray_tracing_solutions``) | ``receive_vectors`` | (``n_showers``, ``n_channels``, ``n_ray_tracing_solutions``, ``3``) | 3D (Cartesian) coordinates of the receive vector of each ray tracing solution, per shower and channel. - ``shower_id`` | (``n_showers``,) | - ``time_shower_and_ray`` | (``n_showers``, ``n_channels``, ``n_ray_tracing_solutions``) | + ``shower_id`` | (``n_showers``,) | + ``time_shower_and_ray`` | (``n_showers``, ``n_channels``, ``n_ray_tracing_solutions``) | ``travel_distances`` | (``n_showers``, ``n_channels``, ``n_ray_tracing_solutions``) | The distance travelled by each ray tracing solution to a specific channel ``travel_times`` | (``n_showers``, ``n_channels``, ``n_ray_tracing_solutions``) | The time travelled by each ray tracing solution to a specific channel ``triggered`` | (``n_showers``,) | Whether each shower contributed to an event that satisfied any trigger condition From f5e8ef4c8e2e6bcb01328b3282eb3e819aa50508 Mon Sep 17 00:00:00 2001 From: Sjoerd Bouma Date: Thu, 19 Jan 2023 15:05:16 +0100 Subject: [PATCH 077/418] update reference files (attempt 2) --- .../1e18_output_ARZ_reference.hdf5 | Bin 91720 -> 90192 bytes .../1e18_output_noise_reference.hdf5 | Bin 98224 -> 104304 bytes .../SingleEvents/1e18_output_reference.hdf5 | Bin 98224 -> 104304 bytes .../test/SingleEvents/MB_1e18_reference.hdf5 | Bin 354720 -> 357024 bytes 4 files changed, 0 insertions(+), 0 deletions(-) diff --git a/NuRadioMC/test/SingleEvents/1e18_output_ARZ_reference.hdf5 b/NuRadioMC/test/SingleEvents/1e18_output_ARZ_reference.hdf5 index 13cb484e8f24da9bb49a197394a6427a613ce850..d3dae44d262942a96383064641c917e47514207a 100644 GIT binary patch delta 6851 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 A_y7O^ diff --git a/NuRadioMC/test/SingleEvents/1e18_output_noise_reference.hdf5 b/NuRadioMC/test/SingleEvents/1e18_output_noise_reference.hdf5 index e68a3ff164ca27b2282b981e8f210011e98d8933..16958b75073b5d451ef93e1f4905566ac4df39eb 100644 GIT binary patch delta 8694 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 S$#R7s3E)hot6^e?>3;#W$4LkP diff --git a/NuRadioMC/test/SingleEvents/MB_1e18_reference.hdf5 b/NuRadioMC/test/SingleEvents/MB_1e18_reference.hdf5 index 7a1baf751498ef95fe32b3828f31ce9ccee7cdc3..6dc677b2d6ad93c5c99812cec3f3eaaf73832141 100644 GIT binary patch delta 43236 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 Date: Fri, 20 Jan 2023 12:07:57 +0100 Subject: [PATCH 078/418] fix typo in get_decays --- NuRadioMC/EvtGen/NuRadioProposal.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NuRadioMC/EvtGen/NuRadioProposal.py b/NuRadioMC/EvtGen/NuRadioProposal.py index ca10c7f84..1eebe940b 100644 --- a/NuRadioMC/EvtGen/NuRadioProposal.py +++ b/NuRadioMC/EvtGen/NuRadioProposal.py @@ -682,7 +682,7 @@ def get_decays(self, decay_energy = np.sum(decay_energies) * units.MeV # TODO: Is it physical to repeat the propagation until a decay (before the energy of low) happened? - if (len(decay_particle) == 0): + if (len(decay_particles) == 0): decay_prop = (None, None) continue From aabedecfbd71f6af8f3cb67ed55aab7e13d1f37c Mon Sep 17 00:00:00 2001 From: lpyras Date: Fri, 20 Jan 2023 22:34:16 +0100 Subject: [PATCH 079/418] rename n_shower of station to m_shower, make shorter lines in table --- .../source/NuRadioMC/pages/HDF5_structure.rst | 84 ++++++++++--------- 1 file changed, 43 insertions(+), 41 deletions(-) diff --git a/documentation/source/NuRadioMC/pages/HDF5_structure.rst b/documentation/source/NuRadioMC/pages/HDF5_structure.rst index 25cd9c788..27b5517dd 100644 --- a/documentation/source/NuRadioMC/pages/HDF5_structure.rst +++ b/documentation/source/NuRadioMC/pages/HDF5_structure.rst @@ -58,13 +58,15 @@ The top-level attributes can be accessed using ``f.attrs``. These contain: :widths: auto :delim: | - ``NuRadioMC_EvtGen_version`` ``NuRadioMC_EvtGen_version_hash`` ``NuRadioMC_version`` ``NuRadioMC_version_hash`` | Hashes + ``NuRadioMC_EvtGen_version`` ``NuRadioMC_EvtGen_version_hash`` | Hashes + ``NuRadioMC_version`` ``NuRadioMC_version_hash`` | Hashes ``Emin`` ``Emax`` | Define energy range for neutrino energies ``phimax`` ``phimin`` | Define azimuth range for incoming neutrino directions ``thetamax`` ``thetamin`` | Define zenith range for incoming neutrino directions ``flavors`` | A list of particle flavors that were simulated, using the PDG convention. ``n_events`` | Total number of generated/simulated events(including those that did not trigger) - ``fiducial_rmax`` ``fiducial_rmin`` ``fiducial_zmax`` ``fiducial_zmin`` or ``fiducial_xmax`` ``fiducial_xmin`` ``fiducial_ymax`` ``fiducial_ymin`` ``fiducial_zmax`` ``fiducial_zmin`` | Specify the simulated cylindrical/quadratic fiducial volume. An event has to produce an interaction within this volume. However, in case of a muon or tau CC interaction the first interaction can occur outside + ``fiducial_xmax`` ``fiducial_xmin`` ``fiducial_ymax`` ``fiducial_ymin`` ``fiducial_zmax`` ``fiducial_zmin`` | Specify the simulated qubic fiducial volume. An event has to produce an interaction within this volume. However, in case of a muon or tau CC interaction the first interaction can occur outside + or ``fiducial_rmax`` ``fiducial_rmin`` ``fiducial_zmax`` ``fiducial_zmin`` | Specify the simulated cylindrical fiducial volume. An event has to produce an interaction within this volume. However, in case of a muon or tau CC interaction the first interaction can occur outside ``rmax`` ``rmin`` ``zmax`` ``zmin`` or ``xmax`` ``xmin`` ``ymax`` ``ymin`` ``zmax`` ``zmin`` | Specify the cylindrical/quadratic volume in which neutrino interactions are generated ``volume`` | Volume of the above specified volume ``area`` | Surface area of the above specified volume @@ -91,29 +93,29 @@ is the number of showers (which may be larger than the number of events), and `` :widths: auto :delim: | - ``event_group_ids`` | (``n_showers``,) | Specifies the event id to which the corresponding shower belongs (``n_events = len(unique(event_group_ids)))``) - ``xx`` ``yy`` ``zz`` | (``n_showers``,) | Specifying coordinates of interaction vertices - ``vertex_times`` | (``n_showers``,) | Time at the interaction vertex. The neutrino interaction (= first interaction) is defined as time 0 - ``azimuths`` ``zeniths`` | (``n_showers``,) | Angle Specifying the neutrino incoming direction (``azimuths = 0`` points east) - ``energies`` | (``n_showers``,) | Energy of the parent particle of a shower. This is typically the energy of the neutrino (for showers produced at the first interaction: all flavor NC, electron CC interactions) or the energy of a muon or tau lepton when those are producing secondary energy losses - ``shower_energies`` | (``n_showers``,) | Energy of the shower which is used to determine the radio emission - ``flavors`` | (``n_showers``,) | Same as above (the parent of an electromagnetic cascade in an electron CC interaction is the neutrino) - ``inelasticity`` | (``n_showers``,) | Inelasticity of the first interaction - ``interaction_type`` | (``n_showers``,) | Interaction type producing the shower (for the first interaction that can be "nc" or "cc") + ``event_group_ids`` | (``n_showers``) | Specifies the event id to which the corresponding shower belongs (``n_events = len(unique(event_group_ids)))``) + ``xx`` ``yy`` ``zz`` | (``n_showers``) | Specifying coordinates of interaction vertices + ``vertex_times`` | (``n_showers``) | Time at the interaction vertex. The neutrino interaction (= first interaction) is defined as time 0 + ``azimuths`` ``zeniths`` | (``n_showers``) | Angle Specifying the neutrino incoming direction (``azimuths = 0`` points east) + ``energies`` | (``n_showers``) | Energy of the parent particle of a shower. This is typically the energy of the neutrino (for showers produced at the first interaction: all flavor NC, electron CC interactions) or the energy of a muon or tau lepton when those are producing secondary energy losses + ``shower_energies`` | (``n_showers``) | Energy of the shower which is used to determine the radio emission + ``flavors`` | (``n_showers``) | Same as above (the parent of an electromagnetic cascade in an electron CC interaction is the neutrino) + ``inelasticity`` | (``n_showers``) | Inelasticity of the first interaction + ``interaction_type`` | (``n_showers``) | Interaction type producing the shower (for the first interaction that can be "nc" or "cc") ``multiple_triggers`` | (``n_showers``, ``n_triggers``) | Information which exact trigger fired each shower. The different triggers are specified in the attributes (``f.attrs["triggers"]``). The order of ``f.attrs["triggers"]`` matches that in ``multiple_triggers`` - ``triggered`` | (``n_showers``,) | boolean; ``True`` if any trigger fired for this shower, ``False`` otherwise - ``n_interaction`` | (``n_showers``,) | Hierarchical counter for the number of showers per event (also accounts for showers which did not trigger and might not be saved) - ``shower_ids`` | (``n_showers``,) | Hierarchical counter for the number of triggered showers - ``shower_realization_ARZ`` | (``n_showers``,) | Which realization from the ARZ shower library was used for each shower (only if ARZ was used for signal generation). - ``shower_type`` | (``n_showers``,) | Type of the shower (so far we only have "em" and "had") - ``weights`` | (``n_showers``,) | Weight for the probability that the neutrino reached the interaction vertex taking into account the attenuation from the earth (Does not include interaction probability in the volume) + ``triggered`` | (``n_showers``) | A boolean; ``True`` if any trigger fired for this shower, ``False`` otherwise + ``n_interaction`` | (``n_showers``) | Hierarchical counter for the number of showers per event (also accounts for showers which did not trigger and might not be saved) + ``shower_ids`` | (``n_showers``) | Hierarchical counter for the number of triggered showers + ``shower_realization_ARZ`` | (``n_showers``) | Which realization from the ARZ shower library was used for each shower (only if ARZ was used for signal generation). + ``shower_type`` | (``n_showers``) | Type of the shower (so far we only have "em" and "had") + ``weights`` | (``n_showers``) | Weight for the probability that the neutrino reached the interaction vertex taking into account the attenuation from the earth (Does not include interaction probability in the volume) Station data ____________ In addition, the HDF5 file contains a key for each station in the simulation. The station contains more detailed information for each event that triggered it: -``n_events`` and ``n_showers`` refer to the number of events and showers that triggered the station. +``m_events`` and ``m_showers`` refer to the number of events and showers that triggered the station. The ``event_group_id`` is the same as in the global dictionary. Therefore you can check for one event with an ``event_group_id`` which stations contain the same ``event_group_id`` and retrieve the information, which station triggered, with which amplitude, etc. The same approach works for ``shower_id``. @@ -125,27 +127,27 @@ station triggered, with which amplitude, etc. The same approach works for ``show :widths: auto :delim: | - ``event_group_ids`` | (``n_events``,) | event group ids of the triggered events - ``event_group_id_per_shower`` | (``n_showers``) | - ``event_ids`` | (``n_events``,) | the event ids of each event. These are unique only within each separate event group, and start from 0. - ``event_id_per_shower`` | (``n_showers``) | - ``focusing_factor`` | (``n_showers``, ``n_channels``, ``n_ray_tracing_solutions``) | - ``launch_vectors`` | (``n_showers``, ``n_channels``, ``n_ray_tracing_solutions``, ``3``) | 3D (Cartesian) coordinates of the launch vector of each ray tracing solution, per shower and channel. - ``max_amp_shower_and_ray`` | (``n_showers``, ``n_channels``, ``n_ray_tracing_solutions``) | Maximum amplitude per shower, channel and ray tracing solution. - ``maximum_amplitudes`` | (``n_events``, ``n_channels``) | Maximum amplitude per event and channel - ``maximum_amplitudes_envelope`` | (``n_events``, ``n_channels``) | Maximum amplitude of the hilbert envelope for each event and channel - ``multiple_triggers`` | (``n_showers``, ``n_triggers``) | A boolean array that specifies if a shower contributed to an event that fulfills a certain trigger. The index of the trigger can be translated to the trigger name via the attribute ``trigger_names``. - ``multiple_triggers_per_event`` | (``n_events``, ``n_triggers``) | A boolean array that specifies if each event fulfilled a certain trigger. The index of the trigger can be translated to the trigger name via the attribute ``trigger_names``. - ``polarization`` | (``n_showers``, ``n_channels``, ``n_ray_tracing_solutions``, ``3``) | 3D (Cartesian) coordinates of the polarization vector - ``ray_tracing_C0`` | (``n_showers``, ``n_channels``, ``n_ray_tracing_solutions``) | One of two parameters specifying the **analytic** ray tracing solution. Can be used to retrieve the solutions without having to re-run the ray tracer. - ``ray_tracing_C1`` | (``n_showers``, ``n_channels``, ``n_ray_tracing_solutions``) | One of two parameters specifying the **analytic** ray tracing solution. Can be used to retrieve the solutions without having to re-run the ray tracer. + ``event_group_ids`` | (``m_events``) | The event group ids of the triggered events in the selected station + ``event_group_id_per_shower`` | (``m_showers``) | The event group id of every shower that triggered the selected station + ``event_ids`` | (``m_events``) | tThe event ids of each event that triggered in that station for every event group id. These are unique only within each separate event group, and start from 0. + ``event_id_per_shower`` | (``m_showers``) | The event ids of each event that triggered in that station. This one is for every shower + ``focusing_factor`` | (``m_showers``, ``n_channels``, ``n_ray_tracing_solutions``) | + ``launch_vectors`` | (``m_showers``, ``n_channels``, ``n_ray_tracing_solutions``, ``3``) | 3D (Cartesian) coordinates of the launch vector of each ray tracing solution, per shower and channel. + ``max_amp_shower_and_ray`` | (``m_showers``, ``n_channels``, ``n_ray_tracing_solutions``) | Maximum amplitude per shower, channel and ray tracing solution. + ``maximum_amplitudes`` | (``m_events``, ``n_channels``) | Maximum amplitude per event and channel + ``maximum_amplitudes_envelope`` | (``m_events``, ``n_channels``) | Maximum amplitude of the hilbert envelope for each event and channel + ``multiple_triggers`` | (``m_showers``, ``n_triggers``) | A boolean array that specifies if a shower contributed to an event that fulfills a certain trigger. The index of the trigger can be translated to the trigger name via the attribute ``trigger_names``. + ``multiple_triggers_per_event`` | (``m_events``, ``n_triggers``) | A boolean array that specifies if each event fulfilled a certain trigger. The index of the trigger can be translated to the trigger name via the attribute ``trigger_names``. + ``polarization`` | (``m_showers``, ``n_channels``, ``n_ray_tracing_solutions``, ``3``) | 3D (Cartesian) coordinates of the polarization vector + ``ray_tracing_C0`` | (``m_showers``, ``n_channels``, ``n_ray_tracing_solutions``) | One of two parameters specifying the **analytic** ray tracing solution. Can be used to retrieve the solutions without having to re-run the ray tracer. + ``ray_tracing_C1`` | (``m_showers``, ``n_channels``, ``n_ray_tracing_solutions``) | One of two parameters specifying the **analytic** ray tracing solution. Can be used to retrieve the solutions without having to re-run the ray tracer. ``ray_tracing_reflection`` | (``n_showers``, ``n_channels``, ``n_ray_tracing_solutions``) | - ``ray_tracing_reflection_case`` | (``n_showers``, ``n_channels``, ``n_ray_tracing_solutions``) | - ``ray_tracing_solution_type`` | (``n_showers``, ``n_channels``, ``n_ray_tracing_solutions``) | - ``receive_vectors`` | (``n_showers``, ``n_channels``, ``n_ray_tracing_solutions``, ``3``) | 3D (Cartesian) coordinates of the receive vector of each ray tracing solution, per shower and channel. - ``shower_id`` | (``n_showers``,) | - ``time_shower_and_ray`` | (``n_showers``, ``n_channels``, ``n_ray_tracing_solutions``) | - ``travel_distances`` | (``n_showers``, ``n_channels``, ``n_ray_tracing_solutions``) | The distance travelled by each ray tracing solution to a specific channel - ``travel_times`` | (``n_showers``, ``n_channels``, ``n_ray_tracing_solutions``) | The time travelled by each ray tracing solution to a specific channel - ``triggered`` | (``n_showers``,) | Whether each shower contributed to an event that satisfied any trigger condition - ``triggered_per_event`` | (``n_events``,) | Whether each event fulfilled any trigger condition. + ``ray_tracing_reflection_case`` | (``m_showers``, ``n_channels``, ``n_ray_tracing_solutions``) | + ``ray_tracing_solution_type`` | (``m_showers``, ``n_channels``, ``n_ray_tracing_solutions``) | + ``receive_vectors`` | (``m_showers``, ``n_channels``, ``n_ray_tracing_solutions``, ``3``) | 3D (Cartesian) coordinates of the receive vector of each ray tracing solution, per shower and channel. + ``shower_id`` | (``m_showers``) | The Shower ids of showers that triggered the selected station + ``time_shower_and_ray`` | (``m_showers``, ``n_channels``, ``n_ray_tracing_solutions``) | + ``travel_distances`` | (``m_showers``, ``n_channels``, ``n_ray_tracing_solutions``) | The distance travelled by each ray tracing solution to a specific channel + ``travel_times`` | (``m_showers``, ``n_channels``, ``n_ray_tracing_solutions``) | The time travelled by each ray tracing solution to a specific channel + ``triggered`` | (``m_showers``,) | Whether each shower contributed to an event that satisfied any trigger condition + ``triggered_per_event`` | (``m_events``) | Whether each event fulfilled any trigger condition. From adc79edfb17c38ca0caf858a1ba83ed625e645c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Sat, 21 Jan 2023 10:20:20 +0100 Subject: [PATCH 080/418] merge rows again, fix typo --- documentation/source/NuRadioMC/pages/HDF5_structure.rst | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/documentation/source/NuRadioMC/pages/HDF5_structure.rst b/documentation/source/NuRadioMC/pages/HDF5_structure.rst index 27b5517dd..e93b244f7 100644 --- a/documentation/source/NuRadioMC/pages/HDF5_structure.rst +++ b/documentation/source/NuRadioMC/pages/HDF5_structure.rst @@ -65,9 +65,8 @@ The top-level attributes can be accessed using ``f.attrs``. These contain: ``thetamax`` ``thetamin`` | Define zenith range for incoming neutrino directions ``flavors`` | A list of particle flavors that were simulated, using the PDG convention. ``n_events`` | Total number of generated/simulated events(including those that did not trigger) - ``fiducial_xmax`` ``fiducial_xmin`` ``fiducial_ymax`` ``fiducial_ymin`` ``fiducial_zmax`` ``fiducial_zmin`` | Specify the simulated qubic fiducial volume. An event has to produce an interaction within this volume. However, in case of a muon or tau CC interaction the first interaction can occur outside - or ``fiducial_rmax`` ``fiducial_rmin`` ``fiducial_zmax`` ``fiducial_zmin`` | Specify the simulated cylindrical fiducial volume. An event has to produce an interaction within this volume. However, in case of a muon or tau CC interaction the first interaction can occur outside - ``rmax`` ``rmin`` ``zmax`` ``zmin`` or ``xmax`` ``xmin`` ``ymax`` ``ymin`` ``zmax`` ``zmin`` | Specify the cylindrical/quadratic volume in which neutrino interactions are generated + ``fiducial_xmax`` ``fiducial_xmin`` ``fiducial_ymax`` ``fiducial_ymin`` ``fiducial_zmax`` ``fiducial_zmin`` / ``fiducial_rmax`` ``fiducial_rmin`` ``fiducial_zmax`` ``fiducial_zmin`` | Specify the simulated qubic/cylindrical fiducial volume. An event has to produce an interaction within this volume. However, in case of a muon or tau CC interaction the first interaction can occur outside + ``rmax`` ``rmin`` ``zmax`` ``zmin`` / ``xmax`` ``xmin`` ``ymax`` ``ymin`` ``zmax`` ``zmin`` | Specify the qubic/cylindrical volume in which neutrino interactions are generated ``volume`` | Volume of the above specified volume ``area`` | Surface area of the above specified volume ``start_event_id`` | ``event_id`` of the first event in the file @@ -129,7 +128,7 @@ station triggered, with which amplitude, etc. The same approach works for ``show ``event_group_ids`` | (``m_events``) | The event group ids of the triggered events in the selected station ``event_group_id_per_shower`` | (``m_showers``) | The event group id of every shower that triggered the selected station - ``event_ids`` | (``m_events``) | tThe event ids of each event that triggered in that station for every event group id. These are unique only within each separate event group, and start from 0. + ``event_ids`` | (``m_events``) | The event ids of each event that triggered in that station for every event group id. These are unique only within each separate event group, and start from 0. ``event_id_per_shower`` | (``m_showers``) | The event ids of each event that triggered in that station. This one is for every shower ``focusing_factor`` | (``m_showers``, ``n_channels``, ``n_ray_tracing_solutions``) | ``launch_vectors`` | (``m_showers``, ``n_channels``, ``n_ray_tracing_solutions``, ``3``) | 3D (Cartesian) coordinates of the launch vector of each ray tracing solution, per shower and channel. From ac5615ab2a410af2f7fd29953185a3b4c521422e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Sat, 21 Jan 2023 10:21:37 +0100 Subject: [PATCH 081/418] rm , --- documentation/source/NuRadioMC/pages/HDF5_structure.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/source/NuRadioMC/pages/HDF5_structure.rst b/documentation/source/NuRadioMC/pages/HDF5_structure.rst index e93b244f7..8300e0c99 100644 --- a/documentation/source/NuRadioMC/pages/HDF5_structure.rst +++ b/documentation/source/NuRadioMC/pages/HDF5_structure.rst @@ -148,5 +148,5 @@ station triggered, with which amplitude, etc. The same approach works for ``show ``time_shower_and_ray`` | (``m_showers``, ``n_channels``, ``n_ray_tracing_solutions``) | ``travel_distances`` | (``m_showers``, ``n_channels``, ``n_ray_tracing_solutions``) | The distance travelled by each ray tracing solution to a specific channel ``travel_times`` | (``m_showers``, ``n_channels``, ``n_ray_tracing_solutions``) | The time travelled by each ray tracing solution to a specific channel - ``triggered`` | (``m_showers``,) | Whether each shower contributed to an event that satisfied any trigger condition + ``triggered`` | (``m_showers``) | Whether each shower contributed to an event that satisfied any trigger condition ``triggered_per_event`` | (``m_events``) | Whether each event fulfilled any trigger condition. From c65ddbb8a580b22bdc1902e3778feeeae6dd3398 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Sat, 21 Jan 2023 10:34:45 +0100 Subject: [PATCH 082/418] Add link to old documentation --- .../source/NuRadioMC/pages/HDF5_structure.rst | 3 +- .../HDF5_structures_history/HDF5_v2.2.rst | 201 ++++++++++++++++++ 2 files changed, 203 insertions(+), 1 deletion(-) create mode 100644 documentation/source/NuRadioMC/pages/HDF5_structures_history/HDF5_v2.2.rst diff --git a/documentation/source/NuRadioMC/pages/HDF5_structure.rst b/documentation/source/NuRadioMC/pages/HDF5_structure.rst index 8300e0c99..44cbc6f78 100644 --- a/documentation/source/NuRadioMC/pages/HDF5_structure.rst +++ b/documentation/source/NuRadioMC/pages/HDF5_structure.rst @@ -3,7 +3,8 @@ HDF5 output structure The output of a NuRadioMC simulation is saved in the HDF5 file format, as well as (optionally) in ``.nur`` files. The data structure of ``.nur`` files is explained :doc:`here `. -This page outlines the structure of the HDF5 files. +This page outlines the structure of the HDF5 files v3.0. Find the structure of v2.2 :doc:`v2.2 `. + Opening the HDF5 file --------------------- diff --git a/documentation/source/NuRadioMC/pages/HDF5_structures_history/HDF5_v2.2.rst b/documentation/source/NuRadioMC/pages/HDF5_structures_history/HDF5_v2.2.rst new file mode 100644 index 000000000..6290e6dda --- /dev/null +++ b/documentation/source/NuRadioMC/pages/HDF5_structures_history/HDF5_v2.2.rst @@ -0,0 +1,201 @@ +HDF5 output structure +===================== + +The output of a NuRadioMC simulation is saved in the HDF5 file format, as well as (optionally) in ``.nur`` files. +The data structure of ``.nur`` files is explained :doc:`here `. +This page outlines the structure of the HDF5 files. + +Opening the HDF5 file +--------------------- +The HDF5 file can be opened using the ``h5py`` module: + +.. code-block:: Python + + import h5py + + f = h5py.File("/path/to/hdf5_file", mode='r') + attributes = f.attrs + + (...) + f.close() + +If you have many HDF5 files, for example because you ran a simulation parallelized over multiple energy bins, +NuRadioMC contains a convenience function to correctly merge these files - +see :ref:`here ` for instructions. + +What's behind the HDF5 files +---------------------------- +The hdf5 file is created in NuRadioMC/simulation/simulation.py A list of vertices with different arrival direction +(zenith and azimuth) and energy is provided by the event generator. Starting from the vertex, several sub-showers are +created along the track. These are not simulated, but the electric field per sub-shower is provided. Sub-showers that +happen within a certain time interval arrive at the antenna simultaneous and interfere constructively, therefore, +they are summed up. + +The ``event_group_id`` is the same for all showers that follow the same first interaction. +The ``shower_id`` is unique for every shower. Shower which interfere constructively are combined into one event and have +the same ``event_id`` starting from 0. + + .. image:: event_sketch.png + :width: 70% + +HDF5 structure +-------------- +The HDF5 files can be thought of as a structured dictionary: + +- The top level :ref:`attributes `, which can be accessed through ``f.attrs``, contain some top-level information about the simulation. +- The :ref:`individual keys ` contain some properties (energy, vertex, ...) for each stored event or shower. +- Finally, the ``station_`` key contains slightly more detailed information (triggers, propagation times, amplitudes...) at the level of individual channels :ref:`for each station `. + +HDF5 file attributes +____________________ + +The top-level attributes can be accessed using ``f.attrs``. These contain: + +* ``Emax``, ``Emin`` + + maximum and minimum energy simulated +* ``NuRadioMC_EvtGen_version``, ``NuRadioMC_EvtGen_version_hash`` +* ``NuRadioMC_version``, ``NuRadioMC_version_hash`` +* ``Tnoise`` + + (explicit) noise temperature used in simulation +* ``Vrms`` +* ``area`` +* ``bandwidth`` +* ``config`` + + the (yaml-style) config file used for the simulation +* ``deposited`` +* ``detector`` + + the (json-format) detector description used for the simulation +* ``dt`` + + the time resolution, i.e. the inverse of the sampling rate used for the simulation. + This is not necessarily the same as the sampling rate of the simulated channels! +* ``fiducial_rmax``, ``fiducial_rmin``, ``fiducial_zmax``, ``fiducial_zmin`` + + Specify the simulated fiducial volume +* ``flavors`` + + a list of particle flavors that were simulated, using the PDG convention. +* ``n_events`` + + total number of events simulated (including those that did not trigger) +* ``n_samples`` +* ``phimax``, ``phimin`` +* ``rmax``, ``rmin`` +* ``start_event_id`` + + ``event_id`` of the first event in the file +* ``thetamax``, ``thetamin`` +* ``trigger_names`` + + list of the names of the different triggers simulated +* ``volume`` +* ``zmax``, ``zmin`` + +HDF5 file contents +__________________ +The HDF5 file contains the following items. Listed are the ``key`` and the ``shape`` of +each HDF5 dataset, where ``n_events`` is the number of events in the file, ``n_showers`` +is the number of showers (which may be larger than the number of events), and ``n_triggers`` +is the number of different triggers simulated. + +* ``azimuths``: (``n_events``,) +* ``energies``: (``n_events``,) +* ``event_group_ids``: (``n_events``,) +* ``flavors``: (``n_events``,) +* ``inelasticity``: (``n_events``,) +* ``interaction_type``: (``n_events``,) +* ``multiple_triggers``: (``n_events``, ``n_triggers``) +* ``n_interaction``: (``n_events``,) +* ``shower_energies``: (``n_showers``,) +* ``shower_ids``: (``n_showers``,) +* ``shower_realization_ARZ``: (``n_showers``,) + + Which realization from the ARZ shower library was used for each shower (only if ARZ + was used for signal generation). +* ``shower_type``: (``n_showers``,) +* ``triggered``: (``n_events``,) + + boolean; ``True`` if the event triggered on any trigger, ``False`` otherwise +* ``vertex_times``: (``n_events``,) +* ``weights``: (``n_events``,) +* ``xx``: (``n_events``,) +* ``yy``: (``n_events``,) +* ``zeniths``: (``n_events``,) +* ``zz``: (``n_events``,) + +Station data +____________ +In addition, the HDF5 file contains a key for each station in the simulation. +The station contains more detailed information for each event that triggered it: +``n_events`` and ``n_shower`` refer to the number of events and showers that triggered the station. +The ``event_group_id`` is the same as in the global dictionary. Therefore you can check for one event with +an ``event_group_id`` which stations contain the same ``event_group_id`` and retrieve the information, which +station triggered, with which amplitude, etc. The same approach works for ``shower_id``. + +* ``event_group_ids``: (``n_events``) +* ``event_group_id_per_shower'``: (``n_shower``) + + event group ids of the triggered events +* ``event_ids``: (``n_events``) +* ``event_id_per_shower``: (``n_shower``) + + the event ids of each event. These are unique only within each separate event group, + and start from 0. +* ``focusing_factor``: (``n_showers``, ``n_channels``, ``n_ray_tracing_solutions``) +* ``launch_vectors``: (``n_showers``, ``n_channels``, ``n_ray_tracing_solutions``, 3) + + 3D (Cartesian) coordinates of the launch vector of each ray tracing solution, + per shower and channel. +* ``max_amp_shower_and_ray``: (``n_showers``, ``n_channels``, ``n_ray_tracing_solutions``) + + Maximum amplitude per shower, channel and ray tracing solution. +* ``maximum_amplitudes``: (``n_events``, ``n_channels``) + + Maximum amplitude per event and channel +* ``maximum_amplitudes_envelope``: (``n_events``, ``n_channels``) + + Maximum amplitude of the hilbert envelope for each event and channel +* ``multiple_triggers``: (``n_showers``, ``n_triggers``) + + a boolean array that specifies if a shower contributed to an event that fulfills a certain trigger. + The index of the trigger can be translated to the trigger name via the attribute ``trigger_names``. +* ``multiple_triggers_per_event``: (``n_events``, ``n_triggers``) + + a boolean array that specifies if each event fulfilled a certain trigger. + The index of the trigger can be translated to the trigger name via the attribute ``trigger_names``. +* ``polarization``: (``n_shower``, ``n_channels``, ``n_ray_tracing_solutions``, 3) + + 3D (Cartesian) coordinates of the polarization vector +* ``ray_tracing_C0``: (``n_showers``, ``n_channels``, ``n_ray_tracing_solutions``) + + One of two parameters specifying the **analytic** ray tracing solution. + Can be used to retrieve the solutions without having to re-run the ray tracer. +* ``ray_tracing_C1``: (``n_showers``, ``n_channels``, ``n_ray_tracing_solutions``) + + One of two parameters specifying the **analytic** ray tracing solution. + Can be used to retrieve the solutions without having to re-run the ray tracer. +* ``ray_tracing_reflection``: (``n_showers``, ``n_channels``, ``n_ray_tracing_solutions``) +* ``ray_tracing_reflection_case``: (``n_showers``, ``n_channels``, ``n_ray_tracing_solutions``) +* ``ray_tracing_solution_type``: (``n_showers``, ``n_channels``, ``n_ray_tracing_solutions``) +* ``receive_vectors``: (``n_showers``, ``n_channels``, ``n_ray_tracing_solutions``, 3) + + 3D (Cartesian) coordinates of the receive vector of each ray tracing solution, + per shower and channel. +* ``shower_id``: (``n_showers``,) +* ``time_shower_and_ray``: (``n_showers``, ``n_channels``, ``n_ray_tracing_solutions``) +* ``travel_distances``: (``n_showers``, ``n_channels``, ``n_ray_tracing_solutions``) + + The distance travelled by each ray tracing solution to a specific channel +* ``travel_times``: (``n_showers``, ``n_channels``, ``n_ray_tracing_solutions``) + + The time travelled by each ray tracing solution to a specific channel +* ``triggered``: (``n_showers``,) + + Whether or not each shower contributed to an event that satisfied any trigger condition +* ``triggered_per_event``: (``n_events``,) + + Whether or not each event fulfilled any trigger condition. From 33acbb05f381a8c5e1a390413946eaabb10d9e39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Sat, 21 Jan 2023 11:35:14 +0100 Subject: [PATCH 083/418] Add sanity check that valid flavors are input --- NuRadioMC/EvtGen/generator.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/NuRadioMC/EvtGen/generator.py b/NuRadioMC/EvtGen/generator.py index ff308a919..7ef14b03b 100644 --- a/NuRadioMC/EvtGen/generator.py +++ b/NuRadioMC/EvtGen/generator.py @@ -1177,6 +1177,12 @@ def generate_eventlist_cylinder(filename, n_events, Emin, Emax, max_n_events_batch = int(max_n_events_batch) attributes = {} n_events = int(n_events) + + # sanity check + for f in flavor: + if f not in [12, -12, 14, -14, 16, -16]: + logger.error(f"Input illegal flavor: {flavor}") + raise ValueError(f"Input illegal flavor: {flavor}") # save current NuRadioMC version as attribute # save NuRadioMC and NuRadioReco versions From 11d864116ec476b603343fca60c8d12c00e10526 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Sat, 21 Jan 2023 11:45:55 +0100 Subject: [PATCH 084/418] Some more style refactoring and code simplification --- NuRadioMC/EvtGen/generator.py | 39 +++++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/NuRadioMC/EvtGen/generator.py b/NuRadioMC/EvtGen/generator.py index 7ef14b03b..de3a0cc2f 100644 --- a/NuRadioMC/EvtGen/generator.py +++ b/NuRadioMC/EvtGen/generator.py @@ -1169,11 +1169,14 @@ def generate_eventlist_cylinder(filename, n_events, Emin, Emax, """ rnd = Generator(Philox(seed)) t_start = time.time() - if(log_level is not None): + + if log_level is not None: logger.setLevel(log_level) + if proposal: from NuRadioMC.EvtGen.NuRadioProposal import ProposalFunctions proposal_functions = ProposalFunctions(config_file=proposal_config) + max_n_events_batch = int(max_n_events_batch) attributes = {} n_events = int(n_events) @@ -1209,15 +1212,17 @@ def generate_eventlist_cylinder(filename, n_events, Emin, Emax, n_batches = int(np.ceil(n_events / max_n_events_batch)) for i_batch in range(n_batches): # do generation of events in batches n_events_batch = max_n_events_batch - if(i_batch + 1 == n_batches): # last batch? + + if i_batch + 1 == n_batches: # last batch? n_events_batch = n_events - (i_batch * max_n_events_batch) + logger.info(f"processing batch {i_batch+1:.2g}/{n_batches:.2g} with {n_events_batch:.2g} events") data_sets["xx"], data_sets["yy"], data_sets["zz"] = generate_vertex_positions(attributes=attributes, n_events=n_events_batch, rnd=rnd) data_sets["azimuths"] = rnd.uniform(phimin, phimax, n_events_batch) data_sets["zeniths"] = np.arccos(rnd.uniform(np.cos(thetamax), np.cos(thetamin), n_events_batch)) - # fmask = (rr_full >= fiducial_rmin) & (rr_full <= fiducial_rmax) & (data_sets["zz"] >= fiducial_zmin) & (data_sets["zz"] <= fiducial_zmax) # fiducial volume mask + # fmask = (rr_full >= fiducial_rmin) & (rr_full <= fiducial_rmax) & (data_sets["zz"] >= fiducial_zmin) & (data_sets["zz"] <= fiducial_zmax) # fiducial volume mask logger.debug("generating event ids") data_sets["event_group_ids"] = np.arange(i_batch * max_n_events_batch, i_batch * max_n_events_batch + n_events_batch) + start_event_id @@ -1233,13 +1238,14 @@ def generate_eventlist_cylinder(filename, n_events, Emin, Emax, data_sets["energies"] = get_energies(n_events_batch, Emin, Emax, spectrum, rnd) # generate charged/neutral current randomly logger.debug("interaction type") - if(interaction_type == "ccnc"): + if interaction_type == "ccnc": data_sets["interaction_type"] = inelasticities.get_ccnc(n_events_batch, rnd=rnd) - elif(interaction_type == "cc"): - data_sets["interaction_type"] = np.full(n_events_batch, "cc", dtype='U2') - elif(interaction_type == "nc"): - data_sets["interaction_type"] = np.full(n_events_batch, "nc", dtype='U2') - + elif interaction_type == "cc" or interaction_type == "nc": + data_sets["interaction_type"] = np.full(n_events_batch, interaction_type, dtype='U2') + else: + logger.error(f"Input illegal interaction type: {interaction_type}") + raise ValueError(f"Input illegal interaction type: {interaction_type}") + # generate inelasticity logger.debug("generating inelasticities") data_sets["inelasticity"] = inelasticities.get_neutrino_inelasticity(n_events_batch, rnd=rnd) @@ -1290,18 +1296,17 @@ def generate_eventlist_cylinder(filename, n_events, Emin, Emax, # we need to be careful to not double cound events. electron CC interactions apear twice in the event list # because of the two distinct showers that get created. Because second interactions are only calculated # for mu and tau cc interactions, this is not a problem. - mask_tau_cc = (data_sets["interaction_type"] == 'cc') & (np.abs(data_sets["flavors"]) == 16) - mask_mu_cc = (data_sets["interaction_type"] == 'cc') & (np.abs(data_sets["flavors"]) == 14) - mask_leptons = mask_tau_cc | mask_mu_cc + mask_tracks = data_sets["interaction_type"] == 'cc' & np.abs(data_sets["flavors"]) != 12 E_all_leptons = (1 - data_sets["inelasticity"]) * data_sets["energies"] lepton_codes = copy.copy(data_sets["flavors"]) + # convert neutrino flavors (makes only sense for cc interaction which is ensured with "mask_leptons") lepton_codes = lepton_codes - 1 * np.sign(lepton_codes) - if("fiducial_rmax" in attributes): + if "fiducial_rmax" in attributes: mask_phi = mask_arrival_azimuth(data_sets, attributes['fiducial_rmax']) - mask_leptons = mask_leptons & mask_phi + mask_tracks = mask_tracks & mask_phi # TODO: combine with `get_intersection_volume_neutrino` function lepton_positions = np.array([data_sets["xx"], data_sets["yy"], data_sets["zz"]]).T @@ -1315,6 +1320,7 @@ def generate_eventlist_cylinder(filename, n_events, Emin, Emax, x_nu = data_sets['xx'][iE] y_nu = data_sets['yy'][iE] z_nu = data_sets['zz'][iE] + # Appending event if it interacts within the fiducial volume if is_in_fiducial_volume(attributes, np.array([x_nu, y_nu, z_nu])): for key in iterkeys(data_sets): @@ -1322,7 +1328,7 @@ def generate_eventlist_cylinder(filename, n_events, Emin, Emax, first_inserted = True - if mask_leptons[iE]: + if mask_tracks[iE]: geometry_selection = get_intersection_volume_neutrino( attributes, [x_nu, y_nu, z_nu], lepton_directions[iE]) @@ -1340,7 +1346,6 @@ def generate_eventlist_cylinder(filename, n_events, Emin, Emax, if is_in_fiducial_volume(attributes, np.array([x, y, z])): # the energy loss or particle is in our fiducial volume - # If the energy loss or particle is in the fiducial volume but the parent # neutrino does not interact there, we add it to know its properties. if not first_inserted: @@ -1357,6 +1362,7 @@ def generate_eventlist_cylinder(filename, n_events, Emin, Emax, n_interaction += 1 data_sets_fiducial['shower_energies'][-1] = product.energy data_sets_fiducial['inelasticity'][-1] = np.nan + # interaction_type is either 'had' or 'em' for proposal products data_sets_fiducial['interaction_type'][-1] = product.shower_type data_sets_fiducial['shower_type'][-1] = product.shower_type @@ -1370,6 +1376,7 @@ def generate_eventlist_cylinder(filename, n_events, Emin, Emax, # Flavors are particle codes taken from NuRadioProposal.py data_sets_fiducial['flavors'][-1] = product.code + time_proposal = time.time() - init_time else: if(n_batches == 1): From df8523bd36db8fe9467f1068e49b261c8c8ff1c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Sat, 21 Jan 2023 12:52:03 +0100 Subject: [PATCH 085/418] add a few more descriptions --- documentation/source/NuRadioMC/pages/HDF5_structure.rst | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/documentation/source/NuRadioMC/pages/HDF5_structure.rst b/documentation/source/NuRadioMC/pages/HDF5_structure.rst index 44cbc6f78..a7c71bbb3 100644 --- a/documentation/source/NuRadioMC/pages/HDF5_structure.rst +++ b/documentation/source/NuRadioMC/pages/HDF5_structure.rst @@ -59,8 +59,7 @@ The top-level attributes can be accessed using ``f.attrs``. These contain: :widths: auto :delim: | - ``NuRadioMC_EvtGen_version`` ``NuRadioMC_EvtGen_version_hash`` | Hashes - ``NuRadioMC_version`` ``NuRadioMC_version_hash`` | Hashes + ``NuRadioMC_EvtGen_version`` ``NuRadioMC_EvtGen_version_hash`` ``NuRadioMC_version`` ``NuRadioMC_version_hash`` | Versions of the generator/framework as integer as hash ``Emin`` ``Emax`` | Define energy range for neutrino energies ``phimax`` ``phimin`` | Define azimuth range for incoming neutrino directions ``thetamax`` ``thetamin`` | Define zenith range for incoming neutrino directions @@ -73,9 +72,9 @@ The top-level attributes can be accessed using ``f.attrs``. These contain: ``start_event_id`` | ``event_id`` of the first event in the file ``trigger_names`` | List of the names of the different triggers simulated ``Tnoise`` | (explicit) noise temperature used in simulation - ``Vrms`` | - ``bandwidth`` | - ``n_samples`` | + ``Vrms`` | RMS of the voltage used as thermal noise floor. Determine from ``Tnoise`` and ``bandwidth`` + ``bandwidth`` | Bandwidth of the antennas/detector (for triggering) + ``n_samples`` | Samples of the to-be generated antenna signals ``config`` | The (yaml-style) config file used for the simulation ``deposited`` | ``detector`` | The (json-format) detector description used for the simulation From 0b56e4a2bb1114f91b274ef5e06a1b408f83ab15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Mon, 23 Jan 2023 11:50:50 +0100 Subject: [PATCH 086/418] Make code more explicity again --- NuRadioMC/EvtGen/generator.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/NuRadioMC/EvtGen/generator.py b/NuRadioMC/EvtGen/generator.py index de3a0cc2f..cd9eb8d5b 100644 --- a/NuRadioMC/EvtGen/generator.py +++ b/NuRadioMC/EvtGen/generator.py @@ -1296,7 +1296,9 @@ def generate_eventlist_cylinder(filename, n_events, Emin, Emax, # we need to be careful to not double cound events. electron CC interactions apear twice in the event list # because of the two distinct showers that get created. Because second interactions are only calculated # for mu and tau cc interactions, this is not a problem. - mask_tracks = data_sets["interaction_type"] == 'cc' & np.abs(data_sets["flavors"]) != 12 + mask_tau_cc = np.logical_and(data_sets["interaction_type"] == 'cc', np.abs(data_sets["flavors"]) == 16) + mask_mu_cc = np.logical_and(data_sets["interaction_type"] == 'cc', np.abs(data_sets["flavors"]) == 14) + mask_tracks = mask_tau_cc | mask_mu_cc E_all_leptons = (1 - data_sets["inelasticity"]) * data_sets["energies"] lepton_codes = copy.copy(data_sets["flavors"]) From aacc9a105cba67ef8d195043e6b6c77fcf73ecb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Mon, 23 Jan 2023 14:09:12 +0100 Subject: [PATCH 087/418] Add comment, improve doc string --- NuRadioMC/EvtGen/NuRadioProposal.py | 9 ++++----- NuRadioMC/EvtGen/generator.py | 2 +- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/NuRadioMC/EvtGen/NuRadioProposal.py b/NuRadioMC/EvtGen/NuRadioProposal.py index 1eebe940b..00c587347 100644 --- a/NuRadioMC/EvtGen/NuRadioProposal.py +++ b/NuRadioMC/EvtGen/NuRadioProposal.py @@ -550,11 +550,10 @@ def get_secondaries_array(self, Returns ------- secondaries_array: 2D-list containing SecondaryProperties objects - List containing the information on the shower-inducing secondaries. The - first dimension indicates the primary lepton and the second dimension - navigates through the secondaries produced by that primary. - - The SecondaryProperties objects are expressed in NuRadioMC units. + For each primary a list containing the information on the shower-inducing secondaries is + returned. The first dimension indicates the (index of the) primary lepton and the second dimension + navigates through the secondaries produced by that primary (time-ordered). The SecondaryProperties + properties are in NuRadioMC units. """ # Converting to PROPOSAL units diff --git a/NuRadioMC/EvtGen/generator.py b/NuRadioMC/EvtGen/generator.py index 47423d3dc..8f6a73992 100644 --- a/NuRadioMC/EvtGen/generator.py +++ b/NuRadioMC/EvtGen/generator.py @@ -959,7 +959,7 @@ def generate_surface_muons(filename, n_events, Emin, Emax, np.array([lepton_positions[iE]]), np.array([lepton_directions[iE]]), **proposal_kwargs) - products = products_array[0] + products = products_array[0] # get secondaries from first (and only) lepton n_interaction = 1 From 32b3ca9b7f17d69ba3043fd7fc9a04b2c48b1b8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= <30903175+fschlueter@users.noreply.github.com> Date: Mon, 23 Jan 2023 18:45:33 +0100 Subject: [PATCH 088/418] Update HDF5_structure.rst Fix reference --- documentation/source/NuRadioMC/pages/HDF5_structure.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/source/NuRadioMC/pages/HDF5_structure.rst b/documentation/source/NuRadioMC/pages/HDF5_structure.rst index a7c71bbb3..fa61c1b8e 100644 --- a/documentation/source/NuRadioMC/pages/HDF5_structure.rst +++ b/documentation/source/NuRadioMC/pages/HDF5_structure.rst @@ -3,7 +3,7 @@ HDF5 output structure The output of a NuRadioMC simulation is saved in the HDF5 file format, as well as (optionally) in ``.nur`` files. The data structure of ``.nur`` files is explained :doc:`here `. -This page outlines the structure of the HDF5 files v3.0. Find the structure of v2.2 :doc:`v2.2 `. +This page outlines the structure of the HDF5 files v3.0. Find the structure of :doc:`v2.2 `. Opening the HDF5 file From 736683a6671e6b67651a5669b5d36bf8b66a0113 Mon Sep 17 00:00:00 2001 From: lpyras Date: Mon, 23 Jan 2023 18:49:53 +0100 Subject: [PATCH 089/418] fix typo --- documentation/source/NuRadioMC/pages/HDF5_structure.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/source/NuRadioMC/pages/HDF5_structure.rst b/documentation/source/NuRadioMC/pages/HDF5_structure.rst index fa61c1b8e..6d2c8b02a 100644 --- a/documentation/source/NuRadioMC/pages/HDF5_structure.rst +++ b/documentation/source/NuRadioMC/pages/HDF5_structure.rst @@ -140,7 +140,7 @@ station triggered, with which amplitude, etc. The same approach works for ``show ``polarization`` | (``m_showers``, ``n_channels``, ``n_ray_tracing_solutions``, ``3``) | 3D (Cartesian) coordinates of the polarization vector ``ray_tracing_C0`` | (``m_showers``, ``n_channels``, ``n_ray_tracing_solutions``) | One of two parameters specifying the **analytic** ray tracing solution. Can be used to retrieve the solutions without having to re-run the ray tracer. ``ray_tracing_C1`` | (``m_showers``, ``n_channels``, ``n_ray_tracing_solutions``) | One of two parameters specifying the **analytic** ray tracing solution. Can be used to retrieve the solutions without having to re-run the ray tracer. - ``ray_tracing_reflection`` | (``n_showers``, ``n_channels``, ``n_ray_tracing_solutions``) | + ``ray_tracing_reflection`` | (``m_showers``, ``n_channels``, ``n_ray_tracing_solutions``) | ``ray_tracing_reflection_case`` | (``m_showers``, ``n_channels``, ``n_ray_tracing_solutions``) | ``ray_tracing_solution_type`` | (``m_showers``, ``n_channels``, ``n_ray_tracing_solutions``) | ``receive_vectors`` | (``m_showers``, ``n_channels``, ``n_ray_tracing_solutions``, ``3``) | 3D (Cartesian) coordinates of the receive vector of each ray tracing solution, per shower and channel. From 9d3a4ad6ab0a72f96ee88a27b5226158b718f4ef Mon Sep 17 00:00:00 2001 From: Steffen Hallmann Date: Mon, 23 Jan 2023 23:45:47 +0100 Subject: [PATCH 090/418] remove old proposal files in examples/tests/docu --- NuRadioMC/EvtGen/generate_cylinder.py | 10 +- NuRadioMC/EvtGen/generator.py | 18 +- .../06_webinar/W01_create_input_extended.py | 11 +- .../06_webinar/config_PROPOSAL_greenland.json | 205 ------------------ .../EvtGen/config_PROPOSAL_greenland.json | 205 ------------------ .../EvtGen/test_generate_cylinder_proposal.sh | 2 +- .../1e18eV/T01generate_event_list.py | 2 +- .../pages/Manuals/event_generation.rst | 12 +- 8 files changed, 12 insertions(+), 453 deletions(-) delete mode 100644 NuRadioMC/examples/06_webinar/config_PROPOSAL_greenland.json delete mode 100644 NuRadioMC/test/EvtGen/config_PROPOSAL_greenland.json diff --git a/NuRadioMC/EvtGen/generate_cylinder.py b/NuRadioMC/EvtGen/generate_cylinder.py index 58a4ae415..9daea0c03 100644 --- a/NuRadioMC/EvtGen/generate_cylinder.py +++ b/NuRadioMC/EvtGen/generate_cylinder.py @@ -67,7 +67,7 @@ help='if integer, PROPOSAL generates a number of propagations equal to resample and then reuses them. Only to be used with a single kind of lepton (muon or tau)') parser.add_argument('--proposal_config', type=str, default="SouthPole", help="""The user can specify the path to their own config file or choose among - the three available options: + the available options: -'SouthPole', a config file for the South Pole (spherical Earth). It consists of a 2.7 km deep layer of ice, bedrock below and air above. -'MooresBay', a config file for Moore's Bay (spherical Earth). It @@ -75,13 +75,7 @@ and bedrock below that. -'InfIce', a config file with a medium of infinite ice -'Greenland', a config file for Summit Station, Greenland (spherical Earth), - same as SouthPole but with a 3 km deep ice layer. - IMPORTANT: If these options are used, the code is more efficient if the - user requests their own "path_to_tables" and "path_to_tables_readonly", - pointing them to a writable directory - If one of these three options is chosen, the user is supposed to edit - the corresponding config_PROPOSAL_xxx.json.sample file to include valid - table paths and then copy this file to config_PROPOSAL_xxx.json.""") + same as SouthPole but with a 3 km deep ice layer.""") parser.add_argument('--start_file_id', type=int, default=0, help="in case the data set is distributed over several files, this number specifies the id of the first file (useful if an existing data set is extended)") args = parser.parse_args() diff --git a/NuRadioMC/EvtGen/generator.py b/NuRadioMC/EvtGen/generator.py index 8f6a73992..0ec6d52a6 100644 --- a/NuRadioMC/EvtGen/generator.py +++ b/NuRadioMC/EvtGen/generator.py @@ -821,7 +821,7 @@ def generate_surface_muons(filename, n_events, Emin, Emax, if True, generate deposited energies instead of primary neutrino energies config_file: string The user can specify the path to their own config file or choose among - the three available options: + the available options: * 'SouthPole', a config file for the South Pole (spherical Earth). It consists of a 2.7 km deep layer of ice, bedrock below and air above. @@ -832,13 +832,6 @@ def generate_surface_muons(filename, n_events, Emin, Emax, * 'Greenland', a config file for Summit Station, Greenland (spherical Earth), same as SouthPole but with a 3 km deep ice layer. - .. Important:: If these options are used, the code is more efficient if the - user requests their own "path_to_tables" and "path_to_tables_readonly", - pointing them to a writable directory - If one of these three options is chosen, the user is supposed to edit - the corresponding config_PROPOSAL_xxx.json.sample file to include valid - table paths and then copy this file to config_PROPOSAL_xxx.json. - proposal_kwargs: dict additional kwargs that are passed to the get_secondaries_array function of the NuRadioProposal class log_level: logging log level or None @@ -1152,7 +1145,7 @@ def generate_eventlist_cylinder(filename, n_events, Emin, Emax, if True, the tau and muon secondaries are calculated using PROPOSAL proposal_config: string or path The user can specify the path to their own config file or choose among - the three available options: + the available options: * 'SouthPole', a config file for the South Pole (spherical Earth). It consists of a 2.7 km deep layer of ice, bedrock below and air above. @@ -1163,13 +1156,6 @@ def generate_eventlist_cylinder(filename, n_events, Emin, Emax, * 'Greenland', a config file for Summit Station, Greenland (spherical Earth), same as SouthPole but with a 3 km deep ice layer. - .. Important:: If these options are used, the code is more efficient if the - user requests their own "path_to_tables" and "path_to_tables_readonly", - pointing them to a writable directory - If one of these three options is chosen, the user is supposed to edit - the corresponding config_PROPOSAL_xxx.json.sample file to include valid - table paths and then copy this file to config_PROPOSAL_xxx.json. - start_file_id: int (default 0) in case the data set is distributed over several files, this number specifies the id of the first file (useful if an existing data set is extended) diff --git a/NuRadioMC/examples/06_webinar/W01_create_input_extended.py b/NuRadioMC/examples/06_webinar/W01_create_input_extended.py index 7e63df120..c098ac2a2 100644 --- a/NuRadioMC/examples/06_webinar/W01_create_input_extended.py +++ b/NuRadioMC/examples/06_webinar/W01_create_input_extended.py @@ -141,16 +141,11 @@ """ proposal_config defines the medium used for the lepton propagation by PROPOSAL. We have four media by default: 'SouthPole', 'MooresBay', 'Greenland' and 'InfIce', -or the user can specify a path to their own files. If the user wants one of the -default media, they have to take the corresponding config*.json.sample file, -modify the paths to the PROPOSAL tables to a valid path in their environment -where they want to save the tables used by PROPOSAL, and then rename the config -file by removing the final .sample ending. So, for instance, the file -config_PROPOSAL_greeenland.json.sample should be renamed to config_PROPOSAL_greeenland.json. +or the user can specify a path to their own files. -In this case we are going to use the Proposal config file in the present folder +In this case we are going to use the Proposal configuration for Greenland """ -proposal_config = 'config_PROPOSAL_greenland.json' +proposal_config = 'Greenland' """ start_event_id is the event id of the first event generated by the generator file. diff --git a/NuRadioMC/examples/06_webinar/config_PROPOSAL_greenland.json b/NuRadioMC/examples/06_webinar/config_PROPOSAL_greenland.json deleted file mode 100644 index 551628ec1..000000000 --- a/NuRadioMC/examples/06_webinar/config_PROPOSAL_greenland.json +++ /dev/null @@ -1,205 +0,0 @@ -{ - "global": - { - "seed" : 12, - "continous_loss_output" : false, - "only_loss_inside_detector" : false, - - "interpolation": - { - "do_interpolation" : true, - "path_to_tables" : "tables", - "path_to_tables_readonly" : "tables", - "do_binary_tables" : false, - "just_use_readonly_path" : false, - "max_node_energy" : 1e14, - "nodes_cross_section" : 100, - "nodes_continous_randomization" : 200, - "nodes_propagate" : 1000 - }, - - "exact_time" : true, - "stopping_decay" : true, - "scattering" : "NoScattering", - - "brems_multiplier" : 1, - "photo_multiplier" : 1, - "ioniz_multiplier" : 1, - "epair_multiplier" : 1, - "ioniz": "IonizBetheBlochRossi", - "epair": "EpairKelnerKokoulinPetrukhin", - "brems" : "BremsKelnerKokoulinPetrukhin", - "photo" : "PhotoAbramowiczLevinLevyMaor97", - "annihilation": "none", - "compton" : "none", - "photopair": "none", - "mupair": "none", - "weak": "none", - "lpm" : true, - "photo_hard_component" : true, - "photo_shadow" : "ShadowButkevichMikhailov", - - "cuts_infront": - { - "e_cut": 1e8, - "v_cut": -1, - "cont_rand": true - }, - "cuts_inside": - { - "e_cut": 1e8, - "v_cut": -1, - "cont_rand": false - }, - "cuts_behind": - { - "e_cut": 1e8, - "v_cut": -1, - "cont_rand": false - }, - "medium": "air", - "geometry": - { - "shape": "sphere", - "origin": [0, 0, -6374134], - "outer_radius": 1000000000, - "inner_radius": 6374134 - } - }, - - "sectors": [ - { - "hierarchy": 1, - "medium": "air", - "density_correction": 0.673, - - "geometry": - { - "shape": "sphere", - "origin": [0, 0, -6374134], - "outer_radius": 1000000000, - "inner_radius": 6374134 - }, - "cuts_inside": - { - "e_cut": 1e8, - "v_cut": -1, - "cont_rand": false - }, - "cuts_infront": - { - "e_cut": 1e8, - "v_cut": -1, - "cont_rand": true - }, - "cuts_behind": - { - "e_cut": 1e8, - "v_cut": -1, - "cont_rand": false - } - }, - { - "hierarchy": 1, - "medium": "ice", - "density_correction": 0.832, - - "geometry": - { - "shape": "sphere", - "origin": [0, 0, -6374134], - "outer_radius": 6374134, - "inner_radius": 6373934 - }, - "cuts_inside": - { - "e_cut": 1e8, - "v_cut": -1, - "cont_rand": false - }, - "cuts_infront": - { - "e_cut": 1e8, - "v_cut": -1, - "cont_rand": true - }, - "cuts_behind": - { - "e_cut": 1e8, - "v_cut": -1, - "cont_rand": false - } - }, - { - "hierarchy": 1, - "medium": "ice", - "density_correction": 1.005, - - "geometry": - { - "shape": "sphere", - "origin": [0, 0, -6374134], - "outer_radius": 6373934, - "inner_radius": 6371024 - }, - "cuts_inside": - { - "e_cut": 1e8, - "v_cut": -1, - "cont_rand": false - }, - "cuts_infront": - { - "e_cut": 1e8, - "v_cut": -1, - "cont_rand": true - }, - "cuts_behind": - { - "e_cut": 1e8, - "v_cut": -1, - "cont_rand": false - } - }, - { - "hierarchy": 1, - "medium": "standardrock", - "density_correction": 1.0, - - "geometry": - { - "shape": "sphere", - "origin": [0, 0, -6374134], - "outer_radius": 6371024, - "inner_radius": 0 - }, - "cuts_inside": - { - "e_cut": 1e8, - "v_cut": -1, - "cont_rand": false - }, - "cuts_infront": - { - "e_cut": 1e8, - "v_cut": -1, - "cont_rand": true - }, - "cuts_behind": - { - "e_cut": 1e8, - "v_cut": -1, - "cont_rand": false - } - } - ], - - "detector": - { - "shape": "cylinder", - "origin" : [0, 0, 0], - "outer_radius": 1e20, - "inner_radius": 0, - "height": 1e20 - } -} diff --git a/NuRadioMC/test/EvtGen/config_PROPOSAL_greenland.json b/NuRadioMC/test/EvtGen/config_PROPOSAL_greenland.json deleted file mode 100644 index b9ce2e3cf..000000000 --- a/NuRadioMC/test/EvtGen/config_PROPOSAL_greenland.json +++ /dev/null @@ -1,205 +0,0 @@ -{ - "global": - { - "seed" : 12, - "continous_loss_output" : false, - "only_loss_inside_detector" : false, - - "interpolation": - { - "do_interpolation" : true, - "path_to_tables" : "/tmp/", - "path_to_tables_readonly" : "/tmp/", - "do_binary_tables" : false, - "just_use_readonly_path" : false, - "max_node_energy" : 1e14, - "nodes_cross_section" : 100, - "nodes_continous_randomization" : 200, - "nodes_propagate" : 1000 - }, - - "exact_time" : true, - "stopping_decay" : true, - "scattering" : "NoScattering", - - "brems_multiplier" : 1, - "photo_multiplier" : 1, - "ioniz_multiplier" : 1, - "epair_multiplier" : 1, - "ioniz": "IonizBetheBlochRossi", - "epair": "EpairKelnerKokoulinPetrukhin", - "brems" : "BremsKelnerKokoulinPetrukhin", - "photo" : "PhotoAbramowiczLevinLevyMaor97", - "annihilation": "none", - "compton" : "none", - "photopair": "none", - "mupair": "none", - "weak": "none", - "lpm" : true, - "photo_hard_component" : true, - "photo_shadow" : "ShadowButkevichMikhailov", - - "cuts_infront": - { - "e_cut": 1e8, - "v_cut": -1, - "cont_rand": true - }, - "cuts_inside": - { - "e_cut": 1e8, - "v_cut": -1, - "cont_rand": false - }, - "cuts_behind": - { - "e_cut": 1e8, - "v_cut": -1, - "cont_rand": false - }, - "medium": "air", - "geometry": - { - "shape": "sphere", - "origin": [0, 0, -6374134], - "outer_radius": 1000000000, - "inner_radius": 6374134 - } - }, - - "sectors": [ - { - "hierarchy": 1, - "medium": "air", - "density_correction": 0.673, - - "geometry": - { - "shape": "sphere", - "origin": [0, 0, -6374134], - "outer_radius": 1000000000, - "inner_radius": 6374134 - }, - "cuts_inside": - { - "e_cut": 1e8, - "v_cut": -1, - "cont_rand": false - }, - "cuts_infront": - { - "e_cut": 1e8, - "v_cut": -1, - "cont_rand": true - }, - "cuts_behind": - { - "e_cut": 1e8, - "v_cut": -1, - "cont_rand": false - } - }, - { - "hierarchy": 1, - "medium": "ice", - "density_correction": 0.832, - - "geometry": - { - "shape": "sphere", - "origin": [0, 0, -6374134], - "outer_radius": 6374134, - "inner_radius": 6373934 - }, - "cuts_inside": - { - "e_cut": 1e8, - "v_cut": -1, - "cont_rand": false - }, - "cuts_infront": - { - "e_cut": 1e8, - "v_cut": -1, - "cont_rand": true - }, - "cuts_behind": - { - "e_cut": 1e8, - "v_cut": -1, - "cont_rand": false - } - }, - { - "hierarchy": 1, - "medium": "ice", - "density_correction": 1.005, - - "geometry": - { - "shape": "sphere", - "origin": [0, 0, -6374134], - "outer_radius": 6373934, - "inner_radius": 6371024 - }, - "cuts_inside": - { - "e_cut": 1e8, - "v_cut": -1, - "cont_rand": false - }, - "cuts_infront": - { - "e_cut": 1e8, - "v_cut": -1, - "cont_rand": true - }, - "cuts_behind": - { - "e_cut": 1e8, - "v_cut": -1, - "cont_rand": false - } - }, - { - "hierarchy": 1, - "medium": "standardrock", - "density_correction": 1.0, - - "geometry": - { - "shape": "sphere", - "origin": [0, 0, -6374134], - "outer_radius": 6371024, - "inner_radius": 0 - }, - "cuts_inside": - { - "e_cut": 1e8, - "v_cut": -1, - "cont_rand": false - }, - "cuts_infront": - { - "e_cut": 1e8, - "v_cut": -1, - "cont_rand": true - }, - "cuts_behind": - { - "e_cut": 1e8, - "v_cut": -1, - "cont_rand": false - } - } - ], - - "detector": - { - "shape": "cylinder", - "origin" : [0, 0, 0], - "outer_radius": 1e20, - "inner_radius": 0, - "height": 1e20 - } -} diff --git a/NuRadioMC/test/EvtGen/test_generate_cylinder_proposal.sh b/NuRadioMC/test/EvtGen/test_generate_cylinder_proposal.sh index 24b1d323b..4be45334f 100755 --- a/NuRadioMC/test/EvtGen/test_generate_cylinder_proposal.sh +++ b/NuRadioMC/test/EvtGen/test_generate_cylinder_proposal.sh @@ -3,4 +3,4 @@ FILE=NuRadioMC/test/EvtGen/test_proposal.hdf5 if test -f "$FILE"; then rm $FILE fi -python NuRadioMC/EvtGen/generate_cylinder.py $FILE 100 1e18 1e18 0 3000 -2700 0 --proposal --proposal_config NuRadioMC/test/EvtGen/config_PROPOSAL_greenland.json \ No newline at end of file +python NuRadioMC/EvtGen/generate_cylinder.py $FILE 100 1e18 1e18 0 3000 -2700 0 --proposal --proposal_config "Greenland" diff --git a/NuRadioMC/test/atmospheric_Aeff/1e18eV/T01generate_event_list.py b/NuRadioMC/test/atmospheric_Aeff/1e18eV/T01generate_event_list.py index 76d8b4b34..0fa142c4a 100755 --- a/NuRadioMC/test/atmospheric_Aeff/1e18eV/T01generate_event_list.py +++ b/NuRadioMC/test/atmospheric_Aeff/1e18eV/T01generate_event_list.py @@ -35,4 +35,4 @@ 2.5e3, 1e18 * units.eV, 1e18 * units.eV, volume, thetamin=thetamin, thetamax=thetamax, - config_file=os.path.join(path, 'config_PROPOSAL_greenland.json')) + config_file="Greenland") diff --git a/documentation/source/NuRadioMC/pages/Manuals/event_generation.rst b/documentation/source/NuRadioMC/pages/Manuals/event_generation.rst index 208d08764..8614eb648 100644 --- a/documentation/source/NuRadioMC/pages/Manuals/event_generation.rst +++ b/documentation/source/NuRadioMC/pages/Manuals/event_generation.rst @@ -208,7 +208,7 @@ NuRadioMC feeds PROPOSAL the lepton properties and PROPOSAL propagates them, sto """ proposal_config: string or path The user can specify the path to their own config file or choose among - the three available options: + the available options: -'SouthPole', a config file for the South Pole (spherical Earth). It consists of a 2.7 km deep layer of ice, bedrock below and air above. -'MooresBay', a config file for Moore's Bay (spherical Earth). It @@ -217,15 +217,9 @@ NuRadioMC feeds PROPOSAL the lepton properties and PROPOSAL propagates them, sto -'InfIce', a config file with a medium of infinite ice -'Greenland', a config file for Summit Station, Greenland (spherical Earth), same as SouthPole but with a 3 km deep ice layer. - IMPORTANT: If these options are used, the code is more efficient if the - user requests their own "path_to_tables" and "path_to_tables_readonly", - pointing them to a writable directory - If one of these three options is chosen, the user is supposed to edit - the corresponding config_PROPOSAL_xxx.json.sample file to include valid - table paths and then copy this file to config_PROPOSAL_xxx.json. """ -PROPOSAL needs a configuration file specifying the geometry to be run. The user can choose among the media listed above or they can specify the path to an own file. Important: the listed media need some input from the user. The files that end with ``.sample`` need to have two writable directories on the user's system to save some tables (which makes PROPOSAL faster), and they need to be renamed by removing the suffix ``.sample``. +PROPOSAL needs a configuration file specifying the geometry to be run. The user can choose among the media listed above or they can specify the path to an own file. .. code-block:: Python @@ -420,4 +414,4 @@ The minimum energy when the lepton propagation stops can be controlled with ``lo So, each property can be retrieved just by taking a SecondaryProperties object and accessing its properties. If the particle code lies between 80 and 90 (except for 86, hadronic decay bundle), the particle has been created upon an interaction before decaying. Any other particle is a product of decay. If there is more than one hadron created during decay, the NuRadioProposal module groups them into a hadronic decay bundle and adds their energies, so that the final shower is hadronic and with the sum of the energies. If the user is only interested in decay energy and distance, -the function ``get_decays`` can be used in a similar way, and it returns a list of (distance, energy) tuples. \ No newline at end of file +the function ``get_decays`` can be used in a similar way, and it returns a list of (distance, energy) tuples. From c4def8d17725bcf5deedbcdb0761b9f0001d7a74 Mon Sep 17 00:00:00 2001 From: Steffen Hallmann Date: Mon, 23 Jan 2023 23:49:05 +0100 Subject: [PATCH 091/418] remove wrong/unflexible number of available configurations --- NuRadioMC/EvtGen/NuRadioProposal.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NuRadioMC/EvtGen/NuRadioProposal.py b/NuRadioMC/EvtGen/NuRadioProposal.py index 00c587347..8a14a8445 100644 --- a/NuRadioMC/EvtGen/NuRadioProposal.py +++ b/NuRadioMC/EvtGen/NuRadioProposal.py @@ -223,7 +223,7 @@ def __init__(self, config_file='SouthPole', log_level=logging.INFO, tables_path= ---------- config_file: string or path The user can specify the path to their own config file or choose among - the three available options: + the available options: -'SouthPole', a config file for the South Pole (spherical Earth). It consists of a 2.7 km deep layer of ice, bedrock below and air above. -'MooresBay', a config file for Moore's Bay (spherical Earth). It From f1dca6c704d258bf9b4b6718b488bd7b21180e53 Mon Sep 17 00:00:00 2001 From: Steffen Hallmann Date: Tue, 24 Jan 2023 00:02:57 +0100 Subject: [PATCH 092/418] add option to choose tables path --- NuRadioMC/EvtGen/generator.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/NuRadioMC/EvtGen/generator.py b/NuRadioMC/EvtGen/generator.py index 0ec6d52a6..046cfff5e 100644 --- a/NuRadioMC/EvtGen/generator.py +++ b/NuRadioMC/EvtGen/generator.py @@ -715,6 +715,7 @@ def generate_surface_muons(filename, n_events, Emin, Emax, spectrum='log_uniform', start_file_id=0, config_file='SouthPole', + tables_path='/tmp', proposal_kwargs={}, log_level=None, max_n_events_batch=1e5, @@ -831,7 +832,8 @@ def generate_surface_muons(filename, n_events, Emin, Emax, * 'InfIce', a config file with a medium of infinite ice * 'Greenland', a config file for Summit Station, Greenland (spherical Earth), same as SouthPole but with a 3 km deep ice layer. - + tables_path: path + path where the proposal cross section tables are stored or should be generated proposal_kwargs: dict additional kwargs that are passed to the get_secondaries_array function of the NuRadioProposal class log_level: logging log level or None @@ -847,7 +849,7 @@ def generate_surface_muons(filename, n_events, Emin, Emax, t_start = time.time() max_n_events_batch = int(max_n_events_batch) from NuRadioMC.EvtGen.NuRadioProposal import ProposalFunctions - proposal_functions = ProposalFunctions(config_file=config_file) + proposal_functions = ProposalFunctions(config_file=config_file, tables_path=tables_path) attributes = {} n_events = int(n_events) @@ -1024,6 +1026,7 @@ def generate_eventlist_cylinder(filename, n_events, Emin, Emax, deposited=False, proposal=False, proposal_config='SouthPole', + proposal_tables_path='/tmp', start_file_id=0, log_level=None, proposal_kwargs={}, @@ -1155,7 +1158,8 @@ def generate_eventlist_cylinder(filename, n_events, Emin, Emax, * 'InfIce', a config file with a medium of infinite ice * 'Greenland', a config file for Summit Station, Greenland (spherical Earth), same as SouthPole but with a 3 km deep ice layer. - + proposal_tables_path: path + path where the proposal cross section tables are stored or should be generated start_file_id: int (default 0) in case the data set is distributed over several files, this number specifies the id of the first file (useful if an existing data set is extended) @@ -1180,7 +1184,7 @@ def generate_eventlist_cylinder(filename, n_events, Emin, Emax, logger.setLevel(log_level) if proposal: from NuRadioMC.EvtGen.NuRadioProposal import ProposalFunctions - proposal_functions = ProposalFunctions(config_file=proposal_config) + proposal_functions = ProposalFunctions(config_file=proposal_config, tables_path=proposal_tables_path) max_n_events_batch = int(max_n_events_batch) attributes = {} n_events = int(n_events) From 23342409665ce9e799c03a1aa169cbd5d6c6af77 Mon Sep 17 00:00:00 2001 From: Steffen Hallmann Date: Tue, 24 Jan 2023 11:15:15 +0100 Subject: [PATCH 093/418] update tables path for examples to proposal7 --- .../06_webinar/W01_create_input_extended.py | 1 + .../1e18eV/T01generate_event_list.py | 3 +- .../1e18eV/config_PROPOSAL_greenland.json | 205 ------------------ 3 files changed, 3 insertions(+), 206 deletions(-) delete mode 100644 NuRadioMC/test/atmospheric_Aeff/1e18eV/config_PROPOSAL_greenland.json diff --git a/NuRadioMC/examples/06_webinar/W01_create_input_extended.py b/NuRadioMC/examples/06_webinar/W01_create_input_extended.py index c098ac2a2..e91678224 100644 --- a/NuRadioMC/examples/06_webinar/W01_create_input_extended.py +++ b/NuRadioMC/examples/06_webinar/W01_create_input_extended.py @@ -168,4 +168,5 @@ n_events_per_file=n_events_per_file, spectrum=spectrum, proposal=proposal, proposal_config=proposal_config, + proposal_tables_path="./tables", start_event_id=start_event_id) diff --git a/NuRadioMC/test/atmospheric_Aeff/1e18eV/T01generate_event_list.py b/NuRadioMC/test/atmospheric_Aeff/1e18eV/T01generate_event_list.py index 0fa142c4a..9cf2e3632 100755 --- a/NuRadioMC/test/atmospheric_Aeff/1e18eV/T01generate_event_list.py +++ b/NuRadioMC/test/atmospheric_Aeff/1e18eV/T01generate_event_list.py @@ -35,4 +35,5 @@ 2.5e3, 1e18 * units.eV, 1e18 * units.eV, volume, thetamin=thetamin, thetamax=thetamax, - config_file="Greenland") + config_file="Greenland", + tables_path="NuRadioMC/test/atmospheric_Aeff/1e18eV/tables") diff --git a/NuRadioMC/test/atmospheric_Aeff/1e18eV/config_PROPOSAL_greenland.json b/NuRadioMC/test/atmospheric_Aeff/1e18eV/config_PROPOSAL_greenland.json deleted file mode 100644 index 27d4a4655..000000000 --- a/NuRadioMC/test/atmospheric_Aeff/1e18eV/config_PROPOSAL_greenland.json +++ /dev/null @@ -1,205 +0,0 @@ -{ - "global": - { - "seed" : 12, - "continous_loss_output" : false, - "only_loss_inside_detector" : false, - - "interpolation": - { - "do_interpolation" : true, - "path_to_tables" : "NuRadioMC/test/atmospheric_Aeff/1e18eV/tables", - "path_to_tables_readonly" : "NuRadioMC/test/atmospheric_Aeff/1e18eV/tables", - "do_binary_tables" : false, - "just_use_readonly_path" : false, - "max_node_energy" : 1e14, - "nodes_cross_section" : 100, - "nodes_continous_randomization" : 200, - "nodes_propagate" : 1000 - }, - - "exact_time" : true, - "stopping_decay" : true, - "scattering" : "NoScattering", - - "brems_multiplier" : 1, - "photo_multiplier" : 1, - "ioniz_multiplier" : 1, - "epair_multiplier" : 1, - "ioniz": "IonizBetheBlochRossi", - "epair": "EpairKelnerKokoulinPetrukhin", - "brems" : "BremsKelnerKokoulinPetrukhin", - "photo" : "PhotoAbramowiczLevinLevyMaor97", - "annihilation": "none", - "compton" : "none", - "photopair": "none", - "mupair": "none", - "weak": "none", - "lpm" : true, - "photo_hard_component" : true, - "photo_shadow" : "ShadowButkevichMikhailov", - - "cuts_infront": - { - "e_cut": 1e8, - "v_cut": -1, - "cont_rand": true - }, - "cuts_inside": - { - "e_cut": 1e8, - "v_cut": -1, - "cont_rand": false - }, - "cuts_behind": - { - "e_cut": 1e8, - "v_cut": -1, - "cont_rand": false - }, - "medium": "air", - "geometry": - { - "shape": "sphere", - "origin": [0, 0, -6374134], - "outer_radius": 1000000000, - "inner_radius": 6374134 - } - }, - - "sectors": [ - { - "hierarchy": 1, - "medium": "air", - "density_correction": 0.673, - - "geometry": - { - "shape": "sphere", - "origin": [0, 0, -6374134], - "outer_radius": 1000000000, - "inner_radius": 6374134 - }, - "cuts_inside": - { - "e_cut": 1e8, - "v_cut": -1, - "cont_rand": false - }, - "cuts_infront": - { - "e_cut": 1e8, - "v_cut": -1, - "cont_rand": true - }, - "cuts_behind": - { - "e_cut": 1e8, - "v_cut": -1, - "cont_rand": false - } - }, - { - "hierarchy": 1, - "medium": "ice", - "density_correction": 0.832, - - "geometry": - { - "shape": "sphere", - "origin": [0, 0, -6374134], - "outer_radius": 6374134, - "inner_radius": 6373934 - }, - "cuts_inside": - { - "e_cut": 1e8, - "v_cut": -1, - "cont_rand": false - }, - "cuts_infront": - { - "e_cut": 1e8, - "v_cut": -1, - "cont_rand": true - }, - "cuts_behind": - { - "e_cut": 1e8, - "v_cut": -1, - "cont_rand": false - } - }, - { - "hierarchy": 1, - "medium": "ice", - "density_correction": 1.005, - - "geometry": - { - "shape": "sphere", - "origin": [0, 0, -6374134], - "outer_radius": 6373934, - "inner_radius": 6371024 - }, - "cuts_inside": - { - "e_cut": 1e8, - "v_cut": -1, - "cont_rand": false - }, - "cuts_infront": - { - "e_cut": 1e8, - "v_cut": -1, - "cont_rand": true - }, - "cuts_behind": - { - "e_cut": 1e8, - "v_cut": -1, - "cont_rand": false - } - }, - { - "hierarchy": 1, - "medium": "standardrock", - "density_correction": 1.0, - - "geometry": - { - "shape": "sphere", - "origin": [0, 0, -6374134], - "outer_radius": 6371024, - "inner_radius": 0 - }, - "cuts_inside": - { - "e_cut": 1e8, - "v_cut": -1, - "cont_rand": false - }, - "cuts_infront": - { - "e_cut": 1e8, - "v_cut": -1, - "cont_rand": true - }, - "cuts_behind": - { - "e_cut": 1e8, - "v_cut": -1, - "cont_rand": false - } - } - ], - - "detector": - { - "shape": "cylinder", - "origin" : [0, 0, 0], - "outer_radius": 1e20, - "inner_radius": 0, - "height": 1e20 - } -} From cef5f51e15775f3fb3848d7fede8b9b3c2ababc6 Mon Sep 17 00:00:00 2001 From: Sjoerd Bouma Date: Tue, 24 Jan 2023 12:23:14 +0100 Subject: [PATCH 094/418] make file-level trigger time minimum over all stations --- NuRadioMC/simulation/simulation.py | 3 ++- .../test/SingleEvents/MB_1e18_reference.hdf5 | Bin 357024 -> 357024 bytes 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/NuRadioMC/simulation/simulation.py b/NuRadioMC/simulation/simulation.py index de0227584..cb626cafe 100644 --- a/NuRadioMC/simulation/simulation.py +++ b/NuRadioMC/simulation/simulation.py @@ -1225,7 +1225,8 @@ def _save_triggers_to_hdf5(self, sg, local_shower_index, global_shower_index): sg['triggered'][iSh] = np.any(sg['multiple_triggers'][iSh]) self._mout['triggered'][iSh2] |= sg['triggered'][iSh] self._mout['multiple_triggers'][iSh2] |= sg['multiple_triggers'][iSh] - self._mout['trigger_times'][iSh2] = sg['trigger_times'][iSh] + self._mout['trigger_times'][iSh2] = np.fmin( + self._mout['trigger_times'][iSh2], sg['trigger_times'][iSh]) sg['event_id_per_shower'][local_shower_index] = self._evt.get_id() sg['event_group_id_per_shower'][local_shower_index] = self._evt.get_run_number() self._output_multiple_triggers_station[self._station_id].append(multiple_triggers) diff --git a/NuRadioMC/test/SingleEvents/MB_1e18_reference.hdf5 b/NuRadioMC/test/SingleEvents/MB_1e18_reference.hdf5 index 6dc677b2d6ad93c5c99812cec3f3eaaf73832141..4a7a19b91a971942e346883bb6be892fffa789e8 100644 GIT binary patch delta 179 zcmZ4RRCK{p(G4kF(_g$~k&xi~rdIUr+e!yV&8VfCE~^~Ce4|wklMAFJHWx^rV4R-u znnl7uzbx*^ThTQRVA^+$L(NC$vD-* T&@wU6)WFohVta!;t3ogUjWI-! delta 86 zcmZ4RRCK{p(G4kFn>C~pn46FAwjbeT1Y#y2W(H!G?MHZ7rwD2oniwXfC8ik|q*+*` kSXvqyCnp=E7+P8w7$qmA0;!ZVOEWVg3*+q#@~jHM03UH1TmS$7 From a08a4737a8c70907e4aa74adf27d271fcb6e3341 Mon Sep 17 00:00:00 2001 From: Steffen Hallmann Date: Tue, 24 Jan 2023 15:09:16 +0100 Subject: [PATCH 095/418] try and find why proposal xsection files are not found after sim --- .../test/atmospheric_Aeff/1e18eV/T01generate_event_list.py | 2 +- NuRadioMC/test/examples/test_webinar.sh | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/NuRadioMC/test/atmospheric_Aeff/1e18eV/T01generate_event_list.py b/NuRadioMC/test/atmospheric_Aeff/1e18eV/T01generate_event_list.py index 9cf2e3632..9dd5a4b2f 100755 --- a/NuRadioMC/test/atmospheric_Aeff/1e18eV/T01generate_event_list.py +++ b/NuRadioMC/test/atmospheric_Aeff/1e18eV/T01generate_event_list.py @@ -36,4 +36,4 @@ volume, thetamin=thetamin, thetamax=thetamax, config_file="Greenland", - tables_path="NuRadioMC/test/atmospheric_Aeff/1e18eV/tables") + tables_path=os.path.join(path,"tables")) diff --git a/NuRadioMC/test/examples/test_webinar.sh b/NuRadioMC/test/examples/test_webinar.sh index bb85dc462..ce1c71203 100755 --- a/NuRadioMC/test/examples/test_webinar.sh +++ b/NuRadioMC/test/examples/test_webinar.sh @@ -9,4 +9,7 @@ python3 W05ElectricFields.py rm -r results rm input_3.2e+19_1.0e+20.hdf5 rm input_3.2e+18_1.0e+19.hdf5.part000? -rm tables/*.txt \ No newline at end of file +echo $PWD +ls . +ls tables +rm tables/*.txt From f79e2277a088a5eec6f5370a7716d73bda4144fd Mon Sep 17 00:00:00 2001 From: Steffen Hallmann Date: Tue, 24 Jan 2023 15:22:51 +0100 Subject: [PATCH 096/418] xsec tables have .dat ending rather than .txt now --- NuRadioMC/test/atmospheric_Aeff/1e18eV/test_build.sh | 2 +- NuRadioMC/test/examples/test_webinar.sh | 5 +---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/NuRadioMC/test/atmospheric_Aeff/1e18eV/test_build.sh b/NuRadioMC/test/atmospheric_Aeff/1e18eV/test_build.sh index 41906e940..0108dcb86 100755 --- a/NuRadioMC/test/atmospheric_Aeff/1e18eV/test_build.sh +++ b/NuRadioMC/test/atmospheric_Aeff/1e18eV/test_build.sh @@ -7,5 +7,5 @@ NuRadioMC/test/atmospheric_Aeff/1e18eV/T02RunSimulation.py 1e18_full.hdf5 ../di NuRadioMC/test/atmospheric_Aeff/1e18eV/T03check_output.py NuRadioMC/test/atmospheric_Aeff/1e18eV/output.hdf5 -rm NuRadioMC/test/atmospheric_Aeff/1e18eV/tables/*txt +rm NuRadioMC/test/atmospheric_Aeff/1e18eV/tables/*.dat rm NuRadioMC/test/atmospheric_Aeff/1e18eV/output* diff --git a/NuRadioMC/test/examples/test_webinar.sh b/NuRadioMC/test/examples/test_webinar.sh index ce1c71203..392cd16cc 100755 --- a/NuRadioMC/test/examples/test_webinar.sh +++ b/NuRadioMC/test/examples/test_webinar.sh @@ -9,7 +9,4 @@ python3 W05ElectricFields.py rm -r results rm input_3.2e+19_1.0e+20.hdf5 rm input_3.2e+18_1.0e+19.hdf5.part000? -echo $PWD -ls . -ls tables -rm tables/*.txt +rm tables/*.dat From 74d96eac686c0b48b50e65af9c2721e79c541389 Mon Sep 17 00:00:00 2001 From: Steffen Hallmann Date: Wed, 25 Jan 2023 08:57:52 +0100 Subject: [PATCH 097/418] add non-pip-installable instructions --- documentation/source/Introduction/pages/installation.rst | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/documentation/source/Introduction/pages/installation.rst b/documentation/source/Introduction/pages/installation.rst index 9237d8206..f8008993d 100644 --- a/documentation/source/Introduction/pages/installation.rst +++ b/documentation/source/Introduction/pages/installation.rst @@ -191,6 +191,13 @@ These packages are recommended to be able to use all of NuRadioMC/NuRadioReco's pip install proposal==7.4.2 + Note that the pip installation for this version of proposal may not work on all systems, in particular: + + - conda cannot be used on all systems (eg. on Mac), in that case use a python venv, see details `here `_ + + - if the linux kernel is too old (eg. on some computing clusters), refer to `this step-by-step guide `_ + + - To use the channelGalacticNoiseAdder, you need the `PyGDSM `_ package. .. code-block:: Bash From 2fdb3aec3a4d72a53528af925526d9407778787e Mon Sep 17 00:00:00 2001 From: Steffen Hallmann Date: Wed, 25 Jan 2023 13:48:59 +0100 Subject: [PATCH 098/418] update installation instructions --- documentation/source/Introduction/pages/installation.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/source/Introduction/pages/installation.rst b/documentation/source/Introduction/pages/installation.rst index f8008993d..824eb8a2f 100644 --- a/documentation/source/Introduction/pages/installation.rst +++ b/documentation/source/Introduction/pages/installation.rst @@ -195,7 +195,7 @@ These packages are recommended to be able to use all of NuRadioMC/NuRadioReco's - conda cannot be used on all systems (eg. on Mac), in that case use a python venv, see details `here `_ - - if the linux kernel is too old (eg. on some computing clusters), refer to `this step-by-step guide `_ + - if the linux kernel is too old (eg. on some computing clusters), refer to `this step-by-step guide `_ - To use the channelGalacticNoiseAdder, you need the `PyGDSM `_ package. From f4e60ed6512a22f91057ab0157b46372c806e157 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Wed, 25 Jan 2023 17:18:31 +0100 Subject: [PATCH 099/418] Cast proposal particle types to int instead of using .value --- NuRadioMC/EvtGen/NuRadioProposal.py | 48 +++++++++++++++-------------- 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/NuRadioMC/EvtGen/NuRadioProposal.py b/NuRadioMC/EvtGen/NuRadioProposal.py index 8a14a8445..99877d747 100644 --- a/NuRadioMC/EvtGen/NuRadioProposal.py +++ b/NuRadioMC/EvtGen/NuRadioProposal.py @@ -92,29 +92,31 @@ def __str__(self): very rarely used). """ -proposal_interaction_names = { pp.particle.Interaction_Type.particle.value: 'particle', - pp.particle.Interaction_Type.brems.value: 'brems', - pp.particle.Interaction_Type.ioniz.value: 'ionized_e', - pp.particle.Interaction_Type.epair.value: 'e_pair', - pp.particle.Interaction_Type.photonuclear.value: 'nucl_int', - pp.particle.Interaction_Type.mupair.value: 'mu_pair', - pp.particle.Interaction_Type.hadrons.value: 'hadrons', - pp.particle.Interaction_Type.continuousenergyloss.value: 'cont_loss', - pp.particle.Interaction_Type.weakint.value: 'weak_int', - pp.particle.Interaction_Type.compton.value: 'compton', - pp.particle.Interaction_Type.decay.value: 'decay' } - -proposal_interaction_codes = { pp.particle.Interaction_Type.particle.value: 80, - pp.particle.Interaction_Type.brems.value: 81, - pp.particle.Interaction_Type.ioniz.value: 82, - pp.particle.Interaction_Type.epair.value: 83, - pp.particle.Interaction_Type.photonuclear.value: 85, - pp.particle.Interaction_Type.mupair.value: 87, - pp.particle.Interaction_Type.hadrons.value: 84, - pp.particle.Interaction_Type.continuousenergyloss.value: 88, - pp.particle.Interaction_Type.weakint.value: 89, - pp.particle.Interaction_Type.compton.value: 90, - pp.particle.Interaction_Type.decay.value: 91 } +# For dicussion why we cast to int instead of using +# e.g. pp.particle.Interaction_Type.particle.value, see https://github.com/nu-radio/NuRadioMC/pull/458 +proposal_interaction_names = { int(pp.particle.Interaction_Type.particle): 'particle', + int(pp.particle.Interaction_Type.brems): 'brems', + int(pp.particle.Interaction_Type.ioniz): 'ionized_e', + int(pp.particle.Interaction_Type.epair): 'e_pair', + int(pp.particle.Interaction_Type.photonuclear): 'nucl_int', + int(pp.particle.Interaction_Type.mupair): 'mu_pair', + int(pp.particle.Interaction_Type.hadrons): 'hadrons', + int(pp.particle.Interaction_Type.continuousenergyloss): 'cont_loss', + int(pp.particle.Interaction_Type.weakint): 'weak_int', + int(pp.particle.Interaction_Type.compton): 'compton', + int(pp.particle.Interaction_Type.decay): 'decay' } + +proposal_interaction_codes = { int(pp.particle.Interaction_Type.particle): 80, + int(pp.particle.Interaction_Type.brems): 81, + int(pp.particle.Interaction_Type.ioniz): 82, + int(pp.particle.Interaction_Type.epair): 83, + int(pp.particle.Interaction_Type.photonuclear): 85, + int(pp.particle.Interaction_Type.mupair): 87, + int(pp.particle.Interaction_Type.hadrons): 84, + int(pp.particle.Interaction_Type.continuousenergyloss): 88, + int(pp.particle.Interaction_Type.weakint): 89, + int(pp.particle.Interaction_Type.compton): 90, + int(pp.particle.Interaction_Type.decay): 91 } def particle_code(pp_type): From 4505af96f33e1a5bb3e82eebd4a038256e734376 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Wed, 25 Jan 2023 17:27:17 +0100 Subject: [PATCH 100/418] some refactoring --- NuRadioMC/EvtGen/NuRadioProposal.py | 30 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/NuRadioMC/EvtGen/NuRadioProposal.py b/NuRadioMC/EvtGen/NuRadioProposal.py index 99877d747..5a1a63875 100644 --- a/NuRadioMC/EvtGen/NuRadioProposal.py +++ b/NuRadioMC/EvtGen/NuRadioProposal.py @@ -276,24 +276,21 @@ def __get_propagator(self, if(particle_code not in self.__propagators): self.__logger.info(f"initializing propagator for particle code {particle_code}") - if (self.__config_file == 'SouthPole'): - config_file_full_path = os.path.join(os.path.dirname(__file__), 'config_PROPOSAL.json') - elif (self.__config_file == 'MooresBay'): - config_file_full_path = os.path.join(os.path.dirname(__file__), 'config_PROPOSAL_mooresbay.json') - elif (self.__config_file == 'InfIce'): - config_file_full_path = os.path.join(os.path.dirname(__file__), 'config_PROPOSAL_infice.json') - elif (self.__config_file == 'Greenland'): - config_file_full_path = os.path.join(os.path.dirname(__file__), 'config_PROPOSAL_greenland.json') - elif (os.path.exists(self.__config_file)): + config_files = { + 'SouthPole': 'config_PROPOSAL.json', 'MooresBay': 'config_PROPOSAL_mooresbay.json', + 'InfIce': 'config_PROPOSAL_infice.json', 'Greenland': 'config_PROPOSAL_greenland.json'} + + if self.__config_file in config_files: + config_file_full_path = os.path.join(os.path.dirname(__file__), config_files[self.__config_file]) + elif os.path.exists(self.__config_file): config_file_full_path = self.__config_file else: raise ValueError("Proposal config file is not valid. Please provide a valid option.") if not os.path.exists(config_file_full_path): - error_message = "Unable to find proposal config file.\n" - error_message += "Make sure that json configuration file under " - error_message += "path {} exists.".format(config_file_full_path) - raise ValueError(error_message) + raise ValueError("Unable to find proposal config file.\n" + "Make sure that json configuration file under " + "path {} exists.".format(config_file_full_path)) pp.InterpolationSettings.tables_path = self.__tables_path @@ -591,10 +588,11 @@ def get_secondaries_array(self, for decay_particle in list(decay_products): - if (abs(decay_particle.type) == 13): + if abs(decay_particle.type) == 13: mu_energy = decay_particle.energy - if (mu_energy <= low): + if mu_energy <= low: continue + mu_position = (decay_particle.position.x, decay_particle.position.y, decay_particle.position.z) mu_direction = (decay_particle.direction.x, decay_particle.direction.y, decay_particle.direction.z) @@ -612,7 +610,7 @@ def get_secondaries_array(self, grouped_decay_products = self.__group_decay_products(decay_products, min_energy_loss, lepton_position) - if (grouped_decay_products is not None): + if grouped_decay_products is not None: shower_inducing_prods.append(grouped_decay_products) secondaries_array.append(shower_inducing_prods) From f22ef63ab3732615afe92e5ae77de1ef8b8b05b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Wed, 25 Jan 2023 17:36:08 +0100 Subject: [PATCH 101/418] introduce function to calculate distance between particles. Make use of api to simplify code --- NuRadioMC/EvtGen/NuRadioProposal.py | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/NuRadioMC/EvtGen/NuRadioProposal.py b/NuRadioMC/EvtGen/NuRadioProposal.py index 5a1a63875..2dfba26d4 100644 --- a/NuRadioMC/EvtGen/NuRadioProposal.py +++ b/NuRadioMC/EvtGen/NuRadioProposal.py @@ -40,6 +40,10 @@ pp_km = 1.e5 +def calculate_distance(pp_position, pos_arr): + return np.linalg.norm(pp_position.cartesian_coordinates - pos_arr) * units.cm + + class Singleton(type): _instances = {} @@ -453,10 +457,7 @@ def __filter_secondaries(self, if self.__produces_shower(sec.type, sec.energy, min_energy_loss): - distance = ((sec.position.x - lepton_position[0]) * units.cm) ** 2 - distance += ((sec.position.y - lepton_position[1]) * units.cm) ** 2 - distance += ((sec.position.z - lepton_position[2]) * units.cm) ** 2 - distance = np.sqrt(distance) + distance = calculate_distance(sec.position, lepton_position) energy = sec.energy * units.MeV @@ -497,15 +498,13 @@ def __group_decay_products(self, sum_decay_particle_energy = 0 for decay_particle in decay_products: - if(is_shower_primary(decay_particle.type)): + if is_shower_primary(decay_particle.type): sum_decay_particle_energy += decay_particle.energy - if (sum_decay_particle_energy > min_energy_loss): + if sum_decay_particle_energy > min_energy_loss: # all decay_particles have the same position, so we can just look at the first in list - distance = ((decay_products[0].position.x - lepton_position[0]) * units.cm) ** 2 - distance += ((decay_products[0].position.y - lepton_position[1]) * units.cm) ** 2 - distance += ((decay_products[0].position.z - lepton_position[2]) * units.cm) ** 2 - distance = np.sqrt(distance) + distance = calculate_distance(decay_products[0].position, lepton_position) + return SecondaryProperties(distance, sum_decay_particle_energy * units.MeV, 'had', 86, particle_names.particle_name(86)) return None @@ -686,10 +685,7 @@ def get_decays(self, continue # all decay particles have the same position, so we can just use the position of the first one - decay_distance = ((decay_particles[0].position.x - lepton_position[0]) * units.cm) ** 2 - decay_distance += ((decay_particles[0].position.y - lepton_position[1]) * units.cm) ** 2 - decay_distance += ((decay_particles[0].position.z - lepton_position[2]) * units.cm) ** 2 - decay_distance = np.sqrt(decay_distance) + decay_distance = calculate_distance(decay_particles[0].position, lepton_position) # TODO: Note that this includes ALL decay particles, including invisible ones like neutrinos decay_prop = (decay_distance, decay_energy) From ce27436d78e9c11b84b61998c66905adeb738bc0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Wed, 25 Jan 2023 17:37:15 +0100 Subject: [PATCH 102/418] refactoring --- NuRadioMC/EvtGen/NuRadioProposal.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/NuRadioMC/EvtGen/NuRadioProposal.py b/NuRadioMC/EvtGen/NuRadioProposal.py index 2dfba26d4..082b6dae5 100644 --- a/NuRadioMC/EvtGen/NuRadioProposal.py +++ b/NuRadioMC/EvtGen/NuRadioProposal.py @@ -262,8 +262,7 @@ def __init__(self, config_file='SouthPole', log_level=logging.INFO, tables_path= self.__tables_path = tables_path self.__upper_energy_limit = upper_energy_limit * pp_eV # convert to PROPOSAL units - def __get_propagator(self, - particle_code=13): + def __get_propagator(self, particle_code=13): """ Returns a PROPOSAL propagator for muons or taus. If it does not exist yet it is being generated. From a1e4dfdde1dda9e3309f0ca581b0939e3badd912 Mon Sep 17 00:00:00 2001 From: Sjoerd Bouma Date: Wed, 25 Jan 2023 17:37:49 +0100 Subject: [PATCH 103/418] added orphan tag to unlisted document --- .../source/NuRadioMC/pages/HDF5_structure.rst | 2 +- .../pages/HDF5_structures_history/HDF5_v2.2.rst | 11 ++++++++--- documentation/source/conf.py | 4 ++-- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/documentation/source/NuRadioMC/pages/HDF5_structure.rst b/documentation/source/NuRadioMC/pages/HDF5_structure.rst index 6d2c8b02a..eb5dbc30e 100644 --- a/documentation/source/NuRadioMC/pages/HDF5_structure.rst +++ b/documentation/source/NuRadioMC/pages/HDF5_structure.rst @@ -3,7 +3,7 @@ HDF5 output structure The output of a NuRadioMC simulation is saved in the HDF5 file format, as well as (optionally) in ``.nur`` files. The data structure of ``.nur`` files is explained :doc:`here `. -This page outlines the structure of the HDF5 files v3.0. Find the structure of :doc:`v2.2 `. +This page outlines the structure of the HDF5 files v3.0. Find the structure of :doc:`v2.2 here `. Opening the HDF5 file diff --git a/documentation/source/NuRadioMC/pages/HDF5_structures_history/HDF5_v2.2.rst b/documentation/source/NuRadioMC/pages/HDF5_structures_history/HDF5_v2.2.rst index 6290e6dda..46205704c 100644 --- a/documentation/source/NuRadioMC/pages/HDF5_structures_history/HDF5_v2.2.rst +++ b/documentation/source/NuRadioMC/pages/HDF5_structures_history/HDF5_v2.2.rst @@ -1,5 +1,10 @@ -HDF5 output structure -===================== +:orphan: + +HDF5 output structure (v2.2) +============================ + +.. Important:: + This version of the HDF5 output structure is outdated. To see the current HDF5 output structure, click :doc:`here`. The output of a NuRadioMC simulation is saved in the HDF5 file format, as well as (optionally) in ``.nur`` files. The data structure of ``.nur`` files is explained :doc:`here `. @@ -35,7 +40,7 @@ The ``event_group_id`` is the same for all showers that follow the same first in The ``shower_id`` is unique for every shower. Shower which interfere constructively are combined into one event and have the same ``event_id`` starting from 0. - .. image:: event_sketch.png + .. image:: ../event_sketch.png :width: 70% HDF5 structure diff --git a/documentation/source/conf.py b/documentation/source/conf.py index 9e8cca5cb..980d10590 100644 --- a/documentation/source/conf.py +++ b/documentation/source/conf.py @@ -79,7 +79,7 @@ # # This is also used if you do content translation via gettext catalogs. # Usually you set "language" from the command line for these cases. -language = None +language = "en" # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. @@ -256,4 +256,4 @@ # return any([fnmatch.fnmatch(name, pat) for pat in exclusions]) # def setup(app): -# app.connect('autodoc-skip-member', skip_modules) \ No newline at end of file +# app.connect('autodoc-skip-member', skip_modules) From 1f923c01d3caa3cb51f48d2dacaa8a71c02ba840 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Wed, 25 Jan 2023 17:40:36 +0100 Subject: [PATCH 104/418] Change default path to store proposal tables in generator.py and NuRadioProposal.py --- NuRadioMC/EvtGen/NuRadioProposal.py | 12 ++++++++++-- NuRadioMC/EvtGen/generator.py | 4 ++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/NuRadioMC/EvtGen/NuRadioProposal.py b/NuRadioMC/EvtGen/NuRadioProposal.py index 082b6dae5..54292f700 100644 --- a/NuRadioMC/EvtGen/NuRadioProposal.py +++ b/NuRadioMC/EvtGen/NuRadioProposal.py @@ -223,7 +223,7 @@ class ProposalFunctions(object): not be used from the outside to avoid mismatching units. """ - def __init__(self, config_file='SouthPole', log_level=logging.INFO, tables_path="/tmp", seed=12, upper_energy_limit=1e14*units.MeV): + def __init__(self, config_file='SouthPole', log_level=logging.INFO, tables_path=None, seed=12, upper_energy_limit=1e14*units.MeV): """ Parameters ---------- @@ -242,7 +242,8 @@ def __init__(self, config_file='SouthPole', log_level=logging.INFO, tables_path= tables_path: path Path to PROPOSAL tables. Should be set to a path where PROPOSAL tables exist, or where PROPOSAL tables can be saved. This avoids that PROPOSAL has to regenerate - tables (which can take several minutes) every time the script is executed + tables (which can take several minutes) every time the script is executed. + Default: None -> create directory "proposal_tables" at the location of this file. seed: int Seed to be used by PROPOSAL upper_energy_limit: float @@ -257,6 +258,13 @@ def __init__(self, config_file='SouthPole', log_level=logging.INFO, tables_path= pp.RandomGenerator.get().set_seed(seed) # set global seed for PROPOSAL + if tables_path is None: + tables_path = os.path.join(os.path.dirname(__file__), "proposal_tables") + + if not os.path.exists(tables_path): + self.__logger.info(f"Create directory {tables_path} to store proposal tables") + os.mkdir(tables_path) + self.__propagators = {} self.__config_file = config_file self.__tables_path = tables_path diff --git a/NuRadioMC/EvtGen/generator.py b/NuRadioMC/EvtGen/generator.py index 046cfff5e..cd95c4819 100644 --- a/NuRadioMC/EvtGen/generator.py +++ b/NuRadioMC/EvtGen/generator.py @@ -715,7 +715,7 @@ def generate_surface_muons(filename, n_events, Emin, Emax, spectrum='log_uniform', start_file_id=0, config_file='SouthPole', - tables_path='/tmp', + tables_path=None, proposal_kwargs={}, log_level=None, max_n_events_batch=1e5, @@ -1026,7 +1026,7 @@ def generate_eventlist_cylinder(filename, n_events, Emin, Emax, deposited=False, proposal=False, proposal_config='SouthPole', - proposal_tables_path='/tmp', + proposal_tables_path=None, start_file_id=0, log_level=None, proposal_kwargs={}, From cac60c2f9275ddeafe7174179f57195b185a6b7c Mon Sep 17 00:00:00 2001 From: Steffen Hallmann Date: Wed, 25 Jan 2023 18:45:53 +0100 Subject: [PATCH 105/418] mock proposal import fails documentation built when casting to int --- .github/workflows/deploy_documentation.yaml | 2 +- documentation/source/conf.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/deploy_documentation.yaml b/.github/workflows/deploy_documentation.yaml index 2e2ebd88d..802f824f0 100644 --- a/.github/workflows/deploy_documentation.yaml +++ b/.github/workflows/deploy_documentation.yaml @@ -50,7 +50,7 @@ jobs: python -m pip install --upgrade pip pip install flake8 pytest export GSLDIR=$(gsl-config --prefix) - python install_dev.py --install --dev documentation --no-interactive + python install_dev.py --install --dev documentation proposal --no-interactive export PYTHONPATH=$PWD:$PYTHONPATH echo $PYTHONPATH diff --git a/documentation/source/conf.py b/documentation/source/conf.py index 9e8cca5cb..8ce006415 100644 --- a/documentation/source/conf.py +++ b/documentation/source/conf.py @@ -227,7 +227,7 @@ autodoc_mock_imports = [ 'ROOT', 'mysql-python', 'pygdsm', 'MySQLdb', 'healpy', 'scripts', - 'uproot', 'proposal', 'radiopropa', 'plotly', 'past', + 'uproot', 'radiopropa', 'plotly', 'past', 'nifty5' ] # Raise warnings if any cross-references are broken @@ -256,4 +256,4 @@ # return any([fnmatch.fnmatch(name, pat) for pat in exclusions]) # def setup(app): -# app.connect('autodoc-skip-member', skip_modules) \ No newline at end of file +# app.connect('autodoc-skip-member', skip_modules) From 36af2377114552b08b0b0a911a0672d76fb0e7b4 Mon Sep 17 00:00:00 2001 From: Steffen Hallmann Date: Thu, 26 Jan 2023 09:44:57 +0100 Subject: [PATCH 106/418] use latest proposal tag, with better installability and some changes to LPM --- documentation/source/Introduction/pages/installation.rst | 2 +- pyproject.toml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/documentation/source/Introduction/pages/installation.rst b/documentation/source/Introduction/pages/installation.rst index 824eb8a2f..0b1d26517 100644 --- a/documentation/source/Introduction/pages/installation.rst +++ b/documentation/source/Introduction/pages/installation.rst @@ -189,7 +189,7 @@ These packages are recommended to be able to use all of NuRadioMC/NuRadioReco's .. code-block:: bash - pip install proposal==7.4.2 + pip install proposal==7.5.0 Note that the pip installation for this version of proposal may not work on all systems, in particular: diff --git a/pyproject.toml b/pyproject.toml index 52763e0b6..26fe70497 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -46,7 +46,7 @@ numba = "*" Sphinx = "*" sphinx-rtd-theme = "*" numpydoc = "1.1.0" -proposal = "7.4.2" +proposal = "7.5.0" pygdsm = {git = "https://github.com/telegraphic/pygdsm"} nifty5 = {git = "https://gitlab.mpcdf.mpg.de/ift/nifty.git", branch="NIFTy_5"} pypocketfft = {git = "https://gitlab.mpcdf.mpg.de/mtr/pypocketfft"} @@ -55,4 +55,4 @@ pypocketfft = {git = "https://gitlab.mpcdf.mpg.de/mtr/pypocketfft"} documentation = ["Sphinx", "sphinx-rtd-theme", "numpydoc"] proposal = ["proposal"] galacticnoise = ['pygdsm'] -ift_reco = ['nifty5', 'pypocketfft'] \ No newline at end of file +ift_reco = ['nifty5', 'pypocketfft'] From c5d29fccfcad5b0f53ce9312ea97ab47dd9a399c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Thu, 26 Jan 2023 10:18:24 +0100 Subject: [PATCH 107/418] Add default location of proposal tables to gitignore --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 4409f607b..20510607a 100644 --- a/.gitignore +++ b/.gitignore @@ -123,3 +123,6 @@ venv.bak/ # ignore .nur files in NuRadioReco/examples/ # this should not apply for NuRadioReco/examples/example_data/ NuRadioReco/examples/*.nur + +# Default location for proposal tables with proposal7 +NuRadioMC/EvtGen/proposal_tables/ From 88423a9ca3a6433d1ce2882df05f47bff7931c91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Thu, 26 Jan 2023 12:49:56 +0100 Subject: [PATCH 108/418] Rename function, add doc string --- NuRadioMC/EvtGen/NuRadioProposal.py | 33 +++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/NuRadioMC/EvtGen/NuRadioProposal.py b/NuRadioMC/EvtGen/NuRadioProposal.py index 54292f700..c00307a17 100644 --- a/NuRadioMC/EvtGen/NuRadioProposal.py +++ b/NuRadioMC/EvtGen/NuRadioProposal.py @@ -40,7 +40,24 @@ pp_km = 1.e5 -def calculate_distance(pp_position, pos_arr): +def __calculate_distance(pp_position, pos_arr): + """ + Calculates distance between secondary and lepton position (both in proposal units). + + Paramters + --------- + + pp_position: ParticleState.position + Position of a secondary particle (in proposal units) + + pos_arr: np.array(3,) + Init. position of the lepton (in proposal units) + + Returns + ------- + + Distance between both coordinates in NuRadioMC units + """ return np.linalg.norm(pp_position.cartesian_coordinates - pos_arr) * units.cm @@ -464,7 +481,7 @@ def __filter_secondaries(self, if self.__produces_shower(sec.type, sec.energy, min_energy_loss): - distance = calculate_distance(sec.position, lepton_position) + distance = __calculate_distance(sec.position, lepton_position) energy = sec.energy * units.MeV @@ -510,7 +527,7 @@ def __group_decay_products(self, if sum_decay_particle_energy > min_energy_loss: # all decay_particles have the same position, so we can just look at the first in list - distance = calculate_distance(decay_products[0].position, lepton_position) + distance = __calculate_distance(decay_products[0].position, lepton_position) return SecondaryProperties(distance, sum_decay_particle_energy * units.MeV, 'had', 86, particle_names.particle_name(86)) @@ -570,8 +587,9 @@ def get_secondaries_array(self, if lepton_positions_nu is None: lepton_positions = [(0, 0, 0)] * len(energy_leptons) else: - lepton_positions = [ np.array(lepton_position_nu) * pp_m for lepton_position_nu in lepton_positions_nu ] - + lepton_positions = [np.array(lepton_position_nu) * pp_m + for lepton_position_nu in lepton_positions_nu] + if lepton_directions is None: lepton_directions = [(0, 0, -1)] * len(energy_leptons) @@ -664,7 +682,8 @@ def get_decays(self, if lepton_positions_nu is None: lepton_positions = [(0, 0, 0)] * len(energy_leptons) else: - lepton_positions = [ np.array(lepton_position_nu) * pp_m for lepton_position_nu in lepton_positions_nu ] + lepton_positions = [np.array(lepton_position_nu) * pp_m + for lepton_position_nu in lepton_positions_nu] if lepton_directions is None: lepton_directions = [(0, 0, 1)] * len(energy_leptons) @@ -692,7 +711,7 @@ def get_decays(self, continue # all decay particles have the same position, so we can just use the position of the first one - decay_distance = calculate_distance(decay_particles[0].position, lepton_position) + decay_distance = __calculate_distance(decay_particles[0].position, lepton_position) # TODO: Note that this includes ALL decay particles, including invisible ones like neutrinos decay_prop = (decay_distance, decay_energy) From f87bd55bb8693f469b0588bbf6c765cd2e903d16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Thu, 26 Jan 2023 14:05:49 +0100 Subject: [PATCH 109/418] Ups, appreciate the concept of name mangeling. Implemented __calculate_distance as a static member method. --- NuRadioMC/EvtGen/NuRadioProposal.py | 48 ++++++++++++++++------------- 1 file changed, 26 insertions(+), 22 deletions(-) diff --git a/NuRadioMC/EvtGen/NuRadioProposal.py b/NuRadioMC/EvtGen/NuRadioProposal.py index c00307a17..79d88205b 100644 --- a/NuRadioMC/EvtGen/NuRadioProposal.py +++ b/NuRadioMC/EvtGen/NuRadioProposal.py @@ -40,25 +40,6 @@ pp_km = 1.e5 -def __calculate_distance(pp_position, pos_arr): - """ - Calculates distance between secondary and lepton position (both in proposal units). - - Paramters - --------- - - pp_position: ParticleState.position - Position of a secondary particle (in proposal units) - - pos_arr: np.array(3,) - Init. position of the lepton (in proposal units) - - Returns - ------- - - Distance between both coordinates in NuRadioMC units - """ - return np.linalg.norm(pp_position.cartesian_coordinates - pos_arr) * units.cm class Singleton(type): @@ -287,6 +268,29 @@ def __init__(self, config_file='SouthPole', log_level=logging.INFO, tables_path= self.__tables_path = tables_path self.__upper_energy_limit = upper_energy_limit * pp_eV # convert to PROPOSAL units + + @staticmethod + def __calculate_distance(pp_position, pos_arr): + """ + Calculates distance between secondary and lepton position (both in proposal units). + + Paramters + --------- + + pp_position: ParticleState.position + Position of a secondary particle (in proposal units) + + pos_arr: np.array(3,) + Init. position of the lepton (in proposal units) + + Returns + ------- + + Distance between both coordinates in NuRadioMC units + """ + return np.linalg.norm(pp_position.cartesian_coordinates - pos_arr) * units.cm + + def __get_propagator(self, particle_code=13): """ Returns a PROPOSAL propagator for muons or taus. If it does not exist yet it is being generated. @@ -481,7 +485,7 @@ def __filter_secondaries(self, if self.__produces_shower(sec.type, sec.energy, min_energy_loss): - distance = __calculate_distance(sec.position, lepton_position) + distance = ProposalFunctions.__calculate_distance(sec.position, lepton_position) energy = sec.energy * units.MeV @@ -527,7 +531,7 @@ def __group_decay_products(self, if sum_decay_particle_energy > min_energy_loss: # all decay_particles have the same position, so we can just look at the first in list - distance = __calculate_distance(decay_products[0].position, lepton_position) + distance = ProposalFunctions.__calculate_distance(decay_products[0].position, lepton_position) return SecondaryProperties(distance, sum_decay_particle_energy * units.MeV, 'had', 86, particle_names.particle_name(86)) @@ -711,7 +715,7 @@ def get_decays(self, continue # all decay particles have the same position, so we can just use the position of the first one - decay_distance = __calculate_distance(decay_particles[0].position, lepton_position) + decay_distance = ProposalFunctions.__calculate_distance(decay_particles[0].position, lepton_position) # TODO: Note that this includes ALL decay particles, including invisible ones like neutrinos decay_prop = (decay_distance, decay_energy) From acb2cf5f91963c4f82b97d980a879691b74533c6 Mon Sep 17 00:00:00 2001 From: Christian Glaser Date: Thu, 26 Jan 2023 18:58:21 +0000 Subject: [PATCH 110/418] update changelog --- changelog.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/changelog.txt b/changelog.txt index 63f7f9742..70f2af152 100644 --- a/changelog.txt +++ b/changelog.txt @@ -2,6 +2,12 @@ Changelog - to keep track of all relevant changes please update the categories "new features" and "bugfixes" before a pull request merge! +version 2.2.0-dev +new features: + +bugfixes: + + version 2.1.7 new features: - add attenuation model from the 2021 measurements taken at Summit Station From 5a6b84510e3221499b7378b8155c3bc99320e320 Mon Sep 17 00:00:00 2001 From: Steffen Hallmann Date: Mon, 30 Jan 2023 09:53:12 +0100 Subject: [PATCH 111/418] add option to download pre-calculated proposal tables --- NuRadioMC/EvtGen/proposal_table_manager.py | 91 +++++++++++++++++++ .../EvtGen/test_generate_cylinder_proposal.sh | 1 + .../atmospheric_Aeff/1e18eV/test_build.sh | 2 + 3 files changed, 94 insertions(+) create mode 100755 NuRadioMC/EvtGen/proposal_table_manager.py diff --git a/NuRadioMC/EvtGen/proposal_table_manager.py b/NuRadioMC/EvtGen/proposal_table_manager.py new file mode 100755 index 000000000..a8557d438 --- /dev/null +++ b/NuRadioMC/EvtGen/proposal_table_manager.py @@ -0,0 +1,91 @@ +#!/usr/bin/env python +from NuRadioMC.EvtGen.NuRadioProposal import ProposalFunctions +import proposal +import os +import shutil +import argparse +import logging + +logger = logging.getLogger('ProposalTablesManager') + +def produce_proposal_tables(config_file, tables_path=None): + + proposal_func = ProposalFunctions(config_file=config_file, tables_path=tables_path) + + for particle_code in [-15, -13, 13, 15]: + logger.warning(f"producing tables for {config_file}, particle {particle_code}") + proposal_func._ProposalFunctions__get_propagator(particle_code=particle_code) + + +def produce_proposal_tables_tarball(config_file, tables_path=None): + if tables_path is None: + proposal_func = ProposalFunctions(config_file=config_file) + tables_path = proposal_func._ProposalFunctions__tables_path + + outdir = f"./{tables_path}/v{proposal.__version__}" + if not os.path.exists(outdir): + os.makedirs(outdir) + + + tarfile = config_file+".tar.gz" + if os.path.isfile(os.path.join(outdir, tarfile)): + logger.error(f"Output tarball {os.path.join(outdir, tarfile)} already exists.") + raise IOError + + tables_path = os.path.join(outdir, config_file) + produce_proposal_tables(config_file, tables_path) + + logger.warning("Producing gzipped tarball") + + shutil.make_archive(tables_path, + 'gztar', tables_path) + +def download_proposal_tables(config_file, tables_path=None): + if tables_path is None: + proposal_func = ProposalFunctions(config_file=config_file) + tables_path = proposal_func._ProposalFunctions__tables_path + + download_file = True + if download_file: + # does not exist yet -> download file + import requests + proposal_version = proposal.__version__ + URL = f'https://rnog-data.zeuthen.desy.de/proposal_tables/v{proposal_version}/{config_file}.tar.gz' + + folder = tables_path #os.path.dirname(tables_path) + if not os.path.exists(folder): + os.makedirs(folder) + logger.warning( + "downloading pre-calculated proposal tables for {} from {}. This can take a while...".format(config_file, URL)) + r = requests.get(URL) + if r.status_code != requests.codes.ok: + logger.error("error in download of proposal tables") + raise IOError + + with open(f"{tables_path}/{config_file}.tar.gz", "wb") as code: + code.write(r.content) + logger.warning("...download finished.") + logger.warning(f"...unpacking archive to {tables_path}") + shutil.unpack_archive(f"{tables_path}/{config_file}.tar.gz", tables_path) + os.remove(f"{tables_path}/{config_file}.tar.gz") + + + +if __name__ == "__main__": + parser = argparse.ArgumentParser("NuRadioProposal tables I/O") + parser.add_argument("option", choices=["create", "download"]) + parser.add_argument('config_file') + parser.add_argument('-t', '--tables_path', default=None) + + args = parser.parse_args() + + if args.option == "create": + if args.config_file == "all": + cfgs = ['InfIce','SouthPole', 'MooresBay', 'Greenland'] + for cfg in cfgs: + produce_proposal_tables_tarball(cfg, args.tables_path) + else: + produce_proposal_tables_tarball(args.config_file, args.tables_path) + + elif args.option == "download": + download_proposal_tables(args.config_file, args.tables_path) diff --git a/NuRadioMC/test/EvtGen/test_generate_cylinder_proposal.sh b/NuRadioMC/test/EvtGen/test_generate_cylinder_proposal.sh index 4be45334f..db75235ee 100755 --- a/NuRadioMC/test/EvtGen/test_generate_cylinder_proposal.sh +++ b/NuRadioMC/test/EvtGen/test_generate_cylinder_proposal.sh @@ -3,4 +3,5 @@ FILE=NuRadioMC/test/EvtGen/test_proposal.hdf5 if test -f "$FILE"; then rm $FILE fi +python NuRadioMC/EvtGen/proposal_table_manager.py download "Greenland" python NuRadioMC/EvtGen/generate_cylinder.py $FILE 100 1e18 1e18 0 3000 -2700 0 --proposal --proposal_config "Greenland" diff --git a/NuRadioMC/test/atmospheric_Aeff/1e18eV/test_build.sh b/NuRadioMC/test/atmospheric_Aeff/1e18eV/test_build.sh index 0108dcb86..aaff3c3d9 100755 --- a/NuRadioMC/test/atmospheric_Aeff/1e18eV/test_build.sh +++ b/NuRadioMC/test/atmospheric_Aeff/1e18eV/test_build.sh @@ -1,6 +1,8 @@ #!/bin/bash set -e +NuRadioMC/EvtGen/proposal_table_manager.py download "Greenland" -t "NuRadioMC/test/atmospheric_Aeff/1e18eV/tables" + NuRadioMC/test/atmospheric_Aeff/1e18eV/T01generate_event_list.py NuRadioMC/test/atmospheric_Aeff/1e18eV/T02RunSimulation.py 1e18_full.hdf5 ../dipole_100m.json ../config.yaml output.hdf5 output.nur From 1e4b50a503a85391c4bbe4d0240ea6af3c3e786d Mon Sep 17 00:00:00 2001 From: Steffen Hallmann Date: Mon, 30 Jan 2023 09:55:54 +0100 Subject: [PATCH 112/418] update changelog --- changelog.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/changelog.txt b/changelog.txt index 70f2af152..da46815e2 100644 --- a/changelog.txt +++ b/changelog.txt @@ -4,7 +4,9 @@ please update the categories "new features" and "bugfixes" before a pull request version 2.2.0-dev new features: - +- upgrade to proposal v 7.5.0 with new NuRadioProposal interface and improved LPM treatment +- add option to download pre-calculated proposal tables for the default +detector configurations bugfixes: From f59896937453d7cf07fd97f3e48de82b68d85f51 Mon Sep 17 00:00:00 2001 From: Steffen Hallmann Date: Mon, 30 Jan 2023 10:33:21 +0100 Subject: [PATCH 113/418] missed change to download in webinar examples --- NuRadioMC/test/examples/test_examples.sh | 2 +- NuRadioMC/test/examples/test_webinar.sh | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/NuRadioMC/test/examples/test_examples.sh b/NuRadioMC/test/examples/test_examples.sh index ac4795a03..7eae224f3 100755 --- a/NuRadioMC/test/examples/test_examples.sh +++ b/NuRadioMC/test/examples/test_examples.sh @@ -35,4 +35,4 @@ python3 W05ElectricFields.py rm -r results rm input_3.2e+19_1.0e+20.hdf5 rm input_3.2e+18_1.0e+19.hdf5.part000? -rm tables/*.txt \ No newline at end of file +rm tables/*.dat diff --git a/NuRadioMC/test/examples/test_webinar.sh b/NuRadioMC/test/examples/test_webinar.sh index 392cd16cc..60e2931d1 100755 --- a/NuRadioMC/test/examples/test_webinar.sh +++ b/NuRadioMC/test/examples/test_webinar.sh @@ -1,4 +1,6 @@ set -e +python3 NuRadioMC/EvtGen/proposal_table_manager.py download "Greenland" -t "NuRadioMC/examples/06_webinar/tables" + cd NuRadioMC/examples/06_webinar python3 W01_create_input.py python3 W01_create_input_extended.py From c38a40cccf2b11511981947c8f071862f95e61c9 Mon Sep 17 00:00:00 2001 From: Steffen Hallmann Date: Mon, 30 Jan 2023 17:39:32 +0100 Subject: [PATCH 114/418] improve info printout and readme --- NuRadioMC/EvtGen/proposal_table_manager.py | 56 ++++++++++++++++++++-- 1 file changed, 51 insertions(+), 5 deletions(-) diff --git a/NuRadioMC/EvtGen/proposal_table_manager.py b/NuRadioMC/EvtGen/proposal_table_manager.py index a8557d438..0edbd5fc4 100755 --- a/NuRadioMC/EvtGen/proposal_table_manager.py +++ b/NuRadioMC/EvtGen/proposal_table_manager.py @@ -9,7 +9,16 @@ logger = logging.getLogger('ProposalTablesManager') def produce_proposal_tables(config_file, tables_path=None): - + """ + produce proposal tables for all relevant flavors + + Parameters + ---------- + config_file: string + one of the default PROPOSAL configurations ['InfIce','SouthPole', 'MooresBay', 'Greenland'] + tables_path: string + output path for the generated tables + """ proposal_func = ProposalFunctions(config_file=config_file, tables_path=tables_path) for particle_code in [-15, -13, 13, 15]: @@ -17,12 +26,33 @@ def produce_proposal_tables(config_file, tables_path=None): proposal_func._ProposalFunctions__get_propagator(particle_code=particle_code) +def get_compiler(): + # proposal (as of V 7.5.0) generates tables with different hashes for clang and gcc + # infer which of the precalculation is relevant here + compiler = "gcc" + if "clang" in sys.version.lower(): + compiler = "clang" + return compiler + def produce_proposal_tables_tarball(config_file, tables_path=None): + """ + produce proposal tables tarball for all relevant flavors + Note: the produced tarballs need to be placed in the + NuRadioMC/proposal_tables/{version}/{compiler} directory on the desy cluster. + + Parameters + ---------- + config_file: string + one of the default PROPOSAL configurations ['InfIce','SouthPole', 'MooresBay', 'Greenland'] + tables_path: string + output path for the generated tables + """ + if tables_path is None: proposal_func = ProposalFunctions(config_file=config_file) tables_path = proposal_func._ProposalFunctions__tables_path - outdir = f"./{tables_path}/v{proposal.__version__}" + outdir = f"./{tables_path}/v{proposal.__version__}/{get_compiler()}" if not os.path.exists(outdir): os.makedirs(outdir) @@ -41,6 +71,18 @@ def produce_proposal_tables_tarball(config_file, tables_path=None): 'gztar', tables_path) def download_proposal_tables(config_file, tables_path=None): + """ + download precalculated proposal tables for all relevant flavors + from the NuRadioMC data storage + + Parameters + ---------- + config_file: string + one of the default PROPOSAL configurations ['InfIce','SouthPole', 'MooresBay', 'Greenland'] + tables_path: string + output path for the generated tables + """ + if tables_path is None: proposal_func = ProposalFunctions(config_file=config_file) tables_path = proposal_func._ProposalFunctions__tables_path @@ -50,7 +92,7 @@ def download_proposal_tables(config_file, tables_path=None): # does not exist yet -> download file import requests proposal_version = proposal.__version__ - URL = f'https://rnog-data.zeuthen.desy.de/proposal_tables/v{proposal_version}/{config_file}.tar.gz' + URL = f'https://rnog-data.zeuthen.desy.de/proposal_tables/v{proposal_version}/{get_compiler()}/{config_file}.tar.gz' folder = tables_path #os.path.dirname(tables_path) if not os.path.exists(folder): @@ -74,12 +116,15 @@ def download_proposal_tables(config_file, tables_path=None): if __name__ == "__main__": parser = argparse.ArgumentParser("NuRadioProposal tables I/O") parser.add_argument("option", choices=["create", "download"]) - parser.add_argument('config_file') - parser.add_argument('-t', '--tables_path', default=None) + parser.add_argument('config_file', help="one of the default configurations ['InfIce','SouthPole', 'MooresBay', 'Greenland'] or 'all'") + parser.add_argument('-t', '--tables_path', default=None, help="target path for table creation/download") args = parser.parse_args() + logger.warning(f"Your compiler type is {get_compiler()}") + if args.option == "create": + logger.warning(f"Creating proposal tables for {args.option}") if args.config_file == "all": cfgs = ['InfIce','SouthPole', 'MooresBay', 'Greenland'] for cfg in cfgs: @@ -88,4 +133,5 @@ def download_proposal_tables(config_file, tables_path=None): produce_proposal_tables_tarball(args.config_file, args.tables_path) elif args.option == "download": + logger.warning(f"Downloading proposal tables for {args.option}") download_proposal_tables(args.config_file, args.tables_path) From 82441f9da7af84457c9f63bef7fc7ac9b7b8cdab Mon Sep 17 00:00:00 2001 From: Steffen Hallmann Date: Mon, 30 Jan 2023 17:52:24 +0100 Subject: [PATCH 115/418] missed import --- NuRadioMC/EvtGen/proposal_table_manager.py | 1 + 1 file changed, 1 insertion(+) diff --git a/NuRadioMC/EvtGen/proposal_table_manager.py b/NuRadioMC/EvtGen/proposal_table_manager.py index 0edbd5fc4..864dab742 100755 --- a/NuRadioMC/EvtGen/proposal_table_manager.py +++ b/NuRadioMC/EvtGen/proposal_table_manager.py @@ -5,6 +5,7 @@ import shutil import argparse import logging +import sys logger = logging.getLogger('ProposalTablesManager') From 8a489a7fff82c07902367d3dd2fe8b3f71a76585 Mon Sep 17 00:00:00 2001 From: Steffen Hallmann Date: Mon, 30 Jan 2023 21:18:05 +0100 Subject: [PATCH 116/418] remove unneeded duplicate of Singleton implementation --- NuRadioMC/EvtGen/NuRadioProposal.py | 12 +----------- changelog.txt | 3 +-- 2 files changed, 2 insertions(+), 13 deletions(-) diff --git a/NuRadioMC/EvtGen/NuRadioProposal.py b/NuRadioMC/EvtGen/NuRadioProposal.py index 79d88205b..d7a65a103 100644 --- a/NuRadioMC/EvtGen/NuRadioProposal.py +++ b/NuRadioMC/EvtGen/NuRadioProposal.py @@ -1,6 +1,7 @@ import proposal as pp import numpy as np from NuRadioReco.utilities import units, particle_names +from NuRadioReco.utilities.metaclasses import Singleton import os import six import json @@ -40,17 +41,6 @@ pp_km = 1.e5 - - -class Singleton(type): - _instances = {} - - def __call__(cls, *args, **kwargs): - if Singleton._instances.get(cls, None) is None: - Singleton._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs) - return Singleton._instances[cls] - - class SecondaryProperties: """ This class stores the properties from secondary particles that are diff --git a/changelog.txt b/changelog.txt index da46815e2..ff79a9575 100644 --- a/changelog.txt +++ b/changelog.txt @@ -5,8 +5,7 @@ please update the categories "new features" and "bugfixes" before a pull request version 2.2.0-dev new features: - upgrade to proposal v 7.5.0 with new NuRadioProposal interface and improved LPM treatment -- add option to download pre-calculated proposal tables for the default -detector configurations +- add script to generate / download pre-calculated proposal tables for known detector configurations bugfixes: From 92941ae296a9106e374c02dd22f8765b49c62b24 Mon Sep 17 00:00:00 2001 From: Steffen Hallmann Date: Mon, 30 Jan 2023 21:43:01 +0100 Subject: [PATCH 117/418] add singleton info --- NuRadioMC/EvtGen/NuRadioProposal.py | 10 +++++++--- NuRadioMC/EvtGen/proposal_table_manager.py | 4 ++-- NuRadioReco/detector/detector_base.py | 4 ++-- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/NuRadioMC/EvtGen/NuRadioProposal.py b/NuRadioMC/EvtGen/NuRadioProposal.py index d7a65a103..8d0227ef2 100644 --- a/NuRadioMC/EvtGen/NuRadioProposal.py +++ b/NuRadioMC/EvtGen/NuRadioProposal.py @@ -1,7 +1,7 @@ import proposal as pp import numpy as np from NuRadioReco.utilities import units, particle_names -from NuRadioReco.utilities.metaclasses import Singleton +import NuRadioReco.utilities.metaclasses import os import six import json @@ -203,7 +203,7 @@ def is_shower_primary(pp_type): return False -@six.add_metaclass(Singleton) +@six.add_metaclass(NuRadioReco.utilities.metaclasses.Singleton) class ProposalFunctions(object): """ This class serves as a container for PROPOSAL functions. The functions that @@ -238,7 +238,11 @@ def __init__(self, config_file='SouthPole', log_level=logging.INFO, tables_path= upper_energy_limit of tables that will be created by PROPOSAL, in NuRadioMC units (eV). There will be an error if primaries with energies above this energy will be injected. Note that PROPOSAL will have to regenerate tables for a new values of upper_energy_limit - + create_new: bool (default:False) + Can be used to force the creation of a new ProposalFunctions object. + By default, the __init__ will only create a new object if none already exists. + For more details, check the documentation for the + `Singleton metaclass `_. """ self.__logger = logging.getLogger("proposal") self.__logger.setLevel(log_level) diff --git a/NuRadioMC/EvtGen/proposal_table_manager.py b/NuRadioMC/EvtGen/proposal_table_manager.py index 864dab742..1d75720d7 100755 --- a/NuRadioMC/EvtGen/proposal_table_manager.py +++ b/NuRadioMC/EvtGen/proposal_table_manager.py @@ -20,7 +20,7 @@ def produce_proposal_tables(config_file, tables_path=None): tables_path: string output path for the generated tables """ - proposal_func = ProposalFunctions(config_file=config_file, tables_path=tables_path) + proposal_func = ProposalFunctions(config_file=config_file, tables_path=tables_path, create_new=True) for particle_code in [-15, -13, 13, 15]: logger.warning(f"producing tables for {config_file}, particle {particle_code}") @@ -85,7 +85,7 @@ def download_proposal_tables(config_file, tables_path=None): """ if tables_path is None: - proposal_func = ProposalFunctions(config_file=config_file) + proposal_func = ProposalFunctions(config_file=config_file, create_new=True) tables_path = proposal_func._ProposalFunctions__tables_path download_file = True diff --git a/NuRadioReco/detector/detector_base.py b/NuRadioReco/detector/detector_base.py index 553be17c6..8d28b0f8d 100644 --- a/NuRadioReco/detector/detector_base.py +++ b/NuRadioReco/detector/detector_base.py @@ -160,8 +160,8 @@ def __init__(self, source='json', json_filename='ARIANNA/arianna_detector_db.jso appending e.g. '_InfFirn' to the antenna model name. if False, the antenna model as specified in the database is used. create_new: bool (default:False) - Can be used to force the creation of a new detector object. By default, the __init__ will anly create a new - object of none already exists. + Can be used to force the creation of a new detector object. By default, the __init__ will only create a new + object if none already exists. """ self._serialization = SerializationMiddleware() self._serialization.register_serializer(DateTimeSerializer(), 'TinyDate') From 76a9d1856cf0189fa61c5dedc5d3d32d6e546965 Mon Sep 17 00:00:00 2001 From: Steffen Hallmann Date: Mon, 30 Jan 2023 22:43:22 +0100 Subject: [PATCH 118/418] fix documentation --- NuRadioMC/EvtGen/proposal_table_manager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NuRadioMC/EvtGen/proposal_table_manager.py b/NuRadioMC/EvtGen/proposal_table_manager.py index 1d75720d7..adec9591f 100755 --- a/NuRadioMC/EvtGen/proposal_table_manager.py +++ b/NuRadioMC/EvtGen/proposal_table_manager.py @@ -39,7 +39,7 @@ def produce_proposal_tables_tarball(config_file, tables_path=None): """ produce proposal tables tarball for all relevant flavors Note: the produced tarballs need to be placed in the - NuRadioMC/proposal_tables/{version}/{compiler} directory on the desy cluster. + NuRadioMC/proposal_tables/{version}/{compiler} directory on the desy cluster. Parameters ---------- From f5d675561a08d4ff8cd3467dce28acede490c646 Mon Sep 17 00:00:00 2001 From: Steffen Hallmann Date: Mon, 30 Jan 2023 23:05:31 +0100 Subject: [PATCH 119/418] automatic table download by default --- NuRadioMC/EvtGen/NuRadioProposal.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/NuRadioMC/EvtGen/NuRadioProposal.py b/NuRadioMC/EvtGen/NuRadioProposal.py index 8d0227ef2..240e9cedc 100644 --- a/NuRadioMC/EvtGen/NuRadioProposal.py +++ b/NuRadioMC/EvtGen/NuRadioProposal.py @@ -260,6 +260,7 @@ def __init__(self, config_file='SouthPole', log_level=logging.INFO, tables_path= self.__propagators = {} self.__config_file = config_file self.__tables_path = tables_path + self.__tables_downloaded = False self.__upper_energy_limit = upper_energy_limit * pp_eV # convert to PROPOSAL units @@ -319,6 +320,12 @@ def __get_propagator(self, particle_code=13): "path {} exists.".format(config_file_full_path)) pp.InterpolationSettings.tables_path = self.__tables_path + # download pre-calculated tables for default configs, but not more than once + if self.__config_file in config_files and not self.__tables_downloaded: + from proposal_tables_manager import download_proposal_tables + + download_proposal_tables(self.__config_file, tables_path=self.__tables_path) + self.__tables_downloaded = True # upper energy lim for proposal tables, in PROPOSAL units (MeV) pp.InterpolationSettings.upper_energy_lim = self.__upper_energy_limit From 9fef9eda3c782b677c3394da19b721a26390c38e Mon Sep 17 00:00:00 2001 From: Steffen Hallmann Date: Mon, 30 Jan 2023 23:07:31 +0100 Subject: [PATCH 120/418] remove manual proposal table download from tests --- NuRadioMC/test/EvtGen/test_generate_cylinder_proposal.sh | 1 - NuRadioMC/test/atmospheric_Aeff/1e18eV/test_build.sh | 1 - NuRadioMC/test/examples/test_webinar.sh | 1 - 3 files changed, 3 deletions(-) diff --git a/NuRadioMC/test/EvtGen/test_generate_cylinder_proposal.sh b/NuRadioMC/test/EvtGen/test_generate_cylinder_proposal.sh index db75235ee..4be45334f 100755 --- a/NuRadioMC/test/EvtGen/test_generate_cylinder_proposal.sh +++ b/NuRadioMC/test/EvtGen/test_generate_cylinder_proposal.sh @@ -3,5 +3,4 @@ FILE=NuRadioMC/test/EvtGen/test_proposal.hdf5 if test -f "$FILE"; then rm $FILE fi -python NuRadioMC/EvtGen/proposal_table_manager.py download "Greenland" python NuRadioMC/EvtGen/generate_cylinder.py $FILE 100 1e18 1e18 0 3000 -2700 0 --proposal --proposal_config "Greenland" diff --git a/NuRadioMC/test/atmospheric_Aeff/1e18eV/test_build.sh b/NuRadioMC/test/atmospheric_Aeff/1e18eV/test_build.sh index aaff3c3d9..911d6ce09 100755 --- a/NuRadioMC/test/atmospheric_Aeff/1e18eV/test_build.sh +++ b/NuRadioMC/test/atmospheric_Aeff/1e18eV/test_build.sh @@ -1,7 +1,6 @@ #!/bin/bash set -e -NuRadioMC/EvtGen/proposal_table_manager.py download "Greenland" -t "NuRadioMC/test/atmospheric_Aeff/1e18eV/tables" NuRadioMC/test/atmospheric_Aeff/1e18eV/T01generate_event_list.py diff --git a/NuRadioMC/test/examples/test_webinar.sh b/NuRadioMC/test/examples/test_webinar.sh index 60e2931d1..f881aa5cc 100755 --- a/NuRadioMC/test/examples/test_webinar.sh +++ b/NuRadioMC/test/examples/test_webinar.sh @@ -1,5 +1,4 @@ set -e -python3 NuRadioMC/EvtGen/proposal_table_manager.py download "Greenland" -t "NuRadioMC/examples/06_webinar/tables" cd NuRadioMC/examples/06_webinar python3 W01_create_input.py From fe553c27d9e8d5cf304978ddd82024993d4d9ff7 Mon Sep 17 00:00:00 2001 From: Steffen Hallmann Date: Mon, 30 Jan 2023 23:43:52 +0100 Subject: [PATCH 121/418] whoops.. typo --- NuRadioMC/EvtGen/NuRadioProposal.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NuRadioMC/EvtGen/NuRadioProposal.py b/NuRadioMC/EvtGen/NuRadioProposal.py index 240e9cedc..615592231 100644 --- a/NuRadioMC/EvtGen/NuRadioProposal.py +++ b/NuRadioMC/EvtGen/NuRadioProposal.py @@ -322,7 +322,7 @@ def __get_propagator(self, particle_code=13): pp.InterpolationSettings.tables_path = self.__tables_path # download pre-calculated tables for default configs, but not more than once if self.__config_file in config_files and not self.__tables_downloaded: - from proposal_tables_manager import download_proposal_tables + from NuRadioMC.EvtGen.proposal_table_manager import download_proposal_tables download_proposal_tables(self.__config_file, tables_path=self.__tables_path) self.__tables_downloaded = True From d638baaf21677ef923067b4afb812959279138f2 Mon Sep 17 00:00:00 2001 From: Steffen Hallmann Date: Tue, 31 Jan 2023 15:07:28 +0100 Subject: [PATCH 122/418] cosmetics --- NuRadioMC/EvtGen/NuRadioProposal.py | 2 +- NuRadioMC/EvtGen/proposal_table_manager.py | 44 +++++++++++----------- 2 files changed, 22 insertions(+), 24 deletions(-) diff --git a/NuRadioMC/EvtGen/NuRadioProposal.py b/NuRadioMC/EvtGen/NuRadioProposal.py index 615592231..eb4f1c961 100644 --- a/NuRadioMC/EvtGen/NuRadioProposal.py +++ b/NuRadioMC/EvtGen/NuRadioProposal.py @@ -242,7 +242,7 @@ def __init__(self, config_file='SouthPole', log_level=logging.INFO, tables_path= Can be used to force the creation of a new ProposalFunctions object. By default, the __init__ will only create a new object if none already exists. For more details, check the documentation for the - `Singleton metaclass `_. + :class:`Singleton metaclass `. """ self.__logger = logging.getLogger("proposal") self.__logger.setLevel(log_level) diff --git a/NuRadioMC/EvtGen/proposal_table_manager.py b/NuRadioMC/EvtGen/proposal_table_manager.py index adec9591f..e50c64a2f 100755 --- a/NuRadioMC/EvtGen/proposal_table_manager.py +++ b/NuRadioMC/EvtGen/proposal_table_manager.py @@ -88,29 +88,27 @@ def download_proposal_tables(config_file, tables_path=None): proposal_func = ProposalFunctions(config_file=config_file, create_new=True) tables_path = proposal_func._ProposalFunctions__tables_path - download_file = True - if download_file: - # does not exist yet -> download file - import requests - proposal_version = proposal.__version__ - URL = f'https://rnog-data.zeuthen.desy.de/proposal_tables/v{proposal_version}/{get_compiler()}/{config_file}.tar.gz' - - folder = tables_path #os.path.dirname(tables_path) - if not os.path.exists(folder): - os.makedirs(folder) - logger.warning( - "downloading pre-calculated proposal tables for {} from {}. This can take a while...".format(config_file, URL)) - r = requests.get(URL) - if r.status_code != requests.codes.ok: - logger.error("error in download of proposal tables") - raise IOError - - with open(f"{tables_path}/{config_file}.tar.gz", "wb") as code: - code.write(r.content) - logger.warning("...download finished.") - logger.warning(f"...unpacking archive to {tables_path}") - shutil.unpack_archive(f"{tables_path}/{config_file}.tar.gz", tables_path) - os.remove(f"{tables_path}/{config_file}.tar.gz") + # does not exist yet -> download file + import requests + proposal_version = proposal.__version__ + URL = f'https://rnog-data.zeuthen.desy.de/proposal_tables/v{proposal_version}/{get_compiler()}/{config_file}.tar.gz' + + folder = tables_path #os.path.dirname(tables_path) + if not os.path.exists(folder): + os.makedirs(folder) + logger.warning( + "downloading pre-calculated proposal tables for {} from {}. This can take a while...".format(config_file, URL)) + r = requests.get(URL) + if r.status_code != requests.codes.ok: + logger.error("error in download of proposal tables") + raise IOError + + with open(f"{tables_path}/{config_file}.tar.gz", "wb") as code: + code.write(r.content) + logger.warning("...download finished.") + logger.warning(f"...unpacking archive to {tables_path}") + shutil.unpack_archive(f"{tables_path}/{config_file}.tar.gz", tables_path) + os.remove(f"{tables_path}/{config_file}.tar.gz") From dba281ac6e51047dc4b79123d87c16628cda7675 Mon Sep 17 00:00:00 2001 From: Steffen Hallmann Date: Tue, 31 Jan 2023 17:06:39 +0100 Subject: [PATCH 123/418] improved download handling for proposal tables --- NuRadioMC/EvtGen/NuRadioProposal.py | 57 ++++++++++++++++++----------- 1 file changed, 35 insertions(+), 22 deletions(-) diff --git a/NuRadioMC/EvtGen/NuRadioProposal.py b/NuRadioMC/EvtGen/NuRadioProposal.py index eb4f1c961..aa4c23d1a 100644 --- a/NuRadioMC/EvtGen/NuRadioProposal.py +++ b/NuRadioMC/EvtGen/NuRadioProposal.py @@ -6,6 +6,7 @@ import six import json import logging +from glob import glob """ This module takes care of the PROPOSAL implementation. Some important things @@ -250,19 +251,47 @@ def __init__(self, config_file='SouthPole', log_level=logging.INFO, tables_path= pp.RandomGenerator.get().set_seed(seed) # set global seed for PROPOSAL + default_configs = { + 'SouthPole': 'config_PROPOSAL.json', 'MooresBay': 'config_PROPOSAL_mooresbay.json', + 'InfIce': 'config_PROPOSAL_infice.json', 'Greenland': 'config_PROPOSAL_greenland.json'} + + if tables_path is None: tables_path = os.path.join(os.path.dirname(__file__), "proposal_tables") + if config_file in default_configs: + # default configurations should append their identifier to the tables path + if not config_file == os.path.dirname(tables_path).split("/")[-1]: + tables_path = os.path.join(tables_path, config_file) + if not os.path.exists(tables_path): self.__logger.info(f"Create directory {tables_path} to store proposal tables") - os.mkdir(tables_path) - + os.makedirs(tables_path) + + if config_file in default_configs: + config_file_full_path = os.path.join(os.path.dirname(__file__), default_configs[config_file]) + + elif os.path.exists(config_file): + config_file_full_path = config_file + else: + raise ValueError("Proposal config file is not valid. Please provide a valid option.") + + if not os.path.exists(config_file_full_path): + raise ValueError("Unable to find proposal config file.\n" + "Make sure that json configuration file under " + "path {} exists.".format(config_file_full_path)) + + self.__propagators = {} self.__config_file = config_file + self.__config_file_full_path = config_file_full_path self.__tables_path = tables_path - self.__tables_downloaded = False self.__upper_energy_limit = upper_energy_limit * pp_eV # convert to PROPOSAL units + self.__download_tables = False + if self.__config_file in default_configs: + if len(glob(self.__tables_path + "/*.dat")) == 0: + self.__download_tables = True @staticmethod def __calculate_distance(pp_position, pos_arr): @@ -303,29 +332,13 @@ def __get_propagator(self, particle_code=13): if(particle_code not in self.__propagators): self.__logger.info(f"initializing propagator for particle code {particle_code}") - config_files = { - 'SouthPole': 'config_PROPOSAL.json', 'MooresBay': 'config_PROPOSAL_mooresbay.json', - 'InfIce': 'config_PROPOSAL_infice.json', 'Greenland': 'config_PROPOSAL_greenland.json'} - - if self.__config_file in config_files: - config_file_full_path = os.path.join(os.path.dirname(__file__), config_files[self.__config_file]) - elif os.path.exists(self.__config_file): - config_file_full_path = self.__config_file - else: - raise ValueError("Proposal config file is not valid. Please provide a valid option.") - - if not os.path.exists(config_file_full_path): - raise ValueError("Unable to find proposal config file.\n" - "Make sure that json configuration file under " - "path {} exists.".format(config_file_full_path)) - pp.InterpolationSettings.tables_path = self.__tables_path # download pre-calculated tables for default configs, but not more than once - if self.__config_file in config_files and not self.__tables_downloaded: + if self.__download_tables: from NuRadioMC.EvtGen.proposal_table_manager import download_proposal_tables download_proposal_tables(self.__config_file, tables_path=self.__tables_path) - self.__tables_downloaded = True + self.__download_tables = False # upper energy lim for proposal tables, in PROPOSAL units (MeV) pp.InterpolationSettings.upper_energy_lim = self.__upper_energy_limit @@ -337,7 +350,7 @@ def __get_propagator(self, particle_code=13): error_str += "Please choose between -/+muon (13/-13) and -/+tau (15/-15)" raise NotImplementedError(error_str) - self.__propagators[particle_code] = pp.Propagator(particle_def=p_def, path_to_config_file=config_file_full_path) + self.__propagators[particle_code] = pp.Propagator(particle_def=p_def, path_to_config_file=self.__config_file_full_path) return self.__propagators[particle_code] From 85bb50a55079c6cf5ec9ac244aca81ec00e8df83 Mon Sep 17 00:00:00 2001 From: Steffen Hallmann Date: Tue, 31 Jan 2023 17:21:50 +0100 Subject: [PATCH 124/418] automize downloads. clean up tests in subdirectories --- NuRadioMC/EvtGen/NuRadioProposal.py | 6 +++++- NuRadioMC/test/atmospheric_Aeff/1e18eV/test_build.sh | 2 +- NuRadioMC/test/examples/test_examples.sh | 2 +- NuRadioMC/test/examples/test_webinar.sh | 2 +- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/NuRadioMC/EvtGen/NuRadioProposal.py b/NuRadioMC/EvtGen/NuRadioProposal.py index aa4c23d1a..630a247eb 100644 --- a/NuRadioMC/EvtGen/NuRadioProposal.py +++ b/NuRadioMC/EvtGen/NuRadioProposal.py @@ -337,7 +337,11 @@ def __get_propagator(self, particle_code=13): if self.__download_tables: from NuRadioMC.EvtGen.proposal_table_manager import download_proposal_tables - download_proposal_tables(self.__config_file, tables_path=self.__tables_path) + try: + download_proposal_tables(self.__config_file, tables_path=self.__tables_path) + except: + self.__logger.warning("requested pre-calculated proposal tables could not be downloaded, calculating manually") + pass self.__download_tables = False # upper energy lim for proposal tables, in PROPOSAL units (MeV) diff --git a/NuRadioMC/test/atmospheric_Aeff/1e18eV/test_build.sh b/NuRadioMC/test/atmospheric_Aeff/1e18eV/test_build.sh index 911d6ce09..0dd872e60 100755 --- a/NuRadioMC/test/atmospheric_Aeff/1e18eV/test_build.sh +++ b/NuRadioMC/test/atmospheric_Aeff/1e18eV/test_build.sh @@ -8,5 +8,5 @@ NuRadioMC/test/atmospheric_Aeff/1e18eV/T02RunSimulation.py 1e18_full.hdf5 ../di NuRadioMC/test/atmospheric_Aeff/1e18eV/T03check_output.py NuRadioMC/test/atmospheric_Aeff/1e18eV/output.hdf5 -rm NuRadioMC/test/atmospheric_Aeff/1e18eV/tables/*.dat +rm NuRadioMC/test/atmospheric_Aeff/1e18eV/tables/**/*.dat rm NuRadioMC/test/atmospheric_Aeff/1e18eV/output* diff --git a/NuRadioMC/test/examples/test_examples.sh b/NuRadioMC/test/examples/test_examples.sh index 7eae224f3..5a7a531b0 100755 --- a/NuRadioMC/test/examples/test_examples.sh +++ b/NuRadioMC/test/examples/test_examples.sh @@ -35,4 +35,4 @@ python3 W05ElectricFields.py rm -r results rm input_3.2e+19_1.0e+20.hdf5 rm input_3.2e+18_1.0e+19.hdf5.part000? -rm tables/*.dat +rm tables/**/*.dat diff --git a/NuRadioMC/test/examples/test_webinar.sh b/NuRadioMC/test/examples/test_webinar.sh index f881aa5cc..50090912d 100755 --- a/NuRadioMC/test/examples/test_webinar.sh +++ b/NuRadioMC/test/examples/test_webinar.sh @@ -10,4 +10,4 @@ python3 W05ElectricFields.py rm -r results rm input_3.2e+19_1.0e+20.hdf5 rm input_3.2e+18_1.0e+19.hdf5.part000? -rm tables/*.dat +rm tables/**/*.dat From cef68f3fcf27af331c527e1407ebf4f084e26264 Mon Sep 17 00:00:00 2001 From: Janna Vischer Date: Thu, 2 Feb 2023 10:46:36 +0100 Subject: [PATCH 125/418] changed comment in trigger module and example code in manual (NuRadioProposal as a standalone module) --- NuRadioReco/framework/trigger.py | 6 +++--- .../source/NuRadioMC/pages/Manuals/event_generation.rst | 3 +-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/NuRadioReco/framework/trigger.py b/NuRadioReco/framework/trigger.py index f84ee810b..cbbe73434 100644 --- a/NuRadioReco/framework/trigger.py +++ b/NuRadioReco/framework/trigger.py @@ -81,7 +81,7 @@ def set_trigger_time(self, time): def get_trigger_time(self): """ - get the trigger time (time with respect to beginning of trace) + get the trigger time (time with respect to the beginning of the event, e.g. the first neutrino interaction) """ return self._trigger_time @@ -97,7 +97,7 @@ def set_trigger_times(self, times): def get_trigger_times(self): """ - get the trigger times (time with respect to beginning of trace) + get the trigger times (time with respect to beginning of trace?) """ return self._trigger_times @@ -375,4 +375,4 @@ def __init__(self, name, threshold, number_of_coincidences=1, self._number_of_coincidences = number_of_coincidences self._coinc_window = channel_coincidence_window self._temperature = temperature - self._Vbias = Vbias \ No newline at end of file + self._Vbias = Vbias diff --git a/documentation/source/NuRadioMC/pages/Manuals/event_generation.rst b/documentation/source/NuRadioMC/pages/Manuals/event_generation.rst index 8614eb648..4f9291717 100644 --- a/documentation/source/NuRadioMC/pages/Manuals/event_generation.rst +++ b/documentation/source/NuRadioMC/pages/Manuals/event_generation.rst @@ -379,8 +379,7 @@ The module ``NuRadioProposal.py`` in EvtGen can also be used standalone to study tau_codes = [15] * N_taus secondaries_array = proposal_functions.get_secondaries_array(energy_leptons, - lepton_codes, - config_file='InfIce', + tau_codes, low_nu=0.1*units.PeV, propagate_decay_muons=True) From 1c60ce1e89e6be0f821885f55381daa6f2f8f9e9 Mon Sep 17 00:00:00 2001 From: Janna Vischer Date: Tue, 7 Feb 2023 14:29:00 +0100 Subject: [PATCH 126/418] changed set_trigger_time to be consistent --- NuRadioReco/framework/trigger.py | 2 ++ NuRadioReco/modules/phasedarray/triggerSimulator.py | 12 ++++++------ NuRadioReco/modules/trigger/highLowThreshold.py | 4 ++-- NuRadioReco/modules/trigger/multiHighLowThreshold.py | 2 ++ NuRadioReco/modules/trigger/powerIntegration.py | 1 + NuRadioReco/modules/trigger/rnog_surface_trigger.py | 2 +- NuRadioReco/modules/trigger/simpleThreshold.py | 3 ++- 7 files changed, 16 insertions(+), 10 deletions(-) diff --git a/NuRadioReco/framework/trigger.py b/NuRadioReco/framework/trigger.py index cbbe73434..28f866220 100644 --- a/NuRadioReco/framework/trigger.py +++ b/NuRadioReco/framework/trigger.py @@ -99,6 +99,8 @@ def get_trigger_times(self): """ get the trigger times (time with respect to beginning of trace?) """ + if self._trigger_times is None and not np.isnan(self._trigger_time): + return np.array(self._trigger_time) return self._trigger_times def get_name(self): diff --git a/NuRadioReco/modules/phasedarray/triggerSimulator.py b/NuRadioReco/modules/phasedarray/triggerSimulator.py index d5bf7c545..adb4d4ef1 100644 --- a/NuRadioReco/modules/phasedarray/triggerSimulator.py +++ b/NuRadioReco/modules/phasedarray/triggerSimulator.py @@ -333,9 +333,9 @@ def phased_trigger(self, station, det, the delays for the primary channels that have caused a trigger. If there is no trigger, it's an empty dictionary trigger_time: float - the earliest trigger time + the earliest trigger time with respect to interaction time. trigger_times: dictionary - all time bins that fulfil the trigger condition per beam. The key is the beam number. + all time bins that fulfil the trigger condition per beam. The key is the beam number. Time with respect to interaction time. """ if(triggered_channels is None): @@ -444,7 +444,7 @@ def phased_trigger(self, station, det, # logger.debug(f"trigger times = {trigger_times[iTrace]}") if is_triggered: # logger.debug(trigger_times) - trigger_time = min([x.min() for x in trigger_times.values()]) + trigger_time = min([x.min() for x in trigger_times.values()])+ channel_trace_start_time # logger.debug(f"minimum trigger time is {trigger_time:.0f}ns") return is_triggered, trigger_delays, trigger_time, trigger_times @@ -564,10 +564,10 @@ def run(self, evt, station, det, primary_angles=phasing_angles, trigger_delays=trigger_delays) trigger.set_triggered(is_triggered) - + if is_triggered: - trigger.set_trigger_time(trigger_time) - trigger.set_trigger_times(trigger_times) + trigger.set_trigger_time(trigger_time)# #trigger_time= time from start of trace + start time of trace with respect to moment of interaction = trigger time from moment of interaction; time offset to interaction time (channel_trace_start_time) already recognized in self.phased_trigger + trigger.set_trigger_times(trigger_times) ##trigger_time= time from start of trace + start time of trace with respect to moment of interaction = trigger time from moment of interaction; time offset to interaction time (channel_trace_start_time) already recognized in self.phased_trigger else: trigger.set_trigger_time(None) diff --git a/NuRadioReco/modules/trigger/highLowThreshold.py b/NuRadioReco/modules/trigger/highLowThreshold.py index 79779b62d..8fbff36c3 100644 --- a/NuRadioReco/modules/trigger/highLowThreshold.py +++ b/NuRadioReco/modules/trigger/highLowThreshold.py @@ -192,8 +192,8 @@ def run(self, evt, station, det, logger.info("Station has NOT passed trigger") else: trigger.set_triggered(True) - trigger.set_trigger_time(triggered_times.min() + channel_trace_start_time) - trigger.set_trigger_times(triggered_times + channel_trace_start_time) + trigger.set_trigger_time(triggered_times.min()+channel_trace_start_time) #trigger_time= time from start of trace + start time of trace with respect to moment of interaction = trigger time from moment of interaction + trigger.set_trigger_times(triggered_times+channel_trace_start_time) #trigger_times= times from start of trace + start time of trace with respect to moment of interaction = trigger times from moment of interaction logger.info("Station has passed trigger, trigger time is {:.1f} ns".format( trigger.get_trigger_time() / units.ns)) diff --git a/NuRadioReco/modules/trigger/multiHighLowThreshold.py b/NuRadioReco/modules/trigger/multiHighLowThreshold.py index 2c43b4907..ae1aa5bf6 100644 --- a/NuRadioReco/modules/trigger/multiHighLowThreshold.py +++ b/NuRadioReco/modules/trigger/multiHighLowThreshold.py @@ -173,9 +173,11 @@ def run(self, evt, station, det, if not has_triggered: trigger.set_triggered(False) logger.info("Station has NOT passed trigger") + trigger.set_trigger_time(None) else: trigger.set_triggered(True) trigger.set_trigger_time(triggered_times.min() + channel_trace_start_time) + #trigger_time= earliest trigger_time from start of trace + start time of trace with respect to moment of interaction = trigger time from moment of interaction logger.info("Station has passed trigger, trigger time is {:.1f} ns".format( trigger.get_trigger_time() / units.ns)) diff --git a/NuRadioReco/modules/trigger/powerIntegration.py b/NuRadioReco/modules/trigger/powerIntegration.py index b7f375219..cd0b8af91 100644 --- a/NuRadioReco/modules/trigger/powerIntegration.py +++ b/NuRadioReco/modules/trigger/powerIntegration.py @@ -131,6 +131,7 @@ def run(self, evt, station, det, logger.debug("station has triggered") else: trigger.set_triggered(False) + trigger.set_trigger_time(None) logger.debug("station has NOT triggered") station.set_trigger(trigger) diff --git a/NuRadioReco/modules/trigger/rnog_surface_trigger.py b/NuRadioReco/modules/trigger/rnog_surface_trigger.py index 4d739a8fa..8b3f75b23 100644 --- a/NuRadioReco/modules/trigger/rnog_surface_trigger.py +++ b/NuRadioReco/modules/trigger/rnog_surface_trigger.py @@ -183,7 +183,7 @@ def run(self, evt, station, det, threshold, coinc_window=60*units.ns, number_coi if has_triggered: trigger.set_triggered(True) - trigger.set_trigger_time(triggered_times.min() + channel_trace_start_time) # trigger_time = time from the beginning of the trace + trigger.set_trigger_time(triggered_times.min()+channel_trace_start_time) # trigger_time = time from moment of interaction logger.debug("station has triggered") else: diff --git a/NuRadioReco/modules/trigger/simpleThreshold.py b/NuRadioReco/modules/trigger/simpleThreshold.py index fa33fc22b..ef164d994 100644 --- a/NuRadioReco/modules/trigger/simpleThreshold.py +++ b/NuRadioReco/modules/trigger/simpleThreshold.py @@ -113,10 +113,11 @@ def run(self, evt, station, det, trigger.set_triggered_channels(channels_that_passed_trigger) if has_triggered: trigger.set_triggered(True) - trigger.set_trigger_time(triggered_times.min() + channel_trace_start_time) + trigger.set_trigger_time(triggered_times.min() + channel_trace_start_time) #trigger_time= earliest trigger_time from start of trace + start time of trace with respect to moment of interaction = trigger time from moment of interaction self.logger.debug("station has triggered") else: trigger.set_triggered(False) + trigger.set_trigger_time(None) self.logger.debug("station has NOT triggered") station.set_trigger(trigger) From 4c418d7ee3fb1afb1efd75b91903574c65d94785 Mon Sep 17 00:00:00 2001 From: Janna Vischer Date: Tue, 7 Feb 2023 15:08:53 +0100 Subject: [PATCH 127/418] deleted ?, removed set_trigger_time(None) again --- NuRadioReco/framework/trigger.py | 2 +- NuRadioReco/modules/trigger/multiHighLowThreshold.py | 1 - NuRadioReco/modules/trigger/powerIntegration.py | 1 - NuRadioReco/modules/trigger/simpleThreshold.py | 3 +-- 4 files changed, 2 insertions(+), 5 deletions(-) diff --git a/NuRadioReco/framework/trigger.py b/NuRadioReco/framework/trigger.py index 28f866220..b873079c8 100644 --- a/NuRadioReco/framework/trigger.py +++ b/NuRadioReco/framework/trigger.py @@ -97,7 +97,7 @@ def set_trigger_times(self, times): def get_trigger_times(self): """ - get the trigger times (time with respect to beginning of trace?) + get the trigger times (time with respect to beginning of trace) """ if self._trigger_times is None and not np.isnan(self._trigger_time): return np.array(self._trigger_time) diff --git a/NuRadioReco/modules/trigger/multiHighLowThreshold.py b/NuRadioReco/modules/trigger/multiHighLowThreshold.py index ae1aa5bf6..8e120dcd6 100644 --- a/NuRadioReco/modules/trigger/multiHighLowThreshold.py +++ b/NuRadioReco/modules/trigger/multiHighLowThreshold.py @@ -173,7 +173,6 @@ def run(self, evt, station, det, if not has_triggered: trigger.set_triggered(False) logger.info("Station has NOT passed trigger") - trigger.set_trigger_time(None) else: trigger.set_triggered(True) trigger.set_trigger_time(triggered_times.min() + channel_trace_start_time) diff --git a/NuRadioReco/modules/trigger/powerIntegration.py b/NuRadioReco/modules/trigger/powerIntegration.py index cd0b8af91..b7f375219 100644 --- a/NuRadioReco/modules/trigger/powerIntegration.py +++ b/NuRadioReco/modules/trigger/powerIntegration.py @@ -131,7 +131,6 @@ def run(self, evt, station, det, logger.debug("station has triggered") else: trigger.set_triggered(False) - trigger.set_trigger_time(None) logger.debug("station has NOT triggered") station.set_trigger(trigger) diff --git a/NuRadioReco/modules/trigger/simpleThreshold.py b/NuRadioReco/modules/trigger/simpleThreshold.py index ef164d994..b04ef5505 100644 --- a/NuRadioReco/modules/trigger/simpleThreshold.py +++ b/NuRadioReco/modules/trigger/simpleThreshold.py @@ -116,8 +116,7 @@ def run(self, evt, station, det, trigger.set_trigger_time(triggered_times.min() + channel_trace_start_time) #trigger_time= earliest trigger_time from start of trace + start time of trace with respect to moment of interaction = trigger time from moment of interaction self.logger.debug("station has triggered") else: - trigger.set_triggered(False) - trigger.set_trigger_time(None) + trigger.set_triggered(False)s self.logger.debug("station has NOT triggered") station.set_trigger(trigger) From 72cdbd509e0e19e1bcf821641ecb1933004a9c5c Mon Sep 17 00:00:00 2001 From: Janna Vischer Date: Tue, 7 Feb 2023 15:10:06 +0100 Subject: [PATCH 128/418] typo --- NuRadioReco/modules/trigger/simpleThreshold.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NuRadioReco/modules/trigger/simpleThreshold.py b/NuRadioReco/modules/trigger/simpleThreshold.py index b04ef5505..f86d860cd 100644 --- a/NuRadioReco/modules/trigger/simpleThreshold.py +++ b/NuRadioReco/modules/trigger/simpleThreshold.py @@ -116,7 +116,7 @@ def run(self, evt, station, det, trigger.set_trigger_time(triggered_times.min() + channel_trace_start_time) #trigger_time= earliest trigger_time from start of trace + start time of trace with respect to moment of interaction = trigger time from moment of interaction self.logger.debug("station has triggered") else: - trigger.set_triggered(False)s + trigger.set_triggered(False) self.logger.debug("station has NOT triggered") station.set_trigger(trigger) From 295b19e92eefd1b11249a2dde4ed8242c83889a5 Mon Sep 17 00:00:00 2001 From: Christoph Date: Tue, 7 Feb 2023 10:26:41 -0600 Subject: [PATCH 129/418] Add detector description for RNO-G 2022 detector --- .../detector/RNO_G/RNO_season_2022.json | 3389 +++++++++++++++++ 1 file changed, 3389 insertions(+) create mode 100644 NuRadioReco/detector/RNO_G/RNO_season_2022.json diff --git a/NuRadioReco/detector/RNO_G/RNO_season_2022.json b/NuRadioReco/detector/RNO_G/RNO_season_2022.json new file mode 100644 index 000000000..0c66c43ce --- /dev/null +++ b/NuRadioReco/detector/RNO_G/RNO_season_2022.json @@ -0,0 +1,3389 @@ +{ + "channels": { + "0": { + "station_id": 11, + "channel_id": 9, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 17.65828620550269, + "ant_position_y": -26.721175490583278, + "ant_position_z": -82.95, + "amp_type": "iglu", + "cab_time_delay": 704.8660580862335, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-11T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "1": { + "station_id": 11, + "channel_id": 10, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 17.65828620550269, + "ant_position_y": -26.721175490583278, + "ant_position_z": -81.94, + "amp_type": "iglu", + "cab_time_delay": 700.3063612901005, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-11T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "2": { + "station_id": 11, + "channel_id": 11, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 17.65828620550269, + "ant_position_y": -26.721175490583278, + "ant_position_z": -80.94, + "amp_type": "iglu", + "cab_time_delay": 695.125480287199, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-11T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_quadslot_v3_air_rescaled_to_n1.74" + }, + "3": { + "station_id": 11, + "channel_id": 21, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 34.17084392926063, + "ant_position_y": 3.189654025408913, + "ant_position_z": -94.66, + "amp_type": "iglu", + "cab_time_delay": 695.0278958661603, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-11T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_quadslot_v3_air_rescaled_to_n1.74" + }, + "4": { + "station_id": 11, + "channel_id": 22, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 34.17084392926063, + "ant_position_y": 3.189654025408913, + "ant_position_z": -95.66, + "amp_type": "iglu", + "cab_time_delay": 700.4737404863125, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-11T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "5": { + "station_id": 11, + "channel_id": 23, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 34.17084392926063, + "ant_position_y": 3.189654025408913, + "ant_position_z": -96.67, + "amp_type": "iglu", + "cab_time_delay": 704.7261333365847, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-11T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "6": { + "station_id": 11, + "channel_id": 0, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -96.215, + "amp_type": "iglu", + "cab_time_delay": 714.4923798064285, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-11T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "7": { + "station_id": 11, + "channel_id": 1, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -95.174, + "amp_type": "iglu", + "cab_time_delay": 709.9935958304959, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-11T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "8": { + "station_id": 11, + "channel_id": 2, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -94.183, + "amp_type": "iglu", + "cab_time_delay": 704.7279049211579, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-11T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "9": { + "station_id": 11, + "channel_id": 3, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -93.155, + "amp_type": "iglu", + "cab_time_delay": 700.4277318007989, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-11T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "10": { + "station_id": 11, + "channel_id": 4, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -91.218, + "amp_type": "iglu", + "cab_time_delay": 690.6185223242599, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-11T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_quadslot_v3_air_rescaled_to_n1.74" + }, + "11": { + "station_id": 11, + "channel_id": 5, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -79.121, + "amp_type": "iglu", + "cab_time_delay": 583.0629875035971, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-11T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "12": { + "station_id": 11, + "channel_id": 6, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -59.131, + "amp_type": "iglu", + "cab_time_delay": 484.257805977493, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-11T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "13": { + "station_id": 11, + "channel_id": 7, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -39.357, + "amp_type": "iglu", + "cab_time_delay": 387.1159239346471, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-11T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "14": { + "station_id": 11, + "channel_id": 8, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -92.177, + "amp_type": "iglu", + "cab_time_delay": 695.0077691915028, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-11T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_quadslot_v3_air_rescaled_to_n1.74" + }, + "15": { + "station_id": 11, + "channel_id": 15, + "ant_rotation_phi": 351.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 81.0, + "ant_orientation_theta": 120.0, + "ant_position_x": 13.094071426842675, + "ant_position_y": -1.3494044168342043, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 52.7, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-11T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "16": { + "station_id": 11, + "channel_id": 16, + "ant_rotation_phi": 351.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 11.930184622833622, + "ant_position_y": -3.680467011662472, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 45.5, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-11T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "17": { + "station_id": 11, + "channel_id": 17, + "ant_rotation_phi": 351.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 261.0, + "ant_orientation_theta": 120.0, + "ant_position_x": 11.294434887851821, + "ant_position_y": -8.874503105185909, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 52.7, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-11T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "18": { + "station_id": 11, + "channel_id": 18, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 180.0, + "ant_orientation_theta": 120.0, + "ant_position_x": 15.668829377380007, + "ant_position_y": -17.09129526105096, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 52.7, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-11T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "19": { + "station_id": 11, + "channel_id": 19, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 18.37079660752329, + "ant_position_y": -16.26019998902143, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 45.5, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-11T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "20": { + "station_id": 11, + "channel_id": 20, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 120.0, + "ant_position_x": 21.331834824350608, + "ant_position_y": -17.227018480620586, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 49.1, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-11T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "21": { + "station_id": 11, + "channel_id": 12, + "ant_rotation_phi": 243.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 333.0, + "ant_orientation_theta": 120.0, + "ant_position_x": 25.416448281676367, + "ant_position_y": -9.147827107359035, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 49.1, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-11T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "22": { + "station_id": 11, + "channel_id": 13, + "ant_rotation_phi": 243.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 24.362331362427312, + "ant_position_y": -6.738870967144862, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 45.5, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-11T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "23": { + "station_id": 11, + "channel_id": 14, + "ant_rotation_phi": 243.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 153.0, + "ant_orientation_theta": 120.0, + "ant_position_x": 22.99219287896267, + "ant_position_y": -4.185859006174496, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 49.1, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-11T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "24": { + "station_id": 12, + "channel_id": 0, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -94.209, + "amp_type": "iglu", + "cab_time_delay": 716.0848684487527, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-16T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "25": { + "station_id": 12, + "channel_id": 1, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -93.243, + "amp_type": "iglu", + "cab_time_delay": 710.0, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-16T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "26": { + "station_id": 12, + "channel_id": 2, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -92.24, + "amp_type": "iglu", + "cab_time_delay": 705.9547809582946, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-16T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "27": { + "station_id": 12, + "channel_id": 3, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -91.262, + "amp_type": "iglu", + "cab_time_delay": 701.837187725609, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-16T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "28": { + "station_id": 12, + "channel_id": 4, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -89.319, + "amp_type": "iglu", + "cab_time_delay": 691.703621620457, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-16T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_quadslot_v3_air_rescaled_to_n1.74" + }, + "29": { + "station_id": 12, + "channel_id": 5, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -77.279, + "amp_type": "iglu", + "cab_time_delay": 583.1145481356763, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-16T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "30": { + "station_id": 12, + "channel_id": 6, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -57.252, + "amp_type": "iglu", + "cab_time_delay": 484.39813876384204, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-16T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "31": { + "station_id": 12, + "channel_id": 7, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -37.262, + "amp_type": "iglu", + "cab_time_delay": 387.28183644102774, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-16T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "32": { + "station_id": 12, + "channel_id": 8, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -90.297, + "amp_type": "iglu", + "cab_time_delay": 696.568527555139, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-16T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_quadslot_v3_air_rescaled_to_n1.74" + }, + "33": { + "station_id": 12, + "channel_id": 14, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 120.0, + "ant_position_x": 2.539586658924236, + "ant_position_y": 13.036622167753876, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 45.5, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-16T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "34": { + "station_id": 12, + "channel_id": 13, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": -0.2654931559418401, + "ant_position_y": 13.217878076629859, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 45.5, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-16T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "35": { + "station_id": 12, + "channel_id": 12, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 180.0, + "ant_orientation_theta": 120.0, + "ant_position_x": -3.34707349198834, + "ant_position_y": 13.389808333216479, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 45.5, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-16T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "36": { + "station_id": 12, + "channel_id": 20, + "ant_rotation_phi": 330.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 240.0, + "ant_orientation_theta": 120.0, + "ant_position_x": -7.438491687251371, + "ant_position_y": 21.576903538867327, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 45.5, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-17T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "37": { + "station_id": 12, + "channel_id": 19, + "ant_rotation_phi": 330.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": -6.30763721672588, + "ant_position_y": 23.948815527683337, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 45.5, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-17T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "38": { + "station_id": 12, + "channel_id": 18, + "ant_rotation_phi": 330.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 60.0, + "ant_orientation_theta": 120.0, + "ant_position_x": -4.532587143004093, + "ant_position_y": 26.735356136899554, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 45.5, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-17T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "39": { + "station_id": 12, + "channel_id": 17, + "ant_rotation_phi": 210.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 120.0, + "ant_orientation_theta": 120.0, + "ant_position_x": 4.158899871513313, + "ant_position_y": 26.003802943914252, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 45.5, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-21T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "40": { + "station_id": 12, + "channel_id": 16, + "ant_rotation_phi": 210.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 5.329066448228559, + "ant_position_y": 23.906866861842673, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 45.5, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-21T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "41": { + "station_id": 12, + "channel_id": 15, + "ant_rotation_phi": 210.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 300.0, + "ant_orientation_theta": 120.0, + "ant_position_x": 6.884704326280371, + "ant_position_y": 21.587278338471833, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 45.5, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-21T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "42": { + "station_id": 12, + "channel_id": 21, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 17.581677025974614, + "ant_position_y": 30.76938616345069, + "ant_position_z": -92.799, + "amp_type": "iglu", + "cab_time_delay": 694.4016530026131, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-17T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_quadslot_v3_air_rescaled_to_n1.74" + }, + "43": { + "station_id": 12, + "channel_id": 22, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 17.581677025974614, + "ant_position_y": 30.76938616345069, + "ant_position_z": -93.764, + "amp_type": "iglu", + "cab_time_delay": 699.8409090956202, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-17T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "44": { + "station_id": 12, + "channel_id": 23, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 17.581677025974614, + "ant_position_y": 30.76938616345069, + "ant_position_z": -94.755, + "amp_type": "iglu", + "cab_time_delay": 704.1016818511831, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-17T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "45": { + "station_id": 12, + "channel_id": 9, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": -17.416838993123974, + "ant_position_y": 30.243742503690555, + "ant_position_z": -93.472, + "amp_type": "iglu", + "cab_time_delay": 704.8326985978704, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-21T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "46": { + "station_id": 12, + "channel_id": 10, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": -17.416838993123974, + "ant_position_y": 30.243742503690555, + "ant_position_z": -92.507, + "amp_type": "iglu", + "cab_time_delay": 700.5853011208408, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-21T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "47": { + "station_id": 12, + "channel_id": 11, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": -17.416838993123974, + "ant_position_y": 30.243742503690555, + "ant_position_z": -91.491, + "amp_type": "iglu", + "cab_time_delay": 695.0992381351823, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-21T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_quadslot_v3_air_rescaled_to_n1.74" + }, + "48": { + "station_id": 13, + "channel_id": 0, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -96.266, + "amp_type": "iglu", + "cab_time_delay": 714.7889003542323, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-30T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "49": { + "station_id": 13, + "channel_id": 1, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -95.25, + "amp_type": "iglu", + "cab_time_delay": 710.125994185995, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-30T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "50": { + "station_id": 13, + "channel_id": 2, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -94.259, + "amp_type": "iglu", + "cab_time_delay": 704.907717791364, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-30T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "51": { + "station_id": 13, + "channel_id": 3, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -93.218, + "amp_type": "iglu", + "cab_time_delay": 700.5047756955887, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-30T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "52": { + "station_id": 13, + "channel_id": 4, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -91.211, + "amp_type": "iglu", + "cab_time_delay": 690.6134090862433, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-30T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_quadslot_v3_air_rescaled_to_n1.74" + }, + "53": { + "station_id": 13, + "channel_id": 5, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -79.175, + "amp_type": "iglu", + "cab_time_delay": 583.6510751776831, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-30T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "54": { + "station_id": 13, + "channel_id": 6, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -59.182, + "amp_type": "iglu", + "cab_time_delay": 484.71366908125884, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-30T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "55": { + "station_id": 13, + "channel_id": 7, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -39.243, + "amp_type": "iglu", + "cab_time_delay": 387.4357117300662, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-30T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "56": { + "station_id": 13, + "channel_id": 8, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -92.215, + "amp_type": "iglu", + "cab_time_delay": 695.082404371683, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-30T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_quadslot_v3_air_rescaled_to_n1.74" + }, + "57": { + "station_id": 13, + "channel_id": 14, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 120.0, + "ant_position_x": 3.786633345246628, + "ant_position_y": 14.166779940559536, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 45.5, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-30T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "58": { + "station_id": 13, + "channel_id": 13, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.5170404001173665, + "ant_position_y": 13.354700187115668, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 45.5, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-30T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "59": { + "station_id": 13, + "channel_id": 12, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 180.0, + "ant_orientation_theta": 120.0, + "ant_position_x": -2.2542482378421482, + "ant_position_y": 13.38742235362679, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 45.5, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-30T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "60": { + "station_id": 13, + "channel_id": 20, + "ant_rotation_phi": 330.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 240.0, + "ant_orientation_theta": 120.0, + "ant_position_x": -6.885310134508927, + "ant_position_y": 21.608732090688136, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 45.5, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-07-04T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "61": { + "station_id": 13, + "channel_id": 19, + "ant_rotation_phi": 330.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": -5.170894448983063, + "ant_position_y": 24.792913281642996, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 45.5, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-07-04T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "62": { + "station_id": 13, + "channel_id": 18, + "ant_rotation_phi": 330.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 60.0, + "ant_orientation_theta": 120.0, + "ant_position_x": -3.818831338219752, + "ant_position_y": 26.426624719792926, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 45.5, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-07-04T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "63": { + "station_id": 13, + "channel_id": 17, + "ant_rotation_phi": 210.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 120.0, + "ant_orientation_theta": 120.0, + "ant_position_x": 5.011324429098067, + "ant_position_y": 26.55067316693976, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 45.5, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "64": { + "station_id": 13, + "channel_id": 16, + "ant_rotation_phi": 210.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 6.441622853624722, + "ant_position_y": 23.596333245058304, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 45.5, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "65": { + "station_id": 13, + "channel_id": 15, + "ant_rotation_phi": 210.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 300.0, + "ant_orientation_theta": 120.0, + "ant_position_x": 7.702699241004211, + "ant_position_y": 21.375716286736406, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 45.5, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "66": { + "station_id": 13, + "channel_id": 9, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": -16.785614958664155, + "ant_position_y": 29.370321702003366, + "ant_position_z": -94.818, + "amp_type": "iglu", + "cab_time_delay": 705.8226166224723, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "67": { + "station_id": 13, + "channel_id": 10, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": -16.785614958664155, + "ant_position_y": 29.370321702003366, + "ant_position_z": -93.802, + "amp_type": "iglu", + "cab_time_delay": 701.4365946711572, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "68": { + "station_id": 13, + "channel_id": 11, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": -16.785614958664155, + "ant_position_y": 29.370321702003366, + "ant_position_z": -92.812, + "amp_type": "iglu", + "cab_time_delay": 696.2095237776895, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_quadslot_v3_air_rescaled_to_n1.74" + }, + "69": { + "station_id": 13, + "channel_id": 21, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 18.521789931312696, + "ant_position_y": 30.147367825982656, + "ant_position_z": -93.091, + "amp_type": "iglu", + "cab_time_delay": 694.966307648661, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-07-04T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_quadslot_v3_air_rescaled_to_n1.74" + }, + "70": { + "station_id": 13, + "channel_id": 22, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 18.521789931312696, + "ant_position_y": 30.147367825982656, + "ant_position_z": -94.082, + "amp_type": "iglu", + "cab_time_delay": 700.4557991679768, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-07-04T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "71": { + "station_id": 13, + "channel_id": 23, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 18.521789931312696, + "ant_position_y": 30.147367825982656, + "ant_position_z": -95.098, + "amp_type": "iglu", + "cab_time_delay": 704.7490940670381, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-07-04T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "72": { + "station_id": 21, + "channel_id": 9, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": -17.202395931048557, + "ant_position_y": 29.097176873979663, + "ant_position_z": -94.7, + "amp_type": "iglu", + "cab_time_delay": 706.0498570594092, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-04T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "73": { + "station_id": 21, + "channel_id": 10, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": -17.202395931048557, + "ant_position_y": 29.097176873979663, + "ant_position_z": -93.71, + "amp_type": "iglu", + "cab_time_delay": 701.7155539494165, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-04T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "74": { + "station_id": 21, + "channel_id": 11, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": -17.202395931048557, + "ant_position_y": 29.097176873979663, + "ant_position_z": -92.7, + "amp_type": "iglu", + "cab_time_delay": 696.5371961764442, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-04T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_quadslot_v3_air_rescaled_to_n1.74" + }, + "75": { + "station_id": 21, + "channel_id": 21, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": -33.64796575784544, + "ant_position_y": -0.8015936150957828, + "ant_position_z": -93.37, + "amp_type": "iglu", + "cab_time_delay": 695.8319798499194, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-04T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_quadslot_v3_air_rescaled_to_n1.74" + }, + "76": { + "station_id": 21, + "channel_id": 22, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": -33.64796575784544, + "ant_position_y": -0.8015936150957828, + "ant_position_z": -94.34, + "amp_type": "iglu", + "cab_time_delay": 701.0882803491144, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-04T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "77": { + "station_id": 21, + "channel_id": 23, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": -33.64796575784544, + "ant_position_y": -0.8015936150957828, + "ant_position_z": -95.37, + "amp_type": "iglu", + "cab_time_delay": 705.241651007666, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-04T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "78": { + "station_id": 21, + "channel_id": 0, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -95.37, + "amp_type": "iglu", + "cab_time_delay": 714.4660516693513, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-04T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "79": { + "station_id": 21, + "channel_id": 1, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -94.37, + "amp_type": "iglu", + "cab_time_delay": 709.9058111253712, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-04T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "80": { + "station_id": 21, + "channel_id": 2, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -93.36, + "amp_type": "iglu", + "cab_time_delay": 704.5363868097872, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-04T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "81": { + "station_id": 21, + "channel_id": 3, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -92.36, + "amp_type": "iglu", + "cab_time_delay": 700.3521325816487, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-04T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "82": { + "station_id": 21, + "channel_id": 4, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -90.39, + "amp_type": "iglu", + "cab_time_delay": 689.9220583040554, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-04T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_quadslot_v3_air_rescaled_to_n1.74" + }, + "83": { + "station_id": 21, + "channel_id": 5, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -78.42, + "amp_type": "iglu", + "cab_time_delay": 583.6085635800221, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-04T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "84": { + "station_id": 21, + "channel_id": 6, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -57.98, + "amp_type": "iglu", + "cab_time_delay": 484.73964774406437, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-04T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "85": { + "station_id": 21, + "channel_id": 7, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -38.33, + "amp_type": "iglu", + "cab_time_delay": 387.6103598042084, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-04T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "86": { + "station_id": 21, + "channel_id": 8, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -91.37, + "amp_type": "iglu", + "cab_time_delay": 695.0287325115062, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-04T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_quadslot_v3_air_rescaled_to_n1.74" + }, + "87": { + "station_id": 21, + "channel_id": 20, + "ant_rotation_phi": 118.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 208.0, + "ant_orientation_theta": 120.0, + "ant_position_x": -11.290159792234533, + "ant_position_y": 3.2254831301034983, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 49.1, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-04T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "88": { + "station_id": 21, + "channel_id": 19, + "ant_rotation_phi": 118.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": -9.89226707611931, + "ant_position_y": 5.594519497753538, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 45.5, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-04T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "89": { + "station_id": 21, + "channel_id": 18, + "ant_rotation_phi": 118.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 28.0, + "ant_orientation_theta": 120.0, + "ant_position_x": -8.529386998481584, + "ant_position_y": 8.05359447730956, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 49.1, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-04T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "90": { + "station_id": 21, + "channel_id": 17, + "ant_rotation_phi": 254.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 344.0, + "ant_orientation_theta": 120.0, + "ant_position_x": -15.625844861430721, + "ant_position_y": 17.5452668631047, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 49.1, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-04T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "91": { + "station_id": 21, + "channel_id": 16, + "ant_rotation_phi": 254.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": -18.205823589177555, + "ant_position_y": 17.169127453384192, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 45.5, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-04T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "92": { + "station_id": 21, + "channel_id": 15, + "ant_rotation_phi": 254.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 164.0, + "ant_orientation_theta": 120.0, + "ant_position_x": -20.612812283165965, + "ant_position_y": 16.93301208843849, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 49.1, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-04T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "93": { + "station_id": 21, + "channel_id": 14, + "ant_rotation_phi": 65.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 155.0, + "ant_orientation_theta": 120.0, + "ant_position_x": -25.071362730198928, + "ant_position_y": 7.489814438818087, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 49.1, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-04T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "94": { + "station_id": 21, + "channel_id": 13, + "ant_rotation_phi": 65.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": -23.818253758031403, + "ant_position_y": 5.257865215171478, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 45.5, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-04T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "95": { + "station_id": 21, + "channel_id": 12, + "ant_rotation_phi": 65.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 335.0, + "ant_orientation_theta": 120.0, + "ant_position_x": -22.461155396339052, + "ant_position_y": 3.2079300892245897, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 49.1, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-04T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "96": { + "station_id": 22, + "channel_id": 9, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": -17.512609715763574, + "ant_position_y": 33.130260578744355, + "ant_position_z": -96.8, + "amp_type": "iglu", + "cab_time_delay": 706.0498570594092, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "97": { + "station_id": 22, + "channel_id": 10, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": -17.512609715763574, + "ant_position_y": 33.130260578744355, + "ant_position_z": -95.8, + "amp_type": "iglu", + "cab_time_delay": 701.7155539494165, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "98": { + "station_id": 22, + "channel_id": 11, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": -17.512609715763574, + "ant_position_y": 33.130260578744355, + "ant_position_z": -94.8, + "amp_type": "iglu", + "cab_time_delay": 696.5371961764442, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_quadslot_v3_air_rescaled_to_n1.74" + }, + "99": { + "station_id": 22, + "channel_id": 21, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 17.289818380904876, + "ant_position_y": 26.163474852590753, + "ant_position_z": -94.61, + "amp_type": "iglu", + "cab_time_delay": 695.0887166749822, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_quadslot_v3_air_rescaled_to_n1.74" + }, + "100": { + "station_id": 22, + "channel_id": 22, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 17.289818380904876, + "ant_position_y": 26.163474852590753, + "ant_position_z": -95.61, + "amp_type": "iglu", + "cab_time_delay": 700.5097259660157, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "101": { + "station_id": 22, + "channel_id": 23, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 17.289818380904876, + "ant_position_y": 26.163474852590753, + "ant_position_z": -96.62, + "amp_type": "iglu", + "cab_time_delay": 704.7852281608289, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "102": { + "station_id": 22, + "channel_id": 0, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -95.67, + "amp_type": "iglu", + "cab_time_delay": 714.7593297729006, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "103": { + "station_id": 22, + "channel_id": 1, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -94.66, + "amp_type": "iglu", + "cab_time_delay": 710.1658529670598, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "104": { + "station_id": 22, + "channel_id": 2, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -93.66, + "amp_type": "iglu", + "cab_time_delay": 704.9040443161012, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "105": { + "station_id": 22, + "channel_id": 3, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -92.66, + "amp_type": "iglu", + "cab_time_delay": 700.4520344958491, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "106": { + "station_id": 22, + "channel_id": 4, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -90.72, + "amp_type": "iglu", + "cab_time_delay": 690.5959592568203, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_quadslot_v3_air_rescaled_to_n1.74" + }, + "107": { + "station_id": 22, + "channel_id": 5, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -78.7, + "amp_type": "iglu", + "cab_time_delay": 583.316058590185, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "108": { + "station_id": 22, + "channel_id": 6, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -58.62, + "amp_type": "iglu", + "cab_time_delay": 484.8636828671781, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "109": { + "station_id": 22, + "channel_id": 7, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -38.53, + "amp_type": "iglu", + "cab_time_delay": 387.5505598225923, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "110": { + "station_id": 22, + "channel_id": 8, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -91.67, + "amp_type": "iglu", + "cab_time_delay": 695.1562845004979, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_quadslot_v3_air_rescaled_to_n1.74" + }, + "111": { + "station_id": 22, + "channel_id": 20, + "ant_rotation_phi": 81.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 351.0, + "ant_orientation_theta": 120.0, + "ant_position_x": 2.457469936325765, + "ant_position_y": 11.075112525619716, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 49.1, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "112": { + "station_id": 22, + "channel_id": 19, + "ant_rotation_phi": 81.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": -0.22255783581442756, + "ant_position_y": 11.485023263238872, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 45.5, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "113": { + "station_id": 22, + "channel_id": 18, + "ant_rotation_phi": 81.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 171.0, + "ant_orientation_theta": 120.0, + "ant_position_x": -2.507538126520444, + "ant_position_y": 11.198884671868882, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 52.7, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "114": { + "station_id": 22, + "channel_id": 17, + "ant_rotation_phi": 330.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 240.0, + "ant_orientation_theta": 120.0, + "ant_position_x": -8.601030022356213, + "ant_position_y": 21.441595538089814, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 52.7, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "115": { + "station_id": 22, + "channel_id": 16, + "ant_rotation_phi": 330.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": -7.492143334449793, + "ant_position_y": 23.84064026792589, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 45.5, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "116": { + "station_id": 22, + "channel_id": 15, + "ant_rotation_phi": 330.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 60.0, + "ant_orientation_theta": 120.0, + "ant_position_x": -6.486244820763773, + "ant_position_y": 25.951689672003567, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 52.7, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "117": { + "station_id": 22, + "channel_id": 14, + "ant_rotation_phi": 213.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 123.0, + "ant_orientation_theta": 120.0, + "ant_position_x": 5.359776608926268, + "ant_position_y": 25.52425338015405, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 49.1, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "118": { + "station_id": 22, + "channel_id": 13, + "ant_rotation_phi": 213.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 7.106892864807833, + "ant_position_y": 23.126331129435584, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 45.5, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "119": { + "station_id": 22, + "channel_id": 12, + "ant_rotation_phi": 213.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 303.0, + "ant_orientation_theta": 120.0, + "ant_position_x": 9.125221448120215, + "ant_position_y": 17.60411927594305, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 49.1, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "120": { + "station_id": 23, + "channel_id": 0, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -94.717, + "amp_type": "iglu", + "cab_time_delay": 715.2854637454359, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-23T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "121": { + "station_id": 23, + "channel_id": 1, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -93.751, + "amp_type": "iglu", + "cab_time_delay": 710.6324767769894, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-23T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "122": { + "station_id": 23, + "channel_id": 2, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -92.735, + "amp_type": "iglu", + "cab_time_delay": 705.3844946995908, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-23T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "123": { + "station_id": 23, + "channel_id": 3, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -91.745, + "amp_type": "iglu", + "cab_time_delay": 701.0937993250889, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-23T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "124": { + "station_id": 23, + "channel_id": 4, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -89.764, + "amp_type": "iglu", + "cab_time_delay": 690.9500500747815, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-23T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_quadslot_v3_air_rescaled_to_n1.74" + }, + "125": { + "station_id": 23, + "channel_id": 5, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -77.699, + "amp_type": "iglu", + "cab_time_delay": 582.3601331742286, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-23T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "126": { + "station_id": 23, + "channel_id": 6, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -57.709, + "amp_type": "iglu", + "cab_time_delay": 483.6670431088573, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-23T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "127": { + "station_id": 23, + "channel_id": 7, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -37.719, + "amp_type": "iglu", + "cab_time_delay": 386.37548644736046, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-23T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "128": { + "station_id": 23, + "channel_id": 8, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -90.729, + "amp_type": "iglu", + "cab_time_delay": 695.8484064369925, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-23T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_quadslot_v3_air_rescaled_to_n1.74" + }, + "129": { + "station_id": 23, + "channel_id": 14, + "ant_rotation_phi": 150.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 60.0, + "ant_orientation_theta": 120.0, + "ant_position_x": -9.145731458784894, + "ant_position_y": 8.913768817867094, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 45.5, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-23T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "130": { + "station_id": 23, + "channel_id": 13, + "ant_rotation_phi": 150.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": -10.299173874425378, + "ant_position_y": 6.6245011479177265, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 45.5, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-23T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "131": { + "station_id": 23, + "channel_id": 12, + "ant_rotation_phi": 150.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 240.0, + "ant_orientation_theta": 120.0, + "ant_position_x": -11.996588285220014, + "ant_position_y": 3.9565460690787404, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 45.5, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-23T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "132": { + "station_id": 23, + "channel_id": 9, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": -34.71897220803157, + "ant_position_y": -0.2424120679356747, + "ant_position_z": -94.945, + "amp_type": "iglu", + "cab_time_delay": 705.2304586807497, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-24T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "133": { + "station_id": 23, + "channel_id": 10, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": -34.71897220803157, + "ant_position_y": -0.2424120679356747, + "ant_position_z": -93.942, + "amp_type": "iglu", + "cab_time_delay": 701.1086074022868, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-24T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "134": { + "station_id": 23, + "channel_id": 11, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": -34.71897220803157, + "ant_position_y": -0.2424120679356747, + "ant_position_z": -92.951, + "amp_type": "iglu", + "cab_time_delay": 695.7224638947405, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-24T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_quadslot_v3_air_rescaled_to_n1.74" + }, + "135": { + "station_id": 23, + "channel_id": 20, + "ant_rotation_phi": 30.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 300.0, + "ant_orientation_theta": 120.0, + "ant_position_x": -21.231347283129708, + "ant_position_y": 4.513950933839169, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 45.5, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-26T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "136": { + "station_id": 23, + "channel_id": 19, + "ant_rotation_phi": 30.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": -22.522938539998904, + "ant_position_y": 6.905528423480973, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 45.5, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-26T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "137": { + "station_id": 23, + "channel_id": 18, + "ant_rotation_phi": 30.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 120.0, + "ant_orientation_theta": 120.0, + "ant_position_x": -24.034716776173582, + "ant_position_y": 9.398254723507762, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 45.5, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-26T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "138": { + "station_id": 23, + "channel_id": 21, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": -17.268506687948047, + "ant_position_y": 29.548845645087567, + "ant_position_z": -93.764, + "amp_type": "iglu", + "cab_time_delay": 696.6159498314443, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-26T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_quadslot_v3_air_rescaled_to_n1.74" + }, + "139": { + "station_id": 23, + "channel_id": 22, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": -17.268506687948047, + "ant_position_y": 29.548845645087567, + "ant_position_z": -94.767, + "amp_type": "iglu", + "cab_time_delay": 701.7183093306504, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-26T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "140": { + "station_id": 23, + "channel_id": 23, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": -17.268506687948047, + "ant_position_y": 29.548845645087567, + "ant_position_z": -95.783, + "amp_type": "iglu", + "cab_time_delay": 706.0542491285506, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-26T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "141": { + "station_id": 23, + "channel_id": 17, + "ant_rotation_phi": 270.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 180.0, + "ant_orientation_theta": 120.0, + "ant_position_x": -19.46415573737886, + "ant_position_y": 17.039319755117504, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 45.5, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-24T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "142": { + "station_id": 23, + "channel_id": 16, + "ant_rotation_phi": 270.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": -16.938725294545748, + "ant_position_y": 17.047938425702796, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 45.5, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-24T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "143": { + "station_id": 23, + "channel_id": 15, + "ant_rotation_phi": 270.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 120.0, + "ant_position_x": -13.914924097241965, + "ant_position_y": 17.110824238700843, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 45.5, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-24T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "144": { + "station_id": 24, + "channel_id": 0, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -97.638, + "amp_type": "iglu", + "cab_time_delay": 714.9553780139191, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-07-05T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "145": { + "station_id": 24, + "channel_id": 1, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -96.622, + "amp_type": "iglu", + "cab_time_delay": 710.3364846158909, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-07-05T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "146": { + "station_id": 24, + "channel_id": 2, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -95.631, + "amp_type": "iglu", + "cab_time_delay": 705.1212411537641, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-07-05T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "147": { + "station_id": 24, + "channel_id": 3, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -94.615, + "amp_type": "iglu", + "cab_time_delay": 700.6546072909622, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-07-05T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "148": { + "station_id": 24, + "channel_id": 4, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -92.659, + "amp_type": "iglu", + "cab_time_delay": 690.761838353226, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-07-05T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_quadslot_v3_air_rescaled_to_n1.74" + }, + "149": { + "station_id": 24, + "channel_id": 5, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -80.594, + "amp_type": "iglu", + "cab_time_delay": 583.7560433649974, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-07-05T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "150": { + "station_id": 24, + "channel_id": 6, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -60.604, + "amp_type": "iglu", + "cab_time_delay": 484.7189595813629, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-07-05T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "151": { + "station_id": 24, + "channel_id": 7, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -40.64, + "amp_type": "iglu", + "cab_time_delay": 387.69316314434445, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-07-05T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "152": { + "station_id": 24, + "channel_id": 8, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -93.65, + "amp_type": "iglu", + "cab_time_delay": 695.2098026860888, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-07-05T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_quadslot_v3_air_rescaled_to_n1.74" + }, + "153": { + "station_id": 24, + "channel_id": 14, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 120.0, + "ant_position_x": -2.4107968530154267, + "ant_position_y": 9.783970419230172, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 45.5, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-07-05T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "154": { + "station_id": 24, + "channel_id": 13, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": -4.9631461923006555, + "ant_position_y": 9.69794171581998, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 45.5, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-07-05T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "155": { + "station_id": 24, + "channel_id": 12, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 180.0, + "ant_orientation_theta": 120.0, + "ant_position_x": -7.77247372095303, + "ant_position_y": 8.763806538503559, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 45.5, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-07-05T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "156": { + "station_id": 24, + "channel_id": 9, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": -27.829750903225204, + "ant_position_y": 17.57035552463367, + "ant_position_z": -97.511, + "amp_type": "iglu", + "cab_time_delay": 705.32011112294, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-07-06T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "157": { + "station_id": 24, + "channel_id": 10, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": -27.829750903225204, + "ant_position_y": 17.57035552463367, + "ant_position_z": -96.495, + "amp_type": "iglu", + "cab_time_delay": 701.118919397236, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-07-06T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "158": { + "station_id": 24, + "channel_id": 11, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": -27.829750903225204, + "ant_position_y": 17.57035552463367, + "ant_position_z": -95.504, + "amp_type": "iglu", + "cab_time_delay": 695.8325149249811, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-07-06T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_quadslot_v3_air_rescaled_to_n1.74" + }, + "159": { + "station_id": 24, + "channel_id": 20, + "ant_rotation_phi": 330.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 240.0, + "ant_orientation_theta": 120.0, + "ant_position_x": -15.114711491152093, + "ant_position_y": 13.728847626744027, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 45.5, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-07-12T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "160": { + "station_id": 24, + "channel_id": 19, + "ant_rotation_phi": 330.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": -14.618930869291262, + "ant_position_y": 15.972603155508295, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 45.5, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-07-12T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "161": { + "station_id": 24, + "channel_id": 18, + "ant_rotation_phi": 330.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 60.0, + "ant_orientation_theta": 120.0, + "ant_position_x": -14.542975793120604, + "ant_position_y": 18.089740914087088, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 45.5, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-07-12T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "162": { + "station_id": 24, + "channel_id": 21, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 9.508991969799126, + "ant_position_y": 25.278154073230326, + "ant_position_z": -78.372, + "amp_type": "iglu", + "cab_time_delay": 696.0136180352841, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-07-12T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_quadslot_v3_air_rescaled_to_n1.74" + }, + "163": { + "station_id": 24, + "channel_id": 22, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 9.508991969799126, + "ant_position_y": 25.278154073230326, + "ant_position_z": -79.375, + "amp_type": "iglu", + "cab_time_delay": 701.1819591709564, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-07-12T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "164": { + "station_id": 24, + "channel_id": 23, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 9.508991969799126, + "ant_position_y": 25.278154073230326, + "ant_position_z": -80.391, + "amp_type": "iglu", + "cab_time_delay": 705.6007352061425, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-07-12T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "165": { + "station_id": 24, + "channel_id": 17, + "ant_rotation_phi": 210.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 120.0, + "ant_orientation_theta": 120.0, + "ant_position_x": -3.523766391932895, + "ant_position_y": 21.12356453178745, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 45.5, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-07-06T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "166": { + "station_id": 24, + "channel_id": 16, + "ant_rotation_phi": 210.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": -1.9287733031173957, + "ant_position_y": 18.788879136683136, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 45.5, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-07-06T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "167": { + "station_id": 24, + "channel_id": 15, + "ant_rotation_phi": 210.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 300.0, + "ant_orientation_theta": 120.0, + "ant_position_x": -0.27397536273974765, + "ant_position_y": 16.187269998868032, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 45.5, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-07-06T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + } + }, + "stations": { + "11": { + "station_id": 11, + "pos_easting": -1572.9090410360927, + "pos_northing": 730.0097743956222, + "pos_altitude": -4.020343715809474, + "pos_site": "summit", + "commission_time": "{TinyDate}:2021-07-11T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00" + }, + "12": { + "station_id": 12, + "pos_easting": -1351.8967744755353, + "pos_northing": 1910.9580108511489, + "pos_altitude": -0.8369486120851661, + "pos_site": "summit", + "commission_time": "{TinyDate}:2022-06-21T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00" + }, + "13": { + "station_id": 13, + "pos_easting": -1147.9083075603453, + "pos_northing": 3123.5718349467593, + "pos_altitude": 1.5406193864012039, + "pos_site": "summit", + "commission_time": "{TinyDate}:2022-07-04T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00" + }, + "21": { + "station_id": 21, + "pos_easting": -309.0768225767666, + "pos_northing": 496.70125599975694, + "pos_altitude": -2.220363866502197, + "pos_site": "summit", + "commission_time": "{TinyDate}:2021-07-04T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00" + }, + "22": { + "station_id": 22, + "pos_easting": -138.90892985064465, + "pos_northing": 1708.3983875984213, + "pos_altitude": -1.7496338754364729, + "pos_site": "summit", + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00" + }, + "23": { + "station_id": 23, + "pos_easting": 82.7152583896534, + "pos_northing": 2949.9462662340484, + "pos_altitude": 0.36723808113731593, + "pos_site": "summit", + "commission_time": "{TinyDate}:2022-06-26T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00" + }, + "24": { + "station_id": 24, + "pos_easting": 276.81579542974464, + "pos_northing": 4137.742814240752, + "pos_altitude": -7.394863138445771, + "pos_site": "summit", + "commission_time": "{TinyDate}:2022-07-12T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00" + } + }, + "devices": { + "1": { + "ant_comment": "Helper String B Cal Vpol", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_position_x": 17.65828620550269, + "ant_position_y": -26.721175490583278, + "ant_position_z": -79.92, + "commission_time": "{TinyDate}:2021-07-11T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "device_id": 1, + "station_id": 11 + }, + "0": { + "ant_comment": "Helper String C Cal Vpol", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_position_x": 34.17084392926063, + "ant_position_y": 3.189654025408913, + "ant_position_z": -93.68, + "commission_time": "{TinyDate}:2021-07-11T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "device_id": 0, + "station_id": 11 + }, + "2": { + "ant_comment": "Surface Cal Pulser", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_position_x": 18.522057653936827, + "ant_position_y": -1.0081566176784236, + "ant_position_z": -0.5, + "commission_time": "{TinyDate}:2021-07-11T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "device_id": 2, + "station_id": 11 + }, + "3": { + "ant_comment": "Helper String C Cal Vpol", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_position_x": 17.581677025974614, + "ant_position_y": 30.76938616345069, + "ant_position_z": -91.821, + "commission_time": "{TinyDate}:2022-06-17T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "device_id": 0, + "station_id": 12 + }, + "4": { + "ant_comment": "Helper String B Cal Vpol", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_position_x": -17.416838993123974, + "ant_position_y": 30.243742503690555, + "ant_position_z": -90.5, + "commission_time": "{TinyDate}:2022-06-21T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "device_id": 1, + "station_id": 12 + }, + "5": { + "ant_comment": "Surface Cal Pulser", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_position_x": -0.6679654868246416, + "ant_position_y": 29.96345015225188, + "ant_position_z": -0.5, + "commission_time": "{TinyDate}:2022-06-21T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "device_id": 2, + "station_id": 12 + }, + "7": { + "ant_comment": "Helper String B Cal Vpol", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_position_x": -16.785614958664155, + "ant_position_y": 29.370321702003366, + "ant_position_z": -91.834, + "commission_time": "{TinyDate}:2022-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "device_id": 1, + "station_id": 13 + }, + "6": { + "ant_comment": "Helper String C Cal Vpol", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_position_x": 18.521789931312696, + "ant_position_y": 30.147367825982656, + "ant_position_z": -92.1, + "commission_time": "{TinyDate}:2022-07-04T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "device_id": 0, + "station_id": 13 + }, + "8": { + "ant_comment": "Surface Cal Pulser", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_position_x": 0.15480992874563526, + "ant_position_y": 36.33766563226254, + "ant_position_z": -0.5, + "commission_time": "{TinyDate}:2022-07-04T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "device_id": 2, + "station_id": 13 + }, + "10": { + "ant_comment": "Helper String B Cal Vpol", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_position_x": -17.202395931048557, + "ant_position_y": 29.097176873979663, + "ant_position_z": -91.72, + "commission_time": "{TinyDate}:2021-07-04T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "device_id": 1, + "station_id": 21 + }, + "9": { + "ant_comment": "Helper String C Cal Vpol", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_position_x": -33.64796575784544, + "ant_position_y": -0.8015936150957828, + "ant_position_z": -92.37, + "commission_time": "{TinyDate}:2021-07-04T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "device_id": 0, + "station_id": 21 + }, + "11": { + "ant_comment": "Surface Cal Pulser", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_position_x": -51.46441417816578, + "ant_position_y": 29.40255089056592, + "ant_position_z": -0.5, + "commission_time": "{TinyDate}:2021-07-04T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "device_id": 2, + "station_id": 21 + }, + "13": { + "ant_comment": "Helper String B Cal Vpol", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_position_x": -17.512609715763574, + "ant_position_y": 33.130260578744355, + "ant_position_z": -93.8, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "device_id": 1, + "station_id": 22 + }, + "12": { + "ant_comment": "Helper String C Cal Vpol", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_position_x": 17.289818380904876, + "ant_position_y": 26.163474852590753, + "ant_position_z": -93.62, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "device_id": 0, + "station_id": 22 + }, + "14": { + "ant_comment": "Surface Cal Pulser", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_position_x": -0.16062226524115886, + "ant_position_y": 33.235129305677674, + "ant_position_z": -0.5, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "device_id": 2, + "station_id": 22 + }, + "16": { + "ant_comment": "Helper String B Cal Vpol", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_position_x": -34.71897220803157, + "ant_position_y": -0.2424120679356747, + "ant_position_z": -91.961, + "commission_time": "{TinyDate}:2022-06-24T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "device_id": 1, + "station_id": 23 + }, + "15": { + "ant_comment": "Helper String C Cal Vpol", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_position_x": -17.268506687948047, + "ant_position_y": 29.548845645087567, + "ant_position_z": -92.774, + "commission_time": "{TinyDate}:2022-06-26T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "device_id": 0, + "station_id": 23 + }, + "17": { + "ant_comment": "Surface Cal Pulser", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_position_x": -28.737720462499283, + "ant_position_y": 20.155169244061653, + "ant_position_z": -0.5, + "commission_time": "{TinyDate}:2022-06-26T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "device_id": 2, + "station_id": 23 + }, + "19": { + "ant_comment": "Helper String B Cal Vpol", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_position_x": -27.829750903225204, + "ant_position_y": 17.57035552463367, + "ant_position_z": -94.513, + "commission_time": "{TinyDate}:2022-07-06T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "device_id": 1, + "station_id": 24 + }, + "18": { + "ant_comment": "Helper String C Cal Vpol", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_position_x": 9.508991969799126, + "ant_position_y": 25.278154073230326, + "ant_position_z": -77.368, + "commission_time": "{TinyDate}:2022-07-12T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "device_id": 0, + "station_id": 24 + }, + "20": { + "ant_comment": "Surface Cal Pulser", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_position_x": -8.563171421938478, + "ant_position_y": 31.402687371741195, + "ant_position_z": -0.5, + "commission_time": "{TinyDate}:2022-07-12T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "device_id": 2, + "station_id": 24 + } + } +} \ No newline at end of file From 782331551a60a611ad479e6d51e5d3aef5ebd0dc Mon Sep 17 00:00:00 2001 From: Janna Vischer Date: Fri, 10 Feb 2023 15:25:05 +0100 Subject: [PATCH 130/418] implemented Steffens pull-request comments --- NuRadioReco/framework/trigger.py | 3 ++- NuRadioReco/modules/phasedarray/triggerSimulator.py | 8 ++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/NuRadioReco/framework/trigger.py b/NuRadioReco/framework/trigger.py index b873079c8..1792f0916 100644 --- a/NuRadioReco/framework/trigger.py +++ b/NuRadioReco/framework/trigger.py @@ -4,6 +4,7 @@ import cPickle as pickle except ImportError: import pickle +import numpy as np def deserialize(triggers_pkl): @@ -81,7 +82,7 @@ def set_trigger_time(self, time): def get_trigger_time(self): """ - get the trigger time (time with respect to the beginning of the event, e.g. the first neutrino interaction) + get the trigger time (absolute time with respect to the beginning of the event) """ return self._trigger_time diff --git a/NuRadioReco/modules/phasedarray/triggerSimulator.py b/NuRadioReco/modules/phasedarray/triggerSimulator.py index adb4d4ef1..2dc66d073 100644 --- a/NuRadioReco/modules/phasedarray/triggerSimulator.py +++ b/NuRadioReco/modules/phasedarray/triggerSimulator.py @@ -444,7 +444,7 @@ def phased_trigger(self, station, det, # logger.debug(f"trigger times = {trigger_times[iTrace]}") if is_triggered: # logger.debug(trigger_times) - trigger_time = min([x.min() for x in trigger_times.values()])+ channel_trace_start_time + trigger_time = min([x.min() for x in trigger_times.values()]) # logger.debug(f"minimum trigger time is {trigger_time:.0f}ns") return is_triggered, trigger_delays, trigger_time, trigger_times @@ -566,9 +566,9 @@ def run(self, evt, station, det, trigger.set_triggered(is_triggered) if is_triggered: - trigger.set_trigger_time(trigger_time)# #trigger_time= time from start of trace + start time of trace with respect to moment of interaction = trigger time from moment of interaction; time offset to interaction time (channel_trace_start_time) already recognized in self.phased_trigger - trigger.set_trigger_times(trigger_times) ##trigger_time= time from start of trace + start time of trace with respect to moment of interaction = trigger time from moment of interaction; time offset to interaction time (channel_trace_start_time) already recognized in self.phased_trigger - else: + #trigger_time(s)= time(s) from start of trace + start time of trace with respect to moment of interaction = trigger time from moment of interaction; time offset to interaction time (channel_trace_start_time) already recognized in self.phased_trigger + trigger.set_trigger_time(trigger_time)# + trigger.set_trigger_times(trigger_times) trigger.set_trigger_time(None) station.set_trigger(trigger) From d1ed94da21304e11a74d4e38e8a78a09fc0bfc7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Thu, 26 Jan 2023 18:04:17 +0100 Subject: [PATCH 131/418] Change hdf5 format to version 3.0. This entails changes to the generator output. In particular energies, interaction_type, flavor changed when simulating the propagation of taus and muons Fix rebase --- NuRadioMC/EvtGen/NuRadioProposal.py | 45 +++++++++++++++----------- NuRadioMC/EvtGen/generator.py | 50 ++++++++++++++--------------- 2 files changed, 51 insertions(+), 44 deletions(-) diff --git a/NuRadioMC/EvtGen/NuRadioProposal.py b/NuRadioMC/EvtGen/NuRadioProposal.py index 630a247eb..3b9010b6e 100644 --- a/NuRadioMC/EvtGen/NuRadioProposal.py +++ b/NuRadioMC/EvtGen/NuRadioProposal.py @@ -46,12 +46,13 @@ class SecondaryProperties: """ This class stores the properties from secondary particles that are relevant for NuRadioMC, namely: - - distance, the distance to the first interaction vertex - - energy, the particle energy - - shower_type, whether the shower they induce is hadronic or electromagnetic - - name, its name according to the particle_name dictionary on this module + - distance : Distance to the first interaction vertex + - energy : Particle energy + - shower_type : Whether the shower they induce is hadronic or electromagnetic + - name : Name according to NuRadioReco.utilities.particle_names + - parent_energy : Energy of the parent particle - Distance and energy are expected to be in NuRadioMC units + Distance and energy are in NuRadioMC units """ def __init__(self, @@ -59,18 +60,21 @@ def __init__(self, energy, shower_type, code, - name): + name, + parent_energy): self.distance = distance self.energy = energy self.shower_type = shower_type self.code = code self.name = name + self.parent_energy = parent_energy def __str__(self): - s = "Particle and code: {:} ({:})\n".format(self.name, self.code) - s += "Energy in PeV: {:}\n".format(self.energy / units.PeV) - s += "Distance from vertex in km: {:}\n".format(self.distance / units.km) - s += "Shower type: {:}\n".format(self.shower_type) + s = "Particle and code : {:} ({:})\n".format(self.name, self.code) + s += "Energy : {:} PeV\n".format(self.energy / units.PeV) + s += "Distance from vertex : {:} km\n".format(self.distance / units.km) + s += "Shower type : {:}\n".format(self.shower_type) + s += "Parent energy : {:} PeV".format(self.parent_energy / units.PeV) return s """ @@ -255,7 +259,6 @@ def __init__(self, config_file='SouthPole', log_level=logging.INFO, tables_path= 'SouthPole': 'config_PROPOSAL.json', 'MooresBay': 'config_PROPOSAL_mooresbay.json', 'InfIce': 'config_PROPOSAL_infice.json', 'Greenland': 'config_PROPOSAL_greenland.json'} - if tables_path is None: tables_path = os.path.join(os.path.dirname(__file__), "proposal_tables") @@ -508,15 +511,18 @@ def __filter_secondaries(self, energy = sec.energy * units.MeV shower_type, code, name = self.__shower_properties(sec.type) - - shower_inducing_prods.append(SecondaryProperties(distance, energy, shower_type, code, name)) + + shower_inducing_prods.append( + SecondaryProperties(distance, energy, shower_type, code, name, + sec.parent_particle_energy * units.MeV)) return shower_inducing_prods def __group_decay_products(self, decay_products, min_energy_loss, - lepton_position): + lepton_position, + decay_energy): """ group remaining shower-inducing decay products so that they create a single shower @@ -528,6 +534,8 @@ def __group_decay_products(self, Threshold for shower production, in PROPOSAL units (MeV) lepton_position: (float, float, float) tuple Original lepton positions in proposal units (cm) + decay_energy: float + Energy of the lepton before decaying (in NuRadioMC units) Returns ------- @@ -546,13 +554,14 @@ def __group_decay_products(self, for decay_particle in decay_products: if is_shower_primary(decay_particle.type): sum_decay_particle_energy += decay_particle.energy - + if sum_decay_particle_energy > min_energy_loss: # all decay_particles have the same position, so we can just look at the first in list distance = ProposalFunctions.__calculate_distance(decay_products[0].position, lepton_position) return SecondaryProperties(distance, sum_decay_particle_energy * units.MeV, - 'had', 86, particle_names.particle_name(86)) + 'had', 86, particle_names.particle_name(86), + decay_energy) return None @@ -628,7 +637,6 @@ def get_secondaries_array(self, min_energy_loss, lepton_position) decay_products = secondaries.decay_products() # array of decay particles - # Checking if there is a muon in the decay products if propagate_decay_muons: @@ -654,7 +662,8 @@ def get_secondaries_array(self, # We have already handled the muon, remove it to avoid double counting. decay_products.remove(decay_particle) - grouped_decay_products = self.__group_decay_products(decay_products, min_energy_loss, lepton_position) + decay_energy = secondaries.final_state().energy * units.MeV # energy of the lepton before decay + grouped_decay_products = self.__group_decay_products(decay_products, min_energy_loss, lepton_position, decay_energy) if grouped_decay_products is not None: shower_inducing_prods.append(grouped_decay_products) diff --git a/NuRadioMC/EvtGen/generator.py b/NuRadioMC/EvtGen/generator.py index f7c95435c..49ef8ae3c 100644 --- a/NuRadioMC/EvtGen/generator.py +++ b/NuRadioMC/EvtGen/generator.py @@ -1,5 +1,17 @@ # -*- coding: utf-8 -*- import logging +import numpy as np +from numpy.random import Generator, Philox +import copy +from six import iterkeys, iteritems +from scipy import constants, interpolate +import h5py +import time + +import NuRadioMC +from NuRadioReco.utilities import units, version, particle_names +from NuRadioMC.utilities import inelasticities +from NuRadioMC.simulation.simulation import pretty_time_delta STATUS = 31 @@ -18,28 +30,8 @@ def status(self, msg, *args, **kwargs): logging.basicConfig(format='%(asctime)s %(levelname)s:%(name)s:%(message)s') logger.setLevel(logging.INFO) -import numpy as np -import NuRadioMC -from NuRadioReco.utilities import units -from NuRadioMC.utilities import inelasticities -from NuRadioReco.utilities import version -from six import iterkeys, iteritems -from scipy import constants -from scipy.integrate import quad -from scipy.interpolate import interp1d -import scipy.interpolate as interpolate -from scipy.optimize import fsolve -from scipy.interpolate import RectBivariateSpline -import h5py -import time -from NuRadioMC.simulation.simulation import pretty_time_delta -import os -import math -from numpy.random import Generator, Philox -import copy - -VERSION_MAJOR = 2 -VERSION_MINOR = 2 +VERSION_MAJOR = 3 +VERSION_MINOR = 0 HEADER = """ # all quantities are in the default NuRadioMC units (i.e., meters, radians and eV) @@ -1358,10 +1350,15 @@ def generate_eventlist_cylinder(filename, n_events, Emin, Emax, data_sets_fiducial['n_interaction'][-1] = n_interaction # specify that new event is a secondary interaction n_interaction += 1 + + # store energy of parent lepton before producing the shower + data_sets_fiducial['energies'][-1] = product.parent_energy data_sets_fiducial['shower_energies'][-1] = product.energy data_sets_fiducial['inelasticity'][-1] = np.nan - # interaction_type is either 'had' or 'em' for proposal products - data_sets_fiducial['interaction_type'][-1] = product.shower_type + + # For neutrino interactions 'interaction_type' contains 'cc' or 'nc' + # For energy losses of leptons use name of produced particle + data_sets_fiducial['interaction_type'][-1] = particle_names.particle_name(product.code) data_sets_fiducial['shower_type'][-1] = product.shower_type data_sets_fiducial['xx'][-1] = x @@ -1371,8 +1368,9 @@ def generate_eventlist_cylinder(filename, n_events, Emin, Emax, # Calculating vertex interaction time with respect to the primary neutrino data_sets_fiducial['vertex_times'][-1] = vertex_time - # Flavors are particle codes taken from NuRadioProposal.py - data_sets_fiducial['flavors'][-1] = product.code + # Store flavor/particle code of parent particle + data_sets_fiducial['flavors'][-1] = lepton_codes[iE] + time_proposal = time.time() - init_time else: if(n_batches == 1): From 641064b262ee4cd441d7042d01ee8bf2870cdb8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Mon, 13 Feb 2023 14:01:22 +0100 Subject: [PATCH 132/418] Add function to properly convert between unit systems in energy --- NuRadioMC/EvtGen/NuRadioProposal.py | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/NuRadioMC/EvtGen/NuRadioProposal.py b/NuRadioMC/EvtGen/NuRadioProposal.py index 3b9010b6e..fe49671ad 100644 --- a/NuRadioMC/EvtGen/NuRadioProposal.py +++ b/NuRadioMC/EvtGen/NuRadioProposal.py @@ -42,6 +42,11 @@ pp_km = 1.e5 +def convert_energy_units(pp_energy): + """ Convert energy from proposal unit to NuRadioMC unit. """ + return pp_energy / pp_MeV * units.MeV + + class SecondaryProperties: """ This class stores the properties from secondary particles that are @@ -332,7 +337,7 @@ def __get_propagator(self, particle_code=13): propagator: PROPOSAL propagator Propagator that can be used to calculate the interactions of a muon or tau """ - if(particle_code not in self.__propagators): + if particle_code not in self.__propagators: self.__logger.info(f"initializing propagator for particle code {particle_code}") pp.InterpolationSettings.tables_path = self.__tables_path @@ -353,8 +358,8 @@ def __get_propagator(self, particle_code=13): try: p_def = pp.particle.get_ParticleDef_for_type(particle_code) except: - error_str = "The propagation of this particle via PROPOSAL is not currently supported.\n" - error_str += "Please choose between -/+muon (13/-13) and -/+tau (15/-15)" + error_str = "The propagation of this particle via PROPOSAL is not currently supported.\n" + \ + "Please choose between -/+muon (13/-13) and -/+tau (15/-15)" raise NotImplementedError(error_str) self.__propagators[particle_code] = pp.Propagator(particle_def=p_def, path_to_config_file=self.__config_file_full_path) @@ -508,13 +513,13 @@ def __filter_secondaries(self, distance = ProposalFunctions.__calculate_distance(sec.position, lepton_position) - energy = sec.energy * units.MeV + energy = convert_energy_units(sec.energy) shower_type, code, name = self.__shower_properties(sec.type) shower_inducing_prods.append( SecondaryProperties(distance, energy, shower_type, code, name, - sec.parent_particle_energy * units.MeV)) + convert_energy_units(sec.parent_particle_energy))) return shower_inducing_prods @@ -559,7 +564,7 @@ def __group_decay_products(self, # all decay_particles have the same position, so we can just look at the first in list distance = ProposalFunctions.__calculate_distance(decay_products[0].position, lepton_position) - return SecondaryProperties(distance, sum_decay_particle_energy * units.MeV, + return SecondaryProperties(distance, convert_energy_units(sum_decay_particle_energy), 'had', 86, particle_names.particle_name(86), decay_energy) return None @@ -662,7 +667,7 @@ def get_secondaries_array(self, # We have already handled the muon, remove it to avoid double counting. decay_products.remove(decay_particle) - decay_energy = secondaries.final_state().energy * units.MeV # energy of the lepton before decay + decay_energy = convert_energy_units(secondaries.final_state().energy) # energy of the lepton before decay grouped_decay_products = self.__group_decay_products(decay_products, min_energy_loss, lepton_position, decay_energy) if grouped_decay_products is not None: @@ -734,7 +739,7 @@ def get_decays(self, decay_particles = secondaries.decay_products() decay_energies = np.array([p.energy for p in decay_particles]) - decay_energy = np.sum(decay_energies) * units.MeV + decay_energy = convert_energy_units(np.sum(decay_energies)) # TODO: Is it physical to repeat the propagation until a decay (before the energy of low) happened? if (len(decay_particles) == 0): From afe690eb0ad8df36492c9e2ff8a9095f91e8c080 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Mon, 13 Feb 2023 15:59:35 +0100 Subject: [PATCH 133/418] remove function for energy unit conversion again and convert explicitly --- NuRadioMC/EvtGen/NuRadioProposal.py | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/NuRadioMC/EvtGen/NuRadioProposal.py b/NuRadioMC/EvtGen/NuRadioProposal.py index fe49671ad..f0e40d44e 100644 --- a/NuRadioMC/EvtGen/NuRadioProposal.py +++ b/NuRadioMC/EvtGen/NuRadioProposal.py @@ -42,11 +42,6 @@ pp_km = 1.e5 -def convert_energy_units(pp_energy): - """ Convert energy from proposal unit to NuRadioMC unit. """ - return pp_energy / pp_MeV * units.MeV - - class SecondaryProperties: """ This class stores the properties from secondary particles that are @@ -513,13 +508,13 @@ def __filter_secondaries(self, distance = ProposalFunctions.__calculate_distance(sec.position, lepton_position) - energy = convert_energy_units(sec.energy) + energy = sec.energy / pp_MeV * units.MeV shower_type, code, name = self.__shower_properties(sec.type) shower_inducing_prods.append( SecondaryProperties(distance, energy, shower_type, code, name, - convert_energy_units(sec.parent_particle_energy))) + sec.parent_particle_energy / pp_MeV * units.MeV)) return shower_inducing_prods @@ -564,7 +559,7 @@ def __group_decay_products(self, # all decay_particles have the same position, so we can just look at the first in list distance = ProposalFunctions.__calculate_distance(decay_products[0].position, lepton_position) - return SecondaryProperties(distance, convert_energy_units(sum_decay_particle_energy), + return SecondaryProperties(distance, sum_decay_particle_energy / pp_MeV * units.MeV, 'had', 86, particle_names.particle_name(86), decay_energy) return None @@ -667,7 +662,7 @@ def get_secondaries_array(self, # We have already handled the muon, remove it to avoid double counting. decay_products.remove(decay_particle) - decay_energy = convert_energy_units(secondaries.final_state().energy) # energy of the lepton before decay + decay_energy = secondaries.final_state().energy / pp_MeV * units.MeV # energy of the lepton before decay grouped_decay_products = self.__group_decay_products(decay_products, min_energy_loss, lepton_position, decay_energy) if grouped_decay_products is not None: @@ -739,7 +734,7 @@ def get_decays(self, decay_particles = secondaries.decay_products() decay_energies = np.array([p.energy for p in decay_particles]) - decay_energy = convert_energy_units(np.sum(decay_energies)) + decay_energy = np.sum(decay_energies) / pp_MeV * units.MeV # TODO: Is it physical to repeat the propagation until a decay (before the energy of low) happened? if (len(decay_particles) == 0): From 8ae25e28db3b16deef0dfb2b1b99c2c5f6302061 Mon Sep 17 00:00:00 2001 From: Sjoerd Bouma Date: Wed, 15 Feb 2023 14:33:36 +0100 Subject: [PATCH 134/418] include sorting by number of bottom reflections --- NuRadioMC/SignalProp/CPPAnalyticRayTracing/wrapper.pyx | 2 +- NuRadioMC/SignalProp/analyticraytracing.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/NuRadioMC/SignalProp/CPPAnalyticRayTracing/wrapper.pyx b/NuRadioMC/SignalProp/CPPAnalyticRayTracing/wrapper.pyx index 05e332da8..957bce70c 100644 --- a/NuRadioMC/SignalProp/CPPAnalyticRayTracing/wrapper.pyx +++ b/NuRadioMC/SignalProp/CPPAnalyticRayTracing/wrapper.pyx @@ -49,7 +49,7 @@ cpdef find_solutions(x1, x2, n_ice, delta_n, z_0, reflection, reflection_case, i 'reflection': reflection, 'reflection_case': reflection_case}) - s = sorted(solutions, key=itemgetter('C0')) + s = sorted(solutions, key=itemgetter('reflection', 'C0')) # print((time.time() - t) * 1000) return s diff --git a/NuRadioMC/SignalProp/analyticraytracing.py b/NuRadioMC/SignalProp/analyticraytracing.py index bb01124be..796e2e4cc 100644 --- a/NuRadioMC/SignalProp/analyticraytracing.py +++ b/NuRadioMC/SignalProp/analyticraytracing.py @@ -1133,7 +1133,7 @@ def find_solutions(self, x1, x2, plot=False, reflection=0, reflection_case=1): import matplotlib.pyplot as plt plt.show() - return sorted(results, key=itemgetter('C0')) + return sorted(results, key=itemgetter('reflection', 'C0')) def plot_result(self, x1, x2, C_0, ax): """ From 7ca0fc5c754a9c806e51fc97c2b85296b5b18785 Mon Sep 17 00:00:00 2001 From: Sjoerd Bouma Date: Wed, 15 Feb 2023 15:09:01 +0100 Subject: [PATCH 135/418] update reference files --- .../1e18_output_ARZ_reference.hdf5 | Bin 90192 -> 90192 bytes .../1e18_output_noise_reference.hdf5 | Bin 104304 -> 104304 bytes .../SingleEvents/1e18_output_reference.hdf5 | Bin 104304 -> 104304 bytes .../test/SingleEvents/MB_1e18_reference.hdf5 | Bin 357024 -> 357024 bytes 4 files changed, 0 insertions(+), 0 deletions(-) diff --git a/NuRadioMC/test/SingleEvents/1e18_output_ARZ_reference.hdf5 b/NuRadioMC/test/SingleEvents/1e18_output_ARZ_reference.hdf5 index d3dae44d262942a96383064641c917e47514207a..e3fb76cb237cdd4d4252d1d840845660de566c28 100644 GIT binary patch delta 459 zcmV;+0W|*5zy;921+X9@7}wMPYO>JAKg2XgP@5L$KTS#w%TGt-Ka(IL7#70}=&(bG z#y@-fo(?A*=s#7stWU^AlTIQUvw$KXAsF5cDJ6z`&A+(pdZVl$@4tHOeFzbon?IAF zLl_tRele}=9nHVj`WQynC-1+Wix5h^rjnD-Lm9F}AQ>3ifRSC)hq*sST$4B8Fsi>K zZ>x!6%EkG%;Z^GdE^qFk&__He)t9WM(vEG&x}imr)u47pG7f0Y)%& B%uE0P delta 459 zcmV;+0W|*5zy;921+X9@7@dO^a(ukTKNK}~qC^4cKO1&8GxuTSKa(IL7#8-z=97YM z#y=Xs@l2Qi=s!kdB#|d*lTIQUvw$KXAsCWv$1Z4L&A;Fd%$XSl@4vZY-=(}1{Ai*rF<+VTFp~W(;2fV+M zt{$?Au&;a&##% zG%;dkVP-HeW;i%xIXN*iV`DI6F*!IeGGk(8IXEz6W;r%CGB`5`mr)u47pG7f0Y;~d B%KHES diff --git a/NuRadioMC/test/SingleEvents/1e18_output_noise_reference.hdf5 b/NuRadioMC/test/SingleEvents/1e18_output_noise_reference.hdf5 index 16958b75073b5d451ef93e1f4905566ac4df39eb..093452baabd9803736afe32ba06098068080cf08 100644 GIT binary patch delta 460 zcmV;-0W<#at_JX~2C(2E7}wMPYO>JAKg2XgP@5L$KTS#w%TGt-Ka=1g7#70}=&(bG z#y@-fo(?A*=s#7stWU^AlMW&pvp^!CC>Y)jDJ6z`&A+(pdZVl$@4tHOeFzbon?IA_ zN*EXYele}=9nHVj`WQynC-1+Wix5h^rjnBnOBu63OQ0Ya+JKQ=)Q7o0MqHCO;4rGc zByX#UVa)Hpli+I@7GcAXHyRb4s05uKx`ZxFqIu&rXI{d zQULipsUFNgXHt!vejCg{+4f+#gtJ|U;|d;lZSsZJRHH!7V$6?4;|d-|w9*GtJ?B5}lf#GmQRhGW4oVj$ zJm)`dfs#$rREkG%;Z^GdE^qFk&__He)t9WM(vEG&x}imqAMb7q{?90f0?y C;n&{) delta 460 zcmV;-0W<#at_JX~2C(2E7@dO^a(ukTKNK}~qC^4cKO1&8GxuTSKa=1g7#8-z=97YM z#y=Xs@l2Qi=s!kdB#|d*lMW&pvp^!CC>WA$$1Z4L&A;Fd%$XSl@4vZY-=(}m$li+I@78)34pOl5PKZa!F1-InF@W&A9Ud<+EL};|d<`lf#GmQRhEKw9*GtJ?B4efs#$r zR_8zb4oVj$JhNWB;tC!N4Gg5Uw3tA==&$PV_Lx9m=w<0*rIJAKg2XgP@5L$KTS#w%TGt-Ka=1g7#70}=&(bG z#y@-fo(?A*=s#7stWU^AlMW&pvp^!CC>Y)jDJ6z`&A+(pdZVl$@4tHOeFzbon?IA_ zN*EXYele}=9nHVj`WQynC-1+Wix5h^rjnBnOBu63OQ0Ya+JKQ=)Q7o0MqHCO;4rGc zByX#UVa)Hpli+I@7GcAXHyRb4s05uKx`ZxFqIu&rXI{d zQULipsUFNgXHt!vejCg{+4f+#gtJ|U;|d;lZSsZJRHH!7VKk>T6b4B>_L`;S>h;%mTAtp5YQ5mivRn z3@gk)xMp9Y4=c<-&A9Ud$6?4;|d-|w9*GtJ?B5}lf#GmQRhGW4oVj$ zJm)`dfs#$rREkG%;Z^GdE^qFk&__He)t9WM(vEG&x}imqAMb7q{?90f0>& CtJHn~ delta 460 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%0D^+ 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 delta 32184 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à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 Date: Wed, 15 Feb 2023 15:33:00 +0100 Subject: [PATCH 136/418] update two more reference files --- NuRadioMC/test/SignalProp/reference_C0.pkl | Bin 16155 -> 16153 bytes .../SignalProp/reference_C0_MooresBay.pkl | Bin 80164 -> 80162 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/NuRadioMC/test/SignalProp/reference_C0.pkl b/NuRadioMC/test/SignalProp/reference_C0.pkl index 6bc14720ef84826363c1c7feb97f486c077f800c..7121c475a76d78f1c672cd1d497871f14ce74c01 100644 GIT binary patch delta 1246 zcmZXTdrXsO7{z(pj`GT-LJJj$>*V4mf-)54V&!SPq(&#GVXHEiPQ26r%EW1%GD@5i zG;YWqT?LHQDFNdU^_x^>See5MQ<)maGB2HqeqW1i@iw3oy8gYL|4(vq&hONf)s%_K zMf*dlMTLT0mDL;X3vWDJ&n_l&3B8$=nRTnw2L5OgScw@8LLGG%bv_c^c?sX5OW03J zkP|hKeOUF*RoXQsZ+!XIAt*$xzmD?H@_)Wr=78PU<)2Iv(CeQ@JJ&mFFP(n@vk=5a zxCo^R zJGeL2+e_#25QLThhW4x|+0`N7VSsf7m`TQi+-ukUD&25F6?A!l*$pRWzc+1390#F| ziunps`1A@9Vd)h*g9b1f&N|qg}$$K|@#_8c&Y}#;+6K zAAn({1z6YB3?@#p&?#Q4zb4gt3*_u-Q>Z1CY7FEnpB!r$oud%G0CJ3yBHvy ztYm_YL>FxyDcZi%2@R?9Xsp=@vyNUrTO)l1Pv@wyIw73=#Wp1P^5&sD(LxSmccPWv zy}0*!<;PCgf|jIyI#4Lg9d7D_r)Zg^Ax*4&vQ|i!ei1%D*SOhYK$pbYRsKHEl0CaHG1Hhat31sUVH0n+mjp zyjlKaArCd!Jk>~b(@Xmr6MNwb=A`N(_srl|UyJ2{lqgFl&EUZOiEOR@AP+CGE0v*l za-P_K`>qczv))u6CKnPONcFx;s_HG5-jvy4RsF=yiXS+*g)qIFTxI2HVnWhUk*=l- zZm2Eyq&%F$;&d~ezPYW&rF#v#Fgb&v$5qCY^M{=vXSEsq0y=B5=E~T9QvSYAi;t>zDpi5cdyPkfgmA3pjE$Z$*9-2^_r6DpjXRZ1d D*9;T! delta 1244 zcmZ9Mc~FyQ5XO0vl<-P|U`Qe|$jB8@sEr~KBy7f`aj=S|R6Jl1JYqRitVpX|(~4lL zgR<3t8e4T3ufgk+B1#O7c!1*7Iy$4N1*P9dAOWu;k;Hy~cmLj2iO@ht@;d$!J$wb#XcrEV zP1qwkM)u*ZPj1rNW0ysgZ}|Y}O9Q#|F`$30V zv5{7a7jJsA&r8elVEj;8} zV}lRh*4v8ba^QnzFBR>{+PLGofCDFE_i7?>*3?_=9#u}bq?25m-{ge#w$G=hgt6dv ze35G32^Jh(2R{zC+8`u8wU~6-KwI{r^ugU;@IdP*JzW*Q!jTqihea6eZJ>E!3FEXs zvLInh-eN*?0+W|@*j__D(;zVrDlxtkJgRsHDNK-0nSi`Nlkb4g=g9z8`-RiP-r@P; zr|;nin*AR8MI|(^%>JSm4C>icy#>ACiS=VLX~n&1-acv@grQWXp%;z$dk`2 z2pxhdlul3*F%v#PL&z=62&p71uqULNM!wWv%pB>32rLO5AU7~SOhuKc$9JFl$ihi9 zg%#0calT=D7w;nmg=dn#u_Rncer5KC-z1`z8V?t)P{q*mOQMQ3xg6|3lWGb<>{J11 zXQUGiBrs>QJMV|>4mc4rkA^lmVAj$0#yZ(+D87`A)sb@YjH!?0^)5&GWD7Zjk0w8- ze_q+$UbWl-MQDy1qC>gDR9C|wbfY;sjhtrWpJoc_;_u~2KL7OdNhwkDL3|&)UaEct zWoTDd2CyY7zfAv)g+psc56kYep!E2<=!}?yHrzE;Ph0b9@9gR0z>U_amEyJisD7*`A*ljg{0vLgNjq2AK^w$uiz>L+zn9%11=YGWUh8;o2dCS)cC&Ct`N zJ9^6_83(5^e?}9H*=(*GFuZ}EFgi{}PwI@PlUxoM%Vfk2322mPo%M=-0DLhcK_m5x zEuX!ugoS0za~x7shlNu2c}q^pLO1VWXM&QpZ5#f5(%}*QIoJ~_Ne>okpVOu%)5rbs Q3kPQ~BQcFAurYDff75Ilc>n+a diff --git a/NuRadioMC/test/SignalProp/reference_C0_MooresBay.pkl b/NuRadioMC/test/SignalProp/reference_C0_MooresBay.pkl index cfb6df141ff069f116d9fcba611e74fc25549c00..0663206b01052397bed0236cc1f61e74e35a9b75 100644 GIT binary patch delta 31494 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 U0Zrg*iX2RR7&A_;Qo}j?53kx+U;qFB delta 30916 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 From 446ca8c445fab242f5a8d3f20d5c830e49475a7d Mon Sep 17 00:00:00 2001 From: Sjoerd Bouma Date: Wed, 15 Feb 2023 15:42:10 +0100 Subject: [PATCH 137/418] replace ray type disagreement warning with reflection in get_focusing --- NuRadioMC/SignalProp/analyticraytracing.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/NuRadioMC/SignalProp/analyticraytracing.py b/NuRadioMC/SignalProp/analyticraytracing.py index ef4f6eb2b..988cc52a5 100644 --- a/NuRadioMC/SignalProp/analyticraytracing.py +++ b/NuRadioMC/SignalProp/analyticraytracing.py @@ -1960,8 +1960,9 @@ def get_focusing(self, iS, dz=-1. * units.cm, limit=2.): lauVec1 = self._r1.get_launch_vector(iS) lauAng1 = np.arccos(lauVec1[2] / np.sqrt(lauVec1[0] ** 2 + lauVec1[1] ** 2 + lauVec1[2] ** 2)) focusing = np.sqrt(distance / np.sin(recAng) * np.abs((lauAng1 - lauAng) / (recPos1[2] - recPos[2]))) - if(self.get_solution_type(iS) != self._r1.get_solution_type(iS)): - self.__logger.error("solution types are not the same") + if (self.get_results()[iS]['reflection'] != self._r1.get_results()[iS]['reflection'] + or self.get_results()[iS]['reflection_case'] != self._r1.get_results()[iS]['reflection_case']): + self.__logger.error("Number or type of reflections are different between solutions - focusing correction may not be reliable.") else: focusing = 1.0 self.__logger.info("too few ray tracing solutions, setting focusing factor to 1") From 4df0b568433260e0cacb5d826760dffd3295775a Mon Sep 17 00:00:00 2001 From: Sjoerd Bouma Date: Wed, 15 Feb 2023 15:44:57 +0100 Subject: [PATCH 138/418] update changelog [ci skip] --- changelog.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/changelog.txt b/changelog.txt index 88a06f116..c4cffda76 100644 --- a/changelog.txt +++ b/changelog.txt @@ -7,7 +7,8 @@ new features: - upgrade to proposal v 7.5.0 with new NuRadioProposal interface and improved LPM treatment - add script to generate / download pre-calculated proposal tables for known detector configurations - adding default RadioPropa ice model object to medium with the feature to set a personlised object as alternative -- add positions array funcionality to simple ice model in average and gradient functions +- add positions array functionality to simple ice model in average and gradient functions +- analytic ray tracing solutions are now sorted consistently from lowest to highest ray bugfixes: From aed13570318b0bc71cbeda189ff05430aed2ec44 Mon Sep 17 00:00:00 2001 From: Janna Vischer Date: Thu, 16 Feb 2023 16:48:48 +0100 Subject: [PATCH 139/418] changed interaction to first interaction --- NuRadioReco/modules/phasedarray/triggerSimulator.py | 6 +++--- NuRadioReco/modules/trigger/highLowThreshold.py | 4 ++-- NuRadioReco/modules/trigger/multiHighLowThreshold.py | 2 +- NuRadioReco/modules/trigger/rnog_surface_trigger.py | 2 +- NuRadioReco/modules/trigger/simpleThreshold.py | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/NuRadioReco/modules/phasedarray/triggerSimulator.py b/NuRadioReco/modules/phasedarray/triggerSimulator.py index 2dc66d073..d7faac39b 100644 --- a/NuRadioReco/modules/phasedarray/triggerSimulator.py +++ b/NuRadioReco/modules/phasedarray/triggerSimulator.py @@ -333,9 +333,9 @@ def phased_trigger(self, station, det, the delays for the primary channels that have caused a trigger. If there is no trigger, it's an empty dictionary trigger_time: float - the earliest trigger time with respect to interaction time. + the earliest trigger time with respect to first interaction time. trigger_times: dictionary - all time bins that fulfil the trigger condition per beam. The key is the beam number. Time with respect to interaction time. + all time bins that fulfil the trigger condition per beam. The key is the beam number. Time with respect to first interaction time. """ if(triggered_channels is None): @@ -566,7 +566,7 @@ def run(self, evt, station, det, trigger.set_triggered(is_triggered) if is_triggered: - #trigger_time(s)= time(s) from start of trace + start time of trace with respect to moment of interaction = trigger time from moment of interaction; time offset to interaction time (channel_trace_start_time) already recognized in self.phased_trigger + #trigger_time(s)= time(s) from start of trace + start time of trace with respect to moment of first interaction = trigger time from moment of first interaction; time offset to interaction time (channel_trace_start_time) already recognized in self.phased_trigger trigger.set_trigger_time(trigger_time)# trigger.set_trigger_times(trigger_times) trigger.set_trigger_time(None) diff --git a/NuRadioReco/modules/trigger/highLowThreshold.py b/NuRadioReco/modules/trigger/highLowThreshold.py index 8fbff36c3..c08e9d7c4 100644 --- a/NuRadioReco/modules/trigger/highLowThreshold.py +++ b/NuRadioReco/modules/trigger/highLowThreshold.py @@ -192,8 +192,8 @@ def run(self, evt, station, det, logger.info("Station has NOT passed trigger") else: trigger.set_triggered(True) - trigger.set_trigger_time(triggered_times.min()+channel_trace_start_time) #trigger_time= time from start of trace + start time of trace with respect to moment of interaction = trigger time from moment of interaction - trigger.set_trigger_times(triggered_times+channel_trace_start_time) #trigger_times= times from start of trace + start time of trace with respect to moment of interaction = trigger times from moment of interaction + trigger.set_trigger_time(triggered_times.min()+channel_trace_start_time) #trigger_time= time from start of trace + start time of trace with respect to moment of first interaction = trigger time from moment of first interaction + trigger.set_trigger_times(triggered_times+channel_trace_start_time) logger.info("Station has passed trigger, trigger time is {:.1f} ns".format( trigger.get_trigger_time() / units.ns)) diff --git a/NuRadioReco/modules/trigger/multiHighLowThreshold.py b/NuRadioReco/modules/trigger/multiHighLowThreshold.py index 8e120dcd6..63c965690 100644 --- a/NuRadioReco/modules/trigger/multiHighLowThreshold.py +++ b/NuRadioReco/modules/trigger/multiHighLowThreshold.py @@ -176,7 +176,7 @@ def run(self, evt, station, det, else: trigger.set_triggered(True) trigger.set_trigger_time(triggered_times.min() + channel_trace_start_time) - #trigger_time= earliest trigger_time from start of trace + start time of trace with respect to moment of interaction = trigger time from moment of interaction + #trigger_time= earliest trigger_time from start of trace + start time of trace with respect to moment of fist interaction = trigger time from moment of first interaction logger.info("Station has passed trigger, trigger time is {:.1f} ns".format( trigger.get_trigger_time() / units.ns)) diff --git a/NuRadioReco/modules/trigger/rnog_surface_trigger.py b/NuRadioReco/modules/trigger/rnog_surface_trigger.py index 8b3f75b23..1fb2c9162 100644 --- a/NuRadioReco/modules/trigger/rnog_surface_trigger.py +++ b/NuRadioReco/modules/trigger/rnog_surface_trigger.py @@ -183,7 +183,7 @@ def run(self, evt, station, det, threshold, coinc_window=60*units.ns, number_coi if has_triggered: trigger.set_triggered(True) - trigger.set_trigger_time(triggered_times.min()+channel_trace_start_time) # trigger_time = time from moment of interaction + trigger.set_trigger_time(triggered_times.min()+channel_trace_start_time) # trigger_time = time from moment of first interaction logger.debug("station has triggered") else: diff --git a/NuRadioReco/modules/trigger/simpleThreshold.py b/NuRadioReco/modules/trigger/simpleThreshold.py index f86d860cd..2989a429d 100644 --- a/NuRadioReco/modules/trigger/simpleThreshold.py +++ b/NuRadioReco/modules/trigger/simpleThreshold.py @@ -113,7 +113,7 @@ def run(self, evt, station, det, trigger.set_triggered_channels(channels_that_passed_trigger) if has_triggered: trigger.set_triggered(True) - trigger.set_trigger_time(triggered_times.min() + channel_trace_start_time) #trigger_time= earliest trigger_time from start of trace + start time of trace with respect to moment of interaction = trigger time from moment of interaction + trigger.set_trigger_time(triggered_times.min() + channel_trace_start_time) #trigger_time= earliest trigger_time from start of trace + start time of trace with respect to moment of first interaction = trigger time from moment of first interaction self.logger.debug("station has triggered") else: trigger.set_triggered(False) From 4d37e500c4ce9149fe861ca32d2e3f5456fe3e06 Mon Sep 17 00:00:00 2001 From: Sjoerd Bouma Date: Fri, 17 Feb 2023 16:55:34 +0100 Subject: [PATCH 140/418] update reference files once more --- .../G01generate_data_set_for_unit_test.py | 3 ++- NuRadioMC/test/SignalProp/reference_C0.pkl | Bin 16153 -> 16153 bytes .../test/Veff/1e18eV/T03check_output_noise.py | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/NuRadioMC/test/SignalProp/G01generate_data_set_for_unit_test.py b/NuRadioMC/test/SignalProp/G01generate_data_set_for_unit_test.py index 9f51e9fd9..c4060fe1a 100644 --- a/NuRadioMC/test/SignalProp/G01generate_data_set_for_unit_test.py +++ b/NuRadioMC/test/SignalProp/G01generate_data_set_for_unit_test.py @@ -33,9 +33,10 @@ t_start = time.time() ff = np.linspace(0, 500 * units.MHz, n_freqs) # tt = 0 +r = ray.ray_tracing(ice) for iX, x in enumerate(points): # t_start2 = time.time() - r = ray.ray_tracing(x, x_receiver, ice) + r.set_start_and_end_point(x, x_receiver) # tt += (time.time() - t_start2) r.find_solutions() if(r.has_solution()): diff --git a/NuRadioMC/test/SignalProp/reference_C0.pkl b/NuRadioMC/test/SignalProp/reference_C0.pkl index 7121c475a76d78f1c672cd1d497871f14ce74c01..0799c027a70b4ee98bbcf19185c44271702db00c 100644 GIT binary patch delta 7377 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≫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 diff --git a/NuRadioMC/test/Veff/1e18eV/T03check_output_noise.py b/NuRadioMC/test/Veff/1e18eV/T03check_output_noise.py index ee2311566..812932e29 100755 --- a/NuRadioMC/test/Veff/1e18eV/T03check_output_noise.py +++ b/NuRadioMC/test/Veff/1e18eV/T03check_output_noise.py @@ -11,7 +11,7 @@ # the event generation has a fixed seed and I switched to Alvarez2000 (also no randomness) # thus, the Veff has no statistical scatter -Veff_mean = 7.576678226341043 +Veff_mean = 8.17491 Veff_sigma = 0.0001 path = os.path.dirname(os.path.abspath(__file__)) From b7838cd808ace00a08e5f434870b6dd5b6482970 Mon Sep 17 00:00:00 2001 From: Sjoerd Bouma Date: Fri, 17 Feb 2023 16:56:55 +0100 Subject: [PATCH 141/418] update changelog --- changelog.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/changelog.txt b/changelog.txt index c4cffda76..22565d4f8 100644 --- a/changelog.txt +++ b/changelog.txt @@ -10,6 +10,7 @@ new features: - add positions array functionality to simple ice model in average and gradient functions - analytic ray tracing solutions are now sorted consistently from lowest to highest ray bugfixes: +- fixed/improved C++ raytracer not finding solutions for some near-horizontal or near-shadowzone vertices version 2.1.7 From a69ed8f6f40e528e0f732474d77a2793774de6bd Mon Sep 17 00:00:00 2001 From: Christoph Date: Fri, 17 Feb 2023 17:09:03 -0600 Subject: [PATCH 142/418] Updates RNO-G amp responses to match what was actually installed in Greenland --- .../iglu_drab_chan0_LinA.csv | 2008 ----------------- .../iglu_drab_placeholder.csv | 2002 ++++++++++++++++ .../HardwareResponses/surface_chan0_LinA.csv | 2008 ----------------- .../HardwareResponses/surface_placeholder.csv | 2002 ++++++++++++++++ .../detector/RNO_G/analog_components.py | 18 +- 5 files changed, 4012 insertions(+), 4026 deletions(-) delete mode 100644 NuRadioReco/detector/RNO_G/HardwareResponses/iglu_drab_chan0_LinA.csv create mode 100644 NuRadioReco/detector/RNO_G/HardwareResponses/iglu_drab_placeholder.csv delete mode 100644 NuRadioReco/detector/RNO_G/HardwareResponses/surface_chan0_LinA.csv create mode 100644 NuRadioReco/detector/RNO_G/HardwareResponses/surface_placeholder.csv diff --git a/NuRadioReco/detector/RNO_G/HardwareResponses/iglu_drab_chan0_LinA.csv b/NuRadioReco/detector/RNO_G/HardwareResponses/iglu_drab_chan0_LinA.csv deleted file mode 100644 index cc320b526..000000000 --- a/NuRadioReco/detector/RNO_G/HardwareResponses/iglu_drab_chan0_LinA.csv +++ /dev/null @@ -1,2008 +0,0 @@ -!CSV A.01.01 -!Keysight Technologies,P5020A,MY58100190,A.14.10.03 -!Date: Tuesday, June 23, 2020 18:36:42 -!Source: Standard - -BEGIN CH1_DATA -Freq(Hz),S11(MAG),S11(DEG),S12(MAG),S12(DEG),S21(MAG),S21(DEG),S22(MAG),S22(DEG) -1000000,1.0017474,-5.5557866,0.0033780951,-136.47556,0.015166974,25.209734,0.9760437,-10.928256 -1499500,0.99827063,-8.2547321,0.00045899872,-110.51553,0.016101129,-175.34964,0.99449337,-17.787683 -1999000,0.99682069,-10.790637,0.0011411759,13.743531,0.011805587,46.693512,0.98214853,-23.962154 -2498500,0.99901849,-14.033757,0.00077941915,60.093746,0.041272115,173.75256,0.94868618,-30.373014 -2998000,0.99654245,-16.50152,0.00080324442,92.309685,0.019363318,-124.5332,0.95226222,-35.762756 -3497500,0.99322641,-19.124844,0.0015765068,80.967468,0.012475405,-121.9377,0.91586512,-42.458134 -3997000,0.99302542,-21.980986,0.001734518,-5.2511363,0.024462735,81.109573,0.92057878,-44.786888 -4496500,0.99540228,-24.62837,0.0011991678,53.234257,0.02329177,40.338001,0.92599893,-52.286537 -4996000,0.99600273,-27.458033,0.00086117239,-123.83961,0.026143383,99.206207,0.88990784,-60.527435 -5495500,0.99079359,-30.180744,0.0006207343,145.46338,0.023871792,-172.86484,0.85450792,-65.44381 -5995000,0.98997182,-32.980255,0.0012008039,66.551941,0.031861976,-160.92165,0.8681705,-69.997246 -6494500,0.9909848,-35.908356,0.00069674628,40.448551,0.024355635,-37.395168,0.83198977,-76.099731 -6994000,0.99115038,-38.760616,0.00113333,-165.40675,0.024256393,86.802284,0.78806812,-81.81382 -7493500,0.98646843,-41.495354,0.00056652998,61.493374,0.034692742,-86.79464,0.68913311,-83.45443 -7993000,0.98507673,-44.483433,0.00076493202,-169.31416,0.020880027,30.475939,0.69814658,-89.819618 -8492500,0.98428309,-47.24015,0.00062032667,90.782394,0.035546806,63.549694,0.67702723,-95.877655 -8992000,0.98175561,-50.158859,0.0010350602,-143.51057,0.043537699,-56.885643,0.66821271,-97.689285 -9491500,0.97853464,-52.99802,0.00024351219,162.90561,0.033708233,18.310427,0.61085814,-104.25504 -9991000,0.98085344,-55.590553,0.00033269799,158.91045,0.018660014,-95.175041,0.58478516,-108.86189 -10490500,0.9751882,-58.580547,0.00052971847,-85.590599,0.013100194,141.79689,0.59063816,-108.54273 -10990000,0.9732219,-61.562824,0.00078421971,-100.89594,0.030114153,-83.446014,0.6052475,-115.17303 -11489500,0.96923113,-64.453896,0.0015462214,-30.282942,0.01923354,-89.81163,0.56554723,-116.11514 -11989000,0.96396035,-67.492477,0.00088536978,45.509361,0.025205791,33.665047,0.52294821,-123.42046 -12488500,0.96167618,-70.543015,0.00056683872,7.5470109,0.021082424,132.22644,0.50443172,-126.20675 -12988000,0.95982736,-73.408371,0.00028545217,133.21758,0.048531041,1.6298798,0.49910769,-128.34094 -13487500,0.9550662,-76.464096,0.00073868304,-178.82646,0.022676036,67.486092,0.48517424,-130.55878 -13987000,0.95348233,-79.433022,0.00047974155,117.44938,0.016219046,-48.706974,0.50671601,-131.57753 -14486500,0.95159799,-82.482895,0.00028473028,-95.246552,0.037028607,61.222004,0.4909496,-140.42555 -14986000,0.94699723,-85.653473,0.00031019212,-21.160152,0.029921763,-53.20808,0.43885398,-138.1575 -15485500,0.94217879,-88.666336,0.00014284549,-163.45645,0.010628851,-116.66525,0.4472422,-141.97032 -15985000,0.94144273,-91.886597,0.0011269435,18.686487,0.019328538,-155.41156,0.45363256,-149.21228 -16484500,0.9372806,-95.133652,0.00084885728,-65.268028,0.060556185,-65.037308,0.42850378,-144.58243 -16984000,0.93619454,-98.485542,0.0012717999,-12.656073,0.054752622,-26.305176,0.39478046,-150.35812 -17483500,0.93387723,-101.76969,0.00020853899,-3.3119535,0.014629209,154.7113,0.40452218,-156.07021 -17983000,0.93094164,-105.13261,0.00078241091,-54.37746,0.034215316,-104.77567,0.41697192,-157.53807 -18482500,0.92983884,-108.66609,0.0010974992,127.91957,0.027984586,-149.57079,0.39694411,-157.93936 -18982000,0.92966694,-112.30935,0.00090236275,175.17799,0.05438666,-15.918681,0.39316347,-166.07222 -19481500,0.92878532,-115.98783,0.00063512381,120.01904,0.033626772,-90.07373,0.39521095,-160.64186 -19981000,0.92915398,-119.8313,0.00057358795,58.807999,0.058278296,-121.86201,0.36743975,-168.62975 -20480500,0.93084979,-123.82815,0.00051313301,-104.17033,0.031946477,157.5869,0.40099725,-171.47815 -20980000,0.93120062,-128.10751,0.00040834665,74.318329,0.021878436,-131.12718,0.36165482,-172.80304 -21479500,0.93630677,-132.48914,0.0001516106,-150.57544,0.03258187,-157.98055,0.35127595,-174.11421 -21979000,0.9414193,-137.26146,0.00059608027,-163.55058,0.049915977,-169.23131,0.36126506,178.30246 -22478500,0.94759661,-142.25217,0.001270898,-31.064882,0.053619787,-130.12093,0.37772331,-178.83365 -22978000,0.95857257,-147.55046,0.001002221,108.57169,0.026691319,72.793755,0.38122302,-179.77701 -23477500,0.97051203,-153.72469,0.00053569302,174.94104,0.020092737,64.365364,0.34926432,178.35176 -23977000,0.98343498,-160.55563,0.0008065615,-96.800934,0.0077994959,58.919891,0.35548976,171.78714 -24476500,1.0000374,-168.06496,0.00085990538,-45.026993,0.059192229,14.066885,0.34536645,172.39125 -24976000,1.0163732,-177.04097,0.00037381161,96.88195,0.061682619,46.719826,0.32006407,168.82077 -25475500,1.0398149,172.90494,0.0011834512,-135.70558,0.16604225,2.1462009,0.36332917,168.9597 -25975000,1.0564195,160.43915,0.0015377392,-135.73367,0.17950034,-24.121456,0.32299313,166.1962 -26474500,1.0640458,145.77858,0.00067091663,-117.23086,0.28375447,-31.23395,0.35168317,162.05553 -26974000,1.0548806,128.16374,0.0019943509,101.4341,0.40370718,-47.010406,0.36383173,159.00339 -27473500,1.0036701,107.65199,0.0013927434,-128.24783,0.50343168,-66.69474,0.32264268,160.0882 -27973000,0.90708154,84.557404,0.00045534232,37.981838,0.61974633,-84.75087,0.36121747,159.3497 -28472500,0.78777951,60.34203,0.00069779798,132.55734,0.73657662,-101.55402,0.32008252,156.63634 -28972000,0.65814078,36.823879,0.0008619781,58.060432,0.77267313,-122.24246,0.35953647,159.16727 -29471500,0.56275988,13.907135,0.00057114306,164.86366,0.81698406,-137.99649,0.3424952,157.56487 -29971000,0.49604547,-7.4367747,0.0011858026,-128.47073,0.89615506,-151.43973,0.33238214,150.25653 -30470500,0.45147553,-26.610718,0.00015324647,115.99684,0.93593532,-163.92899,0.31830698,143.8528 -30970000,0.42898703,-43.302616,0.0013134438,84.734764,1.8416362,-172.77791,0.19372065,-175.91924 -31469500,0.41587153,-57.295582,0.00084159052,118.19,0.81950957,-162.65291,0.29394203,128.72519 -31969000,0.41241395,-69.734795,0.00079126033,100.40092,1.1518459,-167.0524,0.22499296,147.99782 -32468500,0.4076992,-80.65519,0.0002141424,-26.686661,1.7686511,-172.82658,0.44792676,125.15636 -32968000,0.40769553,-89.094109,0.00071550283,145.85516,2.0595808,137.16449,0.29971266,130.66869 -33467500,0.41088912,-97.664261,0.00064087351,-70.864426,0.84189498,162.31532,0.13457049,-173.23462 -33967000,0.40761545,-103.79649,0.0025449758,17.856142,0.023252496,126.47694,0.45547655,143.06812 -34466500,0.41267377,-109.42425,0.00073147693,-44.800911,1.1427953,76.74762,0.39459464,130.43556 -34966000,0.41180319,-115.30585,0.00061120314,109.51485,2.2153158,135.23846,0.47773185,168.16669 -35465500,0.41299671,-120.88081,0.00023203842,-10.8603,2.4028749,92.710899,0.20772538,135.51036 -35965000,0.41585153,-125.06943,0.001494777,-58.23233,2.4150887,99.103157,0.29845965,112.17042 -36464500,0.4120394,-129.24162,0.0017694583,-50.093056,2.1229374,117.87669,0.41585031,141.77293 -36964000,0.40699756,-133.47585,0.001636024,-131.18932,1.8157922,97.562614,0.30065247,124.30933 -37463500,0.4086653,-137.08705,0.0012507539,4.8252778,2.0126722,71.431091,0.48334116,136.08122 -37963000,0.41202193,-141.54645,0.0013434883,-113.89812,3.0592742,65.60434,0.38173932,149.07622 -38462500,0.40444714,-144.80994,0.0028788005,-144.04053,2.0842111,61.141983,0.34066451,92.095879 -38962000,0.39902097,-147.82944,0.00079359737,-112.2547,2.9694808,82.096146,0.417665,114.0573 -39461500,0.40206799,-151.96761,0.00098525966,-134.53558,1.6123022,69.229843,0.13044696,125.46663 -39961000,0.39882028,-154.70483,0.0014006307,-30.320477,3.0849652,62.153191,0.29852861,109.36538 -40460500,0.39798525,-157.43144,0.00064179621,108.37063,4.2055292,57.100548,0.29965341,106.17593 -40960000,0.39839694,-160.64821,0.0017369096,-152.11096,3.9045508,43.093647,0.17444576,172.0311 -41459500,0.39693546,-163.27838,0.0012693127,177.63435,5.4889455,29.635303,0.46917161,115.09867 -41959000,0.39779109,-166.35823,0.00060736533,128.94394,4.8799758,48.475246,0.2064309,95.086723 -42458500,0.38924801,-168.61267,0.0006596694,-5.8335085,4.1262951,25.812706,0.36007592,100.04928 -42958000,0.39261845,-172.22299,0.0014316367,-55.275387,4.2824225,20.541248,0.20933765,95.279945 -43457500,0.38685334,-174.90898,0.0011516642,-28.568003,5.8984594,7.1743307,0.3291418,90.65213 -43957000,0.38299322,-178.35733,0.0023389573,-85.168266,4.4657602,-1.6185012,0.37963226,119.82096 -44456500,0.38381726,179.29141,0.00040055212,76.261177,5.5706716,-1.502187,0.29163924,96.603653 -44956000,0.37747949,176.92009,0.00058888923,-111.93427,5.5647483,-21.2623,0.58526188,118.22253 -45455500,0.37639204,174.07198,0.0019120638,114.34007,5.9780025,-19.512962,0.5696786,73.348381 -45955000,0.37431121,171.18134,0.0010696372,-124.15282,6.7012377,-22.952991,0.11622393,107.20963 -46454500,0.37145385,168.57936,0.00077816175,116.91431,7.7543759,-28.294626,0.40249828,107.4873 -46954000,0.37088573,166.31088,0.00092796568,83.84861,7.5821743,-41.522427,0.32035929,97.954285 -47453500,0.3661671,162.32198,0.0020026998,22.789488,7.7393451,-45.384148,0.24886428,111.04979 -47953000,0.35790342,159.61316,0.00067679939,173.07814,8.4745808,-49.707848,0.21073033,156.19431 -48452500,0.36253658,156.36771,0.001469986,161.23706,9.0025911,-54.887852,0.41465646,103.49523 -48952000,0.36087063,153.79442,0.0012823706,-20.200382,8.782752,-60.572876,0.42057416,80.87339 -49451500,0.36099035,150.99055,0.00045002936,34.334656,9.9745989,-71.107086,0.63655752,106.39789 -49951000,0.35692939,148.20639,0.00041889405,-165.19431,9.3741417,-79.757217,0.42805284,79.288712 -50450500,0.35489962,145.05025,0.0020045154,97.71579,10.898042,-83.195969,0.43149799,101.83289 -50950000,0.35275736,142.40823,0.00061761594,20.863218,10.580898,-88.891418,0.22188076,82.764328 -51449500,0.34784806,139.16081,0.0010739631,-46.502636,11.166875,-91.699554,0.56695884,97.654343 -51949000,0.34952533,137.02094,0.00046624499,105.69015,11.43283,-99.430237,0.4193719,115.40155 -52448500,0.34401321,133.75642,0.00018901414,70.178085,12.368037,-109.14099,0.36228642,97.551819 -52948000,0.34343413,130.62238,0.00067485432,108.10582,12.610648,-116.1215,0.39659274,88.235603 -53447500,0.34317109,128.06502,0.00043073183,-104.69178,13.538619,-118.51481,0.36433589,89.377777 -53947000,0.33978954,124.52546,0.00029577749,164.75471,14.883125,-130.54582,0.38294816,62.594032 -54446500,0.33525363,121.33356,0.00065060507,38.655056,14.015751,-136.68568,0.38106644,76.866737 -54946000,0.33588237,118.97797,0.00087206264,-3.909874,13.442493,-142.31039,0.4500218,61.565018 -55445500,0.33663362,116.06055,0.0006129219,116.48191,15.400011,-149.27963,0.47921544,94.599472 -55945000,0.33026412,112.8008,0.00033041366,18.060966,15.041405,-155.18097,0.41898447,68.320053 -56444500,0.3305285,109.49085,0.00094757648,-22.328424,14.274023,-160.52499,0.4280633,81.952141 -56944000,0.3319492,106.05767,0.0018511437,-125.80934,15.506013,-163.11005,0.34186125,88.935982 -57443500,0.3302851,103.15953,0.0017865429,-97.063919,16.849688,-168.95493,0.3939102,62.365784 -57943000,0.32528174,100.23729,0.0014482029,-109.85168,16.13059,-177.01582,0.44469547,66.624435 -58442500,0.32615894,96.203941,0.00032787133,177.63242,17.404308,175.57458,0.49847123,57.558586 -58942000,0.322137,93.081047,0.00024796138,84.500954,17.567741,171.41113,0.59128457,57.877663 -59441500,0.32700625,90.29628,0.00036797248,-2.413116,17.599743,163.86555,0.42182383,71.011536 -59941000,0.32170519,87.240334,0.00083611539,121.54411,17.580305,159.28429,0.56122029,72.138084 -60440500,0.32247299,83.696335,0.00095835829,-105.25684,19.268747,156.60861,0.5652982,87.440109 -60940000,0.32191727,79.741806,0.001702255,-160.08101,18.750219,149.37744,0.37822232,52.341885 -61439500,0.32017609,76.581795,0.00049023883,101.52712,18.586311,142.04089,0.49747613,62.828266 -61939000,0.32285836,73.269478,0.0010427956,131.59274,19.831644,138.79709,0.62136358,78.038795 -62438500,0.32098925,70.403496,0.00071937463,65.485596,19.563309,133.60036,0.43096235,78.983887 -62938000,0.32140297,66.555992,0.00094050757,-18.192108,19.250589,128.0695,0.36467084,64.394119 -63437500,0.32013425,63.190029,0.0019867094,-152.42751,19.961926,120.30552,0.35163876,82.146637 -63937000,0.31909013,59.70763,0.00062889705,118.10195,19.564089,113.03025,0.3235966,64.863472 -64436500,0.32373801,56.069492,0.00048377909,-30.305696,19.689964,107.81995,0.37661108,59.10466 -64936000,0.31972802,52.795452,0.00068806001,126.61945,19.570627,103.75545,0.49368668,52.580002 -65435500,0.32012948,49.382732,0.00027114205,-118.62289,20.820398,101.05841,0.49077711,66.403854 -65935000,0.32089594,45.619862,0.0002888561,-32.144253,19.372992,91.354752,0.48748174,71.005363 -66434500,0.32097694,42.799026,0.00079479406,9.8333073,19.933788,87.518814,0.37836963,71.329453 -66934000,0.31938255,38.563335,0.00011676661,67.776886,20.154779,78.911423,0.33783615,77.212547 -67433500,0.32634467,35.474667,0.00037192629,102.82824,19.559603,75.630386,0.50516981,51.720131 -67933000,0.32487857,31.838343,0.00087287044,-21.979477,19.008717,72.048401,0.18796968,49.23624 -68432500,0.32279104,28.364162,0.00060205773,-172.01195,19.774689,66.49424,0.51000452,58.366405 -68932000,0.32143414,24.283869,0.00052823249,-147.51093,19.009554,62.550335,0.36963549,71.824524 -69431500,0.32472304,21.753269,0.00068210019,-67.909286,19.744095,59.158276,0.42217633,79.257217 -69931000,0.32204598,18.099005,0.00065759924,-110.80926,18.592945,54.775555,0.4872404,60.259583 -70430500,0.32497337,14.881576,0.0015025625,59.80283,17.881678,46.154156,0.66063559,50.983208 -70930000,0.32486314,11.697217,0.0013943092,-176.80798,18.227724,43.481541,0.58895224,59.923 -71429500,0.32223022,6.9242816,0.0023879358,-105.7421,17.532522,37.223133,0.304279,24.179113 -71929000,0.32837167,4.2929392,0.00090109633,23.543621,16.947372,34.725365,0.43240979,34.008301 -72428500,0.3232353,2.1862113,0.0014827627,-125.85352,16.243505,33.288582,0.32683533,63.121304 -72928000,0.32490665,-2.4307942,0.00066567119,24.549517,15.073597,20.941456,0.58130884,47.735836 -73427500,0.3281002,-5.6785736,0.0016128503,175.33228,14.504542,20.322416,0.59983921,55.380909 -73927000,0.32481211,-8.8985357,0.0013757864,174.9407,14.546135,16.198574,0.60002226,52.676167 -74426500,0.32321078,-11.946316,0.00078810484,-166.46617,13.105666,9.9270763,0.3280403,37.116772 -74926000,0.32155693,-16.04768,0.00079954491,-84.601547,12.91112,11.558486,0.520073,35.688473 -75425500,0.32541153,-17.442768,0.0021152552,-95.469368,11.800971,9.8068571,0.35510096,69.453705 -75925000,0.3197701,-21.703869,0.00091107032,179.39783,11.004528,5.2872567,0.52244461,51.643734 -76424500,0.31777886,-24.45315,0.00011612147,151.07664,9.8134594,7.0412478,0.35944936,52.543232 -76924000,0.32022309,-28.455685,0.00048006285,-64.865425,10.014273,3.715874,0.43162516,36.275116 -77423500,0.31891367,-30.70018,0.00082000624,20.548418,8.1125679,6.2651906,0.41370568,58.839504 -77923000,0.31536162,-34.161591,0.0019606135,159.88097,8.5875893,1.5799477,0.59221405,50.274498 -78422500,0.31588203,-36.898258,0.00024652711,16.293713,7.4016142,7.2298269,0.43594939,53.386826 -78922000,0.31327105,-39.95956,0.0025832916,17.838165,6.2172666,24.373302,0.49552262,42.44529 -79421500,0.3111077,-42.796932,0.00078188645,115.17449,7.6577415,20.109131,0.42411464,32.094109 -79921000,0.3073037,-45.026192,0.0010637868,-103.3511,6.5464005,25.326921,0.6612094,26.348671 -80420500,0.30833706,-47.834507,0.0003249213,146.06355,7.1717973,27.584135,0.5251658,17.629339 -80920000,0.3083216,-50.513371,0.0013414434,106.31727,8.1770849,37.17701,0.4872638,34.042618 -81419500,0.30467308,-53.807766,0.00090760348,-147.0266,8.6963682,43.764545,0.47556809,43.628723 -81919000,0.30563417,-56.17503,0.0010995105,168.26746,10.244211,45.135754,0.37416071,24.344288 -82418500,0.30100861,-58.551682,0.001350992,-111.76548,11.635194,42.873695,0.54078692,19.77997 -82918000,0.29697332,-60.842098,0.0013692202,-171.55861,12.547095,44.322899,0.31432807,28.883083 -83417500,0.29617497,-63.920811,0.00038339326,33.684303,14.082877,38.527439,0.38655695,40.848476 -83917000,0.29821277,-65.807625,0.0018068134,-1.5091747,16.587982,41.485611,0.33442298,11.522005 -84416500,0.28939766,-68.307251,0.0010761837,-72.568726,17.747026,37.979969,0.44955361,32.692364 -84916000,0.28674302,-70.186081,0.00058817287,71.839996,19.090961,38.17968,0.31659168,43.463894 -85415500,0.28312412,-73.344688,0.0010765564,-8.248909,20.863476,33.970863,0.52311826,34.295147 -85915000,0.28072235,-75.461784,0.001097117,101.81624,22.266588,31.082859,0.58168441,27.81031 -86414500,0.27983201,-75.986641,0.0014965398,145.36913,23.868889,25.899412,0.53507477,27.531393 -86914000,0.27613339,-78.412018,0.00075853179,-143.14439,27.417311,23.354088,0.48541546,48.733604 -87413500,0.27676803,-80.979485,0.00073137344,67.821228,28.199543,18.802105,0.3935667,24.636936 -87913000,0.27028102,-84.015984,0.00043423925,136.08131,30.041302,14.554374,0.49335083,33.886784 -88412500,0.26835942,-85.223526,0.00020389917,174.40634,31.997412,11.023723,0.38339281,15.202299 -88912000,0.26556563,-87.858955,0.0008535955,-88.943001,33.477356,7.6795354,0.32777905,29.820023 -89411500,0.2610077,-89.959938,0.0012391171,-88.740456,36.277786,3.9759598,0.34659609,26.616644 -89911000,0.25615868,-90.691223,0.0010261262,-80.605904,37.760174,-0.12234258,0.31373483,21.041044 -90410500,0.25619414,-93.978622,0.00064778927,-74.699097,39.362087,-5.3239942,0.67989284,40.801601 -90910000,0.25201347,-95.061073,0.0014754517,-65.780884,42.005131,-7.2339859,0.363626,9.7310801 -91409500,0.24887131,-96.330078,0.0009364385,-126.98061,43.335125,-12.642532,0.48746479,26.582846 -91909000,0.24746454,-97.824593,0.00083307945,-31.197836,45.617016,-15.601501,0.42307574,13.715392 -92408500,0.24447054,-100.25853,0.00061255379,-76.84877,46.52626,-19.565281,0.66405451,19.497061 -92908000,0.23895006,-101.29963,0.0006465186,-23.506695,50.213627,-23.494234,0.37214056,6.8048639 -93407500,0.23357953,-103.67052,0.00072482694,-81.757072,52.33366,-26.874714,0.34662816,11.911039 -93907000,0.23578681,-103.65668,0.00080944551,-165.67908,53.752438,-31.693598,0.51145101,23.647614 -94406500,0.23724236,-106.48222,0.00043445214,106.73846,56.626209,-35.746262,0.31732994,9.7861633 -94906000,0.23120862,-108.80781,0.00086581678,96.314713,57.682205,-40.403801,0.64385843,19.748568 -95405500,0.22341304,-108.69929,0.00060724426,-102.80311,59.467506,-44.888412,0.54746366,19.926638 -95905000,0.21669459,-111.48161,0.0020224629,-33.04483,60.71241,-47.714993,0.70991224,9.1874428 -96404500,0.22183694,-113.02415,0.00055581133,49.013939,63.85043,-52.626202,0.61125237,28.349545 -96904000,0.21939757,-113.56567,0.00090564019,129.42963,65.551979,-57.073563,0.42123571,28.761019 -97403500,0.21452737,-115.36705,0.0009748895,-49.682579,65.500961,-60.181591,0.7772091,23.186466 -97903000,0.20828563,-117.3465,0.0013592474,-19.854095,68.718521,-64.541344,0.66838056,18.912882 -98402500,0.20965396,-117.3721,0.00015417224,141.18527,72.335938,-67.943939,0.45761785,-1.1374637 -98902000,0.21062525,-118.44932,0.00063781562,138.53772,72.664902,-71.150345,0.53710407,-14.103663 -99401500,0.19708398,-120.38273,0.0014514998,-36.667999,73.251297,-76.770271,0.7120229,-13.931108 -99901000,0.20228709,-122.40675,0.00074152916,127.34075,76.178535,-79.763008,0.52501726,14.026489 -100400500,0.19601335,-122.3083,0.00089239288,-84.915207,77.741364,-83.470314,0.54324007,11.008256 -100900000,0.19323969,-126.41145,0.0017406578,40.411861,79.195908,-87.311188,0.65292192,10.789371 -101399500,0.18793122,-125.29235,0.0013294836,2.2215371,80.38591,-91.818245,0.60642338,9.5401402 -101899000,0.1955457,-124.79311,0.00089179474,-145.95294,85.088799,-94.988068,0.28701466,-35.111694 -102398500,0.19266865,-128.68869,0.0014533661,116.15685,82.418083,-99.62764,0.77404147,0.27841666 -102898000,0.19374871,-129.00177,0.0019648604,156.08333,86.252197,-102.42139,0.52215737,-20.827457 -103397500,0.18726839,-128.81168,0.0016224374,-163.25026,86.322372,-106.66219,0.50811106,7.3624573 -103897000,0.17826284,-127.02409,0.0019163364,-73.272072,88.644691,-109.7229,0.72775149,-13.214701 -104396500,0.17896175,-130.76143,0.00047271032,-88.500252,90.168251,-114.8904,0.16059969,5.1684237 -104896000,0.17658961,-130.21838,0.00086366397,-99.261528,90.249779,-118.0602,0.45186847,-10.814528 -105395500,0.17241871,-134.48763,0.00097282534,87.374878,89.397942,-121.37593,0.60829091,-10.719983 -105895000,0.17596556,-136.04535,0.0010474009,171.07918,91.487213,-124.85613,0.54125702,5.9049854 -106394500,0.17066643,-135.82236,0.000646514,-139.47398,91.177101,-128.36459,0.83773285,-34.621284 -106894000,0.17202131,-133.70941,0.0014746998,-89.732445,90.293938,-133.65833,0.41223362,25.809225 -107393500,0.16401553,-134.4425,0.00078394462,-37.754864,93.397263,-136.4111,0.55184168,-11.643411 -107893000,0.16427793,-137.36841,0.00032541243,-117.02674,91.371094,-138.48407,0.63284522,-16.272779 -108392500,0.15611441,-138.81476,0.00028857306,63.581287,90.653534,-142.22258,0.80381,9.4673147 -108892000,0.15757096,-140.54761,0.00091001164,155.88193,91.525047,-146.75977,0.28438553,-36.648235 -109391500,0.15667003,-138.0127,0.00098031922,-71.015343,89.138802,-148.83315,0.4109624,-3.9939733 -109891000,0.1527874,-140.57428,0.00023476193,73.560577,90.462967,-151.75368,0.39484754,-96.228081 -110390500,0.15339164,-141.25578,0.0005673194,82.387184,86.147957,-152.59023,0.63365328,-10.136882 -110890000,0.15513177,-142.25519,0.001299268,-105.81619,83.810791,-154.75053,0.67126131,2.5400229 -111389500,0.13865308,-141.86459,0.0010468259,55.033306,84.534332,-157.81604,0.61178541,-25.377106 -111889000,0.14374153,-142.34033,0.00084423518,-20.134428,82.412727,-157.88335,0.74786985,-24.763191 -112388500,0.14630735,-142.76169,0.0011089299,-65.895866,78.31794,-158.01819,0.9962967,-15.999274 -112888000,0.13984104,-146.06503,0.0011770007,-172.89545,73.835014,-161.11252,0.47967705,4.3473177 -113387500,0.13699695,-144.80319,0.0009374299,13.874335,73.121605,-158.08322,0.420362,-33.40321 -113887000,0.13730241,-145.31532,0.00038169272,58.196442,69.86441,-155.86708,0.6561498,-9.3877058 -114386500,0.13861637,-148.23672,0.00043630815,-138.2514,70.043007,-152.53816,0.99039066,-18.179165 -114886000,0.13356778,-148.33545,0.00068737846,-176.9283,69.01088,-150.71088,0.45891261,-20.132532 -115385500,0.12873952,-146.68369,0.00093991612,65.120819,71.609062,-143.30649,0.57968968,-11.477951 -115885000,0.13487178,-146.99759,0.001813092,-92.23378,77.698044,-140.12085,0.72587788,-18.538975 -116384500,0.1234218,-146.87367,0.0010860981,56.524578,84.235397,-134.06465,0.7315433,-7.2509999 -116884000,0.12609984,-148.74504,0.00030442595,162.28253,95.495125,-131.4731,0.42490295,-19.430239 -117383500,0.12581627,-147.53696,0.0011864812,-52.391972,109.18452,-130.94514,0.40997657,-46.667995 -117883000,0.11428186,-148.87836,0.0014064661,43.509159,127.55699,-127.90485,0.73100913,-20.671959 -118382500,0.12489288,-148.42522,0.00096312648,-43.94714,146.92361,-128.05536,0.55178583,-21.766613 -118882000,0.11831354,-152.17557,0.00056667288,111.87006,176.52332,-129.65347,1.1878804,-50.707001 -119381500,0.11149063,-149.66823,0.00080316589,65.958763,196.99501,-133.21132,0.2525906,-28.499798 -119881000,0.10483465,-147.86208,0.0011393795,51.257313,229.22887,-135.60474,0.62140328,-18.551664 -120380500,0.10477402,-153.61147,0.00092234713,106.97748,269.46082,-139.31616,0.95748401,-43.27729 -120880000,0.1185964,-151.84435,0.00034810149,-61.09687,300.04956,-143.69934,0.47284392,-14.480231 -121379500,0.11120728,-161.71063,0.0015090946,-174.53616,346.68317,-149.71542,0.65505242,-48.072441 -121879000,0.10149212,-155.81242,0.0006604435,141.63539,387.07974,-155.72508,0.43584898,-79.633774 -122378500,0.11673572,-144.58638,0.0010269658,13.826126,439.56314,-161.85544,0.6549015,-71.927437 -122878000,0.11997941,-157.86681,0.00092055631,-102.92419,481.62131,-167.1227,0.58983099,-41.742512 -123377500,0.098967649,-154.56528,0.00043626552,150.15102,523.53894,-174.22903,0.32636535,-4.3787646 -123877000,0.12013126,-159.14905,0.00067904359,-84.861938,578.13318,177.01385,0.5293619,-119.06547 -124376500,0.090219416,-142.14748,0.00098526815,97.326233,621.40845,171.76157,0.36808497,1.9918027 -124876000,0.14248711,-160.06914,0.0016324584,-47.419197,666.78314,162.11671,0.538764,-136.88631 -125375500,0.10842189,-163.01328,0.00075419364,-93.362099,712.77448,156.4066,0.23993324,-38.037533 -125875000,0.081315324,-168.15436,0.0010190301,-142.96429,749.90741,149.07568,0.17746928,13.360361 -126374500,0.098139614,-134.35555,0.0011307494,107.31102,802.04083,141.71851,0.50783718,-36.33696 -126874000,0.10009312,-138.12531,0.0007984899,108.47221,835.46582,134.04417,0.55949879,-55.881847 -127373500,0.14461148,-154.43939,0.0012825342,25.09623,857.98389,127.15196,0.33644664,-28.883013 -127873000,0.087078951,-155.75655,0.00020983235,-134.24579,893.07312,119.95847,0.61565197,-38.795181 -128372500,0.026940048,-164.07767,0.0017778705,-132.98058,895.55731,112.93007,0.073840812,-35.310005 -128872000,0.1354125,-157.44426,0.0011014526,44.156048,933.57001,106.46514,0.5887484,-44.548592 -129371500,0.098179273,-156.39351,0.0002474481,44.036377,931.73077,100.11524,0.20501676,16.432783 -129871000,0.15873666,-157.69713,0.0017084939,63.219234,955.65771,94.412888,0.44413808,-3.7970908 -130370500,0.079525389,-139.53174,0.00056974369,-154.13567,950.13293,88.038841,0.13085045,80.01442 -130870000,0.067435831,-108.01481,0.0016592545,-141.80759,966.04694,81.272606,0.24937727,-131.6711 -131369500,0.099886581,-127.27649,0.0011399778,-176.30241,1005.1879,75.723709,0.70935535,-38.67355 -131869000,0.11780213,-134.46602,0.0011312825,162.27312,1008.1822,70.277992,0.66385669,-39.849682 -132368500,0.074965104,-173.4653,0.00077896257,-9.0285292,983.61914,64.108826,0.51626956,-154.90558 -132868000,0.14022002,-117.36446,0.0021586036,-169.0079,1014.9421,59.733044,0.36011288,-19.96405 -133367500,0.077852041,-144.31969,0.00040213045,-116.62802,996.89014,54.790508,0.40492272,114.57064 -133867000,0.12806095,-154.52141,0.0011405484,132.8252,1013.0038,48.639027,0.28517896,-113.81244 -134366500,0.076506793,-163.72505,0.00049250736,29.273582,1024.9266,44.847404,0.21049666,27.757221 -134866000,0.10631267,-134.67223,0.00090900646,-148.57005,1061.5205,38.500118,0.86849284,-44.223209 -135365500,0.034163699,-155.59222,0.0011132574,-18.620275,1051.2837,34.460636,0.35587785,-10.47262 -135865000,0.050228473,-115.06701,0.0012264112,-51.091431,1049.0289,28.136105,0.66348523,-88.302452 -136364500,0.088969275,-153.94199,0.00022210779,156.74783,1053.5688,24.885517,0.074820064,-11.770667 -136864000,0.083451778,154.31911,0.0017650691,66.575714,1058.9039,18.803137,0.63069183,-98.007278 -137363500,0.10701597,-119.64751,0.0013530867,-94.984734,1066.9075,15.819549,0.12553352,68.177368 -137863000,0.051973876,179.95932,0.00094822195,57.424236,1064.5909,11.111066,0.12356019,157.41379 -138362500,0.0740306,178.98441,0.00089604512,94.283875,1084.8207,5.9120579,0.26845014,-55.165356 -138862000,0.094927445,-134.05627,0.0007063896,-91.011765,1096.9353,1.2830713,0.41437548,-46.560974 -139361500,0.10307845,-144.07083,0.00073079573,-130.06496,1083.5638,-2.6003501,0.071360163,-112.82555 -139861000,0.099545009,-107.33069,0.0014793819,-44.203613,1098.1909,-7.031817,0.066851646,-36.436924 -140360500,0.06066883,175.41173,0.0010250676,104.27967,1113.8135,-11.655117,0.19175012,-35.577015 -140860000,0.09848462,-145.94446,0.00057075941,-109.31541,1124.3419,-15.392282,0.35135531,41.11293 -141359500,0.087908395,-133.96825,0.00053114869,-51.633381,1127.1212,-19.901236,0.21162279,44.882748 -141859000,0.073338039,-168.53212,0.00057991443,155.67677,1130.9845,-23.524059,0.42413053,87.174187 -142358500,0.047204517,-140.17183,0.00055406801,77.21196,1146.6731,-28.749994,0.33404434,21.119078 -142858000,0.089915819,-143.09497,0.00042025981,-67.137802,1150.6774,-33.847279,0.3369402,-21.199848 -143357500,0.062129129,121.70418,0.0020548382,135.30667,1164.6042,-38.547234,0.59267229,-27.476559 -143857000,0.091088787,-143.53766,0.00044089794,-58.070404,1145.2549,-42.834656,0.49014097,-82.720909 -144356500,0.12121948,-158.21432,0.0010770045,-99.229355,1179.2751,-46.246014,0.34445822,12.286572 -144856000,0.05854376,-156.59268,0.00035775101,163.12053,1173.2289,-51.74152,0.69370836,-40.451435 -145355500,0.025449367,-102.58544,0.0011143906,105.55436,1185.0303,-55.245583,0.49279818,-5.1623831 -145855000,0.08248128,-124.06934,0.00056053768,27.919127,1180.1558,-58.950508,0.20473352,-15.885305 -146354500,0.057183865,-148.75258,0.00018981342,154.27419,1187.515,-63.233139,0.2742857,10.452492 -146854000,0.050894488,-142.7803,0.00036916501,141.08575,1192.2957,-67.825165,0.37619865,-26.530359 -147353500,0.055837013,-15.236947,0.0021986605,128.92099,1191.5626,-71.344337,0.12098411,-15.998218 -147853000,0.074371159,-169.93062,0.00071042392,-115.1133,1186.4773,-75.828606,0.32261938,-70.074623 -148352500,0.031522363,-131.22342,0.00069155439,153.22116,1185.479,-80.179993,0.41223907,-68.372124 -148852000,0.083600461,-127.88689,0.00042770547,52.948349,1189.1599,-84.293739,0.47793561,-75.735451 -149351500,0.084461406,-119.04853,0.00069109316,73.649994,1207.7965,-88.466423,0.35061577,-25.791988 -149851000,0.02416428,-95.133545,0.0010019395,166.33121,1185.6569,-92.587852,0.57138187,-80.61853 -150350500,0.14279543,-141.55988,0.0013610815,10.694996,1218.348,-96.910316,0.52245259,-21.847723 -150850000,0.096925639,-154.37312,0.00055243506,-27.488382,1241.6031,-100.56483,0.58412153,19.818033 -151349500,0.035079684,-162.48047,0.0006879053,-131.42998,1225.9246,-103.88717,0.18476194,6.6152763 -151849000,0.14369559,-155.22313,0.001363471,2.8939481,1223.2842,-108.35158,0.21936366,-34.51997 -152348500,0.13287972,-157.60425,0.0012409475,2.8934329,1219.4664,-112.80592,0.42769876,-34.732609 -152848000,0.12157571,-120.87212,0.0010866568,83.105347,1212.0624,-117.19063,0.63132036,-45.956455 -153347500,0.084243782,-130.63187,0.00036405463,86.024651,1220.5826,-118.98606,0.25474134,-176.34274 -153847000,0.018491022,29.030739,0.001549369,-126.61823,1240.4497,-123.81696,0.17590199,29.557005 -154346500,0.022245085,33.427811,0.0015526538,-121.31377,1228.3025,-128.08115,0.24716179,-32.405315 -154846000,0.033721294,-102.28547,0.00073445158,-134.00246,1215.6722,-131.26971,0.3478618,-94.441307 -155345500,0.068433486,-114.95133,0.00049543695,170.44507,1233.3969,-137.03493,0.655379,-16.395006 -155845000,0.073557712,-136.12894,9.2816124e-005,117.27807,1242.1373,-138.37782,0.26124763,160.47388 -156344500,0.10122519,-74.654778,0.0015363931,-166.81961,1250.5891,-143.50511,0.21284333,15.392033 -156844000,0.12064891,-84.598412,0.001616033,-178.51936,1230.2458,-146.32118,0.30842382,-140.64862 -157343500,0.17505182,-121.65583,0.0017465758,126.35152,1242.9927,-152.27513,0.53956938,-12.175362 -157843000,0.048829973,158.78398,0.0010852054,-32.97319,1255.8021,-155.13884,0.2886664,30.273212 -158342500,0.065935135,-126.31624,0.00018886394,-148.49055,1217.9957,-158.57758,0.47792366,-68.24308 -158842000,0.083340853,168.07227,0.0011170738,10.301439,1234.2375,-163.67265,0.61676997,-11.19793 -159341500,0.068490036,-148.02774,0.00018567566,31.224316,1258.2853,-167.92456,0.79779786,22.38114 -159841000,0.11142594,-164.91,0.00090766692,64.672729,1248.6118,-169.48297,0.075258054,167.64842 -160340500,0.036237676,176.56847,0.00083799451,-16.691891,1219.8405,-174.4118,0.54324818,-43.489239 -160840000,0.13310504,-138.22183,0.00099184702,135.25119,1256.377,-178.29887,0.47145885,28.815929 -161339500,0.041169308,-134.01591,0.00049112528,-32.028637,1239.4301,179.56087,0.14094174,-112.75693 -161839000,0.059564665,-137.48274,0.00017993842,-13.014254,1237.7163,175.87871,0.18264648,-98.429428 -162338500,0.017411338,-172.65843,0.00086973654,-10.280556,1251.9314,172.28322,0.13173574,138.43642 -162838000,0.087882087,-113.97765,0.00052782643,-124.96402,1205.2817,168.65057,0.58910513,-83.453461 -163337500,0.14829998,-127.06568,0.0011544701,-177.02094,1237.1892,165.24792,0.2809411,-126.29639 -163837000,0.15824015,-112.59339,0.0014787019,-145.33913,1251.0789,159.93898,0.3670561,40.926128 -164336500,0.15194871,-101.30666,0.0015012965,-122.59504,1237.2189,158.22614,0.31275117,-128.7265 -164836000,0.1128796,-124.64634,0.00067524181,-151.93137,1232.1354,152.43735,0.47184637,5.6558499 -165335500,0.061956804,-91.633095,0.0007000101,-44.329697,1246.613,151.50945,0.39029026,-157.52461 -165835000,0.070054993,124.10478,0.0016854785,56.158272,1220.6193,146.93556,0.31199145,-92.265869 -166334500,0.09686403,-104.16421,0.00071373972,-82.033974,1202.0931,141.97639,0.65911442,-25.904476 -166834000,0.11310416,-174.27583,0.0011464275,128.52208,1265.6931,138.48535,0.59106833,85.365204 -167333500,0.048184521,20.697014,0.0017881094,25.14345,1221.6346,136.13394,0.21516256,-74.35331 -167833000,0.087484278,-104.39298,0.00059606577,-54.469135,1252.5623,132.11333,0.30903706,100.31258 -168332500,0.029985053,-156.63771,0.00071695464,60.618141,1255.9713,128.4534,0.38978601,96.780396 -168832000,0.054692384,146.74965,0.0012909186,89.521187,1230.1812,124.46725,0.23621285,39.52578 -169331500,0.13750853,-61.777996,0.0019536517,-22.443668,1198.7947,122.95258,0.5314256,-75.412659 -169831000,0.0080039157,10.593622,0.00120521,57.427986,1214.9591,118.7903,0.16746189,-74.29789 -170330500,0.15365769,-142.69923,0.0012482654,-132.99658,1226.3479,116.08717,0.31797141,-134.77782 -170830000,0.11714919,-138.81334,0.00070277799,-131.41325,1203.66,110.78856,0.46071628,-6.8816748 -171329500,0.12019135,-113.70497,0.00079127785,-60.539417,1251.3558,109.14108,0.53572595,176.64325 -171829000,0.17579164,-156.82564,0.00168397,-139.96739,1219.9545,104.94264,0.10610653,-99.111481 -172328500,0.01108323,127.51454,0.0012271693,95.320892,1168.2471,101.60012,0.7548461,-48.633717 -172828000,0.079909511,-137.59341,0.00015982761,-154.43726,1225.5872,98.442848,0.20752561,-156.1317 -173327500,0.084476091,-45.922401,0.0016738602,48.437698,1195.9708,93.645485,0.3567521,8.8012619 -173827000,0.1897615,-130.97226,0.0017284696,-76.48996,1187.3944,91.042313,0.4257029,-30.494961 -174326500,0.066355653,-154.6104,0.00044472914,172.8047,1182.2043,88.073517,0.45957002,-43.325176 -174826000,0.10055084,-173.34035,0.0010265567,-158.38525,1195.3525,83.773361,0.28433672,5.1836643 -175325500,0.089572899,-70.69342,0.0012597343,52.88126,1223.6163,80.63224,0.22590448,119.58775 -175825000,0.079783276,-106.27184,0.00054182514,45.2005,1178.7317,77.407501,0.39919406,-13.610972 -176324500,0.077850588,-91.810295,0.00078335701,60.222126,1195.5497,74.508652,0.12628137,-36.583473 -176824000,0.10314558,-147.00153,0.00052896334,-97.666565,1200.106,70.500015,0.19596399,58.595032 -177323500,0.11738005,-120.74753,0.00067245931,-9.6312227,1172.1763,67.489113,0.46522534,-8.2933655 -177823000,0.12289252,-97.108826,0.0011264763,38.315552,1195.3585,64.359726,0.042150602,-54.817204 -178322500,0.094759256,-95.921249,0.00083801377,59.668247,1182.423,61.167664,0.22343525,-15.030588 -178822000,0.12583181,-122.83306,0.00078528747,-7.0581398,1179.6737,59.035988,0.4538511,-68.163109 -179321500,0.088135324,-122.50824,0.00017456315,47.886303,1195.9783,55.461403,0.36499587,-109.23214 -179821000,0.12270776,-153.0636,0.00088537682,-67.915619,1195.1837,51.026169,0.14871463,98.352036 -180320500,0.069592893,-123.39704,0.00020380178,134.9205,1155.8346,48.963799,0.57126194,-33.75177 -180820000,0.027845269,-149.74382,0.00089094503,-176.64598,1149.9813,44.581734,0.51671904,-2.6034045 -181319500,0.056388468,56.706078,0.0021112603,-176.43956,1158.4709,41.862381,0.43086013,-17.578815 -181819000,0.13581127,-91.368439,0.0013588456,79.837494,1163.4742,38.861546,0.47380888,-36.44849 -182318500,0.11281042,-154.22485,0.00079666858,-52.560474,1179.548,34.369179,0.25637972,67.886093 -182818000,0.13001414,-96.203079,0.0012075866,85.29557,1151.1188,33.732239,0.719464,-50.349358 -183317500,0.082212128,-172.60815,0.00098585919,-90.86235,1174.9819,27.87726,0.19286834,53.450275 -183817000,0.099001236,-106.83399,0.00060938491,106.42294,1143.3485,25.500523,0.60057819,-2.5623944 -184316500,0.1311685,-123.08723,0.00081252569,53.281509,1132.2035,22.370056,0.64178199,-0.62218726 -184816000,0.096315391,-170.72244,0.00098847062,-63.864666,1164.9803,17.475969,0.54451996,73.345802 -185315500,0.07121335,170.56598,0.001277445,-89.118317,1162.6683,14.567693,0.37876195,85.086014 -185815000,0.044807136,-130.52885,0.00058624346,-140.71777,1152.2054,13.258008,0.32666576,-13.431854 -186314500,0.07386446,-137.01366,0.00023534786,-94.241272,1161.144,10.698757,0.43414775,-66.572174 -186814000,0.035822205,-21.260994,0.0016886105,-145.33081,1150.7104,5.774322,0.30420402,56.435581 -187313500,0.066094518,-106.8178,0.00061949558,-165.26465,1143.9946,3.4270651,0.30312511,-8.4942236 -187813000,0.043312442,-102.1591,0.00085956266,-137.24878,1165.287,0.76833379,0.27467781,-80.454857 -188312500,0.11375853,-166.17662,0.0011170318,-14.95929,1133.5919,-2.1719782,0.52810258,-17.793501 -188812000,0.026787881,142.01802,0.0015301517,-86.856316,1135.4601,-5.6740379,0.46454203,-12.971207 -189311500,0.072760105,-148.08154,0.00044211335,-51.291801,1133.6113,-7.9161878,0.63225394,-30.705389 -189811000,0.08320792,-172.55302,0.0010157701,-27.73279,1154.5336,-13.023265,0.20504488,106.51592 -190310500,0.17177843,-112.38186,0.0016250282,124.20121,1144.085,-15.491965,0.19694567,14.510863 -190810000,0.12955213,-140.11957,0.00077234482,67.993103,1168.1462,-16.518856,0.87562889,-83.302528 -191309500,0.12840436,-137.78706,0.00078223407,78.235641,1140.361,-21.571932,0.19722226,3.7034397 -191809000,0.053459365,-120.54432,0.00067275617,-92.760872,1142.9579,-23.548914,0.5017432,-51.406876 -192308500,0.1736764,-146.11598,0.0016676324,80.458488,1148.2468,-27.046576,0.35505587,-64.708199 -192808000,0.03504312,-94.397415,0.0012013708,-85.294662,1098.589,-30.078262,0.85525167,12.113844 -193307500,0.056511756,-104.21104,0.00086170301,-91.331421,1148.6869,-33.676308,0.28838268,-92.637093 -193807000,0.10884896,-99.675743,0.0010453871,-153.23367,1123.4626,-37.082123,0.36934331,33.204609 -194306500,0.12883963,-177.45137,0.0017298576,39.258266,1102.5208,-40.187859,0.60789144,37.586452 -194806000,0.096177548,-157.7117,0.00079271151,40.470398,1138.8994,-42.739136,0.22633424,-50.644875 -195305500,0.049245372,-177.90497,0.0012536539,-9.9974279,1126.4565,-43.746681,1.0018271,-34.933384 -195805000,0.079078652,-105.052,0.00072417996,-96.00853,1131.8062,-49.175816,0.17794463,-39.932602 -196304500,0.073360592,-109.23246,0.00068513909,-78.711945,1134.7323,-51.119347,0.5653922,-46.960392 -196804000,0.1389944,-149.42407,0.0011321711,110.23898,1133.2462,-54.813877,0.19978543,-53.389923 -197303500,0.16410966,-130.05827,0.0013934236,163.26537,1118.3081,-57.263065,0.51409304,-11.438993 -197803000,0.049895689,-135.53279,0.00080435176,-12.777671,1105.3206,-60.468388,0.57640165,15.333698 -198302500,0.11672594,-112.50173,0.00086761173,-128.90889,1153.7673,-64.008163,0.59266728,-101.38144 -198802000,0.093269236,-142.75371,0.00033442798,79.39621,1113.1772,-66.129112,0.56605816,-9.9621458 -199301500,0.15168314,-115.62547,0.0013945618,-140.09251,1124.024,-70.184509,0.14911471,-53.8456 -199801000,0.061991926,-178.3286,0.0013411228,46.760464,1105.3879,-73.059723,0.3642543,28.083992 -200300500,0.1062722,-112.14964,0.00075719546,-94.137054,1137.2811,-75.621857,0.50855684,-71.154839 -200800000,0.089889564,-132.99554,7.5900498e-005,-22.394165,1114.4254,-79.620392,0.18539934,110.61823 -201299500,0.084784843,-161.67183,0.00093393464,83.569176,1097.6127,-81.610802,0.50466031,26.485737 -201799000,0.13603047,-134.2543,0.00098542764,-159.61615,1115.5571,-84.479622,0.41408423,-18.124908 -202298500,0.098998308,-141.5052,0.00028481512,135.59911,1127.8485,-86.491898,0.77065849,-35.868282 -202798000,0.10639526,-127.94574,0.00038525948,-118.91868,1121.3296,-90.975121,0.23733476,-50.081821 -203297500,0.089457937,-109.96883,0.00076187163,-32.858219,1105.129,-93.666206,0.36503705,7.1414952 -203797000,0.029943299,-22.656456,0.0023524624,31.359892,1091.3463,-97.521667,0.40762806,86.286003 -204296500,0.091708966,-162.88016,0.00098347012,116.74982,1118.6049,-98.045174,0.83971369,-22.964113 -204796000,0.14336817,-134.20412,0.0011043955,-128.76851,1120.0121,-102.49333,0.43029577,-40.220551 -205295500,0.043338794,-77.059021,0.0018425388,33.746006,1120.9561,-105.42807,0.46819091,-51.831909 -205795000,0.096672691,-172.89386,0.0014900788,137.21751,1125.7776,-107.93501,0.6958791,-43.489628 -206294500,0.1160654,-130.72778,0.00050402596,-97.848793,1127.4734,-110.76044,0.74338156,-39.686142 -206794000,0.08125037,-145.71111,0.00051141257,130.69724,1101.5038,-114.24279,0.33988735,18.166334 -207293500,0.089240305,-137.47493,0.00020523056,139.66998,1106.5348,-117.70422,0.1610681,-39.011108 -207793000,0.12984654,-104.62116,0.0015117938,-21.018152,1128.6489,-120.27654,0.6733048,-58.461166 -208292500,0.09102384,-147.91652,0.00051559426,160.84695,1121.2285,-123.30128,0.46276784,-63.584759 -208792000,0.054349404,-95.029404,0.0014811882,66.791916,1110.1858,-126.91703,0.32880831,-103.89385 -209291500,0.1515325,-146.25879,0.0014335553,-110.46764,1114.8138,-129.07726,0.39823392,-52.743092 -209791000,0.11838236,-149.37521,0.00090659218,-130.60834,1107.5094,-131.68826,0.38591537,-14.788454 -210290500,0.11098874,-78.377457,0.0023525227,43.829403,1105.926,-134.95683,0.2540037,-49.983204 -210790000,0.1204594,-159.58083,0.0012697401,-135.03616,1110.4069,-137.70143,0.33594972,-24.617279 -211289500,0.12153049,-139.98499,0.00064147869,-86.466919,1102.5525,-140.54507,0.25403827,-13.709105 -211789000,0.073346011,-133.25209,0.00057040941,123.95808,1107.0784,-144.00984,0.28694808,-76.682724 -212288500,0.081521414,-155.02409,0.00085936266,-170.08153,1109.6748,-146.23909,0.41419083,-24.534946 -212788000,0.10706994,-158.46629,0.0010913564,-130.68039,1118.8038,-149.59583,0.63210064,-57.316864 -213287500,0.076094158,-153.10207,0.00094682584,-171.53345,1105.2194,-152.97116,0.41771525,-100.68606 -213787000,0.074860491,-151.55466,0.00087386736,-169.83559,1107.4026,-154.48549,0.45539767,-11.330937 -214286500,0.038344868,-158.10463,0.0016325546,170.26009,1125.4365,-158.20958,0.78164536,-47.187885 -214786000,0.057616554,-115.16952,0.0010882762,140.94547,1096.7289,-160.78415,0.27078906,5.3788414 -215285500,0.078181818,-156.66966,0.00089541235,-143.72998,1094.963,-163.85564,0.099483997,11.590009 -215785000,0.076436438,-147.08459,0.00071424257,-150.9825,1116.6918,-166.92732,0.62009245,-46.350243 -216284500,0.12780908,-135.47275,0.00076255086,-2.5573838,1111.3015,-169.45911,0.46438941,-28.960876 -216784000,0.15444964,-139.0273,0.0013657545,-6.5647407,1117.6674,-172.49477,0.52725238,-31.176849 -217283500,0.12167112,-132.67093,0.00054961175,21.4338,1111.8013,-175.47153,0.55545759,-40.933777 -217783000,0.083232485,-113.31462,0.00090113824,138.43849,1093.6997,-177.13631,0.41333875,67.312141 -218282500,0.072307117,-155.35629,0.00091657758,-119.09106,1096.266,178.14285,0.3957293,-99.482559 -218782000,0.073262118,-138.37334,0.00065418828,-143.68793,1108.9202,176.61134,0.38766477,11.632417 -219281500,0.11156124,-114.50645,0.00098109932,110.66705,1122.8571,173.12975,0.76097375,-31.677301 -219781000,0.10765345,-131.82043,0.00025870901,73.254555,1108.376,169.59917,0.53643847,-63.241745 -220280500,0.079122216,-167.9471,0.0012721446,-85.206856,1119.1503,166.84868,0.718229,-49.84827 -220780000,0.090960629,-137.18053,0.00029203366,-110.14076,1091.3304,164.51469,0.26840872,-105.1938 -221279500,0.12085742,-155.99025,0.0010483448,-22.096889,1105.1205,161.75269,0.21069077,-26.764622 -221779000,0.13733026,-134.53786,0.00092987594,58.968754,1101.8362,159.14447,0.16004656,-3.4583673 -222278500,0.12732697,-130.99142,0.00071292371,80.688538,1113.7411,156.24658,0.3810747,-11.827003 -222778000,0.076240435,-158.73915,0.0010349285,-69.972977,1120.1782,152.92502,0.60905612,-36.267418 -223277500,0.083300151,-162.15662,0.0010344512,-51.39212,1095.071,150.63547,0.10096369,-174.31183 -223777000,0.046343405,-131.23138,0.0012710115,-105.01625,1110.474,146.75879,0.54912031,-59.715763 -224276500,0.12382344,-140.64427,0.0006607332,64.385345,1097.8125,144.91676,0.050621156,172.04276 -224776000,0.12367252,-151.45757,0.00089046755,29.691971,1108.5028,141.21532,0.44992155,-62.178391 -225275500,0.08790911,-130.37576,0.0003703002,-120.82833,1112.4025,138.04475,0.63400686,-60.425652 -225775000,0.056198496,-92.986,0.001610445,-114.14854,1104.4261,136.03839,0.28140974,-66.948509 -226274500,0.09280549,-145.14978,0.00037071228,-40.909851,1127.5552,133.39841,0.42812365,-7.7670965 -226774000,0.10785912,-101.3148,0.0014774498,-150.23979,1091.4553,130.45789,0.37131599,-135.65779 -227273500,0.046987876,-152.29784,0.0012656883,-52.781563,1116.4731,127.67025,0.3459003,-23.129696 -227773000,0.082326882,-106.43948,0.0011078854,-112.02968,1115.88,124.62274,0.40692833,-40.894974 -228272500,0.071302705,-136.93549,0.0006170792,-56.861397,1094.4407,122.12614,0.28663874,-133.40413 -228772000,0.079601049,-114.99555,0.00079680898,-97.66095,1112.4641,118.9146,0.37207243,-45.295673 -229271500,0.093534522,-145.09209,0.00040340787,1.4166249,1099.6593,116.1872,0.42945492,-100.562 -229771000,0.087460048,-126.82124,0.00053193787,-89.182678,1118.6354,112.66402,0.55128932,-49.341228 -230270500,0.088774875,-155.81648,0.00067849719,24.939749,1106.3032,110.71852,0.22102135,-82.637451 -230770000,0.028534072,-166.28389,0.0016238948,-22.160002,1123.5719,107.86568,0.2552129,-8.650321 -231269500,0.11772126,-134.80031,0.00030492604,157.44289,1116.5641,105.62548,0.031196076,35.148964 -231769000,0.16235153,-160.34789,0.0016554361,105.63643,1117.7579,102.08315,0.30298868,-39.538887 -232268500,0.14971316,-136.536,0.00092158833,161.10133,1106.9788,99.126534,0.44920322,-78.697372 -232768000,0.15973876,-130.2942,0.0012261539,-171.92278,1122.4355,96.318085,0.26975965,-33.335258 -233267500,0.12867334,-148.16913,0.00070183782,126.47325,1115.7117,92.614166,0.66249979,-49.44249 -233767000,0.13619843,-120.32394,0.0009614607,-130.11888,1127.7797,91.526802,0.13088132,41.392174 -234266500,0.084302321,-122.52895,0.00060416205,-42.95026,1124.3517,87.176254,0.59863353,-39.364079 -234766000,0.20171835,-170.08652,0.0023854217,129.25586,1134.4939,86.709045,0.36328107,103.45839 -235265500,0.11284243,-128.25734,0.00037025826,-105.48942,1106.8464,82.206627,0.51996899,-81.443474 -235765000,0.1444522,-106.59219,0.001433234,-90.245117,1106.3073,79.031502,0.58970791,-74.671654 -236264500,0.10571764,-167.04539,0.0010159112,98.349327,1135.5098,76.260979,0.48251858,-20.840601 -236764000,0.14615569,-125.20278,0.0009150554,-114.99794,1155.6428,74.155693,0.48365086,32.36084 -237263500,0.16352506,-101.5328,0.0018865579,-75.376297,1120.8102,70.955994,0.36318767,-69.034622 -237763000,0.10807561,-116.57861,0.00065851328,-52.175083,1112.4331,68.749466,0.39950091,-95.922188 -238262500,0.11611885,-169.71509,0.0011276793,125.30949,1148.1622,65.511292,0.37559938,14.319582 -238762000,0.14604813,-130.56769,0.00081059744,-113.17955,1136.9618,62.84182,0.15698496,-43.555859 -239261500,0.056368433,-114.73019,0.0010929778,27.558475,1131.6871,60.806068,0.22446345,-141.07831 -239761000,0.080343984,-134.30142,0.00043376614,43.509239,1125.2773,56.83128,0.4527663,-59.681099 -240260500,0.078152381,-90.934372,0.001329644,7.9187641,1130.9816,52.990383,0.74795282,-33.862831 -240760000,0.063415788,-120.77103,0.00086504157,38.256989,1140.7804,51.563484,0.21864052,-42.466812 -241259500,0.16035803,-168.44925,0.0015539725,178.58752,1116.8848,47.802517,0.78454703,-59.759087 -241759000,0.089853488,-127.01759,0.00036734273,28.778214,1146.9733,46.834835,0.12424137,-175.6843 -242258500,0.090398364,-146.97112,0.00031616155,124.5461,1135.8779,42.176609,0.55964297,-36.288353 -242758000,0.15627374,-140.85175,0.00089252001,-103.49154,1132.4174,39.581184,0.52360666,-45.623402 -243257500,0.073077612,-111.18574,0.00087143824,51.392101,1126.0288,37.796703,0.52073514,-85.626923 -243757000,0.10274123,-118.08611,0.00057113788,7.9377623,1134.5161,35.240746,0.29160154,-98.146042 -244256500,0.14336145,-165.78801,0.0010901289,-157.06076,1143.0446,30.761889,0.52957571,-35.280617 -244756000,0.048117667,-139.07733,0.00097859278,101.32187,1137.681,28.252577,0.58888441,-49.301853 -245255500,0.073331229,-158.02258,0.00067485811,136.34132,1139.5902,26.097759,0.39021045,-66.797684 -245755000,0.073862404,-122.36445,0.00065701111,79.718697,1137.7471,23.746906,0.43825871,-84.798241 -246254500,0.13206123,-73.896507,0.0020702037,45.047585,1167.6487,20.669659,0.16578174,34.88689 -246754000,0.030561639,-178.11514,0.0013254542,131.00734,1131.4006,19.111238,0.64538795,-111.47439 -247253500,0.15998375,-170.3549,0.0014323716,-126.01039,1141.3866,15.85241,0.45616084,-106.56477 -247753000,0.089523368,-157.45828,0.00054036675,-178.45033,1123.1763,11.723495,0.77987617,-63.516872 -248252500,0.16489589,-129.99637,0.0010093721,-24.317053,1146.0879,8.4802132,0.5584569,-35.873295 -248752000,0.10679687,-159.4014,0.00062667776,-141.16589,1137.6189,6.7081242,0.5891667,-71.336052 -249251500,0.080188952,-173.58412,0.00098931266,-167.59262,1151.2589,3.7524111,0.40205419,-64.7631 -249751000,0.081558466,-129.51811,0.00044426142,111.47891,1149.859,0.39133441,0.42878971,-48.443577 -250250500,0.067236803,-158.66165,0.00074519473,176.45905,1117.96,-2.0040817,0.95001715,-69.362602 -250750000,0.10905167,172.51659,0.0013389353,-137.42178,1152.2498,-4.5154896,0.41698599,-75.700996 -251249500,0.11169042,-142.93054,0.00016020998,-40.666977,1149.5536,-6.690589,0.47798651,-100.36053 -251749000,0.10292372,-142.60555,7.843921e-005,-142.86574,1165.6782,-12.018839,0.58995241,-4.7081256 -252248500,0.1356954,-154.70447,0.00061473437,-65.947746,1173.2955,-13.890768,0.22224046,-17.777245 -252748000,0.04145211,-148.40422,0.00096234493,176.98296,1160.9312,-16.026211,0.4110125,-59.776218 -253247500,0.11691383,-148.7652,0.0003055768,-58.789516,1151.3721,-19.006828,0.53864795,-56.768044 -253747000,0.18654676,-133.88142,0.0012864362,14.80985,1205.1053,-21.920225,0.2382872,91.83873 -254246500,0.078085944,-145.66154,0.00037933362,-152.60994,1152.4862,-25.111774,0.6564855,-35.933502 -254746000,0.07236404,-72.001717,0.0015315167,149.1291,1172.7372,-27.729816,0.33350202,-33.68005 -255245500,0.028518666,-157.48642,0.0011411173,-161.60735,1163.2274,-31.582378,0.57602096,-9.6808424 -255745000,0.044542171,-115.3942,0.00095524249,-177.77164,1171.0389,-31.985209,0.44869998,-91.539009 -256244500,0.051219083,-136.00688,0.00079164456,-162.63368,1194.9764,-37.461124,0.51194811,34.557552 -256744000,0.24272533,-138.51228,0.002041941,31.947163,1183.7211,-38.634995,0.19938599,-64.582695 -257243500,0.06826061,-107.85201,0.00084701716,174.18607,1183.6394,-41.715397,0.31744263,-23.287586 -257743000,0.14215738,-165.06874,0.00098901044,-29.786736,1205.9081,-44.657364,0.1298701,81.171288 -258242500,0.15309368,-100.4536,0.0015010345,123.33296,1163.0822,-46.394253,0.65940082,-68.556564 -258742000,0.18820843,-119.68761,0.0014381775,88.891342,1183.5408,-48.560383,0.63536972,-99.592628 -259241500,0.15319479,-121.84197,0.00097919465,100.41681,1168.1483,-53.048767,0.51360965,-36.773514 -259741000,0.12307221,-146.81393,0.00035343488,23.495176,1195.6191,-55.523388,0.15250245,-68.347687 -260240500,0.084602527,-153.35397,0.00043897756,-85.207146,1165.7786,-58.685703,0.57873517,-42.3022 -260740000,0.18248469,-142.10188,0.0011678931,60.105869,1190.5452,-60.753822,0.32220957,-81.444481 -261239500,0.080255054,-101.11842,0.0009558532,-163.90186,1182.972,-61.632275,0.88412452,-100.22389 -261739000,0.13892673,159.01869,0.0018691322,-33.245914,1197.1158,-66.78614,0.20730297,-61.574806 -262238500,0.072668992,-135.51349,0.00045197704,-112.94884,1194.9219,-69.647308,0.26119313,-57.518738 -262738000,0.12420557,-85.892242,0.0015863497,-172.64594,1202.2209,-71.344788,0.4492963,-107.56589 -263237500,0.13522403,-173.21939,0.0010967366,3.4593885,1179.4312,-74.500221,0.62503093,-67.401917 -263737000,0.15119883,-122.25379,0.00094856153,141.61043,1188.8912,-77.088196,0.51373523,-82.645027 -264236500,0.23107709,-151.55061,0.0019822302,74.557854,1173.1752,-80.843567,0.60611022,-38.219589 -264736000,0.16853233,-142.78671,0.00099747477,93.346001,1173.3402,-82.548714,0.77743202,-63.716656 -265235500,0.038775142,-143.86227,0.0009582176,-74.24556,1189.8696,-85.884819,0.48286834,-64.75869 -265735000,0.11420523,-145.60904,0.00023016312,60.685673,1187.3351,-88.989807,0.42593363,-55.175747 -266234500,0.16571233,-126.67966,0.00096665742,144.55922,1211.1055,-90.975067,0.57955945,-96.155319 -266734000,0.042491414,-140.505,0.00093770458,-61.671562,1208.9336,-93.514992,0.63549274,-100.11436 -267233500,0.097021237,-152.13173,0.000321859,8.5149002,1194.1018,-97.05648,0.47352976,-67.187668 -267733000,0.097746931,-111.26027,0.00073846994,-119.46075,1193.3511,-99.940376,0.50466865,-62.084747 -268232500,0.13372341,-159.89101,0.00080378534,65.89502,1193.6235,-102.35484,0.60985738,-67.571281 -268732000,0.087177746,-120.30332,0.00060175511,-92.930786,1181.3563,-106.44746,0.48345426,-26.587492 -269231500,0.12961465,-134.41853,0.00039275605,162.56282,1200.2936,-108.49287,0.398812,-62.385529 -269731000,0.12778805,-141.70964,0.00040612055,128.37086,1189.6719,-112.88601,0.44703653,14.297393 -270230500,0.12634708,-158.03127,0.00071766466,78.564148,1223.0209,-114.63712,0.17145793,-118.74605 -270730000,0.13796663,-140.6015,0.00054503855,148.90593,1203.0215,-117.57764,0.22425231,-19.226343 -271229500,0.13331661,-111.24074,0.0009397039,-119.33869,1195.5898,-119.56491,0.55757058,-52.742661 -271729000,0.10875757,-131.4369,0.00024233676,-123.80914,1223.5575,-122.55101,0.31649426,-106.31282 -272228500,0.12817678,-128.31958,0.00053551479,-141.43338,1226.9456,-124.38592,0.65868336,-101.76735 -272728000,0.16711049,-131.11884,0.0010029103,-165.7453,1206.1428,-127.9062,0.38235375,-64.558022 -273227500,0.10149489,-141.36642,4.2982847e-005,38.577591,1223.8873,-131.01418,0.25587711,-104.74994 -273727000,0.1487754,-134.54327,0.00066997047,-159.87434,1204.0861,-133.33867,0.48221183,-68.077728 -274226500,0.15973809,-129.89577,0.00093816774,-144.67825,1221.4038,-136.49829,0.3509331,-99.506126 -274726000,0.11600988,-118.28596,0.00068750494,-77.331055,1206.7407,-138.91954,0.53032494,-61.975292 -275225500,0.15851736,-164.60326,0.0012391794,134.03116,1207.7456,-140.7383,0.79320419,-67.862007 -275725000,0.15351111,-123.59498,0.00093982875,-111.8139,1229.8301,-143.97452,0.68277603,-95.268364 -276224500,0.11475789,-141.44435,7.253245e-005,-174.2655,1205.3417,-147.05685,0.50896895,-59.413479 -276724000,0.099982746,-139.67177,0.0001554043,21.589222,1179.9874,-150.7408,0.55319083,-1.8793031 -277223500,0.088769466,174.39702,0.0013157917,87.940384,1208.5413,-153.17969,0.35702723,-32.968548 -277723000,0.15303783,-109.72784,0.0013965352,-65.73996,1239.3392,-154.83597,0.84303933,-93.742294 -278222500,0.14493845,-153.50365,0.00074708334,175.43999,1238.3802,-159.60667,0.44284493,-168.83766 -278722000,0.12508349,-154.45078,0.00057298568,160.07426,1251.8275,-162.298,0.52374595,-160.59477 -279221500,0.1644749,-148.39465,0.00095135515,-147.84309,1238.7285,-164.78477,0.35936347,-143.96313 -279721000,0.14059485,-139.4192,0.00051278557,-115.76769,1225.8535,-167.28186,0.16898817,-91.699257 -280220500,0.15290362,-149.98172,0.00087885477,-152.04709,1222.3455,-168.64673,0.74108291,-58.219208 -280720000,0.089737147,168.91534,0.0015100959,117.84273,1216.2522,-172.62888,0.20591469,-38.62466 -281219500,0.21196844,-150.96718,0.0019108078,-129.94516,1240.5149,-174.64815,0.59842747,-85.340378 -281719000,0.12186213,-131.30022,0.00046059524,-35.782898,1219.265,-177.97534,0.29557022,-30.984406 -282218500,0.14393495,-119.13901,0.0011056529,-33.678207,1265.2365,179.41054,0.84308589,-114.44891 -282718000,0.2021841,-155.96732,0.001800691,-127.88975,1221.797,175.56422,0.048245989,87.639526 -283217500,0.12725966,-125.23621,0.00070007844,-14.216745,1223.9504,174.21375,0.51150107,-45.123825 -283717000,0.11565873,-102.47938,0.0014013861,20.123152,1244.1313,170.10495,0.27413177,-133.03436 -284216500,0.11853683,-140.09956,0.0001658517,-82.694893,1240.4756,167.80962,0.29240939,-86.249702 -284716000,0.076267079,-134.72829,0.00060767296,86.104019,1238.8993,166.41705,0.71922684,-45.357304 -285215500,0.12275872,-145.39169,0.00026910959,-100.07052,1241.293,163.22923,0.5749172,-54.59267 -285715000,0.11200213,-178.48071,0.0013228635,-172.06512,1258.8826,159.73889,0.57070845,-97.242638 -286214500,0.11868842,-158.39716,0.00064776,-143.7885,1230.1259,157.53543,0.44960779,-23.192314 -286714000,0.1005751,-140.88081,0.00020481665,105.60291,1291.5054,153.54231,1.1620034,-123.8987 -287213500,0.079270929,-157.94998,0.00081434532,165.86484,1243.4767,150.46085,0.20000866,-157.78497 -287713000,0.122756,-95.873573,0.0018742749,58.297462,1266.2427,148.56773,0.61800921,-94.470085 -288212500,0.10179842,-151.16954,0.00039323454,-161.93314,1226.1223,144.95074,0.26040733,94.425438 -288712000,0.082603164,-168.80568,0.0010055858,-171.47481,1210.6471,143.89655,0.87693405,20.02648 -289211500,0.17840755,-123.20524,0.0017294763,11.881008,1263.3699,140.09421,0.47974494,-93.998558 -289711000,0.16573933,-120.96349,0.0015178057,26.184307,1257.3362,137.35338,0.41512933,-80.628174 -290210500,0.10229528,-95.897301,0.0016213639,95.738144,1267.571,134.37419,0.56841797,-84.055939 -290710000,0.12816803,-132.84424,0.00058306521,32.329414,1254.5057,132.40413,0.56208366,-34.798676 -291209500,0.071960703,-106.98436,0.0014055562,126.62795,1269.6973,129.91107,0.70377779,-49.529182 -291709000,0.14057986,-152.64731,0.00085629063,-49.183926,1271.9589,125.18962,0.68374568,-125.40237 -292208500,0.13494766,-134.0992,0.00070242124,41.201805,1254.4755,123.55397,0.16773602,-51.826534 -292708000,0.082927473,-121.32279,0.00095906993,146.9957,1245.1349,120.43056,0.047363035,-118.79993 -293207500,0.10265322,-166.01627,0.0010294932,-97.127922,1258.8069,117.44054,0.25221965,-94.511902 -293707000,0.12154761,-158.87662,0.00079605996,-61.028641,1298.9111,114.29182,1.1018918,-100.9168 -294206500,0.15164724,-127.27576,0.0011512676,63.48708,1265.8892,112.48299,0.48010057,-66.356117 -294706000,0.11641082,-116.72287,0.0010159344,122.27334,1277.5465,109.94479,0.74114883,-47.169857 -295205500,0.11695051,-177.68616,0.0016337903,-69.939224,1253.9688,106.11082,0.14733158,-138.75803 -295705000,0.10506231,-175.03366,0.0013898154,-71.769844,1257.0903,102.95889,0.40702206,-150.61784 -296204500,0.098146468,-127.26565,0.00061178661,164.33826,1287.48,100.8649,0.73107135,-68.866234 -296704000,0.12261685,-151.76111,0.00057701219,-12.482639,1261.7267,97.934418,0.13415316,-104.23891 -297203500,0.09136688,-139.04697,0.00050212524,-137.78145,1287.1232,95.342834,0.72163558,-68.75396 -297703000,0.098772779,-144.45444,0.00026591468,-103.75182,1275.5046,92.232552,0.42997229,-93.017578 -298202500,0.13976401,-128.89282,0.00090609345,114.61089,1300.4285,88.723198,1.0622679,-91.442413 -298702000,0.13259049,-157.77129,0.00095537928,6.7510867,1276.3988,86.307709,0.51361978,-102.19495 -299201500,0.047029275,-124.86418,0.0015382473,-112.67392,1272.5701,83.907539,0.35419503,-75.933998 -299701000,0.1161373,-120.25372,0.00091090181,-179.47717,1258.0134,81.087471,0.25559598,-136.8688 -300200500,0.14849433,-152.01857,0.0011309083,50.74419,1271.8435,78.621033,0.24266696,-46.415451 -300700000,0.072347105,-157.82372,0.001084541,-56.713234,1267.8599,75.738297,0.16101281,-42.394016 -301199500,0.1280995,-146.62939,0.00046230969,67.552948,1291.4741,73.057907,0.57773179,-51.749374 -301699000,0.10557345,-127.31392,0.0006163987,-152.13365,1280.3107,69.32299,0.50987142,-101.9751 -302198500,0.12271598,176.84091,0.002023438,7.2001395,1267.9521,66.789658,0.35424051,-114.84737 -302698000,0.12209464,-143.04074,0.00024678998,101.0133,1261.2094,63.980293,0.40467763,-149.05417 -303197500,0.06827911,-153.42789,0.0010966427,-37.731472,1282.5289,61.065155,0.55672991,-82.932556 -303697000,0.12298799,-154.36349,0.00065283151,51.807594,1259.0052,58.430321,0.41062731,-154.29849 -304196500,0.10805565,-158.95186,0.00080151344,27.808044,1272.7476,54.653717,0.83547443,-112.73334 -304696000,0.10208566,-148.38405,0.00043106711,7.0731673,1279.9867,52.823509,0.47036159,-84.813599 -305195500,0.14286613,-120.75135,0.0012122191,-146.68317,1277.8242,50.259655,0.3121559,-90.989227 -305695000,0.1911187,-144.43033,0.0017645108,137.10646,1275.9812,47.833538,0.22309387,-23.529564 -306194500,0.14908491,-148.22969,0.00085820345,124.34624,1273.7013,45.608997,0.19327639,53.373104 -306694000,0.050286829,-134.28207,0.0013618541,-23.739708,1265.37,41.30669,0.51619112,-121.52431 -307193500,0.17163227,-167.51538,0.0019366731,101.45011,1298.1597,39.643253,0.59302145,-6.6333098 -307693000,0.15652961,-122.3678,0.0012766162,-136.63725,1265.0546,36.528782,0.11235168,-160.26802 -308192500,0.09773583,-159.37949,0.00081931474,48.82452,1279.1545,34.674919,0.25632712,59.965961 -308692000,0.15467972,-118.65115,0.0013431361,-112.64413,1279.7017,29.981426,0.6228466,-86.206505 -309191500,0.1443823,-140.09914,0.00062412355,-170.67851,1254.1699,27.59132,0.51934648,-146.84309 -309691000,0.12509362,-145.36975,0.00033051704,157.02907,1262.4652,24.219456,0.58582222,-120.3614 -310190500,0.10379425,177.53247,0.0016583917,80.335548,1259.1522,21.099337,0.81275374,-107.50919 -310690000,0.095894404,-148.47971,0.000549455,58.850788,1300.7963,18.988535,0.78028601,-35.000637 -311189500,0.14879508,-104.68153,0.0017803655,-63.322178,1273.1532,16.245464,0.41552913,-87.772339 -311689000,0.13464461,-147.08139,0.00047400605,170.61003,1276.1392,14.176806,0.14592063,-31.059023 -312188500,0.1200776,-134.06316,0.00023271587,-49.432892,1291.7828,10.294683,0.70767206,-56.008648 -312688000,0.13047291,-123.92574,0.00069543906,-60.663078,1255.1763,7.5848904,0.60261172,-105.43136 -313187500,0.11080356,-141.63177,0.00017592456,63.551037,1278.1569,5.1714339,0.29746431,-50.715172 -313687000,0.15499409,-132.72763,0.0008055116,-98.336136,1269.6384,2.2664304,0.3286804,-74.725624 -314186500,0.16931716,-141.68405,0.00097150751,-129.59067,1257.4343,-1.0190535,0.59546894,-88.132027 -314686000,0.10831892,-122.7604,0.00063534291,-8.5271044,1257.34,-2.3874276,0.19780473,179.74425 -315185500,0.15398332,-129.62245,0.00077133143,-68.281151,1261.4882,-5.7953787,0.26134363,-100.56679 -315685000,0.12207781,-171.67741,0.0011916672,150.72229,1284.5671,-8.2125244,0.29140642,9.6302996 -316184500,0.12314221,-150.35274,0.00034573508,-179.74591,1256.5029,-11.528316,0.27626103,-103.00322 -316684000,0.12099615,-136.46048,0.00011983695,-44.692539,1255.6855,-14.37441,0.28307924,-84.375061 -317183500,0.17719214,-103.9362,0.0018644473,-12.866292,1273.1213,-16.936907,0.2670092,-21.162086 -317683000,0.1116087,-95.436432,0.0014777186,30.041374,1241.4758,-19.593719,0.25863633,-121.2879 -318182500,0.068399578,-96.009781,0.0014604338,64.328865,1235.6194,-23.67148,0.70895189,-85.99604 -318682000,0.13040894,-90.821243,0.0017727951,32.32476,1240.8892,-24.470324,0.29356763,-166.50479 -319181500,0.085043587,-137.30109,0.00056136155,101.89706,1252.1843,-27.6998,0.049059246,-31.366148 -319681000,0.13856661,-124.61784,0.00064252265,2.7718871,1215.4615,-29.997751,0.58441913,-147.97054 -320180500,0.1586975,-164.02452,0.0011263709,-129.89276,1246.0793,-33.989338,0.31006277,-60.513153 -320680000,0.17510118,-122.61355,0.0011573514,-10.461683,1242.6085,-35.824142,0.050720137,-105.18434 -321179500,0.14968808,-151.29599,0.00060936343,-99.451843,1218.4618,-39.706238,0.60510159,-86.853294 -321679000,0.17696133,-149.58258,0.00094760972,-77.440689,1251.5675,-41.540009,0.20200509,6.4764123 -322178500,0.097126618,-123.59487,0.00063934166,89.073975,1277.1786,-44.551308,0.64876819,30.693354 -322678000,0.039523408,107.4438,0.0022592861,156.46315,1211.7098,-48.488289,0.81770736,-65.631966 -323177500,0.23673628,-140.86591,0.0018298631,-36.3606,1244.0712,-48.744282,0.20813954,94.907562 -323677000,0.18078835,-129.57961,0.00099324679,-1.3113526,1178.7242,-50.888981,0.88467944,-138.76163 -324176500,0.2101602,-125.76673,0.00150653,6.4128637,1208.2039,-54.308903,0.35710678,-123.82536 -324676000,0.085398786,-105.64945,0.0011058383,116.13033,1190.5737,-56.948574,0.65337551,-122.4989 -325175500,0.21774575,-100.43695,0.0021637853,54.392975,1213.7142,-58.744797,0.32977524,-157.00487 -325675000,0.048561435,176.05197,0.0014264234,-170.86607,1196.1908,-62.595119,0.50524402,-94.921295 -326174500,0.10154393,-179.72586,0.001200275,-132.58104,1241.8142,-64.858704,0.18979715,51.824768 -326674000,0.058199324,-162.06873,0.0010832647,-163.159,1219.1132,-68.352692,0.39967403,-38.602985 -327173500,0.21959573,-136.77699,0.0014177928,8.311305,1242.4667,-68.412903,0.5106554,144.36555 -327673000,0.15368067,-158.67528,0.00080078072,-61.087452,1204.9976,-71.241974,0.50601119,-149.01936 -328172500,0.04537639,-80.391579,0.0015431149,167.94432,1191.2241,-76.004768,0.65560365,-82.089485 -328672000,0.092476659,-124.40844,0.0006162076,159.81151,1206.3442,-78.20636,0.48633906,-78.686455 -329171500,0.14374261,-112.31169,0.00096559443,105.59186,1242.4597,-82.129471,0.53831434,-9.6380997 -329671000,0.19143252,-149.65652,0.0010197411,-2.9673908,1216.8536,-83.742577,0.38281396,-63.998962 -330170500,0.11861624,-154.69328,0.00048178909,-78.502419,1201.5667,-84.926643,0.60612202,-112.31142 -330670000,0.19824977,-124.75771,0.0011513381,65.846321,1184.2511,-89.644905,0.93534768,-67.916634 -331169500,0.20391037,-95.324646,0.0019695503,115.99113,1204.8555,-91.51725,0.58793402,-78.294617 -331669000,0.13597062,-135.99748,0.00024288683,73.140594,1217.6559,-93.726868,0.38305962,-86.484344 -332168500,0.17042556,-109.77619,0.0011045922,117.65591,1232.8308,-93.661858,0.71964556,-157.78125 -332668000,0.15172987,-136.3992,0.00036126145,67.68409,1237.3344,-98.430954,0.29839787,-118.12965 -333167500,0.045941494,140.18466,0.0016329506,-105.85918,1243.1249,-102.30728,0.29052916,-43.202091 -333667000,0.21313693,-131.09174,0.0011608796,74.856972,1240.9718,-103.56667,0.39315912,-121.05176 -334166500,0.11268761,-80.618683,0.0015093645,-172.59523,1244.2052,-106.79743,0.33707365,-99.494659 -334666000,0.11805466,-135.4214,0.00014444547,-153.7005,1265.4569,-110.06909,0.090955831,-48.4921 -335165500,0.18086375,-124.93158,0.00083167647,113.56232,1234.0454,-111.02143,0.67991734,-123.99086 -335665000,0.16531621,-165.95096,0.00094783044,0.11244243,1285.9064,-113.8932,0.50535733,171.43611 -336164500,0.12464444,-146.83572,0.00023014654,-26.388941,1264.3523,-118.26209,0.15216717,-79.234993 -336664000,0.089113899,-82.569107,0.001317068,-142.07736,1210.3339,-121.8357,0.83266485,-63.875732 -337163500,0.094352171,-161.51425,0.0006643089,-50.044941,1269.3285,-122.31297,0.44598833,-145.81865 -337663000,0.23359144,-138.78951,0.0012733056,90.028046,1271.6708,-125.13404,0.4404051,-137.73642 -338162500,0.17535122,-154.12994,0.00076360168,49.017624,1293.0823,-130.42528,0.2976774,32.755383 -338662000,0.25080878,-165.67325,0.0018346637,51.796322,1269.5405,-131.49355,0.2790834,-121.88068 -339161500,0.11560419,-122.66445,0.00042750753,-141.41353,1244.8687,-133.17859,0.68447739,-114.14527 -339661000,0.077607289,174.24718,0.0011519383,-34.903183,1306.3636,-138.0477,0.20263924,98.002518 -340160500,0.15726486,-127.0014,0.0005282287,165.57559,1308.8167,-139.62689,0.40080258,162.28683 -340660000,0.14823604,176.4938,0.0013031526,14.117188,1290.783,-142.17375,0.36513084,-150.98454 -341159500,0.1513662,-167.92545,0.00086125935,35.67392,1307.3564,-146.41728,0.19757384,110.34328 -341659000,0.1561103,-110.24453,0.00086962688,-147.82693,1288.8815,-148.92889,0.086829305,-81.668907 -342158500,0.19388349,-88.321053,0.0017637046,-136.06798,1254.5253,-150.54515,0.5770933,-98.830482 -342658000,0.14289148,-115.37524,0.0006827641,-134.94829,1296.5703,-154.02319,0.18851188,-156.7998 -343157500,0.075752951,-49.435112,0.0017762854,-69.428101,1262.9844,-157.38676,0.39590409,-65.397148 -343657000,0.14445387,-152.0464,0.00044112912,69.363327,1265.6005,-161.04639,0.39767119,-27.847994 -344156500,0.16274123,147.70029,0.0021501961,28.960388,1285.5507,-163.8196,0.23151174,-10.975384 -344656000,0.25649518,-156.14821,0.0016589699,119.15453,1275.3055,-166.12965,0.23288956,-29.426872 -345155500,0.1386335,-151.02112,0.00040066818,75.017906,1285.7301,-168.53732,0.11684602,-57.163441 -345655000,0.17589043,-150.35059,0.00065951457,115.05589,1271.2422,-170.2901,0.43815517,-94.020828 -346154500,0.12157049,-141.54811,0.00020376289,24.054495,1311.6958,-173.82718,0.20564681,162.19073 -346654000,0.1679198,-118.5905,0.00071491709,-126.23668,1250.4083,-176.68542,0.52162683,-57.564137 -347153500,0.045610767,-81.14537,0.0013478672,-24.176315,1283.6018,-179.88531,0.1662619,-34.97823 -347653000,0.079557382,-115.05517,0.00078657659,-31.294224,1234.381,177.93726,0.66801524,-57.662663 -348152500,0.14411855,-98.791306,0.0011301963,-74.196602,1254.6436,174.81653,0.40617338,-49.679317 -348652000,0.13523756,178.1651,0.0012549943,77.924469,1286.5555,173.33919,0.37275207,-113.53574 -349151500,0.10925654,-108.82229,0.0007727425,-42.101357,1268.1929,171.08852,0.57764375,-101.42949 -349651000,0.1777654,-125.70198,0.00066989497,-121.39227,1278.9126,168.9953,0.72089112,-115.90532 -350150500,0.17698807,-111.40546,0.0010040234,-86.332817,1328.0779,164.43982,0.52726716,171.03044 -350650000,0.12948795,-142.93753,0.00013220553,79.815025,1274.2638,160.94939,0.20071949,-59.006081 -351149500,0.12642723,-120.09389,0.0004810965,-36.548573,1319.2247,159.02933,0.46412873,-171.34946 -351649000,0.19956316,-117.63668,0.00098952546,-94.287125,1252.9541,157.36867,0.74040484,-82.651505 -352148500,0.085718125,-60.549061,0.0017525473,2.1841743,1265.3153,154.55273,0.63556987,-98.073135 -352648000,0.19650961,-133.55696,0.00069986144,-122.35207,1257.8894,150.83345,0.54764134,-76.104485 -353147500,0.18418665,-137.04657,0.0005630778,-128.73361,1260.8915,148.65482,0.52863085,-85.087242 -353647000,0.2410773,-156.86636,0.0014344126,-170.47241,1280.3151,145.17526,0.26643994,-103.14525 -354146500,0.14031965,-73.106766,0.0018228472,-4.4553194,1267.7395,142.65448,0.43842182,-78.025513 -354646000,0.13731639,178.2679,0.0012330157,126.96432,1276.5522,140.61436,0.52467471,-107.80061 -355145500,0.27207777,-155.93987,0.0018011114,-151.52197,1347.4961,136.10094,0.82034647,161.63069 -355645000,0.16508436,-154.79088,0.00063348253,178.96727,1262.5808,134.91455,0.54397947,-82.101402 -356144500,0.11330628,-125.93947,0.00046836023,27.366724,1299.6912,130.6257,0.27098456,172.48254 -356644000,0.26805547,-106.32797,0.0020854215,-44.797161,1272.327,127.58714,0.080694385,-33.345909 -357143500,0.17597136,-142.2386,0.00042184076,-115.04769,1280.0613,126.28695,0.42247647,-113.37785 -357643000,0.12457416,-131.50897,0.00026661882,39.6241,1252.4291,122.6805,0.35274321,-36.395367 -358142500,0.16206142,-95.111481,0.0014064958,10.848655,1250.4082,119.50089,0.41180477,-23.757952 -358642000,0.16915204,-100.72517,0.0013779544,6.5228019,1286.5692,116.67866,0.14265029,175.06584 -359141500,0.26678362,-151.48856,0.0016763664,-110.18325,1310.5902,114.3261,0.42177141,-172.49709 -359641000,0.18972826,-112.71497,0.0011348799,-9.1355104,1270.8154,112.32626,0.33440313,-78.034554 -360140500,0.25505111,-146.19844,0.0014746566,-89.386932,1289.6334,108.48338,0.17697994,170.38493 -360640000,0.11066044,-105.09421,0.0010466987,58.090889,1272.4818,105.62048,0.013520325,-24.284021 -361139500,0.045547351,-95.447739,0.0015085018,96.854408,1295.334,102.3575,0.31570274,146.49562 -361639000,0.17117324,-115.39091,0.00093744899,18.559559,1268.283,102.65635,0.74786246,-87.377815 -362138500,0.13460156,-158.73868,0.00061033992,-166.49773,1282.8124,97.810417,0.14724752,-136.44855 -362638000,0.22773133,-123.39816,0.0013134429,-13.372422,1289.4163,96.450989,0.58891851,-109.62825 -363137500,0.19191027,-138.56822,0.00063630712,-44.339844,1279.9712,92.799133,0.27863401,-114.33617 -363637000,0.17164104,-133.16373,0.00044371531,-5.0192533,1262.0525,90.415161,0.40343493,-68.351288 -364136500,0.16300827,-127.26971,0.00057220622,26.41287,1302.7458,87.729599,0.57559776,-136.67656 -364636000,0.17764726,-145.70074,0.00050176989,-66.212242,1306.8845,82.619286,0.59636706,150.02475 -365135500,0.12825604,-155.52097,0.00053197308,-158.4095,1277.8156,81.99704,0.31296837,-102.72539 -365635000,0.14900061,176.21339,0.0014797176,-140.04219,1292.3176,78.149994,0.34684142,-177.89244 -366134500,0.16819406,-136.92604,0.00037638418,6.3166018,1245.6495,77.203781,0.5695703,-42.318634 -366634000,0.14719225,-142.27527,6.4495682e-005,-29.78001,1267.5669,72.672081,0.10238467,106.80006 -367133500,0.19375429,-144.8647,0.0007122269,-29.88422,1245.2278,70.743698,0.39812011,-17.511261 -367633000,0.14985228,-117.86438,0.00087234547,85.511848,1269.6791,68.901978,0.50863647,-78.343559 -368132500,0.078035742,-126.86071,0.0010596582,154.76416,1280.0936,65.819221,0.43402988,-102.80198 -368632000,0.094995297,-155.03433,0.00083141332,-158.32813,1298.5862,61.995579,0.4084253,-156.96553 -369131500,0.15280055,-94.265854,0.0017878113,111.13057,1272.1063,62.098858,1.0037906,-73.432961 -369631000,0.26339862,-141.36241,0.0017338623,4.188796,1256.9083,57.12558,0.33029768,-36.519733 -370130500,0.25038937,-121.51804,0.0018743154,53.652462,1287.2908,54.715961,0.49605882,-108.63396 -370630000,0.15404227,-109.44903,0.00126137,112.9384,1312.9506,52.257862,0.85009974,-115.50066 -371129500,0.16774841,-146.9585,0.00039726106,-13.698591,1281.8944,47.278236,0.41221309,168.70361 -371629000,0.17344353,-141.57494,0.00045136485,24.121647,1275.4215,46.367661,0.44127372,-77.819 -372128500,0.23691945,-146.12601,0.0014441488,17.089617,1263.8947,42.63036,0.021861769,156.86783 -372628000,0.15987268,-145.87726,0.00025171263,5.3084459,1292.8302,40.891785,0.59755266,-113.39091 -373127500,0.19547378,-131.18706,0.0010078149,77.112381,1287.002,37.697906,0.4737792,-116.75051 -373627000,0.07794895,-101.91264,0.0016228642,-170.4192,1257.5966,34.676907,0.16982149,-17.534697 -374126500,0.18368991,-138.13014,0.00070696609,61.486893,1302.448,31.467976,0.70768452,-147.65283 -374626000,0.14558613,-100.63901,0.0018070376,158.8156,1261.6809,29.74725,0.25216523,-60.103786 -375125500,0.13400419,-166.40988,0.00099510269,-59.346188,1271.5432,28.015402,0.74315208,-65.038002 -375625000,0.13995323,-148.22751,0.00022822306,-50.905651,1271.9156,24.271475,0.4380368,-78.597603 -376124500,0.15340592,-172.98975,0.0013591384,-37.406914,1276.3529,20.616713,0.40487206,-128.41225 -376624000,0.20763257,-124.82468,0.0014460774,118.09826,1278.1294,18.556973,0.50024354,-99.644104 -377123500,0.10439736,-128.92908,0.00095792871,-139.32349,1273.7595,15.096085,0.38871768,-132.82741 -377623000,0.12348645,-156.81349,0.00066294777,-57.372196,1278.9105,14.088686,0.81810725,-72.912109 -378122500,0.11439843,-167.13084,0.001104444,-51.687775,1252.6776,11.551149,0.69695371,-33.819885 -378622000,0.15572235,-153.95557,0.00056691817,11.723619,1289.3209,6.1284723,0.76764852,-149.33403 -379121500,0.097843871,-174.48718,0.0014793216,-52.071903,1281.6102,4.6531677,0.63233685,-109.3177 -379621000,0.17312168,-147.36356,0.00063543062,74.292007,1266.0653,1.1241254,0.32341182,-155.85669 -380120500,0.16200395,-139.79613,0.00041783293,134.65999,1264.6897,-1.6084846,0.41265869,-147.42857 -380620000,0.17441659,-145.90347,0.00057405193,87.413994,1255.2421,-3.2561929,0.39027673,-63.008762 -381119500,0.12854241,-139.42496,0.00036190747,-93.335152,1269.8284,-7.9614077,0.77334923,-158.88873 -381619000,0.14036906,-135.92506,0.00032956246,-135.34683,1258.3706,-9.9246988,0.41252354,-137.01028 -382118500,0.20111766,-141.86058,0.0011491432,121.38218,1250.0825,-11.943421,0.29434887,-81.10051 -382618000,0.13059279,-151.24991,0.00058108772,-10.807301,1239.6943,-14.957536,0.096152209,-130.30205 -383117500,0.18009147,-161.32567,0.001317967,61.434822,1258.5275,-17.289873,0.5388518,-94.192375 -383617000,0.13080291,-157.15175,0.00084823515,9.5058508,1254.9095,-20.103579,0.51587337,-93.190239 -384116500,0.13781796,-160.80322,0.00097342854,25.444286,1229.9242,-21.650637,0.59734035,4.1202607 -384616000,0.11148722,-146.45552,0.00085044192,-26.818312,1234.6467,-25.697613,0.019002698,-30.621244 -385115500,0.10099898,-133.5341,0.0012112339,-48.986267,1241.0602,-28.417761,0.29169455,-90.759178 -385615000,0.19726804,-131.70532,0.0013904505,-165.37926,1230.1033,-31.568623,0.28446621,-155.99844 -386114500,0.15801831,-152.26334,0.00065957726,86.279808,1237.1329,-33.722931,0.25884444,-57.195286 -386614000,0.16734315,-127.60851,0.0011512829,-119.8772,1224.8656,-37.29517,0.4298864,-168.79488 -387113500,0.20962058,-156.03809,0.0017819295,126.64606,1212.147,-39.63966,0.43075225,127.93359 -387613000,0.17429312,-128.40732,0.0012483512,-115.9707,1245.6193,-41.797676,0.54804844,-92.692146 -388112500,0.11328764,-144.36072,0.001003586,-0.20450367,1218.193,-44.551907,0.1368327,105.06899 -388612000,0.1683453,-133.84261,0.00080762018,-110.12344,1222.5062,-47.009468,0.19247153,-40.553585 -389111500,0.15493579,-152.9971,0.00071167172,95.178734,1220.4009,-51.100227,0.68217975,-166.96175 -389611000,0.21319187,-132.25845,0.0018727118,-129.24156,1235.2668,-51.851337,0.61348772,-37.81356 -390110500,0.13729112,-148.21492,0.00058234698,55.358047,1210.8818,-55.674698,0.18885028,146.33879 -390610000,0.12353289,-144.02751,0.00086061587,23.17659,1225.2338,-57.922783,0.15267843,-13.595914 -391109500,0.18439132,-157.01968,0.0014067915,147.91862,1227.7478,-60.853783,0.44180414,-91.595055 -391609000,0.17611501,-142.63777,0.00056204898,-137.41586,1211.6985,-63.173191,0.093983516,36.281815 -392108500,0.19357193,-146.29277,0.0010320444,-146.82776,1225.7587,-67.169655,0.74980944,-124.48985 -392608000,0.14442199,-130.50545,0.0011261986,-4.8174276,1211.4921,-68.817009,0.14173396,-70.180382 -393107500,0.10307769,-167.10529,0.002345134,85.106262,1220.6178,-71.929863,0.47260022,-96.27021 -393607000,0.17868747,-134.0069,0.0011076505,-60.121681,1219.1605,-74.205971,0.33910957,-68.378181 -394106500,0.16782752,-138.43524,0.00062134716,-38.674152,1219.2975,-77.003616,0.3516821,-84.519547 -394606000,0.19693103,-142.05754,0.0010808718,-96.853256,1208.804,-79.595146,0.26636803,-109.35622 -395105500,0.166594,-133.77992,0.001044169,-13.441804,1222.6986,-81.835991,0.57755649,-15.952534 -395605000,0.20878963,-130.80232,0.0022243878,-43.417847,1202.2887,-84.433846,0.35708624,75.440842 -396104500,0.16286865,-150.00542,0.0003868379,169.77319,1209.765,-87.4618,0.022846945,-114.65706 -396604000,0.17815357,-136.46703,0.0011149695,-17.350676,1219.6906,-89.887627,0.46598217,-6.9921613 -397103500,0.17995594,-141.9516,0.00076656591,-36.331871,1208.778,-93.475029,0.40413946,-109.9315 -397603000,0.16561477,-151.98711,0.0006504521,-172.94267,1202.9235,-95.767029,0.2735112,-110.5015 -398102500,0.1324424,-167.03279,0.0022206823,157.5183,1192.6897,-98.807846,0.72374374,-141.59024 -398602000,0.17138998,-137.6554,0.00083597162,23.650314,1203.7479,-100.96182,0.114802,-91.30117 -399101500,0.19884084,-152.50665,0.0012288614,-87.132614,1210.0972,-103.96071,0.35109463,-60.865803 -399601000,0.16769876,-168.0905,0.0019267434,-153.03888,1223.072,-106.51711,0.57434618,-30.964516 -400100500,0.15006095,-144.03128,0.00075384701,115.47932,1199.6134,-109.22005,0.32742706,-119.1176 -400600000,0.20118709,-148.18768,0.0010541811,-41.867599,1201.9283,-112.15513,0.40566945,-99.199265 -401099500,0.19923164,-144.02579,0.0010071725,-2.8020747,1204.7407,-114.52148,0.22348543,-91.064873 -401599000,0.13008882,-150.91769,0.001385243,160.42863,1201.9338,-117.39583,0.37020731,-92.925896 -402098500,0.18168749,-133.98196,0.0014746016,59.114365,1196.4436,-119.83806,0.17798965,-151.60854 -402598000,0.16525288,-148.34782,0.00020245498,167.46602,1210.8584,-123.20454,0.62476599,-57.582169 -403097500,0.18533485,-154.90764,0.00070073496,-76.495392,1204.8981,-125.26147,0.25057191,-69.435577 -403597000,0.21433428,-161.55515,0.0018160986,-52.515491,1206.9159,-127.55013,0.20124123,86.6325 -404096500,0.16813011,-150.61858,0.00011522399,-136.42914,1206.1779,-130.41414,0.15753473,52.960346 -404596000,0.23353457,-150.86099,0.0018083217,5.277813,1193.4305,-133.04831,0.39363948,-178.2511 -405095500,0.18562919,-157.79782,0.00082360336,-49.978413,1198.3992,-136.04292,0.11190638,-168.05772 -405595000,0.16431554,-156.41319,0.00055005314,-100.86214,1201.9072,-139.07251,0.18278098,-85.330719 -406094500,0.20644759,-141.9924,0.0012702491,64.401794,1189.1102,-142.01216,0.49470207,-104.98703 -406594000,0.17454684,-146.85271,0.00028805668,123.2327,1194.6854,-145.09338,0.6198473,-79.264862 -407093500,0.17934537,-137.62579,0.0011633001,124.81724,1187.6198,-148.13071,0.77177525,-92.085915 -407593000,0.20958941,-139.89944,0.0013205612,95.72551,1197.972,-150.50391,0.64929521,-69.534477 -408092500,0.14129548,-141.59352,0.0011469328,-173.91185,1206.5198,-152.89162,0.28440601,-11.22852 -408592000,0.22564223,-152.50409,0.0014094043,48.352413,1195.0426,-155.54694,0.28510302,-93.177155 -409091500,0.18931356,-160.03424,0.00072776235,-12.688456,1191.0728,-158.06157,0.36729738,-114.40755 -409591000,0.18060212,-173.15849,0.0015883078,-34.408398,1193.391,-160.61478,0.24726349,-154.70821 -410090500,0.22400454,-142.32253,0.0015870346,103.22396,1180.5177,-163.89595,0.52918541,-104.31441 -410590000,0.2186088,-134.49655,0.0018751448,128.38228,1182.5752,-166.18307,0.28724891,-131.86281 -411089500,0.11264203,-124.19547,0.002188843,-140.5565,1199.156,-168.92221,0.14678486,-34.595306 -411589000,0.21492149,-137.41455,0.0015491243,135.17604,1197.0396,-172.20749,0.31264359,-21.082754 -412088500,0.16804504,-162.02335,0.00056083058,-28.622648,1191.0963,-173.97998,0.3221705,-157.71898 -412588000,0.19472465,-152.36223,0.00051621418,93.940651,1197.0223,-177.20285,0.10414191,-12.505281 -413087500,0.14341143,170.9821,0.0021607475,-31.575846,1197.8916,179.18945,0.33594006,-9.91891 -413587000,0.16071212,170.30074,0.0022624128,-17.384531,1179.3645,176.57953,0.49482855,-72.148071 -414086500,0.18842913,-144.64835,0.0007316168,165.87758,1192.6683,175.59761,0.48769158,154.67326 -414586000,0.14862998,-139.42235,0.0010037288,-124.8018,1154.2117,172.89134,0.94104177,-136.0041 -415085500,0.18318172,-149.88324,0.00034381769,158.89772,1162.0304,168.60521,0.60909206,-85.825867 -415585000,0.18525432,-167.99622,0.00095405971,37.423595,1172.4296,166.95241,0.39010957,-142.7597 -416084500,0.22885226,-152.35646,0.0011749541,131.12234,1166.1969,163.4467,0.41227224,-99.88073 -416584000,0.073968917,-124.54696,0.0023295151,-73.511261,1168.845,159.67291,0.6077469,-43.940334 -417083500,0.23331857,-157.39272,0.0012157338,118.3457,1157.5215,158.48839,0.52795565,-113.34521 -417583000,0.15076752,-165.46127,0.00078674877,7.4393311,1182.0258,155.24678,0.09875837,8.1650858 -418082500,0.19386141,-162.43565,0.00065460766,81.43177,1185.3918,153.36653,0.28174904,164.88368 -418582000,0.18475515,-123.23138,0.0018068827,-117.26067,1171.3213,150.16132,0.1341006,-101.81974 -419081500,0.17955232,-166.11559,0.00073869224,58.35276,1198.6277,148.04034,0.44247174,126.36965 -419581000,0.11618564,-151.6472,0.0011005191,-32.640945,1165.8962,144.53412,0.20573872,-90.313095 -420080500,0.2301193,-146.48814,0.0012251575,-172.61304,1162.5138,141.84056,0.1672031,-100.67466 -420580000,0.19514619,-151.39204,0.00045041303,-167.49748,1145.9567,138.87892,0.4598653,-77.035782 -421079500,0.12100456,-152.57686,0.0010026086,-22.759212,1159.3512,134.99854,0.46874762,-19.831659 -421579000,0.19100949,-159.10507,0.00031736566,125.9595,1166.5605,133.9454,0.1937077,-133.39677 -422078500,0.12843604,-164.19472,0.00095194491,18.423786,1151.4802,131.06778,0.29438442,-90.118912 -422578000,0.19196427,-158.58302,0.00034097375,141.53102,1150.1888,127.715,0.33061081,-49.852966 -423077500,0.20476274,-148.99869,0.00061774976,-141.70421,1143.2782,127.67828,0.82725364,-139.87883 -423577000,0.20052151,-151.95438,0.00046430645,-154.87364,1132.7235,123.68456,0.57532787,-103.72783 -424076500,0.16166203,-164.60361,0.00054028799,68.681107,1142.2776,120.47784,0.30050787,-102.45148 -424576000,0.20023024,-149.37863,0.00056677766,-127.22178,1158.2443,117.42214,0.068150811,99.351479 -425075500,0.21322292,-159.58342,0.00065846991,176.1953,1157.1947,115.89199,0.38424969,-157.54256 -425575000,0.14492613,-142.64528,0.00082826958,-21.185852,1142.6793,112.7819,0.41265211,-130.19257 -426074500,0.19097735,-162.10262,0.00039834986,152.78928,1160.5701,109.34181,0.15270731,135.44974 -426574000,0.1968222,-160.77399,0.00044722937,171.70752,1139.4464,107.58086,0.36729348,-126.52662 -427073500,0.068460688,-159.00584,0.001740366,39.205357,1111.0919,104.50383,0.59532011,-83.494423 -427573000,0.23865852,-155.74771,0.00097452552,-139.0123,1124.8651,103.0869,0.67163777,-119.29301 -428072500,0.15676038,-144.27344,0.00061018264,-5.7349515,1128.83,99.798538,0.45885023,-112.10824 -428572000,0.1826043,-145.73715,0.000531992,-40.399834,1118.3225,96.896431,0.57384837,-101.8964 -429071500,0.21629071,-177.19081,0.0012915087,159.28065,1158.9559,92.708565,0.28814471,98.198112 -429571000,0.1548896,-165.60846,0.00055891369,100.08921,1127.8185,90.759018,0.23716292,-84.235535 -430070500,0.17902459,-157.37799,5.2940966e-005,-140.1545,1116.8837,89.922211,0.72172773,-116.99729 -430570000,0.14262636,177.67952,0.0012046659,115.56886,1141.1284,86.693214,0.51521885,-151.16771 -431069500,0.22409606,-149.38542,0.00075809855,-73.247658,1116.1724,83.278793,0.41997886,-91.967384 -431569000,0.076419905,-113.28474,0.0021155353,52.089062,1128.9321,79.1297,0.21572374,4.6044302 -432068500,0.15856594,-152.02455,0.00041605128,45.795048,1114.222,77.759682,0.35202271,-76.380661 -432568000,0.17362298,-164.16661,0.00035892316,159.54295,1107.8488,74.131638,0.40535975,-32.858036 -433067500,0.21433161,-152.02863,0.00055490469,-68.763443,1115.6162,73.507813,0.56778479,-108.51902 -433567000,0.18871558,-146.1259,0.00052037853,-10.198316,1089.3479,70.632729,0.75292242,-75.267685 -434066500,0.21666691,-142.55231,0.0009393025,-21.385355,1100.5746,68.403419,0.78143829,-98.120262 -434566000,0.14894152,176.88008,0.0012238977,154.88815,1121.5542,64.324921,0.18390651,-96.918266 -435065500,0.12346977,-136.6424,0.0012288832,69.987381,1108.4824,61.429253,0.3298429,-69.276901 -435565000,0.19684838,-141.13452,0.00081372808,8.1631851,1125.7444,58.425854,0.043021668,-51.631367 -436064500,0.21188696,-125.57111,0.0016187954,21.484118,1112.4957,56.253632,0.27413729,-72.825378 -436564000,0.18670222,-148.38348,0.00044774602,23.764341,1118.2129,53.32914,0.18386029,-83.607719 -437063500,0.17655815,-149.71904,0.0004065707,47.488831,1125.7108,50.694252,0.15557882,-137.49861 -437563000,0.22275819,-142.0014,0.00099963136,5.6227326,1100.1429,48.933994,0.53754807,-79.21669 -438062500,0.17579438,-168.95293,0.00049830717,-161.73331,1114.0784,43.913063,0.2929655,32.607216 -438562000,0.18402226,-153.1713,0.00024604486,27.309719,1110.0194,44.102638,0.54607594,-102.72035 -439061500,0.13311665,134.81491,0.0026329805,177.39212,1112.5698,40.521862,0.35446757,-97.839287 -439561000,0.19295824,-149.61745,0.0004360707,31.381886,1125.2506,37.968723,0.35006362,-127.13012 -440060500,0.18285866,-177.02011,0.0007986484,-134.52832,1106.7661,33.454769,0.25160772,23.901276 -440560000,0.1350958,112.60429,0.0032462089,-176.31772,1084.0675,31.775146,0.50651234,-32.2897 -441059500,0.28399569,-135.59251,0.001991556,28.417803,1101.9882,31.535431,0.86905921,-96.909836 -441559000,0.13423561,169.32587,0.0014918299,-160.71011,1119.307,26.828718,0.26992846,-109.9468 -442058500,0.17322533,-169.34334,0.00055908412,-134.96677,1124.7881,24.171473,0.31649432,-125.99187 -442558000,0.1882322,-151.64153,0.00038058407,67.908897,1133.5123,22.531431,0.61886752,-133.11659 -443057500,0.11908195,173.41872,0.0014316469,-158.16707,1094.11,18.911541,0.45243052,-60.630661 -443557000,0.19818749,-169.1385,0.00044318169,-86.625633,1118.9108,16.121838,0.39600858,-121.25842 -444056500,0.19224454,-168.84717,0.00043487453,-90.161636,1131.4391,13.670191,0.46488228,-138.82724 -444556000,0.18072003,-170.63562,0.00049891742,-108.61338,1110.858,9.9533482,0.13307267,-131.75139 -445055500,0.22561239,-167.65211,0.00072161807,-34.849365,1113.0641,7.6627107,0.20150451,-107.53355 -445555000,0.21909438,-171.08501,0.00073211687,-45.0327,1109.484,5.9291677,0.47041672,-105.06339 -446054500,0.1868467,-143.5737,0.00085504097,108.4436,1097.3999,2.2734849,0.23127706,-70.242874 -446554000,0.15742321,-154.74913,0.00046642029,167.46149,1098.0526,-1.0876993,0.13379435,-16.360563 -447053500,0.15272908,-172.41467,0.00071243435,-121.38846,1127.7721,-1.587291,0.74846238,-121.97006 -447553000,0.18845539,-160.02113,8.0085854e-005,26.27916,1129.1224,-5.628356,0.41762093,-144.69507 -448052500,0.23978615,-126.44597,0.002045586,110.27016,1115.7987,-7.2149525,0.59601671,-104.55385 -448552000,0.20225227,-165.47249,0.00032313459,-15.190881,1110.7019,-10.830683,0.35617271,-104.9965 -449051500,0.20925637,-144.4767,0.000922999,111.1888,1105.051,-13.808187,0.2099663,-104.42801 -449551000,0.15904397,-150.87552,0.0006248483,176.68393,1101.6678,-17.307947,0.094492681,-117.02058 -450050500,0.18404862,-158.36243,0.00015490498,146.84541,1128.7729,-19.641333,0.46784601,-160.91136 -450550000,0.2569876,171.12929,0.0018521056,-21.855968,1107.9163,-20.935686,0.51304615,-105.78266 -451049500,0.18439917,-152.55498,0.00045317024,140.60551,1087.436,-24.674343,0.26675901,-49.024971 -451549000,0.14251576,-150.70386,0.00083171332,-155.69807,1085.9039,-28.29368,0.15270866,20.352638 -452048500,0.28769213,176.84857,0.0020473266,8.4172506,1095.7255,-30.808184,0.014065719,-146.95151 -452548000,0.16930695,-159.05278,0.00025100345,-154.61301,1092.0237,-33.581917,0.029795267,15.475352 -453047500,0.14183751,176.37148,0.0011419092,-69.838638,1103.1958,-35.499916,0.25255394,-121.93304 -453547000,0.21635713,-166.84026,0.00058066676,42.935955,1109.1537,-39.131729,0.2811372,-175.18633 -454046500,0.20500839,-160.26237,0.00037877008,99.278656,1092.9012,-40.815563,0.2528488,-89.082184 -454546000,0.2190295,-144.81242,0.0011489219,150.85211,1111.6504,-43.95126,0.44304782,-141.30006 -455045500,0.17108546,156.31221,0.0019727906,-32.690765,1083.2451,-47.167629,0.050074842,43.685322 -455545000,0.12916549,-125.30193,0.0018745975,-136.34367,1103.9084,-49.528206,0.32805356,-146.96135 -456044500,0.13468574,-156.4473,0.00083598628,-105.69427,1065.6616,-50.990025,0.55494702,-33.967709 -456544000,0.15003023,176.79834,0.0011142779,-33.195942,1102.2601,-54.773598,0.32839051,-133.39423 -457043500,0.23752828,-160.21185,0.00092086621,112.5285,1088.6743,-58.222389,0.14014095,167.496 -457543000,0.19175003,-172.3266,0.00048313182,27.468969,1084.9155,-60.549408,0.10450127,-168.05283 -458042500,0.16732179,-156.38049,0.00044724651,-122.41789,1085.5433,-62.491089,0.29172269,-79.51152 -458542000,0.15270515,-150.27492,0.00087354827,-114.73489,1106.4276,-65.718277,0.48334464,-143.26649 -459041500,0.076674715,-167.92834,0.0018092534,-62.186489,1095.9946,-68.641212,0.34384289,-150.66824 -459541000,0.20854306,-162.76001,0.0004680636,136.92844,1051.535,-71.760963,0.46036848,54.94257 -460040500,0.2080722,-176.02716,0.00079215877,62.925709,1087.1703,-73.53524,0.26284263,-112.22177 -460540000,0.20550534,-154.62508,0.00075646042,-173.30803,1109.6409,-75.938507,0.66813594,-121.50071 -461039500,0.14771152,-161.5247,0.00065641385,-59.012611,1072.9574,-78.832901,0.20647827,-61.438549 -461539000,0.1628354,-163.34126,0.00032547553,-56.706429,1084.0552,-81.326355,0.35843405,-83.539452 -462038500,0.18019377,-138.67215,0.0014803838,-115.42312,1086.7999,-84.002655,0.41165334,-91.958977 -462538000,0.18613647,-179.40091,0.00083479751,56.46114,1070.1827,-87.093513,0.128451,-68.906639 -463037500,0.19881171,-169.24501,0.00039867026,114.24648,1083.0306,-89.118362,0.44555104,-91.506599 -463537000,0.18758562,-146.03589,0.0011690265,-111.90012,1074.0548,-92.782082,0.16892841,-120.76749 -464036500,0.22946429,-166.60698,0.00091264246,154.92276,1070.7583,-95.469803,0.13381608,-131.98917 -464536000,0.11664568,-164.93913,0.0011609929,-18.397665,1076.2786,-96.991455,0.49433169,-66.662643 -465035500,0.21909884,178.06351,0.0013267179,102.33801,1063.5963,-99.044495,0.72458404,-47.712624 -465535000,0.20300481,166.06996,0.0018600537,81.992348,1069.8369,-103.69162,0.13923147,-146.98552 -466034500,0.20980443,-138.81219,0.0019640904,-98.948059,1082.392,-105.16612,0.66350543,-81.94442 -466534000,0.17738539,-142.74576,0.0014547016,-77.406845,1092.9374,-107.43094,0.93057317,-84.495209 -467033500,0.18230405,-163.67468,0.00019834805,-112.45797,1072.3148,-112.09644,0.32447752,-139.72627 -467533000,0.19069369,-144.30438,0.0015723146,-77.435074,1065.2068,-113.39822,0.39278194,-68.360237 -468032500,0.24513552,-162.05435,0.0014912854,-148.64816,1055.9014,-116.98387,0.082291819,-85.607948 -468532000,0.15264669,-167.06419,0.00057990703,20.245554,1054.8208,-119.48975,0.10404883,-39.145988 -469031500,0.18557513,-174.30901,0.00050476869,129.19998,1063.3711,-122.45204,0.24688731,-147.13539 -469531000,0.13226262,173.43219,0.0016000223,66.446129,1046.1785,-124.26591,0.36789161,-5.8756638 -470030500,0.15256757,-165.34993,0.0004926633,17.73546,1067.8334,-127.84982,0.32574025,-108.49516 -470530000,0.16923535,-174.00534,0.00051164848,100.09028,1062.4296,-131.26128,0.46237102,-161.85318 -471029500,0.1430224,179.98396,0.0011348897,80.823296,1063.67,-132.60938,0.38698557,-69.593788 -471529000,0.19397788,-154.3197,0.0011211844,-60.362568,1056.4073,-135.85728,0.19654034,-115.38717 -472028500,0.21251711,178.37764,0.0014849528,170.69327,1056.1906,-138.43895,0.2149944,-88.754829 -472528000,0.18347862,-170.25174,0.00029517044,175.38359,1066.7234,-141.69385,0.60763305,-118.23174 -473027500,0.16612808,-175.72421,0.00062675728,122.17276,1050.8975,-143.61353,0.15161511,-50.738705 -473527000,0.21045446,-154.76906,0.0014662074,-59.451874,1060.3165,-146.42126,0.39553401,-74.993828 -474026500,0.16253534,-163.45872,0.00047507684,32.527035,1060.3029,-149.15578,0.46333092,-85.259758 -474526000,0.21402808,-179.14771,0.0014629207,-154.9527,1056.8888,-152.4332,0.39765424,-113.83702 -475025500,0.12331947,-178.90656,0.0016098467,101.67806,1068.3378,-154.28348,0.70252353,-77.988503 -475525000,0.15841788,-173.9561,0.00064656493,140.22433,1048.9745,-157.18343,0.2997438,-52.880836 -476024500,0.21954201,-162.24542,0.0014515135,-62.585228,1042.5962,-160.19266,0.052345078,177.67661 -476524000,0.17277879,-178.00719,0.00093049835,179.02548,1045.53,-161.96603,0.48731759,-18.174282 -477023500,0.16913953,168.59229,0.0019805634,177.88052,1047.1582,-166.16508,0.40633011,-125.67574 -477523000,0.18793751,-161.28906,0.00069665984,-7.6800294,1046.3044,-168.19518,0.32028341,-93.366699 -478022500,0.20157337,-174.13647,0.0010187685,-106.70815,1043.8102,-171.21805,0.28529227,-113.25507 -478522000,0.14801286,176.46446,0.0014713403,166.91472,1040.0303,-173.7359,0.20304215,-124.82384 -479021500,0.20636077,-175.05899,0.0012237823,-89.18718,1046.5502,-176.50266,0.27892959,-88.618881 -479521000,0.2138932,-160.91855,0.0014474632,-20.918787,1035.7819,-179.37549,0.26620954,-124.64116 -480020500,0.18282484,-173.75946,0.00055270788,-96.324326,1037.9772,178.54816,0.16715911,11.533428 -480520000,0.15866949,177.53076,0.0013167135,-154.84886,1027.7299,175.65887,0.202455,118.55785 -481019500,0.18746932,-177.20068,0.00098026334,-109.27988,1055.1503,172.94215,0.70988911,-59.334972 -481519000,0.1955602,-173.79475,0.00086449314,-67.906746,1034.7186,170.53917,0.071805462,10.366585 -482018500,0.17948744,-167.59326,0.00029568753,12.060428,1030.099,166.79897,0.56060338,-147.35686 -482518000,0.16243245,178.60794,0.001241766,-137.4774,1039.8569,165.61031,0.4863719,11.666888 -483017500,0.21316804,178.17212,0.0019475601,-63.389675,1028.0719,161.74359,0.27760208,-136.09993 -483517000,0.19784027,-169.28134,0.00096621638,-2.0181167,1034.9847,158.76385,0.39469987,-101.9108 -484016500,0.16290927,-171.2213,0.00032382077,-171.23515,1036.3575,156.65169,0.21703656,-82.492401 -484516000,0.1508415,-177.34782,0.00099155027,-128.39445,1022.8162,153.9532,0.22160402,-155.12079 -485015500,0.15519427,-168.582,0.00058256584,-178.04771,1033.0863,151.16716,0.29743376,-69.604736 -485515000,0.14931759,-167.84409,0.00075264269,-169.05746,1027.843,148.28613,0.29416105,-103.78465 -486014500,0.17735411,179.90654,0.0010642321,-60.733135,1030.649,146.12758,0.066374406,-37.67522 -486514000,0.16116042,-167.09045,0.0005430209,173.1017,1040.8054,143.16174,0.43147215,-46.040012 -487013500,0.16191214,-161.65184,0.00079324201,144.9146,1024.3082,140.77843,0.12789312,72.155174 -487513000,0.14419296,174.78627,0.0017221991,-93.529282,1018.5724,138.09518,0.26142481,177.21182 -488012500,0.17912313,-167.73328,0.00036060152,91.920654,1024.9502,134.63795,0.41595009,-84.042908 -488512000,0.19695936,-169.32227,0.00084428221,67.630058,1029.9434,131.96352,0.40234193,-78.061798 -489011500,0.14632542,-162.7285,0.0010234575,-154.76689,1040.4877,130.2675,0.606094,12.388569 -489511000,0.13702734,179.59373,0.0013793044,-86.059494,1029.7618,126.74706,0.24278082,-38.02301 -490010500,0.13773818,-155.13579,0.0017211948,-158.57591,1016.6001,123.62202,0.51072884,-126.85985 -490510000,0.1575986,-171.38919,0.00044956664,-96.245247,1027.0271,121.14914,0.3863951,-70.532333 -491009500,0.15414836,-162.18643,0.00090201199,-147.7885,1025.2201,118.90328,0.21493192,-29.266565 -491509000,0.18934701,-155.09445,0.0017094919,160.40848,1014.8052,115.92635,0.30989653,-133.72882 -492008500,0.1947816,-178.95525,0.001015481,37.530334,1016.8137,114.10522,0.32737443,142.91577 -492508000,0.16395997,175.16112,0.001265271,-7.9380236,1023.6847,110.01405,0.4856047,-55.709511 -493007500,0.16483302,-171.8009,0.00010961985,-130.08987,1018.8644,108.00022,0.068905279,-151.97672 -493507000,0.15720613,-179.94691,0.00079484156,-12.411016,1012.5764,104.97226,0.30559468,-115.5142 -494006500,0.13405372,169.77269,0.0017455225,-21.013758,1024.6613,102.41404,0.23988672,-21.11154 -494506000,0.19342427,-171.31915,0.00067128224,125.43243,1008.6836,99.240028,0.49610183,-101.99872 -495005500,0.14744791,-161.35052,0.0010460442,-105.77055,1001.8591,97.50531,0.49415144,-160.06654 -495505000,0.17107363,-177.71997,0.00052554265,50.44722,1012.0422,93.932861,0.31082407,-82.74601 -496004500,0.21687557,-168.39917,0.0013394656,154.59904,1010.1266,91.167313,0.42498565,-102.07638 -496504000,0.15703951,-174.11328,0.00033911006,-14.468503,1019.3409,88.675598,0.25981188,-43.779186 -497003500,0.1771861,-165.2328,0.00066893979,-143.79866,1006.0847,86.198257,0.32108587,-132.72722 -497503000,0.17752929,-166.73407,0.00062349293,-140.83643,1009.2592,83.441994,0.28668544,-128.25987 -498002500,0.19590002,176.72285,0.0010498961,94.946182,1008.1594,81.024445,0.27404001,-146.3429 -498502000,0.14858541,-177.72543,0.0005991541,12.0718,1014.5376,77.704399,0.21206279,-35.539764 -499001500,0.13860768,-168.17596,0.00080107059,-35.522251,1012.8332,75.427055,0.090535998,-101.04314 -499501000,0.13111161,-158.66151,0.0012896608,-50.624741,998.69696,71.664742,0.60838968,-76.541489 -500000500,0.12648265,161.17046,0.0019959586,35.070232,998.58356,68.81176,0.72388613,-78.289612 -500500000,0.14035864,-175.43932,0.00066522649,12.520911,1007.0447,67.070473,0.19153811,-106.75614 -500999500,0.10362706,-156.47197,0.0017583448,-20.001608,1011.8007,64.085625,0.1725183,-48.182899 -501499000,0.18157794,-162.13408,0.0010090891,-100.57583,1005.5981,61.268402,0.17008057,-88.685196 -501998500,0.13756208,-165.09233,0.00089109817,-25.757416,986.42761,57.44397,0.86742306,-73.197433 -502498000,0.1956958,173.59418,0.0011523615,135.79716,999.22406,56.6287,0.36529002,-136.81302 -502997500,0.19107065,-164.34555,0.00093789113,-107.47214,995.00671,54.221359,0.41867062,-157.52556 -503497000,0.19045566,-164.24422,0.00080476963,-91.953888,995.15302,49.844116,0.56289566,-74.034592 -503996500,0.16026525,167.37292,0.0012382555,105.4972,996.00116,47.95504,0.34491771,-98.91552 -504496000,0.23310344,-177.45554,0.0014603689,-158.15802,1016.7325,45.50201,0.14596608,105.00504 -504995500,0.15169805,-159.82719,0.00096608943,-29.112879,999.12952,42.126842,0.19616073,-78.050652 -505495000,0.21233758,-172.60703,0.0010313081,-132.33508,975.16174,40.048119,0.64770365,-107.92174 -505994500,0.18799815,-163.86322,0.00088208652,-77.199318,981.30005,38.048908,0.62188262,-133.10126 -506494000,0.17870188,173.81871,0.00078927301,164.10365,999.60382,34.00584,0.11522066,-82.09227 -506993500,0.12057044,-166.22296,0.0010023428,39.914703,979.32635,32.264961,0.66423821,-118.34579 -507493000,0.16435206,167.25555,0.0010533299,142.94766,996.82544,28.459282,0.23320474,-86.067993 -507992500,0.18752196,-174.94095,0.00054000941,-113.60995,975.74622,26.247101,0.5575785,-104.56095 -508492000,0.16695851,-166.90369,0.00039434433,-33.647209,994.29285,23.59444,0.18720557,-126.34994 -508991500,0.11165566,177.7029,0.0010044897,90.375565,981.45404,20.137934,0.40710381,-80.999886 -509491000,0.19315286,-171.73068,0.00065664499,-84.012108,992.81024,18.389858,0.31083292,-143.09821 -509990500,0.17438124,169.96898,0.0008561986,-177.89421,978.86908,14.676912,0.46822509,-83.619148 -510490000,0.15881561,168.88046,0.00081337721,171.09277,985.99933,12.017035,0.26795405,-89.945961 -510989500,0.20002979,175.70473,0.000933078,-127.31034,964.23926,9.9476042,0.68785727,-96.870651 -511489000,0.1383498,-154.96864,0.0010089548,39.920834,979.26984,7.7122188,0.53513789,-129.55707 -511988500,0.14097553,-160.22267,0.00084028003,42.346752,987.17725,4.0919762,0.2621291,-120.82011 -512488000,0.14253365,-170.39891,0.00040323799,69.909943,976.13629,0.9994489,0.36603585,-84.989792 -512987500,0.1866089,-141.49474,0.0018717363,23.640919,976.97052,-0.20231667,0.62060845,-130.51433 -513487000,0.20677231,176.22543,0.00095579028,-96.289124,974.46442,-3.1794615,0.60408944,-126.74353 -513986500,0.17405169,-158.05626,0.00086056488,18.742159,969.6925,-6.7792678,0.43626124,-90.772942 -514486000,0.16759686,166.68282,0.00089993083,-147.20274,968.15765,-9.8313475,0.46090856,-86.485039 -514985500,0.18956079,-164.17221,0.00084665749,-0.88585395,966.58698,-11.986616,0.49930614,-104.72803 -515485000,0.18823773,173.2798,0.00083563419,-104.66736,966.8479,-15.585666,0.4609302,-69.889153 -515984500,0.13460335,170.10567,0.00078611152,-163.29942,969.37085,-18.521898,0.34038872,-54.332733 -516484000,0.12182084,167.15431,0.00098298653,-177.18469,976.49768,-20.170658,0.41517529,-120.80486 -516983500,0.18728752,-122.29456,0.0025920488,71.868858,964.55658,-23.017775,0.46216935,-95.43586 -517483000,0.1726726,160.62067,0.00122314,-120.15539,965.04102,-25.320251,0.55843037,-111.12852 -517982500,0.16644584,-174.73969,0.00023594749,-17.703985,965.61987,-30.179987,0.34645665,-28.176359 -518482000,0.18420075,174.70073,0.00069851847,-71.434067,967.38373,-30.702824,0.52891493,-122.5753 -518981500,0.19969179,-148.36969,0.0014936322,59.178501,979.08539,-34.106014,0.31099629,-131.56934 -519481000,0.12671487,162.86455,0.00097591395,-134.34467,963.53809,-38.307167,0.27598587,-23.134014 -519980500,0.065377973,178.14047,0.0014324114,178.19321,938.87866,-39.485661,0.67968905,-78.230354 -520480000,0.21148151,171.30521,0.0012095158,-48.448444,980.61914,-42.495983,0.29333904,-152.41142 -520979500,0.21902405,179.21536,0.0010954307,-20.643852,949.70398,-46.17733,0.48003069,-52.482597 -521479000,0.20667559,-160.94452,0.0011171558,48.644093,962.38232,-48.549294,0.22076847,-71.583633 -521978500,0.12836786,-179.04936,0.00047422404,-145.29703,970.76617,-51.244015,0.15797764,-114.2142 -522478000,0.13610509,-167.68303,0.00035899982,153.10229,960.03052,-54.374542,0.19130458,-50.581055 -522977500,0.13874063,-154.03372,0.00073800684,133.43201,951.62482,-55.711578,0.51879305,-89.219574 -523477000,0.19535014,177.00812,0.00082630554,-13.824563,951.44983,-58.275059,0.55153877,-99.819405 -523976500,0.11575033,-175.2757,0.00056358619,-148.35895,972.02686,-60.080387,0.76030046,-136.45566 -524476000,0.11728792,-152.48361,0.00094397657,168.20056,951.04852,-64.137581,0.47682646,-95.375175 -524975500,0.13859285,-146.91254,0.0010939211,149.70502,962.96497,-66.886353,0.40970841,-123.53143 -525475000,0.21394581,-156.44312,0.0013319809,88.597382,937.69586,-70.005341,0.48507768,-74.934822 -525974500,0.17865139,-151.87151,0.0010667943,122.99541,942.58057,-72.793686,0.45934871,-84.910172 -526474000,0.27213004,-170.12476,0.0020131213,56.990746,945.06976,-75.475906,0.36128357,-88.38237 -526973500,0.10383878,141.82822,0.0016623794,-83.727272,942.78821,-77.510551,0.57887006,-96.112434 -527473000,0.17286412,176.83865,0.00053810957,2.7519095,952.67755,-81.736374,0.19452733,-106.81067 -527972500,0.16154093,-162.65591,0.00052040047,132.54289,942.03278,-83.311996,0.48470852,-94.893684 -528472000,0.17274667,173.20447,0.00070018199,-0.98162723,953.91022,-87.010284,0.20583026,-125.55782 -528971500,0.052355308,-168.47032,0.0015327957,-110.47424,957.01617,-90.759247,0.13822925,115.74438 -529471000,0.13112415,-168.90373,0.0003414689,-138.63826,945.55048,-92.475777,0.19974938,-101.39775 -529970500,0.17242442,-168.39455,0.00046670201,105.15305,957.57996,-94.8097,0.31188315,-142.41856 -530470000,0.076633036,-153.19055,0.0012342259,-113.61571,939.41376,-96.089745,0.68945104,-100.40778 -530969500,0.24931021,-146.33409,0.0020836894,144.43559,939.04138,-98.799118,0.73222011,-99.998642 -531469000,0.16189605,-161.22871,0.00048528615,166.97476,935.07153,-103.36256,0.30004284,-79.778969 -531968500,0.18047249,-129.04803,0.0019370529,-165.28322,930.42993,-106.57787,0.24113496,-48.054817 -532468000,0.11864524,-171.44357,0.00045893784,-78.108612,931.05859,-108.04198,0.49721709,-85.503738 -532967500,0.20154609,-150.33792,0.001310011,166.68918,955.0426,-111.08412,0.46064195,-135.83128 -533467000,0.21665429,-151.06516,0.0015050028,163.37201,942.39917,-114.59675,0.19887696,-126.11832 -533966500,0.22680107,-152.74869,0.0015669886,160.61859,934.44708,-116.05025,0.53424585,-94.984436 -534466000,0.11103078,143.95235,0.0016476386,-11.866974,916.36365,-119.81445,0.34836245,-56.060265 -534965500,0.13675973,149.02643,0.0014950078,8.9617805,918.89337,-122.42033,0.32229272,-67.220551 -535465000,0.22704963,-170.1507,0.0013122417,130.80608,945.18506,-125.87667,0.25151804,-158.42307 -535964500,0.18540494,170.80589,0.0011110245,71.860199,922.14697,-128.25269,0.21941997,-61.890072 -536464000,0.12639159,-152.88225,0.00075102434,-100.32158,917.98737,-130.78122,0.31955555,-67.549126 -536963500,0.16819334,-132.37323,0.0017558978,-120.3556,953.93457,-134.78539,0.50651973,172.04973 -537463000,0.12556754,-166.81313,0.000315629,-45.626255,937.38599,-135.43817,0.53088838,-108.35589 -537962500,0.17704551,178.89371,0.00073813944,101.175,936.13068,-138.41617,0.52554071,-113.07883 -538462000,0.13292359,-170.6815,0.00014854032,7.3599677,946.55188,-142.40959,0.39724201,-163.19781 -538961500,0.16170087,-170.01755,0.00029745951,151.68489,938.46936,-143.79803,0.58470953,-117.82292 -539461000,0.17084198,177.86305,0.00073844986,105.50985,922.65277,-146.25014,0.5612275,-89.099777 -539960500,0.14828849,-165.8515,0.00011985479,-139.60092,906.62793,-149.44128,0.45551178,-63.799587 -540460000,0.10724427,-147.18857,0.00098550937,-50.502804,910.13873,-152.11766,0.44373831,-71.426346 -540959500,0.16714863,-166.07019,0.00041667972,-173.97739,925.92065,-155.24561,0.38054916,-111.5515 -541459000,0.072244607,129.69003,0.0021595163,31.448927,913.55365,-159.24016,0.040275238,-162.40732 -541958500,0.10595175,-157.96809,0.00073217356,-15.360335,910.34338,-161.31598,0.2392018,-85.789909 -542458000,0.20242655,-155.07936,0.0012349681,-129.2372,926.67468,-162.96858,0.58453429,-106.3663 -542957500,0.18025981,-149.97737,0.0010665263,-101.78336,934.57544,-166.91733,0.48324424,-140.34308 -543457000,0.11257325,-157.12947,0.00064503693,-15.904197,918.63892,-168.48488,0.52356887,-98.847717 -543956500,0.15702419,-162.07745,0.00033446812,-110.96519,910.95728,-171.44313,0.45882201,-81.334656 -544456000,0.18576334,-156.48683,0.00098357361,-110.77728,906.53754,-174.7068,0.22093236,-83.044792 -544955500,0.15335308,179.20299,0.00066186115,135.45181,912.56964,-177.83525,0.26737684,-116.49684 -545455000,0.10348064,-147.84517,0.00097067252,0.93361932,907.51447,179.12753,0.14029999,-102.06866 -545954500,0.221086,-157.6378,0.0014763025,-111.97313,924.43353,177.46996,0.63486153,-109.22797 -546454000,0.20342147,-152.93324,0.0013157018,-95.518616,902.7782,174.38356,0.33813116,-72.578156 -546953500,0.16750649,-139.2767,0.0013519021,-41.787533,903.42151,171.20561,0.26451951,-93.569801 -547453000,0.11049847,-170.8367,0.00057439465,73.332634,919.6925,167.06474,0.49272099,-177.32278 -547952500,0.15065922,-176.7941,0.00056192256,156.76306,897.61719,166.65286,0.53281474,-67.764748 -548452000,0.11500122,-175.55945,0.00070069666,101.73865,902.91296,162.26118,0.23280032,-137.91835 -548951500,0.063190736,159.40303,0.0018934072,94.4226,906.78461,160.11177,0.38164839,-114.01954 -549451000,0.11797494,-139.04173,0.0013005305,22.470129,890.87335,157.11829,0.12846713,-100.94051 -549950500,0.12827413,-159.97221,0.00035986112,43.65723,902.76227,155.23552,0.46910027,-87.204964 -550450000,0.127772,-166.16052,0.00028782035,92.117302,901.30048,152.25702,0.35432175,-92.31469 -550949500,0.166475,178.17197,0.0010467315,-162.63055,893.61438,150.03857,0.47267807,-67.107002 -551449000,0.13155405,-178.752,0.0007256532,161.87349,897.5069,146.60797,0.32126051,-90.890205 -551948500,0.16594636,-157.24435,0.00053163461,-42.731926,915.21875,143.61804,0.68096304,-115.80393 -552448000,0.18798779,-137.00859,0.0017070371,-4.0311594,914.63904,139.44952,0.6976096,-155.57774 -552947500,0.18689658,-160.4026,0.00094484939,-58.59219,902.47461,138.27286,0.45567966,-101.70467 -553447000,0.12219153,-125.07709,0.0017850983,56.905033,926.62561,136.23175,1.071672,-101.49418 -553946500,0.10686477,-175.37312,0.0010497629,151.05008,894.45233,132.34926,0.37468326,-107.17428 -554446000,0.14852571,-141.16725,0.0011072509,40.438057,884.59863,129.88719,0.28700984,-68.901344 -554945500,0.18579754,-176.4464,0.0012246725,-104.4469,880.46509,126.69865,0.12642124,-102.39744 -555445000,0.12379595,-145.70526,0.00086023868,76.491692,877.28864,124.48827,0.23401991,-30.440071 -555944500,0.16113056,-141.7388,0.0011741339,42.11771,879.60278,121.39619,0.16464999,-66.38208 -556444000,0.11110682,-142.00119,0.00117225,97.962929,888.78845,119.16373,0.39962816,-72.892967 -556943500,0.16727263,-146.68384,0.00097418454,34.258076,888.21692,116.65761,0.51592332,-63.200069 -557443000,0.1951054,-167.14293,0.0012486522,-50.038055,897.67865,112.69221,0.47742593,-112.59519 -557942500,0.12712091,-161.06084,0.00033915311,162.73682,884.7077,109.59222,0.33810648,-151.67041 -558442000,0.17057863,-178.79663,0.0012406829,-92.039444,896.98395,108.54986,0.77532244,-74.854843 -558941500,0.19665688,-165.21817,0.0012311783,-32.226349,884.37848,103.95791,0.34886351,-142.21172 -559441000,0.14787441,-169.32651,0.00052269665,-96.733688,882.14331,101.33469,0.32560071,-143.00333 -559940500,0.098235048,-153.67572,0.0012050294,165.22855,875.31232,99.027481,0.13492884,-100.03943 -560440000,0.12283795,-159.99551,0.00064075645,-168.32889,887.03857,96.076553,0.56851709,-104.82594 -560939500,0.1607306,-152.43761,0.00053181022,64.734932,886.26563,93.106247,0.55457556,-117.36291 -561439000,0.19111693,-159.28593,0.0010704058,13.88448,877.06982,90.172478,0.44860584,-135.89172 -561938500,0.14008844,-170.7106,0.00072377321,-92.358704,869.95776,88.086021,0.12177698,-101.67928 -562438000,0.1989543,-164.54169,0.0013929897,-1.6988366,868.69684,84.420181,0.33145365,-152.67601 -562937500,0.20584005,-139.38033,0.0020170535,82.943703,876.07971,82.237633,0.3727653,-99.642159 -563437000,0.15402371,-155.40793,0.0002374762,112.59505,868.53522,79.812088,0.1854762,-74.397934 -563936500,0.14918485,-144.91209,0.00095997046,139.12596,878.79535,76.745949,0.50570869,-100.31891 -564436000,0.14279741,-170.36906,0.00082802639,-66.592232,864.74701,73.386002,0.36430657,-166.68147 -564935500,0.11333921,-164.88728,0.0010286936,-108.13713,865.20514,70.956985,0.22105341,-129.21278 -565435000,0.17606281,-151.53377,0.00082015333,88.771843,875.90735,68.748741,0.33635697,-67.986763 -565934500,0.14823815,-168.60664,0.00092357589,-42.332813,885.48865,65.24807,0.72880262,-90.348022 -566434000,0.16008726,-162.42535,0.00046381413,0.79533154,857.53693,61.728374,0.45429522,-170.64516 -566933500,0.092607282,-169.18532,0.001738722,-91.031693,858.25378,59.753834,0.18925937,-167.38167 -567433000,0.15881369,-149.15764,0.00049206044,156.25377,869.48596,55.900314,0.7429052,-127.88386 -567932500,0.20663045,-156.43629,0.001388424,82.646965,874.4519,54.688931,0.4888941,-72.220078 -568432000,0.13218072,-145.92159,0.00087043789,-135.59892,864.43475,51.111206,0.36761093,-107.94667 -568931500,0.20270817,-153.54669,0.0013218898,98.620316,856.35248,49.010284,0.098050043,-64.098244 -569431000,0.17351887,-133.56015,0.0018109541,-176.03111,864.02271,45.193256,0.56213909,-116.73976 -569930500,0.14580023,177.29826,0.0019031075,-7.162981,861.04987,42.822517,0.32838193,-122.37991 -570430000,0.17789946,-142.70346,0.0012435938,178.7621,868.4762,40.329517,0.48570824,-78.669609 -570929500,0.15188974,-155.55661,0.00017458637,-84.680969,862.84973,37.638638,0.2971139,-81.676247 -571429000,0.073999852,-168.20546,0.0024403895,-50.68808,868.98322,34.311611,0.54566205,-89.620399 -571928500,0.15039693,-161.15742,0.00041716432,4.0471697,859.44537,31.450094,0.43050641,-115.92329 -572428000,0.16926104,-145.07741,0.00084013736,-154.8801,848.16296,28.563423,0.43440562,-147.75337 -572927500,0.15235421,-152.4687,0.00033264994,-85.027641,849.13318,25.144306,0.69883162,-136.59288 -573427000,0.12530532,-165.55402,0.0012413709,-9.2624893,853.00104,23.559032,0.17119528,-120.68798 -573926500,0.18084216,-134.80145,0.0018160292,-133.81117,851.5694,20.124619,0.35136139,-120.59165 -574426000,0.17700034,-179.40025,0.0022143831,62.505157,860.29974,17.714081,0.42540345,-70.282036 -574925500,0.22242343,-145.12633,0.0020046681,-169.77266,847.18243,14.683194,0.31877565,-128.55038 -575425000,0.12818171,-169.39381,0.0015447845,21.110741,853.83752,12.403074,0.22959641,-79.864967 -575924500,0.18334751,-159.1922,0.00073709013,126.73663,835.32574,9.1986628,0.451446,-162.07057 -576424000,0.16055793,-154.74208,0.00014899409,-19.969973,847.51544,6.8615913,0.085488297,-149.63052 -576923500,0.18229683,-158.58795,0.00057688198,140.41478,843.15686,2.6182444,0.71161044,-125.00881 -577423000,0.15346955,-135.40967,0.0016511674,-62.685108,845.9436,0.2221498,0.51468378,-113.85171 -577922500,0.16198514,-148.6521,0.00044401776,-62.034996,843.62189,-2.6079812,0.52573961,-103.8971 -578422000,0.13989116,-122.16438,0.0026026997,-40.33176,844.43579,-5.3548536,0.4926872,-115.59067 -578921500,0.10899836,-130.07553,0.0023819555,-8.4546165,837.7851,-7.2535071,0.2337034,-150.72427 -579421000,0.18479925,-158.28087,0.00062469003,159.77522,842.78027,-10.137765,0.094727494,-90.014473 -579920500,0.18694885,-158.28528,0.00065610942,170.80989,837.34692,-13.892903,0.48459449,-118.8832 -580420000,0.12756498,-157.11693,0.0013027468,50.406368,836.59723,-15.52692,0.14862324,174.43607 -580919500,0.1663979,-145.53285,0.00071357883,-34.143951,834.05585,-19.577486,0.51462686,-114.81911 -581419000,0.1539121,-161.52773,0.00082315999,97.389885,846.94916,-21.561676,0.20526205,-16.141253 -581918500,0.15042979,-146.65723,0.00089886639,18.688023,841.28735,-25.518717,0.51824176,-91.44606 -582418000,0.17061421,-129.42102,0.0020806373,-13.457199,833.0639,-28.103277,0.48973182,-103.79156 -582917500,0.23709348,-147.26059,0.0018686096,-88.938591,836.62537,-30.716579,0.32532513,-105.77873 -583417000,0.1677102,-159.6436,0.000639576,148.21915,832.98364,-32.937382,0.15641151,-139.04004 -583916500,0.17465393,-158.06903,0.00042817066,150.96005,827.87469,-36.226509,0.41264293,-130.50978 -584416000,0.12143853,-153.18761,0.0016022625,83.13427,818.96503,-38.709984,0.55246621,-152.74898 -584915500,0.19072695,-142.41385,0.00096993323,-18.513462,821.02686,-42.620594,0.72513634,-112.30807 -585415000,0.14471802,-142.26131,0.0012060133,58.520267,822.03687,-44.969196,0.41925749,-116.11694 -585914500,0.17119443,-149.67128,0.00036800595,39.178848,832.40613,-47.664692,0.21248642,-103.64827 -586414000,0.19729374,-153.88432,0.00046428063,-86.782913,827.24811,-50.435089,0.28202298,-108.88822 -586913500,0.20802629,-140.67398,0.0013504231,-5.5645761,819.39063,-53.541637,0.50439632,-121.32069 -587413000,0.1792165,-157.91599,0.0003983553,-169.85657,820.57782,-56.095676,0.3410762,-131.74367 -587912500,0.21193749,-145.32722,0.0009859089,-13.949357,818.49127,-59.155502,0.44882512,-113.60868 -588412000,0.16919036,-156.24557,0.00049848744,155.7366,817.95477,-62.053486,0.45362708,-110.24332 -588911500,0.19367561,-139.52606,0.0012422019,33.042084,820.84448,-65.206413,0.39783493,-100.419 -589411000,0.24239674,-167.90012,0.0020340739,-100.34992,824.25458,-68.105324,0.39748421,-77.241821 -589910500,0.20693898,-142.95213,0.001005249,21.30283,809.53455,-70.502213,0.46630126,-124.42319 -590410000,0.21123596,-163.21439,0.0010829824,-97.06369,813.28925,-73.092674,0.38579106,-136.93092 -590909500,0.14433873,-149.79231,0.0011546208,136.89317,810.36761,-76.478561,0.49207696,-113.59316 -591409000,0.1852193,-157.42441,0.00036536582,-147.9377,818.77808,-79.193542,0.28014961,-97.307411 -591908500,0.20327544,-154.57419,0.00028424241,-52.027531,799.54883,-81.911255,0.68024421,-123.35638 -592408000,0.18897934,-128.03635,0.0020441636,90.81073,791.61389,-84.550957,0.84928751,-126.95349 -592907500,0.17001836,-167.61444,0.0013082906,-136.34669,812.92212,-87.297058,0.30489349,-136.40273 -593407000,0.12875628,-158.57616,0.0016212155,-175.47607,806.44678,-90.803299,0.42456126,-107.53357 -593906500,0.21674703,-144.6021,0.00094003725,63.345955,806.26642,-93.420166,0.45835766,-118.2177 -594406000,0.21341661,-164.55138,0.00096700637,-67.578979,813.21985,-96.389458,0.23269965,-108.45301 -594905500,0.21481372,-163.61038,0.00097260665,-63.213314,823.31024,-99.263,0.079376392,-22.874336 -595405000,0.21306908,-138.48712,0.0012286967,99.869469,803.0116,-101.47376,0.47178829,-128.74075 -595904500,0.17652744,-143.83606,0.0010581596,148.19713,805.49408,-105.41385,0.37679821,-97.589851 -596404000,0.21698466,-141.92752,0.0010764545,97.849174,803.24847,-108.21086,0.32005906,-89.976234 -596903500,0.17105559,-140.29147,0.0012564275,159.62595,801.03906,-110.28263,0.41137376,-126.47163 -597403000,0.15392028,-168.27304,0.0014549759,-110.14392,783.45422,-113.8934,0.70479739,-104.42241 -597902500,0.23674473,-157.2113,0.00066929834,16.511736,805.46509,-116.04401,0.31516737,-143.60878 -598402000,0.18743162,-156.97475,0.00049610925,-117.60571,797.88531,-119.649,0.40232289,-99.961365 -598901500,0.17937779,-158.65639,0.00075957429,-104.16013,811.16748,-122.1961,0.073935635,-131.12444 -599401000,0.25457394,-148.752,0.0011507503,79.857681,791.65118,-124.75839,0.43327373,-122.91615 -599900500,0.28511682,-150.98277,0.0016797989,68.296127,785.46405,-127.31358,0.5903576,-122.34621 -600400000,0.13370937,-150.27162,0.0016691684,-125.8479,788.98206,-131.0787,0.40775174,-97.241295 -600899500,0.20508492,-151.72461,0.00025483299,176.67029,789.2431,-133.73503,0.40720096,-113.06943 -601399000,0.30708349,-145.40543,0.002205933,97.611984,796.4325,-136.1368,0.29634976,-134.98613 -601898500,0.22486204,-160.63055,0.00055261882,6.2279334,793.96381,-138.98659,0.4012177,-141.47202 -602398000,0.2040741,-145.85086,0.00077916798,-167.88823,791.50818,-142.11273,0.37490451,-131.10846 -602897500,0.24249661,-166.16977,0.0010849958,14.182688,787.62164,-144.69148,0.46595114,-129.16666 -603397000,0.24068522,-155.93806,0.00048199156,88.484177,786.30371,-148.45576,0.36390582,-98.310974 -603896500,0.18645762,-164.16647,0.00092667353,-50.928699,776.14319,-151.49434,0.48938435,-90.125557 -604396000,0.20259534,-138.8181,0.0013204004,-151.56601,776.90326,-153.95506,0.43068731,-103.17377 -604895500,0.30781761,-158.23759,0.0017998968,92.338806,797.5976,-157.36273,0.063966013,-176.44861 -605395000,0.28239885,-164.1356,0.0014418055,73.267097,788.41925,-159.4424,0.32796934,-147.41989 -605894500,0.29047114,-171.82166,0.0019936885,53.819027,790.73053,-161.70616,0.49250284,-155.8587 -606394000,0.16389421,-175.58136,0.0018763876,-29.889643,785.92371,-166.44962,0.18401451,-65.349312 -606893500,0.18054667,-148.13454,0.0011622459,-92.534225,783.12952,-167.80899,0.46267864,-147.45782 -607393000,0.25469118,-155.66006,0.00061557081,135.85217,776.0733,-171.036,0.42256361,-126.02132 -607892500,0.20060772,-152.05252,0.00073712284,-76.219856,764.57294,-173.61836,0.64300132,-107.34921 -608392000,0.21567075,-150.86034,0.00060383172,-107.91474,778.39374,-176.27879,0.53302819,-139.88252 -608891500,0.25275782,-167.12953,0.00093177479,74.676941,780.44928,179.75188,0.23363151,-142.50061 -609391000,0.29323491,-158.1514,0.0012455885,136.59386,771.06433,177.33109,0.4280813,-117.81271 -609890500,0.28934085,-147.96782,0.0014620282,-171.40373,765.48175,174.42827,0.48905823,-112.34147 -610390000,0.14881089,-144.85759,0.0018816525,-52.679134,747.28815,171.89407,0.76033843,-98.835373 -610889500,0.3017312,-159.41444,0.0012749452,150.6377,778.62195,168.9207,0.51396906,-150.78537 -611389000,0.28941107,-153.96396,0.0010993271,176.38655,770.2337,165.82317,0.39205363,-124.40341 -611888500,0.22903545,-155.7621,0.0003158855,-63.770382,769.40277,162.53191,0.3452504,-129.80914 -612388000,0.25164828,-159.24173,0.00018232252,172.18126,775.03918,159.52357,0.36281264,-151.19669 -612887500,0.25451869,-140.38486,0.0016326818,-94.243225,755.02246,157.04648,0.57736385,-101.68236 -613387000,0.269936,-161.78607,0.00054668559,160.7496,776.23438,153.2104,0.28298298,-174.23737 -613886500,0.32936686,-154.91528,0.0018747688,-163.67329,760.56567,151.68922,0.5654757,-127.01658 -614386000,0.22793396,-169.1046,0.00075989199,68.049179,766.07184,148.04372,0.40478992,-145.80461 -614885500,0.22639613,-168.23325,0.00072703057,62.862999,746.95593,144.86241,0.49336299,-97.805901 -615385000,0.28979322,-157.48648,0.00091894198,-149.79112,758.50085,141.68675,0.27556345,-105.9029 -615884500,0.26762784,-158.47945,0.00049089297,-128.27536,752.59454,138.61314,0.29139209,-111.31419 -616384000,0.26356158,-150.18095,0.0010596559,-79.886002,749.36243,136.42781,0.47718546,-112.91221 -616883500,0.24403168,-164.51103,0.00029349819,91.738205,754.30035,133.51695,0.46283424,-124.95255 -617383000,0.23937005,-174.46936,0.0011519105,100.60403,747.46368,129.8468,0.290941,-98.893509 -617882500,0.25904998,-172.4444,0.0009761409,128.43947,748.83588,127.48206,0.42482671,-116.6928 -618382000,0.28888145,-169.84718,0.0011306469,170.44777,755.92645,124.47374,0.39180765,-140.92503 -618881500,0.25284728,-146.71815,0.0014060325,-37.186306,743.48077,121.61323,0.42005074,-106.07114 -619381000,0.25216618,-159.06708,0.00041846896,-25.175482,745.65546,119.6414,0.69495815,-123.53885 -619880500,0.23500407,-149.81291,0.0011418153,-14.074844,755.91327,116.42775,0.59379166,-139.86508 -620380000,0.32272598,-167.19836,0.001451895,-144.55388,747.9137,112.39339,0.32568979,-135.66644 -620879500,0.29438439,-162.26704,0.000769993,-108.59968,744.50543,110.04852,0.5400424,-122.64752 -621379000,0.33268332,-164.44109,0.0015207189,-116.29628,746.81042,107.04536,0.51432592,-134.22827 -621878500,0.24675396,-154.27867,0.00090991962,0.34721684,740.27521,103.91867,0.42855704,-119.5237 -622378000,0.25985706,-167.7608,0.00026105554,164.34961,739.64264,100.33894,0.25922811,-130.16869 -622877500,0.32330701,-157.22784,0.0014315144,-66.119949,734.47778,97.903412,0.44788784,-111.57466 -623377000,0.20264064,-164.50751,0.0012940946,80.372314,732.9364,95.116768,0.44908947,-111.91135 -623876500,0.28527838,177.77382,0.0017492701,-176.55087,735.02893,92.474739,0.51123571,-122.6709 -624376000,0.27316025,179.26099,0.0015468193,178.78821,742.59009,88.766632,0.44020119,-148.14859 -624875500,0.20160066,177.56046,0.0019799187,131.99554,715.5954,85.929016,0.44795901,-71.156525 -625375000,0.26867995,-157.65463,0.00082148198,11.69576,730.83569,82.499596,0.25520787,-134.57137 -625874500,0.20149221,-174.03877,0.0015654317,124.52399,726.99298,79.658875,0.27995944,-121.55432 -626374000,0.29407212,-166.97112,0.00057008798,-75.458099,720.56659,76.804161,0.28844383,-98.072845 -626873500,0.2988255,-165.97585,0.00060530606,-51.975475,732.11603,74.321976,0.52676624,-129.85176 -627373000,0.24349658,-165.58104,0.00051266415,99.852501,716.22064,70.971146,0.26249638,-87.398132 -627872500,0.3195608,-161.92694,0.0012764833,-27.71489,730.8645,67.513283,0.3627533,-156.93813 -628372000,0.24029028,-171.97658,0.00083678856,152.66356,721.7536,64.752869,0.29954898,-123.8274 -628871500,0.19628903,-155.57243,0.0019968709,100.36819,716.69049,62.585823,0.45856899,-104.65524 -629371000,0.24714345,-160.88705,0.00098556362,85.174767,716.62567,59.395271,0.45528352,-103.5549 -629870500,0.23374873,-155.14484,0.0017007641,87.276321,715.5246,55.776669,0.30070052,-124.6879 -630370000,0.35040447,174.24808,0.002594274,-97.482361,723.62872,51.841057,0.39110854,175.11084 -630869500,0.22845007,-173.79372,0.001189147,167.13324,722.06073,50.26252,0.53242588,-125.4499 -631369000,0.22238514,-166.31334,0.0013370744,131.78979,707.33252,46.272438,0.16978356,-150.72911 -631868500,0.26051629,-167.28351,0.00050569186,110.80064,717.14185,44.422947,0.51847327,-121.10035 -632368000,0.30629098,-168.84103,0.00069753733,-0.28618833,714.82434,40.823833,0.43192908,-140.64084 -632867500,0.26883179,-168.47755,0.0003306281,106.88554,714.25745,37.81506,0.39340755,-137.99307 -633367000,0.32224247,-176.66486,0.0011629567,-46.670067,705.22668,34.733047,0.27455583,-132.07019 -633866500,0.33478653,-171.69849,0.0012554743,-7.2150984,718.7135,31.6593,0.58041811,-146.26259 -634366000,0.30438662,-161.62856,0.0013903158,68.940529,707.94855,28.696278,0.30873683,-142.35539 -634865500,0.35445839,178.10567,0.0020850999,-39.160084,700.72803,25.671585,0.28842127,-140.30487 -635365000,0.29136524,-173.19061,0.00024312934,0.67507088,696.98523,22.601711,0.24163251,-110.93566 -635864500,0.2497523,-177.89064,0.00094158051,-138.29276,694.58368,19.263163,0.16719586,-148.76843 -636364000,0.30249557,-179.4753,0.0009053353,-47.237797,707.72339,16.60008,0.50295901,-137.6922 -636863500,0.27081132,-179.62764,0.00070437964,-106.00212,695.23193,14.375492,0.42393842,-109.04392 -637363000,0.28707349,-173.47926,0.00015709084,79.650032,707.25696,11.793736,0.71773702,-115.77834 -637862500,0.28295907,-178.44942,0.00045570685,-76.798981,689.20691,7.9030771,0.31176823,-104.00749 -638362000,0.25593677,-167.10764,0.0012604702,164.24942,685.58759,4.339026,0.15089971,-125.84209 -638861500,0.27068675,-169.68544,0.00085792155,155.98714,692.47485,1.7538562,0.37169504,-126.67504 -639361000,0.24652201,-176.68996,0.0011500355,-131.93468,688.85767,-1.9719708,0.36038893,-144.99693 -639860500,0.29925683,-175.78624,0.0003314545,49.059853,682.5426,-4.2507319,0.33085817,-98.897446 -640360000,0.31316507,-173.31549,0.00079197861,85.796249,689.47888,-7.5895262,0.48679206,-127.53743 -640859500,0.31253523,171.45729,0.0016506067,-20.370253,680.21887,-11.576808,0.37041157,176.32829 -641359000,0.32668415,178.57581,0.0011128018,29.636246,677.99445,-13.492479,0.23264909,-119.31636 -641858500,0.30208227,-178.63211,0.00035214887,46.481739,681.06555,-16.772789,0.36231902,-130.90785 -642358000,0.33736509,-170.26645,0.0018199349,114.67012,681.92981,-19.671892,0.40792161,-125.39133 -642857500,0.27813092,-175.94861,0.00047902946,-154.86415,681.0589,-22.617437,0.44796538,-117.08548 -643357000,0.26657352,-178.41292,0.0006658698,-117.36,683.41486,-25.882429,0.54059297,-133.07729 -643856500,0.30676535,-173.61769,0.00098345964,148.76306,685.50317,-29.299105,0.65949285,-135.13528 -644356000,0.28454459,173.98695,0.00071115058,-21.884293,682.96222,-31.693867,0.61398923,-121.13136 -644855500,0.25496769,179.54202,0.00098920218,-88.981468,674.59503,-35.006214,0.40889439,-119.06998 -645355000,0.30386087,-173.53641,0.0012046896,168.85887,679.7915,-38.346268,0.61309654,-128.29521 -645854500,0.30322316,177.69783,0.00030064015,94.087715,668.98065,-41.792976,0.47920126,-150.32007 -646354000,0.29841137,173.53954,0.00075124518,28.261589,658.19489,-44.297352,0.12059771,-129.56036 -646853500,0.30336347,174.77652,0.00051936239,63.513664,664.34491,-46.964233,0.31954098,-105.23918 -647353000,0.26844418,178.98621,0.00063862262,-93.269478,670.10938,-50.184048,0.49688965,-110.32441 -647852500,0.34911489,175.70195,0.0017301167,115.74533,658.5072,-53.366844,0.28023094,-124.93115 -648352000,0.25711998,173.42479,0.00099663448,-35.907146,657.92615,-56.600834,0.2539736,-121.42779 -648851500,0.30466089,169.22499,0.0010993665,59.426353,658.80646,-60.217113,0.43954176,-138.92426 -649351000,0.2828891,165.98979,0.0014557634,29.840988,654.39832,-63.022217,0.34191719,-136.56915 -649850500,0.29997283,174.15086,0.00040038602,139.35381,659.35944,-66.230659,0.45369282,-130.11099 -650350000,0.31437951,174.98135,0.00088937144,157.42769,657.0155,-69.292427,0.45563701,-130.43959 -650849500,0.2233285,170.30424,0.0022242614,-20.408001,650.53632,-72.835953,0.49783382,-146.58629 -651349000,0.2858952,174.23653,0.00028085237,-81.412109,649.53247,-75.615593,0.41933003,-146.28008 -651848500,0.28277415,177.01712,0.00074532372,-101.44022,649.34576,-78.887749,0.44825813,-139.54645 -652348000,0.29091933,167.97935,0.00071277638,82.790932,646.38171,-81.672356,0.33811545,-111.92176 -652847500,0.2533837,165.0164,0.0014738311,23.81275,644.58759,-84.662056,0.35593984,-123.26645 -653347000,0.29036722,176.34579,0.00091089995,-96.263931,649.06165,-87.982346,0.52851987,-114.21192 -653846500,0.27293575,167.84534,0.0005700342,33.066654,645.31903,-90.770264,0.4487457,-108.0118 -654346000,0.26307955,168.10664,0.00076283916,23.538584,639.40472,-94.946121,0.52409011,-143.8645 -654845500,0.28515327,167.3772,0.00035612506,110.46605,636.86737,-97.235657,0.30318668,-130.71193 -655345000,0.25138208,163.96017,0.0013534373,40.356945,639.37775,-100.83407,0.51092684,-125.77036 -655844500,0.26964381,173.73482,0.00095417368,-40.182316,631.08826,-104.25762,0.49215773,-146.55843 -656344000,0.30223185,167.54497,0.00061440386,-160.39255,629.13727,-106.95216,0.36070246,-137.26996 -656843500,0.29725459,161.74886,0.0010434876,142.617,630.30103,-110.33353,0.45913443,-131.56053 -657343000,0.27378598,170.73438,0.00057766133,-40.429867,625.6897,-113.57391,0.35596117,-130.0804 -657842500,0.28277984,167.32971,0.00016736367,-108.21016,623.92041,-116.83815,0.52906168,-131.96562 -658342000,0.25679874,171.53114,0.0011739973,-5.7243061,624.19409,-120.06051,0.52699232,-126.73838 -658841500,0.26237902,171.15903,0.0011950335,-9.241395,615.24152,-122.9082,0.36903644,-161.21065 -659341000,0.25681895,167.75783,0.00084851752,26.385172,614.05737,-126.34483,0.43783697,-144.86996 -659840500,0.29429248,163.73337,0.00066169165,-126.12052,611.86633,-129.33321,0.39560992,-153.42786 -660340000,0.2901867,160.54314,0.00077929598,-163.57332,616.9035,-132.43134,0.38801131,-111.9194 -660839500,0.272057,165.8511,0.00036962895,4.2201223,606.89777,-135.51401,0.34798157,-146.5412 -661339000,0.30082679,159.79568,0.0010042136,-125.55422,612.49884,-138.83321,0.34946477,-116.72887 -661838500,0.24755555,162.94655,0.00080607284,63.090706,611.78723,-142.5441,0.5121389,-112.44584 -662338000,0.25013596,162.30438,0.00078356464,69.825958,606.50043,-145.4433,0.44495368,-124.1077 -662837500,0.31463918,156.87932,0.0016839096,-113.71927,600.39685,-148.32121,0.30980152,-150.88667 -663337000,0.31774643,162.53766,0.0019052357,-66.231018,599.37042,-152.0069,0.41283548,-137.293 -663836500,0.23787217,161.40932,0.0010271551,84.555916,599.25372,-155.42302,0.50192869,-120.59661 -664336000,0.27965075,152.54634,0.0010711318,-147.87479,594.48877,-157.6131,0.21032569,-156.08003 -664835500,0.29541996,160.50882,0.0011710945,-45.26989,593.11743,-161.47429,0.36884749,-134.56592 -665335000,0.27415133,158.00993,0.00047655372,-47.960522,593.88861,-164.948,0.42278919,-116.30468 -665834500,0.26243114,157.52986,0.00021174777,16.410717,585.82306,-167.88913,0.37419,-150.56659 -666334000,0.26282761,164.92485,0.0014527921,33.224209,588.41382,-171.40024,0.36445627,-120.59188 -666833500,0.24927442,150.38266,0.00073569751,-162.87598,585.66833,-174.19226,0.23512563,-139.83322 -667333000,0.26522267,149.718,0.00086482783,-123.37141,579.26556,-177.58372,0.38145304,-137.24568 -667832500,0.25890642,152.99373,0.00017400166,-52.762291,577.04828,178.96117,0.35796401,-144.43399 -668332000,0.23499858,157.47093,0.00081903121,106.88799,579.67145,175.74069,0.35736707,-118.11267 -668831500,0.25232881,143.6608,0.0013894648,-119.49857,573.79968,172.43382,0.33653265,-130.10446 -669331000,0.24135597,146.4012,0.00085404405,-139.80951,574.66095,168.85939,0.42540744,-115.91133 -669830500,0.2291436,154.1893,0.00050908444,119.20007,564.40607,166.20152,0.31802636,-156.34712 -670330000,0.28836972,146.35635,0.0016800023,-42.625607,569.06879,162.59637,0.27559161,-110.0866 -670829500,0.24107413,154.28343,0.00058295671,79.419647,561.35791,159.23216,0.39680427,-129.83647 -671329000,0.23351139,148.29091,0.0002391952,-142.09496,558.64447,156.00534,0.39952672,-140.0699 -671828500,0.28482401,143.22209,0.0017771166,-34.995995,554.26752,152.46143,0.43826151,-134.38657 -672328000,0.20425726,157.36086,0.0014897995,134.62059,551.63757,148.65477,0.53741813,-123.05051 -672827500,0.25916317,150.81952,0.00095515046,36.534657,549.98328,145.76831,0.45750612,-126.13175 -673327000,0.21635653,149.20062,0.00052767817,169.99162,549.48218,143.21004,0.28632692,-143.69214 -673826500,0.27538732,147.73045,0.0015462991,26.413553,545.69391,139.26399,0.3612279,-125.36446 -674326000,0.23456454,143.31322,0.00056362874,-4.7079782,543.565,135.86618,0.29659742,-122.34253 -674825500,0.1977146,138.21603,0.00098296534,-107.9397,541.83398,132.73712,0.25375867,-120.48432 -675325000,0.18490474,139.58287,0.0011277867,-129.47214,538.26642,128.7446,0.3999086,-109.11834 -675824500,0.2411615,144.70187,0.00075662765,57.898129,535.42773,125.80952,0.34837085,-122.56277 -676324000,0.26415727,154.82024,0.0024005745,87.241623,523.52728,122.9326,0.43207371,-147.395 -676823500,0.22209431,157.28964,0.0018467809,129.93349,526.94489,119.65926,0.29437658,-143.15114 -677323000,0.22276416,143.0943,0.00070418906,54.084324,521.33032,116.42556,0.3300525,-143.50664 -677822500,0.19730227,140.19824,0.00013834157,-39.491592,512.34827,112.37699,0.54025489,-125.50034 -678322000,0.1561407,134.88617,0.0012804817,-105.53392,509.55093,109.01015,0.53207511,-132.14671 -678821500,0.14906529,143.2065,0.0013549419,-133.08893,509.68164,105.9889,0.38493609,-139.7683 -679321000,0.18756945,146.19281,0.00072467735,174.53235,508.27933,102.30379,0.41551501,-120.06462 -679820500,0.20991077,133.5663,0.0008753835,45.058846,506.36664,98.924011,0.32117614,-121.40212 -680320000,0.17037338,132.85464,0.00058626087,-55.518166,499.27213,95.706039,0.46056339,-128.907 -680819500,0.16259749,137.24074,0.00044022981,-108.64116,498.05576,92.375954,0.35972312,-129.85271 -681319000,0.16305505,140.25218,0.00048642667,-134.11612,489.52808,89.421654,0.50154293,-141.0036 -681818500,0.1709404,134.58635,3.3071134e-005,-151.83249,484.96771,85.237099,0.5534324,-123.794 -682318000,0.20264685,132.9453,0.0011524654,82.421883,486.7825,82.435768,0.38260424,-134.44507 -682817500,0.19553195,138.44095,0.001060297,126.65746,483.05145,79.404213,0.39065161,-153.43974 -683317000,0.1602736,120.88645,0.0010738926,9.9178801,483.91931,75.067909,0.26001889,-106.94327 -683816500,0.15927632,138.3087,0.00053967501,-176.05876,474.92175,71.984833,0.39544249,-126.21819 -684316000,0.15745397,143.92435,0.00094907382,-159.83018,467.19608,68.595848,0.53010678,-125.98925 -684815500,0.15638828,134.53674,0.0003393876,159.77681,465.85403,65.784874,0.46559289,-142.23022 -685315000,0.14345822,146.82289,0.0013495603,-141.70944,460.87241,61.697235,0.46545082,-124.91008 -685814500,0.071566343,165.06638,0.0027387647,-80.3536,454.88516,58.325897,0.51323432,-122.19404 -686314000,0.12995444,158.86667,0.0021202576,-121.74494,452.0108,55.226578,0.50153685,-133.23056 -686813500,0.12318107,119.27778,0.0006953954,18.416214,449.24567,51.439945,0.46068147,-120.55948 -687313000,0.11528501,83.096184,0.0028636581,22.059717,444.38324,48.129307,0.51333761,-123.19942 -687812500,0.13601124,147.6787,0.0014587957,-130.56642,441.86868,45.174957,0.49274394,-134.38373 -688312000,0.088609837,130.84869,0.00092309079,-44.858612,441.18863,41.43998,0.36423233,-131.18608 -688811500,0.1094114,136.43217,0.00062394468,-101.00104,433.92462,37.911011,0.46346903,-124.96938 -689311000,0.098634824,128.26062,0.00038498893,-42.712276,430.13809,34.868294,0.44595975,-132.73143 -689810500,0.10506868,115.67095,0.00055165862,76.838928,424.72192,31.19272,0.4538269,-125.51723 -690310000,0.15987702,140.90483,0.002271187,-152.35858,422.6116,28.028532,0.41692066,-134.60297 -690809500,0.073072493,141.73523,0.0010244995,-44.599873,419.43268,24.502504,0.44759116,-130.32776 -691309000,0.11926376,132.9612,0.0010643353,-153.45694,415.49164,20.990929,0.4107891,-125.14586 -691808500,0.10456505,128.01529,0.00071274792,-162.08961,411.24606,17.593315,0.39890963,-127.8848 -692308000,0.071356684,100.78302,0.00096077693,69.416626,403.61182,14.103623,0.51378208,-122.19936 -692807500,0.048819162,145.91342,0.001174837,-21.086323,399.82159,10.597195,0.49941295,-123.0241 -693307000,0.084784538,85.722717,0.0015937937,103.17685,397.18549,6.8770528,0.40860823,-117.36055 -693806500,0.069967568,130.4377,0.00048578711,-95.456299,395.09604,4.1696601,0.40022197,-140.79077 -694306000,0.01462079,127.65293,0.0015732909,25.430559,389.45605,0.13082185,0.42653698,-118.55274 -694805500,0.094207048,122.4495,0.0012801976,-148.43799,389.39188,-2.8862441,0.34896249,-143.45808 -695305000,0.091839753,101.39881,0.001573928,172.14192,381.17087,-6.581737,0.37849513,-122.24065 -695804500,0.025693791,162.62988,0.0010446809,5.5094562,376.30637,-9.7597904,0.45120287,-128.65315 -696304000,0.040113028,128.36044,8.2345978e-005,-57.423038,371.39124,-13.432664,0.45383945,-119.60074 -696803500,0.069374017,166.44092,0.0017055077,-52.57621,369.58282,-16.793489,0.39567631,-133.20064 -697303000,0.024179159,-43.91449,0.00174863,64.636765,361.35272,-20.177139,0.48061049,-116.63954 -697802500,0.0024400693,-125.33341,0.00087929453,61.551315,358.9227,-23.901047,0.39726841,-114.7291 -698302000,0.013507371,167.46521,0.00042527626,27.766243,355.84702,-26.748869,0.43189701,-133.75415 -698801500,0.025045298,45.438148,0.0010732104,140.79262,348.88971,-30.248182,0.51037824,-124.54828 -699301000,0.041840479,169.43367,0.0010836192,-52.189915,343.66791,-33.191383,0.59903097,-127.51917 -699800500,0.023712246,175.63629,0.00058864919,-44.715931,340.59225,-37.467533,0.42425162,-121.25365 -700300000,0.054096561,87.073837,0.0021855899,-136.44835,337.76678,-41.230633,0.34466854,-115.4297 -700799500,0.011842575,173.63605,0.00034285506,-123.75597,335.97943,-44.614525,0.33167139,-127.96413 -701299000,0.029246353,170.24609,0.0010886217,-65.764305,328.7637,-47.263214,0.46887445,-132.13676 -701798500,0.029296121,-78.747223,0.00046395362,132.99329,325.96356,-51.002975,0.38272721,-120.78892 -702298000,0.024685491,-170.14178,0.001112065,-63.791401,324.08157,-54.634697,0.31018564,-138.60503 -702797500,0.043696899,-71.170059,0.00076498522,135.53662,315.0856,-57.834942,0.43871602,-121.70886 -703297000,0.032977235,-141.74348,0.0010559316,-39.641052,309.48227,-60.952942,0.51777095,-122.62911 -703796500,0.055952825,-138.88744,0.001641538,-8.5282297,307.508,-64.380341,0.46584707,-130.86153 -704296000,0.044733025,-48.494953,0.0014986921,-157.56151,301.95911,-68.438499,0.39944178,-115.15799 -704795500,0.061243817,-118.69472,0.0011398377,8.6696062,298.77783,-71.358704,0.43082258,-125.62184 -705295000,0.035987273,-97.63385,0.00099755952,-77.359108,296.09189,-74.804344,0.40934455,-125.64433 -705794500,0.063111857,-107.72805,0.00063985045,18.278936,288.52753,-78.257629,0.46387658,-116.61537 -706294000,0.055539384,-49.282211,0.0020346518,-126.05266,285.93155,-81.79026,0.37991226,-122.87888 -706793500,0.05480843,-92.673752,0.0008795691,-70.036613,284.87088,-84.958916,0.41405195,-138.55763 -707293000,0.063183032,-73.245171,0.0013346641,-114.52637,277.60794,-88.197151,0.48947313,-126.02036 -707792500,0.11999874,-94.716812,0.0015974492,126.86472,274.55753,-91.444656,0.52553344,-130.60086 -708292000,0.065407954,-87.099464,0.001186342,-81.836212,271.07755,-95.167183,0.44089001,-135.0916 -708791500,0.11758674,-90.800583,0.0012533664,162.66223,265.15005,-98.536964,0.50109822,-126.0693 -709291000,0.1173157,-98.08107,0.00097313558,120.94427,261.93552,-101.89661,0.47151408,-129.03764 -709790500,0.13430284,-100.43134,0.0012828914,115.95583,258.85291,-105.24332,0.43771881,-127.87573 -710290000,0.097657673,-100.78236,0.00066629611,-5.8508258,254.12793,-108.70627,0.42424744,-129.36844 -710789500,0.11080295,-108.98325,0.0010128808,34.969463,251.48735,-112.06696,0.48153004,-138.50986 -711289000,0.15778606,-99.428123,0.0019754593,146.79965,246.10533,-115.05125,0.51982814,-129.14914 -711788500,0.11865809,-89.929123,0.0011892978,-89.249252,242.14354,-118.63795,0.4926334,-128.70744 -712288000,0.13714388,-103.8276,0.00069899386,96.883118,239.33862,-122.18704,0.40291628,-135.78146 -712787500,0.13081422,-104.66399,0.00061061996,42.310089,234.98109,-125.26788,0.4997766,-134.58321 -713287000,0.13692041,-96.036552,0.00080271851,-79.481895,230.14172,-129.04471,0.41730735,-126.1485 -713786500,0.14496943,-103.41985,0.0003245853,23.430027,228.10057,-132.06323,0.48241642,-133.94943 -714286000,0.13288742,-108.93102,0.0012797249,28.510248,223.03268,-135.77448,0.41260681,-131.32536 -714785500,0.16542986,-108.53364,0.0011355121,111.30032,220.32596,-138.78981,0.45642191,-134.91 -715285000,0.16787109,-106.60474,0.00051061285,111.78436,216.36272,-142.06381,0.49829343,-132.0755 -715784500,0.17188622,-92.439232,0.0023090178,-80.789284,210.80156,-145.23474,0.53028333,-120.22636 -716284000,0.17179868,-95.217445,0.0018012048,-64.715218,207.9409,-149.02306,0.39275077,-122.06585 -716783500,0.17513046,-105.73085,0.00013747055,15.94609,204.54677,-152.14,0.46233684,-128.55923 -717283000,0.17013246,-113.79157,0.0018587691,78.020729,201.78691,-155.48694,0.45615628,-133.99739 -717782500,0.21369724,-108.48635,0.0019779799,-170.14658,199.1797,-158.50299,0.53591675,-136.05872 -718282000,0.1655774,-102.50839,0.0022092639,-9.4517746,193.49835,-162.14586,0.46756852,-130.83684 -718781500,0.18986461,-103.41277,0.0012433446,-31.582361,191.05678,-165.40443,0.45948726,-130.76923 -719281000,0.17596392,-109.73125,0.001764807,55.545269,187.86571,-168.60919,0.45684177,-133.66278 -719780500,0.21635731,-107.39534,0.00097374601,-104.61866,184.24139,-171.54192,0.55313432,-129.29231 -720280000,0.21041676,-110.91169,0.00036887714,142.51389,181.03925,-175.30843,0.4566533,-133.99767 -720779500,0.21312793,-109.4434,0.00046933154,9.0915842,177.25935,-178.32455,0.49576083,-127.33702 -721279000,0.20806868,-112.31464,0.00072181795,53.362965,173.39046,178.28333,0.47341955,-126.18233 -721778500,0.21853006,-109.97624,0.00076839013,-1.39373,170.71683,175.18193,0.49894208,-125.01997 -722278000,0.2205542,-110.4587,0.0010321331,20.5536,168.17986,171.65457,0.48587745,-130.24783 -722777500,0.23346935,-115.40901,0.00097879337,145.4014,165.5647,168.24229,0.46479842,-135.34344 -723277000,0.2350335,-119.50748,0.002238407,143.69971,162.36951,164.93336,0.47611558,-137.92921 -723776500,0.25627109,-112.47213,0.0014246423,-73.055161,158.99425,162.28075,0.55246079,-128.12505 -724276000,0.22815561,-115.66524,0.0015522952,92.640701,155.93871,158.84508,0.49617106,-130.65868 -724775500,0.25880149,-117.08211,0.0011286288,-141.44092,153.18105,155.31459,0.47384572,-132.24704 -725275000,0.24915981,-113.21745,0.0014111504,22.048847,149.90477,152.37083,0.48262101,-125.20723 -725774500,0.25390854,-118.35056,0.00067511655,156.99268,147.22955,149.25356,0.51726407,-130.15404 -726274000,0.25377971,-121.36248,0.001878251,151.76781,144.42188,145.66774,0.49891761,-136.49156 -726773500,0.25759611,-116.52583,0.0010187423,66.215164,141.4725,142.63499,0.47042289,-130.11284 -727273000,0.26307639,-120.03436,0.00087492773,137.70576,139.127,139.51178,0.497226,-130.93753 -727772500,0.27706996,-120.94932,0.00096700172,-111.51833,136.47264,136.29384,0.51683944,-136.05861 -728272000,0.28675568,-122.23954,0.0016382781,-120.83717,133.67583,132.91187,0.477983,-136.29657 -728771500,0.28707322,-120.29025,0.00068646588,-21.83412,130.87488,129.65971,0.50544417,-134.54791 -729271000,0.2855919,-121.59624,0.00040599253,136.55653,128.31874,126.51941,0.49207422,-128.37251 -729770500,0.28426003,-125.8278,0.0025385222,-161.34038,126.1109,123.36663,0.50322723,-136.17056 -730270000,0.29853234,-120.64474,0.0010630682,18.500563,123.62255,120.29047,0.54104543,-129.73784 -730769500,0.29530746,-122.8013,0.00098883559,144.36304,121.318,116.93864,0.49754733,-134.6472 -731269000,0.29634997,-123.5295,0.00032153807,106.25851,118.55288,114.0632,0.50024837,-133.1722 -731768500,0.30344951,-124.48359,0.00045116385,149.37384,116.21693,110.70552,0.51648623,-129.86214 -732268000,0.31954917,-125.17417,0.0016490665,-34.436932,114.27699,107.40979,0.53197938,-138.66988 -732767500,0.31847173,-125.16058,0.00067222322,-22.68956,111.7575,104.25729,0.49806926,-130.89011 -733267000,0.31298587,-126.52681,0.00075910176,-140.67885,109.80074,101.36316,0.54533553,-130.82172 -733766500,0.32110265,-126.65981,0.00028781284,-125.7003,107.42578,97.955139,0.53646523,-133.58752 -734266000,0.31890044,-126.60118,0.0013960701,108.66743,105.1086,94.862976,0.51712352,-134.16844 -734765500,0.32845324,-126.00362,0.0024004485,71.292648,102.85407,91.854637,0.52390468,-131.88919 -735265000,0.33524206,-128.49272,0.00050370081,6.0715647,101.09836,88.264313,0.52522582,-140.86143 -735764500,0.33142379,-128.47322,0.00035949872,134.82614,99.161629,85.621399,0.54839021,-131.78036 -736264000,0.3347781,-128.83466,0.00092674041,98.967255,96.992073,82.511017,0.51346719,-135.05109 -736763500,0.35123485,-129.25928,0.0020700546,29.475176,95.024834,79.143723,0.54678267,-134.62491 -737263000,0.35175273,-131.34148,0.0014881811,-10.626635,92.804504,75.970825,0.53745925,-136.86472 -737762500,0.34872591,-131.25154,0.0005756215,36.922401,90.986061,72.961258,0.54572314,-133.8271 -738262000,0.35179648,-131.85504,0.00046888276,-71.516312,89.107132,69.884171,0.54402369,-133.76752 -738761500,0.35105291,-133.24574,0.0012750722,-84.561249,87.21241,66.711815,0.5219661,-136.93846 -739261000,0.35637948,-131.50053,0.00081666594,106.95581,85.826294,63.496342,0.54909623,-134.21507 -739760500,0.35921565,-133.40184,0.00052937662,-127.60147,83.6511,60.527744,0.5368343,-136.17767 -740260000,0.35859543,-133.44922,0.0015886613,174.96286,82.281433,57.452801,0.5346067,-136.0475 -740759500,0.35617912,-134.07166,0.0022810351,-130.785,80.491135,54.135014,0.56579906,-138.17978 -741259000,0.36804497,-135.11974,0.000498757,-75.076035,78.441231,50.961369,0.51701915,-138.66856 -741758500,0.36444762,-135.31972,0.002185046,-126.19695,76.909317,48.040928,0.55670804,-136.20741 -742258000,0.37644601,-136.1376,0.00066298182,-108.24091,75.337967,44.858391,0.60946077,-136.78822 -742757500,0.37493363,-136.11478,0.0005651575,-125.22924,73.787422,41.881931,0.53490341,-138.94292 -743257000,0.37990755,-136.65672,0.00062205957,-62.982643,71.954681,38.520283,0.54976392,-139.20927 -743756500,0.38566187,-137.84828,0.0011606836,70.139854,70.671844,35.649181,0.55882001,-140.93202 -744256000,0.38692772,-138.04135,0.00099290605,3.6657929,69.072144,32.511471,0.52880383,-139.42282 -744755500,0.39144683,-137.31337,0.0030698103,157.39558,67.652924,29.472708,0.55275494,-139.04953 -745255000,0.38834086,-138.75066,0.0010225178,-158.46672,66.102867,26.451159,0.53559804,-140.44714 -745754500,0.39426535,-139.19264,0.0005150233,-123.64611,64.589821,23.385321,0.53758216,-135.33171 -746254000,0.39342222,-140.17332,0.0013401306,-49.668903,63.164043,20.288177,0.52903855,-140.86072 -746753500,0.40609339,-140.4505,0.0028600446,109.30939,61.888882,17.157869,0.56525296,-138.32268 -747253000,0.39866003,-140.13644,0.0018333804,-136.01123,60.662647,14.126614,0.56500047,-136.18167 -747752500,0.40300822,-141.66533,0.00073796569,71.946716,59.388897,11.07777,0.57181233,-138.02104 -748252000,0.40739536,-142.14816,0.00068273686,47.27536,58.005108,8.1057196,0.54009151,-139.30188 -748751500,0.41055107,-142.19289,0.00078159897,-131.8739,56.637661,5.0387387,0.58671331,-139.75143 -749251000,0.41512293,-142.74582,0.00071866805,124.3088,55.328987,1.9370445,0.54245794,-142.27806 -749750500,0.41398528,-143.6433,0.0010056774,32.59874,54.087719,-0.93066567,0.56099397,-141.43401 -750250000,0.41827336,-143.89484,0.00040906493,12.916712,52.802998,-4.1047788,0.59549683,-138.86955 -750749500,0.42149663,-144.10539,0.00163591,130.19942,51.681911,-7.1932888,0.55357403,-140.62379 -751249000,0.42068464,-144.62697,0.00044138156,-91.480026,50.556847,-10.229797,0.55707943,-140.60455 -751748500,0.42500803,-144.75076,0.0011084479,-110.85587,49.426342,-13.160299,0.6017043,-140.00504 -752248000,0.42788115,-145.52466,0.00088513794,171.52759,48.367619,-16.222805,0.58276087,-139.83273 -752747500,0.4264805,-145.76163,0.00023194928,79.899452,47.180439,-19.385418,0.57916993,-139.68201 -753247000,0.43014044,-146.57262,0.00078883505,-121.05896,46.070076,-22.241758,0.5783971,-143.30713 -753746500,0.42986768,-147.19908,0.00087483897,48.042046,45.118729,-25.253353,0.55414242,-141.62346 -754246000,0.43448561,-147.354,0.0010658075,-26.821413,44.180237,-28.168762,0.564282,-138.83543 -754745500,0.44250828,-148.21588,0.0026463817,-148.61203,43.068447,-31.089922,0.6087814,-140.90677 -755245000,0.44297367,-148.91164,0.0019045364,164.84912,42.102707,-34.191532,0.55046654,-141.36086 -755744500,0.43980855,-148.89679,0.00050847244,27.546152,41.08522,-37.32196,0.62630206,-144.92149 -756244000,0.44817191,-148.97705,0.00051648478,-103.05316,40.181057,-40.151787,0.58015132,-143.29472 -756743500,0.44697604,-149.68231,0.00043333453,-179.9071,39.119747,-43.070427,0.60011119,-142.81818 -757243000,0.44670159,-149.67137,0.0010008418,-8.006896,38.261444,-46.271858,0.56468701,-144.48996 -757742500,0.45091164,-150.61859,0.00047450495,108.69748,37.528988,-49.32798,0.59060955,-141.96863 -758242000,0.45075667,-151.29889,0.00084567064,75.258949,36.517742,-52.377472,0.60609633,-142.69542 -758741500,0.45215741,-151.36684,0.00038818212,158.46191,35.680435,-55.348049,0.58190978,-143.7206 -759241000,0.45535889,-151.98979,0.00073633285,-179.22711,34.775974,-58.221115,0.5422132,-146.80734 -759740500,0.4550854,-152.45618,0.00028887353,53.650093,33.872448,-61.280327,0.60438234,-143.97469 -760240000,0.46207848,-152.81497,0.00063527981,-110.81828,33.242409,-64.120407,0.58875823,-144.11063 -760739500,0.46289492,-152.62001,0.00067589839,61.927959,32.249832,-67.284592,0.60578042,-143.5544 -761239000,0.46364433,-153.83966,0.0012344514,172.14072,31.598951,-70.178444,0.58858502,-144.759 -761738500,0.46314681,-153.72729,0.00063489017,160.82863,30.833029,-73.175568,0.58016545,-145.81848 -762238000,0.46787995,-154.5322,0.00099396019,-31.911453,30.184422,-76.253098,0.59133285,-141.56578 -762737500,0.46942943,-154.20758,0.00042756161,78.14946,29.229755,-79.137489,0.60097259,-145.86775 -763237000,0.4747999,-155.5152,0.00016693072,-96.20652,28.644922,-81.943893,0.6184426,-147.66658 -763736500,0.47259131,-155.55714,0.001101426,27.039934,27.862745,-84.912193,0.59414482,-147.95723 -764236000,0.47362325,-155.71584,0.00050358061,134.334,27.166031,-87.988991,0.5898217,-146.5009 -764735500,0.477393,-156.52663,0.0014153697,-100.87875,26.500431,-90.963272,0.59974581,-147.13144 -765235000,0.48077261,-156.89005,0.00053130439,-102.31709,25.812717,-93.718414,0.61353785,-148.88963 -765734500,0.47842497,-157.15411,0.00089419581,-151.95427,25.146353,-96.716957,0.61394477,-147.35204 -766234000,0.4833329,-157.42624,0.0013363248,2.1184602,24.601639,-99.746986,0.59191716,-146.05397 -766733500,0.48269817,-157.87784,0.0013241958,-34.142227,23.900511,-103.01101,0.61218387,-145.86562 -767233000,0.48788905,-158.41751,0.0010126338,-48.5429,23.330891,-105.54442,0.59050721,-146.83347 -767732500,0.48553839,-158.82234,0.00094127917,-143.07771,22.721916,-108.51897,0.63582397,-148.1958 -768232000,0.48678815,-159.37885,0.0010812206,-155.74089,22.224672,-111.45353,0.59564227,-148.32191 -768731500,0.49331191,-159.51675,0.0011240018,11.736125,21.616537,-114.41182,0.60864228,-148.55544 -769231000,0.48866287,-159.69675,0.0012916698,6.7881646,20.991802,-117.4706,0.618312,-152.47672 -769730500,0.49318305,-160.0112,0.00075911282,-134.54184,20.513741,-120.32655,0.5954923,-143.90039 -770230000,0.49463487,-160.44514,0.00034863484,136.91945,19.977844,-123.05326,0.62662041,-150.70239 -770729500,0.49780032,-160.89136,0.0023557155,108.48901,19.484261,-126.03714,0.61243927,-149.37836 -771229000,0.50006616,-161.3978,0.00081415265,-12.143534,18.915981,-129.01874,0.61816478,-149.84753 -771728500,0.49819806,-161.3181,0.00049893785,22.970514,18.381289,-132.09113,0.61274165,-145.96637 -772228000,0.50094563,-161.741,0.00035655941,90.867653,17.86722,-134.77618,0.63131177,-151.4481 -772727500,0.49874818,-162.19679,0.00063824246,-154.49626,17.390537,-137.63461,0.61988419,-148.3801 -773227000,0.50572187,-162.85051,0.00075186248,-72.204536,16.921099,-140.66403,0.6169759,-149.90692 -773726500,0.50379986,-162.77072,0.0008762998,116.42178,16.479971,-143.50536,0.62950343,-151.80226 -774226000,0.50604248,-163.4691,0.0014602927,80.008713,16.070919,-146.39162,0.61024147,-152.44466 -774725500,0.50899404,-164.20625,0.0002930414,-121.56311,15.532662,-149.65843,0.62205267,-148.49962 -775225000,0.50565666,-164.49092,0.00096766319,44.221546,15.18156,-152.492,0.59684002,-154.22906 -775724500,0.50979942,-164.30421,0.00028628338,103.71854,14.714635,-154.81612,0.62758172,-151.62112 -776224000,0.50947791,-165.17133,0.00069778727,-63.376671,14.320039,-158.13507,0.62631875,-152.53743 -776723500,0.51339591,-165.47223,0.0012875631,-27.935381,13.866119,-160.78123,0.65420479,-153.59164 -777223000,0.51703012,-165.54091,0.00037730852,-81.127716,13.553148,-163.83482,0.63852584,-150.38242 -777722500,0.51246053,-165.46123,0.00065524486,-125.80042,13.078842,-166.39282,0.6533165,-151.27852 -778222000,0.51404279,-166.33971,0.00033823322,-144.79494,12.716311,-169.69159,0.63405889,-150.85437 -778721500,0.5150339,-167.16765,0.0011171622,-97.880775,12.279705,-172.56065,0.6642276,-153.23827 -779221000,0.51975214,-166.87073,0.0015166475,-168.78603,11.926192,-175.11125,0.62946111,-153.05145 -779720500,0.51632154,-167.11128,0.00075375178,47.75053,11.597388,-178.21823,0.64236778,-153.52057 -780220000,0.52731937,-167.93367,0.001689971,-65.986061,11.34737,179.27225,0.63483071,-154.66356 -780719500,0.52574253,-167.7092,0.00037266809,126.61959,10.932884,176.70415,0.63535446,-153.90457 -781219000,0.51880139,-168.71808,0.0011196925,149.78537,10.591352,173.44537,0.6163615,-154.60133 -781718500,0.52161896,-169.03455,0.00016219525,-177.34274,10.288074,170.80841,0.62662542,-154.967 -782218000,0.52791774,-169.08681,0.0014664322,-2.1102383,9.8805876,167.91978,0.62950152,-153.0088 -782717500,0.52736825,-169.65298,0.00024046784,-83.794502,9.6144829,165.15082,0.64841688,-152.60455 -783217000,0.53097206,-169.71268,0.00029982216,39.483284,9.370225,162.75012,0.62953818,-155.62289 -783716500,0.53174704,-170.13681,0.0014773848,36.140411,8.9985924,159.53958,0.6411562,-152.10402 -784216000,0.52973598,-171.21645,0.001008646,50.409332,8.7491293,156.83923,0.65023309,-155.38695 -784715500,0.53025621,-170.53181,0.00054917694,-102.41859,8.4305906,154.67079,0.65908235,-154.64143 -785215000,0.53677171,-170.99518,0.0005705881,-28.486403,8.1566887,151.32256,0.6208086,-154.22284 -785714500,0.52773529,-171.54024,0.00093639822,98.275444,7.9302058,148.40419,0.64198458,-157.14877 -786214000,0.53649622,-171.93051,0.00019219515,105.09976,7.664001,146.14076,0.64546317,-154.39268 -786713500,0.53436738,-172.29353,0.00043467534,57.053619,7.4121594,143.54807,0.65368086,-155.99809 -787213000,0.5353508,-171.47884,0.00044066165,5.6697383,7.122282,140.96794,0.67508745,-158.17036 -787712500,0.53586668,-172.97733,0.00059929449,52.360813,6.8839746,138.71605,0.64964718,-156.13173 -788212000,0.53927463,-172.88144,0.0005571954,-43.802834,6.6626706,135.86719,0.67948598,-156.32533 -788711500,0.53820324,-173.39224,0.00065789459,-80.702049,6.4239988,133.03452,0.6597684,-157.05241 -789211000,0.54407156,-173.28967,0.00080584461,86.794319,6.1980457,130.15096,0.6300649,-155.54747 -789710500,0.54254246,-173.83778,0.0012709082,36.867668,6.0072775,127.5229,0.66925114,-158.39873 -790210000,0.54546958,-174.85336,0.0013475285,78.878632,5.7517142,125.48386,0.64200544,-158.9362 -790709500,0.54479378,-174.13123,0.0013575031,-146.3933,5.6024947,123.09228,0.64128405,-158.50262 -791209000,0.5464648,-175.06664,0.0016465223,-163.53836,5.3882103,120.30578,0.64875972,-156.52516 -791708500,0.54636794,-174.92198,0.00079395314,-115.72451,5.1985803,118.19045,0.65213388,-159.80313 -792208000,0.54081029,-175.04924,0.00069085823,-85.08445,4.9729524,115.73992,0.65525931,-158.78992 -792707500,0.55001694,-175.76367,0.00098867062,48.770161,4.7998972,113.82359,0.67913175,-157.85329 -793207000,0.54914188,-176.25797,0.00067038031,-110.59331,4.5621405,111.19674,0.70349085,-159.34293 -793706500,0.55035943,-176.60817,0.00069786148,-157.83185,4.4688525,108.09158,0.66152698,-157.59525 -794206000,0.54967326,-176.81873,0.00044479908,47.765907,4.2454886,106.07443,0.67530859,-158.341 -794705500,0.55007005,-177.05135,0.0015077601,-1.4198415,4.1261678,104.12305,0.6552282,-161.37454 -795205000,0.54773498,-177.90686,0.00032616273,-14.048192,4.0019145,101.01011,0.66355091,-161.31726 -795704500,0.55824715,-177.45544,0.0020937175,106.06124,3.8500674,99.776337,0.66819894,-158.89848 -796204000,0.55489522,-177.34863,0.0015036021,-21.323862,3.721041,97.054169,0.68339473,-159.20726 -796703500,0.55347586,-178.47495,0.00099785079,161.73004,3.542625,95.555763,0.66952062,-160.98474 -797203000,0.55808824,-178.55383,0.0025611655,-93.165321,3.40766,92.73954,0.66910028,-163.11241 -797702500,0.55819565,-179.16583,0.0005258937,-68.514717,3.268321,90.534203,0.68603867,-162.58159 -798202000,0.55769145,-179.40752,0.00098393147,-76.457565,3.108243,89.201607,0.66809863,-161.96384 -798701500,0.55768621,-179.49518,0.0013752988,146.48584,2.9831684,87.790924,0.67766207,-163.44473 -799201000,0.55527318,-179.71729,9.5128191e-005,-175.25323,2.8360045,85.675056,0.6926074,-163.66145 -799700500,0.55634141,179.94376,0.00072068122,-5.9092836,2.8024271,84.277145,0.67809796,-162.1378 -800200000,0.55718136,179.43257,0.00095755892,-33.04858,2.6764212,81.011414,0.66024423,-162.84753 -800699500,0.55946404,179.60347,0.00033709631,-94.189201,2.6444418,80.642479,0.68494534,-162.04391 -801199000,0.55982018,179.01978,0.0016269952,-126.85601,2.5177627,78.909073,0.67465454,-163.59203 -801698500,0.56000918,178.77315,0.00039216437,73.01989,2.4306443,76.738777,0.66542888,-163.49405 -802198000,0.56036222,178.5112,0.00096729421,-70.014305,2.3272347,74.547714,0.64477605,-163.44609 -802697500,0.56424004,177.60078,0.0024595161,143.13777,2.19186,72.640556,0.65985721,-162.28192 -803197000,0.56539446,177.56442,0.00093405467,-127.34364,2.1996739,71.765427,0.66165745,-162.43094 -803696500,0.56398475,177.18474,0.00076769339,169.71753,2.0800698,72.200623,0.66048843,-163.87846 -804196000,0.56474972,177.34761,0.0010123072,-123.86073,1.9637252,69.538391,0.65731543,-163.20584 -804695500,0.56533998,176.70012,0.00088545232,-35.786301,1.9684284,67.716423,0.6608696,-167.25378 -805195000,0.5656606,176.73376,0.0010336692,99.862015,1.8736,69.81514,0.68429923,-164.7766 -805694500,0.56508785,176.36041,0.0018479668,178.89198,1.8146068,64.306442,0.69292116,-165.7809 -806194000,0.56648695,175.71286,0.00026541072,96.72525,1.7803179,65.264557,0.67869824,-165.12997 -806693500,0.56873721,175.74738,0.00071808189,-14.668318,1.6967534,64.461609,0.69630051,-168.1178 -807193000,0.56849241,174.9782,0.00093024183,29.569078,1.6733376,61.491646,0.67530918,-165.68648 -807692500,0.56869107,174.88354,0.0009259365,-85.420334,1.5724591,63.104187,0.6762886,-166.95741 -808192000,0.56788611,174.8302,0.00051716121,-96.338402,1.561728,61.769527,0.6753819,-167.42313 -808691500,0.56941569,174.35651,0.0016233007,-171.73186,1.5284176,58.989708,0.68563211,-165.4034 -809191000,0.56947207,174.01921,0.0021291049,41.940559,1.5033895,61.854725,0.68807012,-167.75763 -809690500,0.57005888,173.65363,0.00063882512,100.49657,1.4876069,58.140675,0.68544793,-167.19499 -810190000,0.57376027,173.77937,0.0023178526,33.906105,1.4517301,57.784084,0.68055487,-166.94093 -810689500,0.57326096,173.2132,0.00042006082,144.26003,1.3317021,57.77375,0.69861627,-167.7356 -811189000,0.57378405,172.79784,0.00028802967,-135.36543,1.3346419,57.362267,0.6781559,-167.06308 -811688500,0.57368976,172.54483,0.0014342394,26.730436,1.3374665,52.295074,0.69344324,-167.85228 -812188000,0.57262486,172.52226,0.0020207039,158.61121,1.324626,52.38287,0.69634753,-169.05707 -812687500,0.57097,172.23627,0.00079391379,-32.001869,1.3144987,52.512184,0.6960842,-166.93707 -813187000,0.572963,171.97319,0.0016804164,-9.8280964,1.2837367,52.62027,0.69213343,-167.05504 -813686500,0.57850242,171.6147,0.0014173061,38.862629,1.2363192,50.125896,0.68823898,-166.63222 -814186000,0.57525951,171.17819,0.0015641802,114.89055,1.263509,47.826866,0.66798842,-171.66159 -814685500,0.57235187,171.05426,0.00064388133,-107.87305,1.2425017,49.899036,0.70881003,-170.80441 -815185000,0.57381648,170.47301,0.0024552618,63.986771,1.2425095,47.305595,0.67030901,-170.20152 -815684500,0.57115167,170.24138,0.0019372773,30.170513,1.2487321,44.481281,0.69210845,-170.6819 -816184000,0.57397622,170.20172,0.0016328166,-169.47,1.2041737,42.720676,0.68320709,-171.04312 -816683500,0.57670057,169.6937,0.0002627683,-99.05397,1.1580608,40.207191,0.68609172,-169.64749 -817183000,0.57798702,169.42865,0.0017490707,41.56702,1.2213635,38.760197,0.68519527,-173.54761 -817682500,0.57948714,169.13397,0.00042981782,-176.6096,1.1437684,40.86879,0.72763103,-170.81117 -818182000,0.57897961,168.85571,0.00061060808,61.13966,1.1592118,34.65353,0.70512521,-169.99469 -818681500,0.57952386,168.66141,0.00040940908,32.620911,1.1665096,35.6576,0.67882901,-171.61192 -819181000,0.57872492,168.22234,0.0019800758,10.933147,1.1204209,32.321045,0.70498091,-172.31056 -819680500,0.5810343,168.09077,0.0011478629,131.3914,1.1542563,31.088692,0.70861918,-174.33046 -820180000,0.58035886,167.72707,0.0020533572,-171.94347,1.0953991,29.166328,0.69746482,-174.19379 -820679500,0.5842042,167.45174,0.0014018331,129.34274,1.1114,25.488823,0.66449022,-174.0806 -821179000,0.58273232,167.01276,0.0010497231,-50.224037,1.0738695,26.532434,0.68039739,-171.30467 -821678500,0.58059341,167.00171,0.0027485881,-109.84447,1.1136423,25.881247,0.67769045,-173.06036 -822178000,0.57914984,166.53003,0.001431354,69.354485,1.0647641,24.102568,0.66760403,-174.81013 -822677500,0.58233923,166.24551,0.00021847643,-96.060051,1.1118232,19.704025,0.69914544,-173.64262 -823177000,0.58516741,166.28415,0.0013552189,73.303879,1.0197893,16.614754,0.69258457,-172.1467 -823676500,0.58023745,165.70392,0.00064639916,13.392693,1.0759393,14.250968,0.6845367,-176.9841 -824176000,0.58186579,165.68727,0.00076476409,21.764647,1.0660399,12.65484,0.70556736,-175.92867 -824675500,0.58316123,165.43622,0.00073454413,73.920731,1.0043137,7.6459894,0.68564409,-174.15263 -825175000,0.58287799,164.91249,0.00092004333,148.44408,1.0135404,6.853632,0.68029553,-175.79263 -825674500,0.58381802,164.6105,0.0010910996,-95.179634,1.0221112,6.546772,0.70853162,-172.97661 -826174000,0.58594769,164.21951,0.0005100714,74.055626,0.99206716,6.6781101,0.69246632,-175.49821 -826673500,0.58520728,164.20792,0.0014888517,-28.617262,1.0029752,0.43155333,0.70740527,-176.5444 -827173000,0.58544886,164.01875,0.00067406241,132.02518,0.98579752,-1.250607,0.69001174,-176.80321 -827672500,0.58598411,163.92535,0.001503972,0.84106511,0.93825603,-1.5489634,0.7040931,-175.43993 -828172000,0.58897823,163.14732,0.0011319298,-64.984245,0.91846919,-5.3202028,0.69452494,-177.38524 -828671500,0.58571523,163.03581,0.0010705992,-25.163349,0.9146958,-6.7859759,0.68100017,-176.4243 -829171000,0.59035516,162.7657,0.00037547393,-174.43468,0.89074785,-7.8093872,0.6931957,-176.78383 -829670500,0.58784246,162.60907,0.00046982765,50.912891,0.91085869,-10.47405,0.66069847,-178.2737 -830170000,0.58746153,162.12117,0.00090027618,-139.42854,0.92758632,-12.653564,0.71633428,-178.44116 -830669500,0.58715403,161.86896,0.00062199164,-155.95573,0.84532398,-17.549206,0.68270159,-176.61656 -831169000,0.58889443,161.68837,0.00089957198,-31.462786,0.88394833,-19.066984,0.70780051,179.92714 -831668500,0.58591163,161.32898,0.00087826763,-45.056591,0.82878011,-22.157688,0.68783182,177.23941 -832168000,0.58630508,160.82791,0.0016076567,29.55887,0.8052156,-27.305624,0.69863617,179.47728 -832667500,0.58854645,160.92563,0.00041848866,-75.960205,0.91280627,-25.793938,0.6929881,-179.14624 -833167000,0.58330262,160.63489,0.0011802883,-145.21388,0.79692346,-29.099377,0.70288301,178.6051 -833666500,0.58993506,160.00954,0.00091672078,2.4931877,0.80604261,-29.881401,0.6987105,-179.1826 -834166000,0.5865227,160.07401,0.00065533421,-12.800598,0.76221842,-32.156284,0.69079328,179.66327 -834665500,0.58981621,159.45451,0.000252167,4.4582863,0.69300616,-34.766121,0.69038063,177.78915 -835165000,0.5912891,159.2845,0.0023733128,4.6267085,0.74033844,-36.406128,0.67882276,179.34628 -835664500,0.59035438,158.92834,0.00084874034,83.360489,0.71933931,-38.224709,0.69924945,179.70493 -836164000,0.59067959,158.90657,0.0011236919,9.3990669,0.68150979,-40.959988,0.6877805,179.11507 -836663500,0.58908075,158.78452,0.0017334098,68.768036,0.68896747,-44.658802,0.6694389,178.76019 -837163000,0.59249216,158.12534,0.00051580806,-118.91151,0.66660106,-44.911816,0.67063308,176.22595 -837662500,0.59213305,157.95241,0.00070008961,128.92122,0.678734,-47.907448,0.71380472,178.03383 -838162000,0.59227836,157.64679,0.0013017682,-170.59081,0.67910898,-51.29541,0.69864124,178.48636 -838661500,0.59034193,158.10518,0.00037340153,41.823765,0.65864909,-53.407444,0.70326322,176.56033 -839161000,0.59172457,157.18707,0.00086077471,-166.88542,0.63987315,-60.983898,0.67499882,176.96902 -839660500,0.5958308,157.01695,0.00087866635,-100.91739,0.62389821,-57.856968,0.67454165,176.3777 -840160000,0.59683716,156.8049,0.0021275708,-173.20296,0.63409352,-62.444744,0.69516057,176.02463 -840659500,0.5923667,156.60068,0.00084803277,-13.660331,0.5905838,-63.203957,0.69189787,173.86198 -841159000,0.58863777,156.55194,0.00074569002,-12.109038,0.58047718,-66.71682,0.68340462,174.62228 -841658500,0.59095484,155.83031,0.001248817,-121.04534,0.5934096,-69.050957,0.70402157,175.87036 -842158000,0.59409755,155.47198,0.0019196868,-100.17838,0.54856974,-70.788467,0.68753833,176.3506 -842657500,0.5946908,155.27466,0.0015776837,130.81416,0.52672386,-73.39769,0.68145221,174.86679 -843157000,0.59219122,155.33133,0.00042584029,-78.21608,0.50441754,-78.523766,0.69603968,175.6627 -843656500,0.59052753,154.77121,0.0015252356,-160.96773,0.55600172,-79.092598,0.68769544,174.9982 -844156000,0.59591472,154.45625,0.0015230136,-143.58398,0.55532855,-79.015831,0.68484771,174.69394 -844655500,0.59647381,154.24635,0.00061231543,-137.90405,0.50416386,-81.138046,0.68702054,172.0914 -845155000,0.5904544,153.74677,0.0012715152,69.325111,0.50480884,-80.22477,0.69046789,171.11433 -845654500,0.5923298,153.61447,0.0010346039,23.574862,0.48232079,-85.654839,0.68620455,171.26755 -846154000,0.58636278,153.5864,0.00055011234,113.79885,0.50197679,-87.87088,0.67229038,172.27547 -846653500,0.59521663,153.45311,0.0015158802,169.84477,0.45169574,-90.840393,0.68775457,171.39314 -847153000,0.59317303,153.1617,0.00021349592,106.88527,0.45576099,-96.771713,0.68472213,172.2612 -847652500,0.59241313,152.47243,0.00087686843,50.92416,0.41205344,-97.654243,0.67642474,172.57095 -848152000,0.59276789,152.64273,0.0010129529,-57.490891,0.42053786,-98.912323,0.68528545,171.81931 -848651500,0.59556454,152.58382,0.0016268658,177.155,0.40639424,-100.45141,0.69173586,172.53871 -849151000,0.59646231,152.01787,0.00029981643,121.90216,0.38363039,-106.50221,0.68897331,173.83173 -849650500,0.59819108,152.0966,0.00034251099,-67.362381,0.40237787,-103.19654,0.6809172,172.05214 -850150000,0.59678334,151.82202,0.00081804727,-145.76483,0.39622709,-112.46586,0.67494583,168.73546 -850649500,0.59378803,151.47807,0.00097502902,-98.060799,0.39991572,-111.34577,0.67106968,171.86821 -851149000,0.5956381,150.64133,0.00046820231,-134.50198,0.34392202,-106.8695,0.64639544,169.66794 -851648500,0.59649879,150.44522,0.0014682394,55.319603,0.34258115,-113.33318,0.65908444,169.18932 -852148000,0.59548533,151.02695,0.00085619878,-53.078323,0.35130197,-112.99107,0.66096711,169.61014 -852647500,0.59114385,150.28812,0.00082490715,-33.35603,0.31994012,-118.21149,0.65274781,165.70578 -853147000,0.59833544,149.93022,0.00094726041,34.608349,0.36759228,-117.90212,0.66240686,169.57056 -853646500,0.58902884,149.85667,0.00097275298,108.18211,0.3405591,-125.09621,0.67242342,166.99243 -854146000,0.59287691,149.608,0.001304232,-45.989525,0.3123686,-123.95901,0.65361905,168.6698 -854645500,0.59406948,149.33475,0.0010303648,-39.413578,0.26909554,-126.33499,0.68438357,169.8717 -855145000,0.59690899,149.18745,0.0022805752,20.153151,0.29356131,-127.52715,0.6735211,167.62338 -855644500,0.59365362,148.55927,0.00096123148,-93.115929,0.26528373,-130.72231,0.64309365,168.21236 -856144000,0.59421146,148.52956,0.00095852854,3.7387257,0.2338337,-134.73306,0.66053849,167.58144 -856643500,0.59607637,148.17464,0.0015572662,-118.60488,0.30895826,-128.46887,0.67552227,165.99857 -857143000,0.59556264,148.13182,0.00068716245,-170.56166,0.26050955,-138.39197,0.66786259,165.84911 -857642500,0.59302545,147.8167,0.00088766916,124.5241,0.25423032,-137.31177,0.65170085,167.38277 -858142000,0.59515601,147.73792,0.002371337,-68.664284,0.2640357,-141.93513,0.65310812,164.86555 -858641500,0.59649968,147.52913,0.00082504924,-83.417511,0.2562179,-134.51321,0.66977251,163.37856 -859141000,0.59249419,146.94383,0.0012293985,-21.415234,0.22674064,-143.64085,0.64042568,164.03336 -859640500,0.59108138,147.57855,0.0010978013,45.293503,0.20454188,-140.61076,0.65896672,163.53389 -860140000,0.60057455,146.4149,0.0012403126,-142.12547,0.2302916,-144.96547,0.65937686,163.5748 -860639500,0.59788603,146.44156,0.00071947253,-176.52032,0.19101553,-136.3929,0.65594065,163.95255 -861139000,0.59237438,146.45082,0.0010490109,-134.54507,0.20247978,-142.74432,0.64890385,162.32393 -861638500,0.59833992,146.17577,0.0020886117,154.08386,0.16079706,-153.46527,0.63985229,165.4039 -862138000,0.59784752,145.39272,0.00022799407,110.83952,0.19878784,-152.43233,0.65736884,161.58751 -862637500,0.59615624,145.2713,0.00088755722,-3.5559633,0.23207361,-151.10776,0.63857961,162.77245 -863137000,0.59791195,145.15331,0.00077788642,61.643208,0.19035338,-157.50143,0.63319999,163.40446 -863636500,0.59856552,145.17999,0.000393116,-10.86112,0.18077783,-158.62358,0.66820288,162.41284 -864136000,0.5950622,144.69815,0.0014187747,-29.742203,0.19047472,-150.69551,0.63759881,164.79967 -864635500,0.59895921,144.32884,0.0007332447,-28.069632,0.13565713,-159.90524,0.64723778,161.78729 -865135000,0.59888089,144.47298,0.0001227974,-92.825539,0.14899504,-155.94888,0.61884958,163.3 -865634500,0.59823644,144.24762,0.00067476608,-10.649015,0.14268485,-166.89688,0.64028108,159.12526 -866134000,0.59907806,143.71748,0.00084839872,-108.49906,0.14368024,-172.6039,0.62891394,163.26103 -866633500,0.60237229,143.58073,0.00099079218,172.94037,0.14882632,-160.26135,0.6053496,161.75848 -867133000,0.59005409,142.95888,0.0011288732,-57.456432,0.1388281,-157.39891,0.62619209,160.04968 -867632500,0.59261876,143.09723,0.0013375456,-85.637215,0.16681904,-169.62038,0.66846579,159.58493 -868132000,0.59810758,142.70586,0.0013969619,160.3291,0.16064319,-168.81784,0.63995552,158.76366 -868631500,0.59396154,142.70288,0.0010927151,-170.89313,0.14102168,-175.12115,0.64234054,160.53383 -869131000,0.59719366,142.18477,0.0011438297,-176.93034,0.10622393,-178.61952,0.66121709,159.68839 -869630500,0.59815955,141.98042,0.0012635886,-106.41353,0.13029455,-166.52792,0.65269065,156.89015 -870130000,0.59635437,141.36847,0.001902211,-167.25548,0.14445382,-178.62512,0.65998954,158.92052 -870629500,0.59529799,141.63739,0.0005200312,-106.5465,0.11548696,-177.01273,0.61677057,156.53117 -871129000,0.59672982,140.77371,0.00056007411,-73.098862,0.14058189,178.45781,0.61093158,158.48734 -871628500,0.59492207,140.92868,0.00072317716,-120.80481,0.10346002,166.99644,0.62310499,157.5278 -872128000,0.596241,140.6199,0.00044470761,25.405556,0.092924871,164.22969,0.62035459,160.83353 -872627500,0.59689134,141.1046,0.00079955719,87.543053,0.12102072,-178.16103,0.63253063,157.88249 -873127000,0.59437901,140.35854,0.00028004794,158.04306,0.088352293,179.81511,0.62211788,157.68396 -873626500,0.59834403,140.70006,0.001296773,-103.09944,0.11793357,-179.05196,0.61748224,159.32912 -874126000,0.59476757,140.31291,0.001020027,-112.26611,0.10119888,177.81271,0.60908961,156.5052 -874625500,0.59568071,139.96846,0.00010973451,-162.67101,0.095674537,-169.85167,0.62448877,157.43367 -875125000,0.59201068,139.59164,0.001112777,83.519043,0.072113574,162.91867,0.60921305,155.6637 -875624500,0.59328038,139.4418,0.00055455155,-42.406406,0.099247262,171.49123,0.6177606,154.43112 -876124000,0.58729941,139.37064,0.0017288423,-126.10988,0.10840565,159.47421,0.61177731,157.13608 -876623500,0.59923065,138.71494,0.00064772164,170.64801,0.11834271,173.46474,0.59562665,155.65915 -877123000,0.59254193,138.4361,0.00041977875,63.632706,0.081153095,167.26292,0.60494906,154.45169 -877622500,0.59537274,138.38368,0.0023137159,19.190672,0.083533645,173.99281,0.59138602,155.592 -878122000,0.59230304,137.879,0.00036582715,168.24405,0.1069731,165.61298,0.61513156,151.51659 -878621500,0.59557533,137.54282,0.0014547427,-117.85731,0.095520146,-174.39865,0.63174695,154.13336 -879121000,0.59381533,137.53452,0.00054574339,-23.522278,0.12246888,167.53386,0.58453178,154.56984 -879620500,0.58809745,137.04483,0.00026267581,-101.2487,0.070460707,169.16142,0.63576585,155.90633 -880120000,0.58845288,137.42067,0.0020131597,-131.14462,0.082877465,161.5183,0.60507447,150.86458 -880619500,0.59661955,137.01062,0.0007665226,54.147335,0.10273445,141.68138,0.56533998,154.25694 -881119000,0.59185457,136.77991,0.001928173,-5.6275196,0.10046703,166.93254,0.59745514,152.76688 -881618500,0.59022355,136.52521,0.00042418839,-42.829147,0.051572178,172.59158,0.61178863,150.66646 -882118000,0.59388578,135.80946,0.0018340603,110.90328,0.065077402,172.49991,0.58711636,151.71898 -882617500,0.58871776,136.32005,0.00075930334,-167.92209,0.093556061,157.62915,0.58955657,151.68805 -883117000,0.59198123,136.1636,0.0016949198,-10.797927,0.086151585,154.65591,0.57170928,152.26086 -883616500,0.59664857,135.50926,0.00085801398,100.18431,0.093951494,143.31747,0.60237247,150.92621 -884116000,0.58862686,135.2614,0.0007974754,-100.61784,0.070117764,159.70799,0.60213882,153.57878 -884615500,0.59323144,135.70766,0.00050958729,-95.498978,0.13517246,144.74092,0.62647027,150.70502 -885115000,0.59144235,134.70073,0.00079408212,32.100853,0.073046155,156.20229,0.58896703,152.90215 -885614500,0.59208757,134.76894,0.00032794266,-11.584755,0.052201271,169.67026,0.59653991,149.62276 -886114000,0.5908854,134.52531,0.0002771228,78.994934,0.095856562,145.81827,0.59606856,148.60855 -886613500,0.58367264,134.18243,0.0010240735,54.712379,0.10533288,166.65427,0.57536405,149.60899 -887113000,0.59389234,134.52907,0.0019352919,164.88525,0.073215298,158.03622,0.58458632,151.56264 -887612500,0.59132314,133.75142,0.00065293559,-151.95961,0.079950131,146.20868,0.56610101,151.50946 -888112000,0.59221071,133.4063,0.00060996518,-171.80278,0.076696619,131.75227,0.59026861,147.83775 -888611500,0.5888862,133.38554,0.0011913601,-132.49431,0.061833207,141.07339,0.56264287,149.35483 -889111000,0.59126431,132.8457,0.0008830055,-159.87759,0.053552937,134.04147,0.59465027,146.18715 -889610500,0.58778846,132.72318,0.0020333629,115.0484,0.059915904,137.75284,0.56331509,148.16859 -890110000,0.58729082,132.40169,0.0011651866,116.51179,0.052174442,128.83063,0.58811706,147.79057 -890609500,0.58971643,132.34245,0.000595966,142.32132,0.072478808,113.965,0.57443827,147.67198 -891109000,0.5904054,131.98033,0.0010766611,62.30508,0.061006602,138.19946,0.56868458,147.14648 -891608500,0.5885632,132.0363,0.0012687263,-2.9727252,0.066040665,136.84734,0.57422239,146.14209 -892108000,0.58797008,131.58005,0.0015490701,48.555603,0.05450438,111.83061,0.56414062,149.6151 -892607500,0.58735001,131.4978,0.00015647765,-102.43226,0.054077342,146.87482,0.58313763,146.73801 -893107000,0.59133244,131.18462,0.00093754451,-128.06062,0.05421707,128.97995,0.56493884,146.4873 -893606500,0.58796287,131.20799,0.0018341647,145.0493,0.061352957,135.198,0.57875419,145.73869 -894106000,0.5856607,130.77008,0.00098883396,-140.8679,0.035365257,166.25352,0.53462017,146.49414 -894605500,0.58924198,130.50552,0.0012125259,-86.956337,0.051157814,86.396523,0.55517918,143.93059 -895105000,0.59102434,130.36258,0.00090182316,-125.6796,0.063478455,132.7002,0.56999409,143.49937 -895604500,0.58714044,129.93822,0.00023487821,-151.85121,0.08634986,80.425316,0.56058878,144.60603 -896104000,0.58543032,129.59158,0.00099414296,61.810413,0.01755091,99.707458,0.56897521,143.81201 -896603500,0.58958417,129.76146,0.0021075872,12.606621,0.032484829,119.87319,0.57973963,144.05 -897103000,0.58584118,129.61754,0.00081206858,-11.979643,0.061201442,94.850754,0.54578376,141.66991 -897602500,0.58847618,129.23933,0.0013364441,-62.553638,0.049264286,102.99136,0.57309741,143.08585 -898102000,0.5856483,128.91327,0.0013119653,122.0425,0.0340086,108.90012,0.5525291,143.88614 -898601500,0.58591264,128.84727,0.0013964791,19.116056,0.041497786,55.32119,0.55673194,141.89035 -899101000,0.58530545,128.51013,0.0007862192,113.71977,0.044714626,130.58211,0.54565185,145.24565 -899600500,0.58411282,128.36221,0.00011359948,164.54259,0.065217681,112.34006,0.54522616,142.2202 -900100000,0.58686113,127.7612,0.0012942518,74.263214,0.046597876,108.06674,0.55726594,141.74028 -900599500,0.58119386,127.91057,0.00077050983,6.4910922,0.06707418,92.175797,0.52906388,143.11046 -901099000,0.5850662,127.59952,0.0015582854,152.74059,0.046031669,82.937935,0.54955459,143.98041 -901598500,0.58246386,126.74939,0.00092929631,10.278211,0.03589654,54.280476,0.53155851,145.77977 -902098000,0.5831582,127.2704,0.00081996719,-154.82492,0.028695958,50.999306,0.52954638,143.45415 -902597500,0.58498192,127.02061,0.0017288016,-53.831078,0.040188264,89.607178,0.52323449,139.71295 -903097000,0.58085835,126.35469,0.0013881427,113.60233,0.047896743,61.585964,0.54311734,139.0356 -903596500,0.58109778,126.17416,0.0006929629,-163.88924,0.068549536,38.438663,0.56804365,140.39529 -904096000,0.58176374,126.00883,0.00058092561,-100.62977,0.052930124,79.657631,0.55591315,139.18121 -904595500,0.58606619,125.98333,0.0015512491,-123.76257,0.0074286107,69.624046,0.54677588,139.8508 -905095000,0.58144182,125.78537,0.0016471146,-121.73912,0.041385487,60.920029,0.53257245,140.76483 -905594500,0.58020085,125.51994,0.0012431919,38.775318,0.01959216,69.970192,0.51027191,137.72523 -906094000,0.58210665,125.42171,0.00089874153,-66.815414,0.043155536,50.234669,0.5277403,139.91676 -906593500,0.58103573,124.98128,0.0016503382,-81.556458,0.047454532,87.773109,0.52317429,140.56577 -907093000,0.58070368,124.65778,0.00088373723,141.85333,0.036906224,60.980968,0.52280068,138.39464 -907592500,0.57957941,124.6813,0.0028294907,-174.1445,0.020327648,126.44202,0.52677155,136.50499 -908092000,0.58170027,124.44702,0.00093833951,41.712685,0.04476269,105.08972,0.52688193,139.15431 -908591500,0.57665545,124.06801,0.001280291,-143.13084,0.03540482,67.000977,0.54083019,137.79774 -909091000,0.57960808,123.73286,0.0016511766,-168.80429,0.04084494,118.5284,0.49969932,135.06187 -909590500,0.57822853,123.76273,0.00056340988,81.45752,0.032543842,99.705887,0.49907878,138.23001 -910090000,0.57628286,123.37051,0.00189413,122.46655,0.062786788,44.477406,0.51295394,136.2697 -910589500,0.57627809,123.36761,0.0016316018,52.576439,0.028945237,42.340275,0.51176566,137.5471 -911089000,0.57534683,122.85184,0.00093377195,-171.55797,0.024293184,-4.5783548,0.53148031,138.88376 -911588500,0.57841122,122.96712,0.001588195,115.90181,0.031654667,66.607803,0.50221658,138.28615 -912088000,0.57632989,122.74205,0.00094603177,146.79982,0.014558647,-176.5551,0.51122111,138.96709 -912587500,0.57698387,122.43744,0.00038178565,143.82603,0.036641192,36.411697,0.50407195,135.86859 -913087000,0.57531029,122.07283,0.0012044903,-71.458481,0.036662202,61.233917,0.50923252,134.89149 -913586500,0.57632673,121.90906,0.0014107228,-152.05948,0.043664481,48.176842,0.50929606,136.52831 -914086000,0.57837456,121.56826,0.00048752225,-121.36723,0.044999938,50.840443,0.4964554,136.61949 -914585500,0.57248122,121.61481,0.0010269909,-110.27595,0.045467891,38.793591,0.49251997,135.29167 -915085000,0.57335395,121.00816,0.0010446963,114.59718,0.043692552,125.99772,0.50545442,134.0098 -915584500,0.57489872,121.08826,0.00074496563,32.438129,0.0081352871,-40.457504,0.48027107,135.07506 -916084000,0.57399243,120.39565,0.00078545284,8.8929873,0.0062451554,-86.895454,0.48279801,132.10616 -916583500,0.57430255,120.52023,0.00014547441,91.024757,0.040314984,95.758278,0.49555671,135.51906 -917083000,0.57105207,119.90131,0.00047741947,-31.039341,0.038573723,25.957283,0.47992504,132.01585 -917582500,0.57230437,120.08258,0.0012505018,154.01794,0.014176705,75.35952,0.47947267,133.73323 -918082000,0.57052529,120.12566,0.00022749626,13.485472,0.026789796,-23.213268,0.49499679,132.41963 -918581500,0.57236797,119.5819,0.00084746233,116.19731,0.043972101,44.135406,0.47967768,134.55701 -919081000,0.56768161,119.1459,0.00087343331,145.78174,0.017918132,-13.576782,0.51700389,134.53333 -919580500,0.57015646,118.70616,0.0013212217,-108.15217,0.0057598664,83.10096,0.46893665,130.17705 -920080000,0.57014632,118.91178,0.0011476375,50.116676,0.036490131,-35.298824,0.48706618,132.92557 -920579500,0.56677508,118.77434,0.0014574137,107.29718,0.04391139,8.3560886,0.46923542,130.39407 -921079000,0.5694204,118.04166,0.00072289113,-173.44533,0.0055009075,-7.6694751,0.48279443,132.41156 -921578500,0.57017565,118.22413,0.0010461627,40.145588,0.032190185,7.8079658,0.48436439,132.84013 -922078000,0.56778526,118.07561,0.00056094438,-85.139465,0.015261613,92.824226,0.46464914,133.2216 -922577500,0.57173198,117.238,0.00082907791,36.116951,0.021059534,132.614,0.46817815,130.37253 -923077000,0.56388575,117.5635,0.0011819551,138.35864,0.016826324,84.679588,0.46612918,131.53288 -923576500,0.56711614,117.2361,0.00090360944,-26.422262,0.020676155,-13.237069,0.48561198,130.30739 -924076000,0.5666694,117.09563,0.00045494852,-154.70125,0.025382536,-57.067173,0.48477256,131.5262 -924575500,0.56501019,116.71561,0.00089308835,-67.94175,0.0034568536,-29.824739,0.4536632,127.50414 -925075000,0.56077892,116.31036,0.00071634271,30.862705,0.017870473,-7.1059427,0.49376664,131.67084 -925574500,0.56503087,116.26791,0.00068283849,-127.27313,0.023632169,48.94825,0.46902499,129.08383 -926074000,0.56492668,116.29569,0.00068845641,-15.343544,0.005833243,148.08728,0.48119956,127.2783 -926573500,0.56213313,116.12807,0.0015001893,107.29434,0.026518622,102.40808,0.44676948,130.7211 -927073000,0.56703216,115.5292,0.00044937106,-178.84122,0.015700748,105.64912,0.46311581,127.90167 -927572500,0.56434941,115.36339,0.00083375303,128.40964,0.022639506,-7.2716937,0.44870558,131.87849 -928072000,0.56083405,115.15312,0.00083492091,-132.32828,0.0031652555,86.504692,0.47014499,130.60638 -928571500,0.56214464,115.02135,0.0010934798,-176.31462,0.018673716,52.701458,0.47114524,128.3513 -929071000,0.56536144,114.44301,0.00012016876,-107.06207,0.019181568,7.2641068,0.47043899,132.24327 -929570500,0.5616703,114.48209,0.00078186399,1.4711748,0.022890002,-17.119823,0.44873357,127.58351 -930070000,0.5621469,114.02042,0.0014225397,37.529827,0.019614464,-124.73472,0.45212388,127.24246 -930569500,0.55835193,113.90561,0.00038713886,67.006195,0.015053669,-152.61221,0.44748402,124.87448 -931069000,0.56420583,113.85709,0.00083790673,56.500195,0.020395465,128.15189,0.43326384,127.57583 -931568500,0.55929935,113.4949,0.0026691239,49.898346,0.011872949,22.119478,0.44333678,126.56258 -932068000,0.55790526,112.79935,0.0029129856,-108.63914,0.017530967,30.652554,0.44188455,125.78671 -932567500,0.56114525,112.63863,0.0012527684,0.28609812,0.033792511,58.330391,0.42506906,128.22581 -933067000,0.55611813,112.69324,0.00029197923,-55.050892,0.031837739,57.683872,0.443645,126.7161 -933566500,0.55877233,112.66521,0.00071628595,63.178978,0.027043298,71.773109,0.46382388,127.88698 -934066000,0.55841106,111.97616,0.00012424024,-30.591455,0.0070584593,-22.485668,0.45747751,127.76955 -934565500,0.56422037,111.56062,0.0014620934,147.37253,0.013361309,13.264513,0.42282152,125.35658 -935065000,0.55524534,111.65733,0.001455277,-32.892105,0.031053448,113.64191,0.41860765,126.56376 -935564500,0.55206025,112.32572,0.00060648017,171.07471,0.019276584,-76.24839,0.44817385,123.37563 -936064000,0.55395758,111.45954,0.001072012,128.90887,0.009493364,-73.041176,0.45089707,124.62633 -936563500,0.55543727,111.24255,0.00075949967,12.895972,0.010429258,31.583088,0.43268594,125.38658 -937063000,0.55553907,111.2192,0.0020072809,-151.5687,0.01161454,47.108982,0.41717991,125.66474 -937562500,0.55146658,110.56853,0.00086479884,157.53975,0.0077347807,149.83665,0.40236044,123.98141 -938062000,0.55432528,110.18475,0.00062161236,-115.01047,0.020796167,22.516418,0.3998358,128.00426 -938561500,0.55731201,110.32886,0.00054449518,-25.868626,0.0168199,15.663089,0.43590218,122.64516 -939061000,0.54659665,110.1293,0.0011712146,-40.282501,0.026179692,49.597431,0.43452847,123.16077 -939560500,0.55010086,109.54797,0.00057229021,154.8976,0.016068032,137.61497,0.40849191,121.48624 -940060000,0.55314851,109.72723,0.0013033089,-77.892235,0.037974756,0.1764311,0.40354371,124.21925 -940559500,0.55298394,108.9732,0.00082327321,-148.03302,0.013028916,-26.606176,0.41005576,121.88246 -941059000,0.55394918,108.94119,0.0014673928,31.089762,0.032448202,-23.378273,0.42054603,126.00079 -941558500,0.54222894,108.83624,0.00088772806,21.894842,0.015866971,-14.728784,0.39894775,120.46464 -942058000,0.54708809,108.52822,0.00080057757,171.95279,0.013029202,-80.720329,0.41649267,126.25349 -942557500,0.55021739,108.38955,0.0013180421,130.4827,0.010055511,20.020941,0.43480375,122.93855 -943057000,0.54625875,107.92323,0.00064816611,-103.04362,0.032324616,33.800121,0.37926057,122.82993 -943556500,0.54908133,108.31066,0.00091371796,-21.983974,0.0059676426,42.676968,0.40293518,123.26096 -944056000,0.5459457,107.61111,0.0009189361,-80.555908,0.019715073,49.442444,0.39704537,120.77779 -944555500,0.54488403,107.27935,0.0012106667,-111.33186,0.021355197,-3.2134809,0.37990004,122.61652 -945055000,0.54506117,106.73917,0.0012686468,112.16917,0.015639335,-76.938316,0.40861237,119.35812 -945554500,0.54810554,106.66619,0.00062772864,-79.007545,0.017365845,84.878181,0.4187648,123.76659 -946054000,0.5446952,106.88237,0.00017664804,-115.84541,0.032439962,16.933422,0.41551206,121.40385 -946553500,0.54309314,106.30775,0.00092489581,69.180496,0.02302463,13.866122,0.400621,120.84293 -947053000,0.54465961,105.95183,0.0015629872,-105.14629,0.018405607,52.595314,0.39671439,120.92059 -947552500,0.54027545,105.82987,0.00060946093,120.78674,0.010975434,-13.934464,0.39853999,119.01743 -948052000,0.54172724,105.83685,0.00074362353,-40.375729,0.019263625,19.220421,0.40152565,118.17199 -948551500,0.5431084,105.60434,0.001280149,-144.00729,0.016385272,39.170853,0.40247723,118.3908 -949051000,0.5426842,105.17551,0.0018261295,-167.85104,0.012248226,116.02814,0.38712367,118.61633 -949550500,0.53884786,104.98768,0.00043110657,91.16732,0.01821379,77.478851,0.35895112,120.46293 -950050000,0.53726774,105.26978,0.00188841,-27.439329,0.0065116072,16.804142,0.37754032,118.82096 -950549500,0.5367828,104.57346,0.0005732493,-176.55179,0.0096949013,51.297436,0.36670136,116.91867 -951049000,0.53280574,104.53052,0.0014833838,-72.331947,0.017980419,44.814236,0.36813188,120.09639 -951548500,0.5335868,104.52852,0.00070561602,53.505978,0.02153096,70.62175,0.37144381,116.49446 -952048000,0.53876126,103.83702,0.00036290431,41.545471,0.010867394,149.08937,0.36644855,116.03275 -952547500,0.53937221,103.40037,0.00044541014,-58.47887,0.016493112,-31.860949,0.36348113,115.29935 -953047000,0.53588593,103.20871,0.0020144077,40.298637,0.037164845,-7.7898779,0.36275712,119.52534 -953546500,0.53327769,103.41911,0.0013086419,159.0687,0.022092247,-14.12541,0.38718221,120.16848 -954046000,0.53818005,103.14619,0.0024078949,-7.3421955,0.025225289,36.076733,0.37837672,118.48663 -954545500,0.53949279,102.58457,0.0018240047,-59.5051,0.033370472,-17.227884,0.36678362,117.51268 -955045000,0.53565693,102.05073,0.0012869989,137.8857,0.02122733,60.612507,0.38158351,116.90232 -955544500,0.5341782,102.33506,0.0014392985,102.16772,0.018727465,18.556282,0.36823618,119.15617 -956044000,0.53696984,102.44894,0.001404069,-88.599846,0.014751596,7.1762042,0.35987929,117.9473 -956543500,0.53180194,101.80138,0.0012030187,126.4903,0.022728423,45.346527,0.39196157,114.49991 -957043000,0.53185111,101.80752,0.0010246711,159.7072,0.037968356,35.249874,0.3597517,117.5023 -957542500,0.53330851,101.15179,0.0020218918,169.60205,0.012628409,63.250011,0.37194169,114.08392 -958042000,0.53009939,101.10996,0.00047205057,17.236252,0.03457997,32.887535,0.34671021,114.85358 -958541500,0.52753979,100.33623,0.0013086506,-125.72936,0.017663483,-52.029366,0.37186351,113.67649 -959041000,0.53245163,100.54671,0.0014172002,65.706299,0.011977284,-53.309834,0.34833252,111.69899 -959540500,0.52952451,100.24581,0.00086771767,147.37358,0.02817579,57.235909,0.34952053,113.51564 -960040000,0.52496135,99.977074,0.0021132254,101.90805,0.027995814,8.0673075,0.35428271,113.86898 -960539500,0.53135806,100.00401,0.0017474665,115.35948,0.018891146,34.601864,0.34733286,112.30206 -961039000,0.52634794,99.453102,0.0012370503,107.59202,0.008968981,-39.224262,0.34439272,111.43024 -961538500,0.52543604,99.544075,0.0017122104,-31.440256,0.027398886,-17.269484,0.33588409,114.98532 -962038000,0.52703637,99.17907,0.0011250152,14.692832,0.024197148,-33.005634,0.34008861,111.14743 -962537500,0.52492428,99.315636,0.0003293679,-124.76033,0.015315565,16.818871,0.34219652,114.70452 -963037000,0.52673727,98.855782,0.00063045573,-68.190353,0.0070498846,-159.22504,0.36467424,114.57245 -963536500,0.522089,98.593735,0.0019518696,29.567957,0.012024717,-42.840199,0.34741786,112.26063 -964036000,0.52619851,98.266777,0.00079077482,-56.324295,0.039757892,-31.784958,0.32676256,112.07624 -964535500,0.52732825,98.505112,0.00060849206,29.485603,0.015921991,-75.104202,0.35021722,109.92615 -965035000,0.52022111,97.735527,0.00083039608,-79.799637,0.012251575,-80.767181,0.34065637,113.41505 -965534500,0.51861358,97.193718,0.00094303628,-7.652339,0.020060709,-12.976713,0.33284891,114.01603 -966034000,0.52289104,97.334724,0.00014496724,141.38261,0.031767752,-47.362572,0.3309103,109.24153 -966533500,0.51639289,97.68544,0.00093769468,80.656021,0.040002298,-71.968239,0.32548657,109.62122 -967033000,0.51483303,96.648926,0.0016600598,-151.29312,0.027006697,-64.70356,0.33546817,110.50945 -967532500,0.51633394,96.645714,0.00055718725,75.835976,0.028675998,-45.265846,0.32334089,114.25697 -968032000,0.51840597,96.693436,0.00089421048,-14.73724,0.031085394,20.069712,0.31000975,114.36453 -968531500,0.51393479,96.038734,0.00041937266,124.36081,0.033528842,-72.726837,0.3327263,107.36226 -969031000,0.51466274,95.67482,0.00048197608,-40.987282,0.029991858,-48.431984,0.3124257,110.14889 -969530500,0.51512104,95.861977,0.00075815123,147.41125,0.026707083,-98.507561,0.32330737,110.0938 -970030000,0.51392668,95.232895,0.0018511508,-115.02631,0.026899086,-5.8113899,0.30597007,111.18346 -970529500,0.51710933,95.116837,0.0011911594,-14.165401,0.024169412,-93.336945,0.31101686,110.0838 -971029000,0.51214671,94.706871,0.0019468062,-65.42823,0.012317767,-138.58888,0.28269866,108.22246 -971528500,0.51486653,94.333755,0.0019789522,172.61285,0.010180344,-132.97661,0.30352011,107.94376 -972028000,0.51287371,94.620941,0.0013048991,-125.60337,0.016169291,129.62881,0.31409246,108.59017 -972527500,0.51409966,94.239288,0.0012487087,165.05568,0.025807457,-33.810493,0.33831331,107.81989 -973027000,0.51463538,94.194778,0.0011998509,-89.302139,0.013576195,-60.34359,0.31347036,110.10506 -973526500,0.50725895,93.390739,0.0014767668,87.329422,0.0092180669,7.7961497,0.29913941,105.26315 -974026000,0.50774485,93.657059,0.0010741906,139.68903,0.027379775,-100.5639,0.29618478,108.44871 -974525500,0.51039106,93.235802,0.0013654967,150.19237,0.010786279,-5.0184054,0.29495573,106.78403 -975025000,0.50834817,92.887619,0.00090477511,93.098206,0.031706352,50.753956,0.32507789,108.5635 -975524500,0.50941229,92.625351,0.00051749195,-65.010841,0.035807852,-48.603203,0.29681078,108.56355 -976024000,0.50437552,92.606407,0.00033423727,116.08065,0.013459198,-100.02655,0.31299105,105.21082 -976523500,0.505099,92.654373,0.0024854038,-150.80794,0.036011554,-39.595943,0.30053106,109.79047 -977023000,0.5067367,92.016907,0.001599217,51.486671,0.046980388,-120.8109,0.26968265,107.0428 -977522500,0.50537747,92.003372,0.0015341234,95.539673,0.035519429,2.9864516,0.28059024,105.4453 -978022000,0.50195616,92.06601,0.0001654434,92.254532,0.025149716,-11.812061,0.28593406,104.33272 -978521500,0.50018996,91.555984,0.0018162564,89.322746,0.022036707,-56.126801,0.29640162,104.05884 -979021000,0.50125343,91.028885,0.00068741926,120.82403,0.020691071,164.68721,0.29314634,104.07181 -979520500,0.49820429,91.282593,0.0013133783,43.955956,0.020644281,-97.988525,0.28088239,108.36946 -980020000,0.49990496,90.643784,0.00020972302,-16.962988,0.038172036,-106.20205,0.2819415,102.35171 -980519500,0.49938816,90.89373,0.00089637534,-123.57619,0.022979081,-97.868439,0.27366173,100.83282 -981019000,0.50024498,90.363052,0.0015963911,107.69216,0.021736523,-57.826492,0.25689182,101.97269 -981518500,0.49862659,90.011238,0.0018749837,-89.06881,0.023588546,-96.753014,0.26491693,102.17339 -982018000,0.49709153,89.925735,0.0018967591,-14.948014,0.01719594,-74.47802,0.26787618,100.11585 -982517500,0.4961718,89.503418,0.0012929672,25.317427,0.0050925217,-166.90115,0.27915984,102.22415 -983017000,0.49454314,89.416756,0.00059161591,143.69861,0.0078436099,-105.17831,0.25951868,100.45833 -983516500,0.4941529,89.039177,0.0010131219,85.876122,0.036470037,-77.469841,0.24869284,102.82336 -984016000,0.49414542,88.811409,0.00084036757,-40.430328,0.058046907,-66.69796,0.27119157,101.96161 -984515500,0.49606836,88.605598,0.0018755909,49.842075,0.010048683,-114.11134,0.26994276,103.47781 -985015000,0.49339047,88.159302,0.0013506777,-179.5984,0.029450823,-24.706509,0.25201964,104.1692 -985514500,0.48941574,88.071892,0.00089157716,36.593529,0.032647979,-107.99266,0.27706441,104.27041 -986014000,0.49054688,87.612679,0.0010827387,-177.20076,0.022055781,-19.638771,0.26985505,100.55962 -986513500,0.48907623,87.647949,0.00076509413,-147.86153,0.018366426,-129.5096,0.26909328,100.71655 -987013000,0.49098536,87.571495,0.00026932877,34.022911,0.0092492336,120.59338,0.26532099,99.07737 -987512500,0.48902711,86.919296,0.0012442404,117.64088,0.0085542724,126.19713,0.26155141,104.39926 -988012000,0.48839,86.456322,0.0013515642,-160.95956,0.011185626,-118.36512,0.25016969,99.867981 -988511500,0.48577669,86.627274,0.0018437764,-72.421852,0.026637278,-39.568764,0.28282699,95.996742 -989011000,0.48602274,86.420486,0.00048182029,150.80966,0.026164649,-87.093124,0.27351782,101.04333 -989510500,0.48437747,85.825043,0.00072636455,-97.315842,0.02906841,-60.63271,0.25707716,98.242264 -990010000,0.4843075,85.895386,0.0006500032,142.92622,0.02694037,-44.926033,0.27154467,100.57348 -990509500,0.48222026,85.240082,0.00068819686,-110.0176,0.0370881,-55.031563,0.25302917,98.121773 -991009000,0.48319563,85.575928,0.0014749448,-160.70255,0.028530346,-72.835274,0.23584208,95.546196 -991508500,0.48259819,85.028908,0.0013900603,-63.27161,0.02613651,70.205971,0.25694424,101.7973 -992008000,0.47973129,84.919418,0.00066857482,-110.2774,0.023932168,-88.423767,0.23194012,97.208061 -992507500,0.48361248,84.416725,0.0015656466,59.422592,0.031342708,-92.330978,0.24247029,93.556732 -993007000,0.47642794,84.617455,0.0015076795,176.4326,0.030007353,-65.672417,0.2373939,96.78894 -993506500,0.47891244,84.328293,0.00040212105,-171.28214,0.0050221309,-77.738663,0.23739456,98.456642 -994006000,0.47842216,83.762917,0.00039742378,107.21197,0.018439891,-98.391525,0.24229871,97.466919 -994505500,0.47617549,83.492729,0.0018126145,-135.84845,0.014859078,-124.30311,0.23402885,97.28405 -995005000,0.47949788,83.218605,0.0012584948,-110.35548,0.015242545,-118.26662,0.2449329,95.100967 -995504500,0.47549754,83.479843,0.00081386429,-88.620842,0.032702964,-19.171379,0.25144601,90.33638 -996004000,0.47474885,83.189209,0.00031009261,74.732124,0.016433503,-118.74989,0.22258018,91.670845 -996503500,0.47218952,82.796326,0.0015438757,93.762283,0.017324854,-147.8089,0.23115002,94.084702 -997003000,0.47587886,82.52021,0.0022984361,97.048767,0.037039418,-80.861916,0.23686048,93.119629 -997502500,0.47475693,82.239311,0.00094400917,-107.43743,0.01962526,-77.599007,0.22282074,91.471642 -998002000,0.47135127,81.953346,0.0023474973,-21.112204,0.025321184,-121.41735,0.23435779,94.639359 -998501500,0.46782768,81.763405,0.00055478665,-49.937565,0.021665456,-80.659012,0.22544126,92.23156 -999001000,0.46942616,81.728188,0.00090348552,77.059601,0.018264567,-91.075035,0.22155264,88.492081 -999500500,0.46980229,81.452988,0.00078029535,140.58897,0.038617399,-108.61705,0.21684964,95.229408 -1000000000,0.46783143,80.686089,0.00025315891,-146.85167,0.012748078,-50.618038,0.21918537,92.197845 diff --git a/NuRadioReco/detector/RNO_G/HardwareResponses/iglu_drab_placeholder.csv b/NuRadioReco/detector/RNO_G/HardwareResponses/iglu_drab_placeholder.csv new file mode 100644 index 000000000..f032139fb --- /dev/null +++ b/NuRadioReco/detector/RNO_G/HardwareResponses/iglu_drab_placeholder.csv @@ -0,0 +1,2002 @@ +Frequency [Hz],Gain,phase [rad] +1000000.0,0.09224962627195446,4.097896416020089 +1499500.0,0.06860348719297664,2.920677380244773 +1999000.0,0.048994958502161616,1.8820479484265884 +2498500.0,0.03309380748766739,0.9702071337205762 +2998000.0,0.020581803532475296,0.17375243695825882 +3497500.0,0.011152718114390059,-0.5183201533523585 +3997000.0,0.0045123248060396914,-1.116616161026788 +4496500.0,0.00037839927487562375,-1.63134262220406 +4996000.0,-0.0015192807168274286,-2.072308085346725 +5495500.0,-0.0014389353119713538,-2.4489226112408478 +5995000.0,0.00037321744136531443,-2.7701977729960126 +6494500.0,0.0036829615899273416,-3.044746656045322 +6994000.0,0.008268083275282917,-3.280783858145397 +7493500.0,0.013918370733823487,-3.4861254893763727 +7993000.0,0.020435614296763924,-3.668189172141907 +8492500.0,0.027633606390142465,-3.8339940411691726 +8992000.0,0.03533814153482065,-3.99016074350886 +9491500.0,0.043387016346483384,-4.14291143853518 +9991000.0,0.05163002953563883,-4.2980697979458595 +10490500.0,0.05992898190761872,-4.461061005762143 +10990000.0,0.06815767636257784,-4.636911758328792 +11489500.0,0.07620191789549471,-4.830250264314089 +11989000.0,0.08395951359617088,-5.04530624470983 +12488500.0,0.09134027264923127,-5.285910932831334 +12988000.0,0.09826600633412436,-5.555497074317436 +13487500.0,0.10467052802512179,-5.857098927130486 +13987000.0,0.11049965319131874,-6.193352261556355 +14486500.0,0.11571119939663335,-6.566494360204422 +14986000.0,0.12027498629980762,-6.978364018007608 +15485500.0,0.12417283565440647,-7.430401542222326 +15985000.0,0.1273985713088185,-7.9236487524285275 +16484500.0,0.12995801920625571,-8.458748980529656 +16984000.0,0.13186900738475252,-9.035947070752695 +17483500.0,0.13316136597716827,-9.655089379648146 +17983000.0,0.13387692721118455,-10.315623776090021 +18482500.0,0.13397087037318464,-11.370354018802939 +18982000.0,0.11903298539628115,-12.15505004397153 +19481500.0,0.11990035929999754,-12.971087231587575 +19981000.0,0.11709272453294475,-13.892142607129816 +20480500.0,0.10929670924344002,-14.877761547602132 +20980000.0,0.09894303388472245,-15.908590098214521 +21479500.0,0.09833042287103662,-16.93300335199522 +21979000.0,0.11414452265501888,-18.000509622324703 +22478500.0,0.14147755776968896,-19.071023041363194 +22978000.0,0.152850382113678,-20.143527856646127 +23477500.0,0.15766104079735893,-21.143688477293363 +23977000.0,0.14370613570578022,-22.07229409237366 +24476500.0,0.14270299881819273,-23.035050081019993 +24976000.0,0.1909872340036131,-23.881339302749343 +25475500.0,0.21518660485087743,-24.64611406404165 +25975000.0,0.23084613484278743,-25.27660391576303 +26474500.0,0.26143316121266447,-25.856605002691893 +26974000.0,0.27416729662132977,-26.43511146987466 +27473500.0,0.28867750881284676,-26.863656163079742 +27973000.0,0.3142186643809723,-27.28692752419982 +28472500.0,0.319822186378652,-27.637821430883587 +28972000.0,0.3416577138991346,-27.907171801398107 +29471500.0,0.3438987612362546,-28.092121962555893 +29971000.0,0.38001893544611237,-28.21100294328945 +30470500.0,0.41223281361102004,-28.233100557283247 +30970000.0,0.4524050108331666,-28.244223409370438 +31469500.0,0.47743207942970844,-28.296180234354804 +31969000.0,0.4955397789566164,-28.303094155833225 +32468500.0,0.5011712885376964,-28.32341224462444 +32968000.0,0.529070802195953,-28.3039583018081 +33467500.0,0.5190597519985662,-28.313815770116406 +33967000.0,0.5487097951618072,-28.29003559548144 +34466500.0,0.5525704186412146,-28.301120362950343 +34966000.0,0.5878476928159602,-28.3326986982177 +35465500.0,0.6357656277355055,-28.3791487979027 +35965000.0,0.656806684169683,-28.477809780730038 +36464500.0,0.6999181710005795,-28.60306290076779 +36964000.0,0.760223795864633,-28.759997087133993 +37463500.0,0.7953723247700605,-28.96214860554806 +37963000.0,0.8396254195792288,-29.20022045531271 +38462500.0,0.9126913146082705,-29.505088015850067 +38962000.0,0.9702525747069154,-29.872337112186678 +39461500.0,1.0294085074716923,-30.29495515965254 +39961000.0,1.0983751053767712,-30.784375266518506 +40460500.0,1.2099941935675533,-31.34798295843869 +40960000.0,1.2835365979004885,-31.973487404635424 +41459500.0,1.382580284102837,-32.642813482397706 +41959000.0,1.5265199588755032,-33.37015512774669 +42458500.0,1.6212056951945168,-34.17342009786488 +42958000.0,1.7610506740386036,-35.03888676542312 +43457500.0,1.9777472715046134,-35.96077601338931 +43957000.0,2.174456854594957,-36.93093637315702 +44456500.0,2.4407434444135743,-37.94827212246026 +44956000.0,2.655689659686112,-39.00936180068276 +45455500.0,2.9071382882864008,-40.08232531127804 +45955000.0,3.2742930393930916,-41.17228585666546 +46454500.0,3.5945353589626903,-42.265113949435026 +46954000.0,4.037762270232279,-43.354483144591775 +47453500.0,4.342384166277934,-44.41745976787549 +47953000.0,4.7957187121178375,-45.437028807588774 +48452500.0,5.329780186461893,-46.446771460355905 +48952000.0,5.887488093175925,-47.42784812032281 +49451500.0,6.481790182586392,-48.36653850305317 +49951000.0,7.201429692212491,-49.239749397869716 +50450500.0,7.818312916910375,-50.14494375500561 +50950000.0,8.762390070854355,-50.96405397062986 +51449500.0,9.634125649512583,-51.82709256174482 +51949000.0,10.300417872560367,-52.678012295000656 +52448500.0,11.22377245851047,-53.478913455800175 +52948000.0,12.109304460875396,-54.235665824433816 +53447500.0,13.080589726771796,-55.0381345606334 +53947000.0,14.336706625078643,-55.88960151071983 +54446500.0,15.434493088800116,-56.77190950517121 +54946000.0,16.48022281290927,-57.63908461883468 +55445500.0,17.788688916943073,-58.494728225059916 +55945000.0,19.56997857499755,-59.36831679404906 +56444500.0,21.254790235007047,-60.247528690120745 +56944000.0,22.745528191570845,-61.11920257240259 +57443500.0,24.752427891150642,-61.974391011386466 +57943000.0,26.739458300086078,-62.84867460793971 +58442500.0,28.834495883801974,-63.69726163452084 +58942000.0,31.36277097481417,-64.57960615424514 +59441500.0,34.35398410825045,-65.43361913407504 +59941000.0,36.84946729622063,-66.29495568849048 +60440500.0,39.94857701931608,-67.15912151830982 +60940000.0,42.982087690585125,-68.00554229121153 +61439500.0,46.710129962097845,-68.86378580134479 +61939000.0,49.94896153946759,-69.71948293992277 +62438500.0,54.09910718510197,-70.58998886886576 +62938000.0,58.015367450306314,-71.4487798896572 +63437500.0,62.62828067238075,-72.31135062985346 +63937000.0,66.99869759396404,-73.16943238841857 +64436500.0,72.90485767842755,-74.04276849496833 +64936000.0,77.81621892677522,-74.90818315142057 +65435500.0,83.08407834909688,-75.77001766460216 +65935000.0,88.87078739848509,-76.636789726107 +66434500.0,95.81894495007916,-77.50276034651311 +66934000.0,102.86517916827357,-78.36687767514266 +67433500.0,110.62963189046839,-79.22967486768307 +67933000.0,119.34796207901196,-80.09822361340517 +68432500.0,127.66693561260067,-80.9656494126824 +68932000.0,136.96824558865973,-81.83316632835792 +69431500.0,146.706468491867,-82.69788206570757 +69931000.0,155.4603012330969,-83.56489206046435 +70430500.0,166.1463941257468,-84.43443473608778 +70930000.0,177.8864670643264,-85.2993062608451 +71429500.0,189.26246044728632,-86.16680736532227 +71929000.0,202.41820307516116,-87.03536653380336 +72428500.0,215.53106990341027,-87.90640780166453 +72928000.0,228.70958010892153,-88.77545503657242 +73427500.0,243.3081372884331,-89.64505139201911 +73927000.0,259.1764511484391,-90.51558484411535 +74426500.0,275.26553763222194,-91.3902065422522 +74926000.0,292.50331388418067,-92.26323887156481 +75425500.0,309.1890939421781,-93.13574851602404 +75925000.0,325.95450747358024,-94.00940088355405 +76424500.0,344.42987841928067,-94.88385712963904 +76924000.0,363.0916083556888,-95.75921263046325 +77423500.0,382.55378155950973,-96.63587216653103 +77923000.0,402.0785501718653,-97.51158309839377 +78422500.0,422.540745683379,-98.38775314494588 +78922000.0,442.4482248870597,-99.26428300840386 +79421500.0,462.79356894653506,-100.14138490052768 +79921000.0,483.8430388232047,-101.01942004935628 +80420500.0,505.0488422961493,-101.89515136593488 +80920000.0,527.5038382095466,-102.77126715242338 +81419500.0,549.3524761071222,-103.64925426786249 +81919000.0,571.0330757458822,-104.52780337133102 +82418500.0,592.2479204744155,-105.40734956019071 +82918000.0,613.6207514005829,-106.28256394906178 +83417500.0,635.3831438948009,-107.16017205738885 +83917000.0,656.7084148778604,-108.03921344124524 +84416500.0,678.57940857329,-108.91877951767101 +84916000.0,696.7510614455526,-109.79538107845953 +85415500.0,717.8198630511854,-110.67148432902101 +85915000.0,736.8346938859484,-111.54873697346513 +86414500.0,754.6047088739859,-112.42317289051942 +86914000.0,771.423334513005,-113.29735112036933 +87413500.0,787.4161341620623,-114.16824388310408 +87913000.0,804.2905511599075,-115.03921389947213 +88412500.0,818.4699922049396,-115.91148122226949 +88912000.0,833.1885551305271,-116.78171522288454 +89411500.0,848.1099143142433,-117.65055809842318 +89911000.0,861.8540337450153,-118.52021076165765 +90410500.0,876.1030868650382,-119.38891992493758 +90910000.0,889.2959328948081,-120.25420018785891 +91409500.0,901.3691631496393,-121.11953925444944 +91909000.0,912.3081463805624,-121.98527377712821 +92408500.0,923.5719843533072,-122.84833207903432 +92908000.0,934.764390332355,-123.70982237203287 +93407500.0,946.7383294874462,-124.57357924094686 +93907000.0,956.595095240978,-125.433678624827 +94406500.0,966.6893123667887,-126.29261776214734 +94906000.0,975.7732447014264,-127.1532738397149 +95405500.0,984.5532955445209,-128.01034466657336 +95905000.0,993.237333899705,-128.86621467356147 +96404500.0,1002.7994937894855,-129.7224314993635 +96904000.0,1010.1239219447339,-130.57714322594012 +97403500.0,1015.2638406599862,-131.43085193088044 +97903000.0,1022.1554351817256,-132.28499795612439 +98402500.0,1029.3613011665739,-133.13672908105696 +98902000.0,1035.7376739591846,-133.98793524756508 +99401500.0,1042.005350492173,-134.83835986022507 +99901000.0,1050.5423521735413,-135.68826031245823 +100400500.0,1058.590378539857,-136.53746545490066 +100900000.0,1065.577398555928,-137.38541335444123 +101399500.0,1070.174840422459,-138.23390926974074 +101899000.0,1077.5429812031298,-139.07927567452737 +102398500.0,1083.5086001856134,-139.92753630991555 +102898000.0,1086.9174700626293,-140.77357100818952 +103397500.0,1093.887963225816,-141.6194727590494 +103897000.0,1098.505816453918,-142.46297126870917 +104396500.0,1101.3535280580413,-143.30776074374123 +104896000.0,1108.8719935262657,-144.1507556919966 +105395500.0,1112.6072298064682,-144.99349913283365 +105895000.0,1117.651539131184,-145.83848621147553 +106394500.0,1123.5554903313132,-146.68205984016402 +106894000.0,1128.4501480249137,-147.52413160935723 +107393500.0,1133.448959051782,-148.3656198383145 +107893000.0,1140.5671236539674,-149.20774267477717 +108392500.0,1146.9686978811778,-150.04975636779463 +108892000.0,1154.2719703682549,-150.8933236267716 +109391500.0,1160.3114425319998,-151.73189904326694 +109891000.0,1166.0099403722522,-152.5711572189193 +110390500.0,1169.7142943966246,-153.4117354630831 +110890000.0,1178.667749926654,-154.25117655641102 +111389500.0,1183.8484926257179,-155.09035984902698 +111889000.0,1187.2811374254372,-155.92945126312418 +112388500.0,1190.3482900920199,-156.76988324616332 +112888000.0,1197.1663158985646,-157.6077772090953 +113387500.0,1200.8522426404977,-158.44664306177944 +113887000.0,1204.9646989443756,-159.28363612208742 +114386500.0,1210.2256609434166,-160.1224244249944 +114886000.0,1215.6314170562623,-160.95960031889783 +115385500.0,1222.001407250698,-161.7989066660178 +115885000.0,1226.1967296009288,-162.63862876908715 +116384500.0,1232.9823456575116,-163.4765001346953 +116884000.0,1236.3634270411353,-164.31246449914104 +117383500.0,1242.6226136375822,-165.14812621501426 +117883000.0,1249.5302359734626,-165.98683577523562 +118382500.0,1256.2924880631076,-166.82347873528835 +118882000.0,1261.1738285999525,-167.6594751513166 +119381500.0,1267.748188760983,-168.49667950659116 +119881000.0,1275.2051129752142,-169.33316607669167 +120380500.0,1280.1043150607989,-170.16840096443647 +120880000.0,1284.7651560315385,-171.00300076640863 +121379500.0,1288.5183876626752,-171.83781210491335 +121879000.0,1294.4542437615553,-172.67211174502307 +122378500.0,1297.9227245576203,-173.50686664710443 +122878000.0,1300.0227390933496,-174.3392287462395 +123377500.0,1306.3627906989093,-175.17175184777162 +123877000.0,1312.7876674639335,-176.00497486048644 +124376500.0,1320.3691009481854,-176.83673087891654 +124876000.0,1325.9559082280832,-177.66778792444995 +125375500.0,1327.3033301365901,-178.4982773883791 +125875000.0,1326.3170920101784,-179.32996788842348 +126374500.0,1328.4542035189384,-180.1607257303724 +126874000.0,1332.7430736265705,-180.99001647121966 +127373500.0,1338.1247512562384,-181.82176702354934 +127873000.0,1337.8588520302146,-182.65297049248767 +128372500.0,1337.3070130040628,-183.4811029983706 +128872000.0,1338.8825418166846,-184.30979746045648 +129371500.0,1340.7886905408068,-185.14047820791316 +129871000.0,1344.7462154646269,-185.96766712162244 +130370500.0,1346.7347028483157,-186.79838596447453 +130870000.0,1348.7924760476146,-187.62743290254937 +131369500.0,1348.215714699246,-188.45727235797486 +131869000.0,1348.1444316608968,-189.28564798579743 +132368500.0,1352.384473879822,-190.11376972356786 +132868000.0,1354.3638470169992,-190.94232300589812 +133367500.0,1354.994505490491,-191.76804391288113 +133867000.0,1359.2688478333737,-192.5963038768692 +134366500.0,1363.0645771748736,-193.42451512664968 +134866000.0,1366.1814373030852,-194.25260683738176 +135365500.0,1369.9609036777101,-195.0810245204094 +135865000.0,1370.8970893086134,-195.9109322676952 +136364500.0,1375.242619437742,-196.73970907618093 +136864000.0,1376.4038568533463,-197.5693214639563 +137363500.0,1378.42198266271,-198.39810976462712 +137863000.0,1382.667592512537,-199.22797152290892 +138362500.0,1383.370740133652,-200.0565506324438 +138862000.0,1385.7988440863792,-200.88511492587034 +139361500.0,1391.9577950136586,-201.7145356501383 +139861000.0,1392.6455866974964,-202.54444909709161 +140360500.0,1396.6294178465548,-203.37350485279677 +140860000.0,1398.6942915766806,-204.19983588165925 +141359500.0,1403.050562364661,-205.0283134856525 +141859000.0,1407.802856412315,-205.85878459247877 +142358500.0,1413.498938305876,-206.68701179808826 +142858000.0,1417.520372746117,-207.51469144431917 +143357500.0,1421.6059972980288,-208.3426216390794 +143857000.0,1427.19459567899,-209.16815441484124 +144356500.0,1429.054489862209,-209.99388110625588 +144856000.0,1433.9269085335848,-210.81910411644722 +145355500.0,1440.7405406967798,-211.64515643656563 +145855000.0,1442.4000252088708,-212.471287973295 +146354500.0,1444.657960803759,-213.2979649446369 +146854000.0,1447.3516154375282,-214.12325880742608 +147353500.0,1452.446338650292,-214.94626068653406 +147853000.0,1451.898713547552,-215.7696647685705 +148352500.0,1453.8953974792478,-216.59289011298623 +148852000.0,1457.3714181031876,-217.418123207324 +149351500.0,1459.2770173054782,-218.24242249233924 +149851000.0,1459.8161615356887,-219.06760241769553 +150350500.0,1461.4076547469263,-219.88970126567796 +150850000.0,1461.6596508917046,-220.7128585950892 +151349500.0,1457.8986177128625,-221.535396673456 +151849000.0,1457.0912118196577,-222.35859615683475 +152348500.0,1455.9141375348463,-223.18098260550914 +152848000.0,1453.815175707222,-224.00273018939697 +153347500.0,1451.5659282086986,-224.8257696957883 +153847000.0,1454.4457173105002,-225.64968771675703 +154346500.0,1451.3403029549609,-226.47089005121566 +154846000.0,1450.448180425688,-227.29476702192702 +155345500.0,1448.011094615357,-228.11878381180188 +155845000.0,1446.3210282387438,-228.94202974024566 +156344500.0,1445.5887532052905,-229.76481347115146 +156844000.0,1444.1058145373904,-230.58705880203982 +157343500.0,1445.4129119690015,-231.40855156883873 +157843000.0,1448.6623377498402,-232.23245493015554 +158342500.0,1452.5474213091975,-233.05482394913653 +158842000.0,1453.7770462321012,-233.876691712649 +159341500.0,1449.4317811554147,-234.69837080141906 +159841000.0,1446.5785645985163,-235.51963352283735 +160340500.0,1444.3726392950848,-236.3409012173352 +160840000.0,1445.903948991112,-237.16239146824915 +161339500.0,1444.7713962248592,-237.98494988741115 +161839000.0,1442.7611300823912,-238.80790410495584 +162338500.0,1440.4909356744909,-239.6282259550222 +162838000.0,1440.980046191619,-240.45037964613255 +163337500.0,1441.4316119473997,-241.27164669760614 +163837000.0,1443.8147704818948,-242.09531766883345 +164336500.0,1442.8149602436426,-242.9160428659071 +164836000.0,1440.563303429762,-243.73847894535558 +165335500.0,1440.0812680221052,-244.55717465499663 +165835000.0,1440.6273482186423,-245.37917881866332 +166334500.0,1441.4655281536125,-246.19863105058917 +166834000.0,1445.9394492545175,-247.0181099863904 +167333500.0,1444.8450978733485,-247.8386870079207 +167833000.0,1446.893619161814,-248.65674580936673 +168332500.0,1450.6726039073637,-249.4769584347697 +168832000.0,1452.1695585665018,-250.29648124605143 +169331500.0,1453.6133126469424,-251.1178913000458 +169831000.0,1458.694595750511,-251.93874832815618 +170330500.0,1457.874476814342,-252.76007582055527 +170830000.0,1460.789780382652,-253.57905433459194 +171329500.0,1460.1268770519473,-254.39955295907473 +171829000.0,1460.601630408172,-255.21824099440218 +172328500.0,1460.0611737000897,-256.0387964962897 +172828000.0,1459.7222751134307,-256.85738255872434 +173327500.0,1464.8491477803025,-257.6773336691074 +173827000.0,1464.6483295424741,-258.497446810934 +174326500.0,1463.7000004269182,-259.31742025469623 +174826000.0,1464.5857321141295,-260.13610279812025 +175325500.0,1464.629913307267,-260.95580926414607 +175825000.0,1466.0032282746527,-261.7757246499078 +176324500.0,1465.5927997378317,-262.59433310937374 +176824000.0,1465.3574856444855,-263.41269844424687 +177323500.0,1463.255850211171,-264.2320067691646 +177823000.0,1461.5023998867177,-265.0522979867332 +178322500.0,1462.8916488749114,-265.87106903053166 +178822000.0,1460.1826158511087,-266.6884894075249 +179321500.0,1462.2171499866654,-267.50719801967574 +179821000.0,1460.1186909090868,-268.3272401937124 +180320500.0,1461.6214078391695,-269.1459627756333 +180820000.0,1461.7921720270615,-269.9631439858321 +181319500.0,1461.791698696247,-270.7797126951444 +181819000.0,1461.109336087472,-271.59603693435963 +182318500.0,1461.2816006414337,-272.41370376425954 +182818000.0,1460.0702777226784,-273.2322822285032 +183317500.0,1461.034777389734,-274.05104299084763 +183817000.0,1458.1655495186556,-274.86722596410726 +184316500.0,1457.1215040556979,-275.6839891852194 +184816000.0,1454.1927065744958,-276.50012603011334 +185315500.0,1450.230794154858,-277.3177630092715 +185815000.0,1448.6276394529527,-278.13389728921976 +186314500.0,1445.6770377451514,-278.95074530949984 +186814000.0,1442.2688135833648,-279.7664605483909 +187313500.0,1446.0255216957223,-280.5829124563757 +187813000.0,1444.8890543679443,-281.40044749900966 +188312500.0,1444.4448681385018,-282.2180836043226 +188812000.0,1441.7996591224144,-283.0356142918369 +189311500.0,1440.1495138671048,-283.85465253297576 +189811000.0,1437.2889244273088,-284.6702166388149 +190310500.0,1439.0486412679015,-285.48643140123494 +190810000.0,1440.1656695617844,-286.3035895252309 +191309500.0,1439.0775302897077,-287.1209828725848 +191809000.0,1437.7270710365513,-287.9378411462575 +192308500.0,1437.8025853798094,-288.75341880957484 +192808000.0,1438.1614880095028,-289.5696371958839 +193307500.0,1435.9070175121365,-290.38481029430875 +193807000.0,1434.521157819657,-291.1988162881705 +194306500.0,1434.1764618743478,-292.01254798258617 +194806000.0,1433.0738872122772,-292.8265077993973 +195305500.0,1433.2753237050094,-293.6437193110464 +195805000.0,1435.0476989447488,-294.4595791333818 +196304500.0,1433.8200565925183,-295.27311058115146 +196804000.0,1436.4843570887776,-296.0892822964769 +197303500.0,1436.5246162527853,-296.9044690213575 +197803000.0,1439.2529682832114,-297.71916918480497 +198302500.0,1440.083622026241,-298.5340500681084 +198802000.0,1438.8158338914243,-299.3466665403486 +199301500.0,1440.1763031244666,-300.15976075196716 +199801000.0,1441.5668421378532,-300.97469121674834 +200300500.0,1443.8089495981746,-301.7889314567783 +200800000.0,1444.611354885993,-302.60447225922024 +201299500.0,1445.1172769714283,-303.41892817683316 +201799000.0,1442.8268637608883,-304.23545120215243 +202298500.0,1443.1969627522792,-305.0507683242151 +202798000.0,1445.0138249174565,-305.8666518427715 +203297500.0,1443.5143663574045,-306.6821910659548 +203797000.0,1445.2797458556543,-307.4987837835401 +204296500.0,1446.8616874411766,-308.3141119066784 +204796000.0,1445.0954461309063,-309.1298088253006 +205295500.0,1444.861639197414,-309.94469746138753 +205795000.0,1442.8984506783158,-310.7603400493935 +206294500.0,1443.1477345374692,-311.5727951588431 +206794000.0,1443.3138134588485,-312.38874475913366 +207293500.0,1444.693161969447,-313.2034192950144 +207793000.0,1446.3633108570264,-314.0180521813121 +208292500.0,1443.140562987403,-314.83377922150953 +208792000.0,1445.9583957415146,-315.6487647671892 +209291500.0,1446.066416639952,-316.4629303304949 +209791000.0,1444.623411010425,-317.2769172586795 +210290500.0,1442.6186232781902,-318.0913649635978 +210790000.0,1443.4610120087823,-318.90646137865434 +211289500.0,1445.3345156819807,-319.7217184465319 +211789000.0,1440.1462195824154,-320.5355555982685 +212288500.0,1438.606900800332,-321.35057522708917 +212788000.0,1439.6764373214623,-322.1635553311635 +213287500.0,1439.5083976076103,-322.97841903698304 +213787000.0,1438.530320268363,-323.7943754911494 +214286500.0,1438.53372496962,-324.60870567143945 +214786000.0,1440.634332330305,-325.42261746836857 +215285500.0,1440.780032690888,-326.23612206098903 +215785000.0,1438.835003195027,-327.0509716104714 +216284500.0,1438.4001791842607,-327.86584153339624 +216784000.0,1440.2538597907132,-328.6805759499298 +217283500.0,1438.9386528167136,-329.4979186424996 +217783000.0,1437.7515781844472,-330.31096675681465 +218282500.0,1435.7368069863749,-331.1225174957208 +218782000.0,1437.7618965799595,-331.9360663076879 +219281500.0,1434.8383972029264,-332.7494853822322 +219781000.0,1437.9432085323938,-333.56305317832266 +220280500.0,1438.698816956591,-334.3767148063212 +220780000.0,1436.9579282135721,-335.1915784336745 +221279500.0,1438.4205859050378,-336.0037540905165 +221779000.0,1443.2294737708864,-336.8196728210663 +222278500.0,1440.790339896762,-337.6344749361349 +222778000.0,1441.5089412532275,-338.4481727561791 +223277500.0,1444.3155102899707,-339.2620135893771 +223777000.0,1445.4542320972507,-340.07645498720825 +224276500.0,1447.4523732446228,-340.8912232744839 +224776000.0,1450.3367740670647,-341.7079325181884 +225275500.0,1449.6914494874748,-342.5227511621202 +225775000.0,1446.3090532905785,-343.33766244929313 +226274500.0,1446.927964508562,-344.15182574902894 +226774000.0,1446.2899738711305,-344.9659829566481 +227273500.0,1446.3159685603764,-345.78126140239465 +227773000.0,1446.8106698232696,-346.59507347505934 +228272500.0,1447.9433210096877,-347.40947782603223 +228772000.0,1448.4878685807537,-348.22414966761585 +229271500.0,1450.5888739050918,-349.0393841255561 +229771000.0,1450.3516718680323,-349.8548389289804 +230270500.0,1451.816719700773,-350.66777171481925 +230770000.0,1451.8085559928252,-351.4805301239716 +231269500.0,1456.2105501983208,-352.2954089738063 +231769000.0,1457.0002642517054,-353.1072389020694 +232268500.0,1460.6430002068964,-353.91893026025946 +232768000.0,1460.6774139296786,-354.72930243304774 +233267500.0,1459.959271145666,-355.5397244105842 +233767000.0,1460.0126598884021,-356.34999791595317 +234266500.0,1458.3562269529073,-357.1627095542972 +234766000.0,1458.6098394703622,-357.97367773536524 +235265500.0,1457.8257409555342,-358.78860399912037 +235765000.0,1458.7433478906353,-359.60108485573335 +236264500.0,1458.767636778391,-360.4155031564527 +236764000.0,1456.9520775134254,-361.2271664483055 +237263500.0,1460.0344059512224,-362.0379109317853 +237763000.0,1457.899983781428,-362.84983375647596 +238262500.0,1459.5510438815118,-363.6619218982988 +238762000.0,1460.1851625201168,-364.47393563658073 +239261500.0,1462.620597013763,-365.2869353506594 +239761000.0,1464.4217519723575,-366.09835538473385 +240260500.0,1464.7959673207085,-366.91141797122987 +240760000.0,1466.1546967892184,-367.7217225684654 +241259500.0,1466.9896447782542,-368.5331744823736 +241759000.0,1468.5415347384248,-369.3448301391701 +242258500.0,1472.0398677041924,-370.15822808995847 +242758000.0,1475.0925671176278,-370.9725894664979 +243257500.0,1478.8080587455042,-371.7857885106555 +243757000.0,1479.47094073373,-372.5993732358366 +244256500.0,1480.2397635997015,-373.41266278389264 +244756000.0,1481.1491787836571,-374.2272650502893 +245255500.0,1484.4934627138084,-375.0385671454842 +245755000.0,1485.4895183547596,-375.8510565431502 +246254500.0,1484.6237291697594,-376.66225925446554 +246754000.0,1487.1741294827775,-377.47475191272383 +247253500.0,1486.3214429150266,-378.2871151461896 +247753000.0,1485.8676959821792,-379.0998091581862 +248252500.0,1484.4744020671844,-379.9132925849762 +248752000.0,1484.3558232425883,-380.7267394372733 +249251500.0,1487.6481525290624,-381.5383884738828 +249751000.0,1488.9057500346692,-382.35192444226675 +250250500.0,1486.9012252994328,-383.1660240605707 +250750000.0,1488.8719626939983,-383.97949688324917 +251249500.0,1490.5243029653686,-384.7929980273803 +251749000.0,1490.781083043028,-385.6070196704588 +252248500.0,1489.3546713852693,-386.41586148806897 +252748000.0,1490.061607058086,-387.2287396733455 +253247500.0,1490.9303626758522,-388.04080063938716 +253747000.0,1490.5776691178596,-388.8532842793814 +254246500.0,1490.946339215585,-389.6653016396404 +254746000.0,1492.8473203720644,-390.47709687040054 +255245500.0,1493.4969850889509,-391.28824763049016 +255745000.0,1493.5751364595033,-392.0990308805182 +256244500.0,1491.385553886406,-392.91183249789634 +256744000.0,1494.2408942108584,-393.72159595882096 +257243500.0,1496.530209660729,-394.5327336502945 +257743000.0,1498.8771854260403,-395.3450108946891 +258242500.0,1501.8996412194745,-396.15761445891553 +258742000.0,1503.0299917889697,-396.970357978156 +259241500.0,1504.1208949891652,-397.78251386714516 +259741000.0,1508.3183540461498,-398.59246626123524 +260240500.0,1510.9334222623725,-399.4044349063352 +260740000.0,1513.3162385470853,-400.21810461896865 +261239500.0,1512.8003856251162,-401.03075461904234 +261739000.0,1518.7202209945638,-401.8436158851227 +262238500.0,1523.9337216697265,-402.65793057751415 +262738000.0,1525.677242793889,-403.47087660938206 +263237500.0,1528.3432481628479,-404.2834763151079 +263737000.0,1530.7931140165326,-405.09671749310684 +264236500.0,1532.836686243789,-405.9081222753757 +264736000.0,1536.230428513056,-406.72025384186463 +265235500.0,1537.6487412488104,-407.5322345366884 +265735000.0,1536.8739713058117,-408.34618680338593 +266234500.0,1537.2348587587135,-409.1584249754174 +266734000.0,1538.9802535659444,-409.9702072227101 +267233500.0,1540.988518235267,-410.78220917548833 +267733000.0,1541.3314221924707,-411.59515914588445 +268232500.0,1542.246675060043,-412.4081103223489 +268732000.0,1543.6621166395817,-413.2220226145736 +269231500.0,1544.1581019444393,-414.03497450229054 +269731000.0,1541.8239722586156,-414.84778728183164 +270230500.0,1541.7589870253905,-415.65949243586766 +270730000.0,1536.9176920420364,-416.4729312118827 +271229500.0,1537.13224224727,-417.2818710020519 +271729000.0,1540.0668059180962,-418.0941684412806 +272228500.0,1539.5733357133686,-418.9056065120729 +272728000.0,1537.1088956289948,-419.71684565415745 +273227500.0,1539.5398585503046,-420.5291646222597 +273727000.0,1542.7078439660152,-421.3400658938566 +274226500.0,1544.545006981568,-422.15204834467147 +274726000.0,1541.3664497338902,-422.96343352024405 +275225500.0,1542.2941948699752,-423.77268870200817 +275725000.0,1544.7312225134938,-424.5828481002237 +276224500.0,1547.8216159595922,-425.3950301985807 +276724000.0,1549.84120738946,-426.2072486269307 +277223500.0,1550.1476593417485,-427.0200007928162 +277723000.0,1552.5934990363028,-427.83055006013313 +278222500.0,1553.2579467652831,-428.6429659298204 +278722000.0,1554.6565511801834,-429.4533316922596 +279221500.0,1554.43399519754,-430.2651899113738 +279721000.0,1555.851937040745,-431.07445638921206 +280220500.0,1558.4854899340519,-431.8858939390677 +280720000.0,1561.2779949797005,-432.69765910884 +281219500.0,1560.5804290269648,-433.5082720149379 +281719000.0,1560.9704454879868,-434.3195812572489 +282218500.0,1564.9676630258323,-435.1311408427534 +282718000.0,1565.775472712935,-435.9445394491291 +283217500.0,1567.4619021295537,-436.756676428963 +283717000.0,1568.9185184634862,-437.5681978503404 +284216500.0,1569.5050481796488,-438.3820782999031 +284716000.0,1573.3812680402102,-439.1955408327862 +285215500.0,1576.6367695449944,-440.0082785821313 +285715000.0,1580.6356686503034,-440.82199066176054 +286214500.0,1581.869922208547,-441.6345777351748 +286714000.0,1582.2741352143314,-442.44936094151336 +287213500.0,1582.9102997871548,-443.2628555237044 +287713000.0,1585.1536261535398,-444.0743218033104 +288212500.0,1588.3211454715138,-444.88646874437296 +288712000.0,1589.2730344650213,-445.69871976553713 +289211500.0,1593.271656346872,-446.51079136964506 +289711000.0,1592.8136495689241,-447.32285943255545 +290210500.0,1591.4758235849,-448.1340900116472 +290710000.0,1591.8936896785133,-448.94538695443384 +291209500.0,1599.1963899001114,-449.7577761122951 +291709000.0,1602.9262502643448,-450.56908019518215 +292208500.0,1606.8054876129763,-451.3792220725597 +292708000.0,1610.9596101971383,-452.19189929812785 +293207500.0,1612.498814694606,-453.00525175173294 +293707000.0,1616.0716820669115,-453.8175004109284 +294206500.0,1620.0219504403258,-454.62794326533776 +294706000.0,1623.044565991407,-455.43938091899975 +295205500.0,1626.6243594615444,-456.2498776898214 +295705000.0,1630.984300666388,-457.06078285053934 +296204500.0,1637.1158941525166,-457.8713747736636 +296704000.0,1638.6115945433307,-458.6836815269499 +297203500.0,1638.3882332261064,-459.49355185620556 +297703000.0,1641.464610969292,-460.30475952559874 +298202500.0,1643.7959902987388,-461.1158340682773 +298702000.0,1645.0552974510879,-461.9266686176783 +299201500.0,1645.931291957302,-462.7389283433225 +299701000.0,1646.4726184210263,-463.55188063415136 +300200500.0,1649.6542216084506,-464.36443641668535 +300700000.0,1654.0459253405386,-465.17519589391014 +301199500.0,1656.1156226021667,-465.98756067561976 +301699000.0,1661.6662147608424,-466.7993232620268 +302198500.0,1661.345440873836,-467.61193959200426 +302698000.0,1661.7996054229468,-468.42367743387075 +303197500.0,1660.900023163111,-469.2342177633636 +303697000.0,1661.3294068820699,-470.0445827736088 +304196500.0,1659.2043945314513,-470.85577871995997 +304696000.0,1662.241880521223,-471.6677035674992 +305195500.0,1662.5395286955957,-472.4806576210585 +305695000.0,1664.9614856093365,-473.2906929786851 +306194500.0,1665.696753439768,-474.10406835607336 +306694000.0,1663.8759189694938,-474.91488161012074 +307193500.0,1663.530651830944,-475.7268127211004 +307693000.0,1669.4775116436797,-476.5388124546971 +308192500.0,1670.9060476761056,-477.3514035458353 +308692000.0,1667.8455514707482,-478.16324751911924 +309191500.0,1666.2865868393196,-478.97408732247214 +309691000.0,1667.432298414151,-479.78770765374577 +310190500.0,1670.2916549755023,-480.5975498452998 +310690000.0,1669.951495393045,-481.4079606031759 +311189500.0,1671.5243069431817,-482.21964193962145 +311689000.0,1671.182422578075,-483.0321739917856 +312188500.0,1673.3904814861899,-483.84313109070456 +312688000.0,1672.256804565233,-484.6556282116178 +313187500.0,1674.0348177283583,-485.46749809949154 +313687000.0,1674.3598719058862,-486.27930373670523 +314186500.0,1677.297047664714,-487.08974853215864 +314686000.0,1679.7265973063047,-487.90144876068905 +315185500.0,1682.5905561445811,-488.7118787882409 +315685000.0,1682.0331072724532,-489.5207877894513 +316184500.0,1686.2970494592498,-490.33267391361863 +316684000.0,1687.6704288181318,-491.14619780219334 +317183500.0,1689.5129568710856,-491.95929789791546 +317683000.0,1694.4021405702254,-492.7713223182923 +318182500.0,1697.9543029663687,-493.58221335451714 +318682000.0,1703.0556784350033,-494.39394781204834 +319181500.0,1708.2658267112765,-495.2059690035231 +319681000.0,1709.545959020117,-496.02076800022456 +320180500.0,1713.8717997474578,-496.8356222947895 +320680000.0,1714.1323054548645,-497.64870727648054 +321179500.0,1715.5898633207999,-498.46136454426886 +321679000.0,1717.071138546073,-499.27210885967634 +322178500.0,1720.8651352096683,-500.0844156405753 +322678000.0,1719.0128116102535,-500.89655844623576 +323177500.0,1722.0496761838845,-501.70849162458427 +323677000.0,1722.091039244335,-502.5192928675006 +324176500.0,1723.349696059009,-503.33190672226004 +324676000.0,1723.3023976070174,-504.14432691776904 +325175500.0,1725.1552715104579,-504.958372342772 +325675000.0,1731.289261758031,-505.7724512128028 +326174500.0,1731.912837209917,-506.5843659900643 +326674000.0,1728.757921928029,-507.39956892052055 +327173500.0,1728.0906461304985,-508.21359798643743 +327673000.0,1729.7143390728343,-509.0278174622903 +328172500.0,1731.9814259337536,-509.8395555347586 +328672000.0,1732.9619562918542,-510.64998764209093 +329171500.0,1735.4552650164894,-511.4612717015059 +329671000.0,1738.1750639317547,-512.2708423317092 +330170500.0,1736.8990618010594,-513.0824388476436 +330670000.0,1734.9985257974618,-513.8946257002583 +331169500.0,1735.177784377745,-514.7061321385665 +331669000.0,1735.2993414851073,-515.516806301615 +332168500.0,1735.3223908021746,-516.3299686006445 +332668000.0,1735.0532931017244,-517.1427167627753 +333167500.0,1732.8450957838818,-517.955135073224 +333667000.0,1734.7905535316188,-518.7688738632997 +334166500.0,1736.532481264706,-519.5807128248412 +334666000.0,1738.1159050383558,-520.3919389613077 +335165500.0,1735.406966640744,-521.20349418972 +335665000.0,1734.8827545026204,-522.0160930830021 +336164500.0,1731.88570011133,-522.8291461246589 +336664000.0,1729.0497894257055,-523.6421812187976 +337163500.0,1727.1764045369625,-524.4533461459885 +337663000.0,1726.4707857847197,-525.2657671758582 +338162500.0,1730.8256762058797,-526.0798668734391 +338662000.0,1727.616056237143,-526.8908290199306 +339161500.0,1730.8265776488665,-527.703527475024 +339661000.0,1727.6943266476685,-528.5165113753926 +340160500.0,1728.6426943683937,-529.329446888944 +340660000.0,1729.6486037404247,-530.1419159894474 +341159500.0,1729.8936663690336,-530.9548646929866 +341659000.0,1732.3392641416208,-531.7660698475347 +342158500.0,1734.1331276839069,-532.5793692991587 +342658000.0,1736.9286691379734,-533.3908000468099 +343157500.0,1737.0407671867977,-534.2022003388922 +343657000.0,1738.7699587373902,-535.0147802595916 +344156500.0,1739.8712187238864,-535.8269071644258 +344656000.0,1742.1679453918239,-536.6354587375866 +345155500.0,1739.4875948724712,-537.4471712296609 +345655000.0,1739.3645299022776,-538.2607462740925 +346154500.0,1737.964003442693,-539.0743178546306 +346654000.0,1740.9320265925028,-539.8867108027868 +347153500.0,1741.258939678592,-540.6990395287447 +347653000.0,1741.6921469023096,-541.5130122004235 +348152500.0,1739.356321576099,-542.323844179497 +348652000.0,1738.8023566819306,-543.1357746865006 +349151500.0,1738.42252464412,-543.9493146240201 +349651000.0,1738.7296624624184,-544.7608748683905 +350150500.0,1736.5969950002097,-545.5735552834296 +350650000.0,1738.1655451635218,-546.3875067817715 +351149500.0,1734.106727121989,-547.2017916038554 +351649000.0,1736.0967964720944,-548.0135632092359 +352148500.0,1738.1449386741792,-548.8252798216381 +352648000.0,1735.1305506401427,-549.6351581372616 +353147500.0,1733.50155893526,-550.448918000657 +353647000.0,1733.8143176768083,-551.260335037894 +354146500.0,1734.6568018737962,-552.0737027498387 +354646000.0,1734.7227246801415,-552.8840667064717 +355145500.0,1732.4297606542577,-553.6943932938561 +355645000.0,1732.2095049142597,-554.50394567397 +356144500.0,1729.4961823622848,-555.3140816067942 +356644000.0,1727.779648168142,-556.1249388422673 +357143500.0,1723.4196857335764,-556.9353684591398 +357643000.0,1723.3986815973378,-557.7457643003581 +358142500.0,1714.3864056565953,-558.5551619250391 +358642000.0,1712.3314427784162,-559.365915883641 +359141500.0,1710.9001150726367,-560.176737887777 +359641000.0,1710.5384926405495,-560.9870449897793 +360140500.0,1707.8023295906103,-561.7974517917356 +360640000.0,1702.6677391913297,-562.6068637816619 +361139500.0,1697.9579709012257,-563.4178464290975 +361639000.0,1697.610202070447,-564.2243683027395 +362138500.0,1698.5402899651544,-565.0349249781508 +362638000.0,1697.6288905597667,-565.8413424395458 +363137500.0,1690.3863046163676,-566.6517168590635 +363637000.0,1689.8920480568615,-567.4599898077157 +364136500.0,1690.2845778175972,-568.2674635009882 +364636000.0,1692.0104901906705,-569.0777404052999 +365135500.0,1692.6796709767182,-569.8874973762644 +365635000.0,1696.1560703303114,-570.6957413283798 +366134500.0,1697.0282284852126,-571.5073573142284 +366634000.0,1695.5360767089635,-572.3177271341802 +367133500.0,1697.2602192024544,-573.1268002426345 +367633000.0,1700.2844148064873,-573.9363216620086 +368132500.0,1704.8604513325145,-574.7463125223634 +368632000.0,1704.2086371133,-575.5558689951824 +369131500.0,1703.6067185442823,-576.3653929056179 +369631000.0,1703.5857920136104,-577.1752894907002 +370130500.0,1705.0457381185427,-577.9889994296597 +370630000.0,1703.6305075431967,-578.7999939769335 +371129500.0,1705.2896030235834,-579.6105233761984 +371629000.0,1705.8011173877817,-580.4214628829342 +372128500.0,1708.3191286400984,-581.233705523446 +372628000.0,1710.1930347635373,-582.0458588493257 +373127500.0,1711.5788090884998,-582.8558276034971 +373627000.0,1714.415815695411,-583.6676780196399 +374126500.0,1716.5052566582406,-584.4800922304505 +374626000.0,1723.9007416995005,-585.2922825725833 +375125500.0,1725.6959647731483,-586.1053458805419 +375625000.0,1730.0116831607388,-586.9159801255345 +376124500.0,1734.0608599240395,-587.7262080682308 +376624000.0,1736.3791148890843,-588.5385448235302 +377123500.0,1742.16853371902,-589.3487478584003 +377623000.0,1742.946426493507,-590.1603836011225 +378122500.0,1744.3215718930812,-590.9705424322154 +378622000.0,1746.0815958081662,-591.7804564448488 +379121500.0,1748.0788491303335,-592.5910725653097 +379621000.0,1747.9649763233506,-593.402200791976 +380120500.0,1749.8450176589056,-594.2141933363664 +380620000.0,1752.5424485404312,-595.0248242578906 +381119500.0,1755.6822809086123,-595.8344806768937 +381619000.0,1756.139509896468,-596.6443663435351 +382118500.0,1755.6300107185477,-597.4555873545625 +382618000.0,1755.709422662164,-598.265894307981 +383117500.0,1759.26902257728,-599.0768906963898 +383617000.0,1761.4690351850556,-599.8888487981937 +384116500.0,1763.0074776987437,-600.6991227466162 +384616000.0,1762.4479575733976,-601.5104862661102 +385115500.0,1764.3385676367418,-602.3224746481733 +385615000.0,1766.632000622277,-603.1348957102022 +386114500.0,1767.47562252016,-603.9460603881043 +386614000.0,1767.1078843667951,-604.75659084685 +387113500.0,1765.1148581837274,-605.5679371472636 +387613000.0,1767.9601044176347,-606.3817855014448 +388112500.0,1767.3000195833029,-607.1927792276507 +388612000.0,1768.6879924419454,-608.0047860120301 +389111500.0,1765.0527296110297,-608.8174511186902 +389611000.0,1763.582498902181,-609.6296772957002 +390110500.0,1761.4511059351282,-610.4402490107702 +390610000.0,1756.973773593247,-611.2532699831247 +391109500.0,1755.9929378060806,-612.0669519132625 +391609000.0,1754.161186381264,-612.8803141950015 +392108500.0,1750.5830686508257,-613.6933746361772 +392608000.0,1748.0604208716056,-614.5042265524133 +393107500.0,1751.4210371603297,-615.3165855037506 +393607000.0,1753.9335538094804,-616.1287154257205 +394106500.0,1755.511305135829,-616.9412947785769 +394606000.0,1753.2713906487877,-617.752504578247 +395105500.0,1755.1524246931833,-618.5632256375177 +395605000.0,1755.0898239450491,-619.3745958181075 +396104500.0,1754.1460498380038,-620.1856594784517 +396604000.0,1754.4448538119584,-620.9973868906401 +397103500.0,1751.7326122484637,-621.8072724956784 +397603000.0,1749.8743850003825,-622.6210441703018 +398102500.0,1755.537611751396,-623.4315324346372 +398602000.0,1757.7008075741742,-624.242106132946 +399101500.0,1761.258520332805,-625.0549245628354 +399601000.0,1759.309048918222,-625.8665584051571 +400100500.0,1758.3040200563607,-626.6781425126647 +400600000.0,1758.7122640056023,-627.4915711115542 +401099500.0,1759.21987725584,-628.3016933218322 +401599000.0,1762.3297274238682,-629.1140276001371 +402098500.0,1765.9093304326132,-629.9254801725128 +402598000.0,1763.4190733048144,-630.7390590615289 +403097500.0,1763.797694433501,-631.5511260351723 +403597000.0,1764.0659111552961,-632.3639246840892 +404096500.0,1765.0069051094927,-633.1764591159596 +404596000.0,1766.1630709290146,-633.9898337629093 +405095500.0,1769.0850369919933,-634.8021251194183 +405595000.0,1764.565710987868,-635.6160172042341 +406094500.0,1764.7135982448167,-636.4284691390501 +406594000.0,1763.728990735702,-637.2413410648425 +407093500.0,1763.4949329262122,-638.0556907211513 +407593000.0,1764.839556462418,-638.8682826516907 +408092500.0,1761.9011216982415,-639.6807987418766 +408592000.0,1764.3747962320363,-640.4937044565071 +409091500.0,1764.3608204439497,-641.3041888182645 +409591000.0,1763.6388737412199,-642.1177774446556 +410090500.0,1766.6494968401296,-642.9292558060326 +410590000.0,1765.6638952982796,-643.7433625132188 +411089500.0,1764.3164357380117,-644.5564369050197 +411589000.0,1766.6402153330148,-645.3702413150571 +412088500.0,1759.603679595682,-646.1808033494319 +412588000.0,1755.5081963876696,-646.9930177160521 +413087500.0,1752.963118188561,-647.8052986327656 +413587000.0,1750.3988503991075,-648.6168345063869 +414086500.0,1745.0031043518413,-649.4285540990071 +414586000.0,1738.762509957805,-650.2396266620455 +415085500.0,1737.8670069749585,-651.0487726634046 +415585000.0,1735.347589280731,-651.8577418625305 +416084500.0,1735.3589662340955,-652.6696202521541 +416584000.0,1734.1763599552257,-653.48107403818 +417083500.0,1732.4028620947588,-654.2904066862943 +417583000.0,1732.8840584774673,-655.0991179789145 +418082500.0,1733.7477092900265,-655.9102054967027 +418582000.0,1735.2136474579613,-656.7184986266238 +419081500.0,1736.0836693316667,-657.5279243086538 +419581000.0,1737.9442159164694,-658.3377815864569 +420080500.0,1739.0254695109572,-659.1468046158593 +420580000.0,1736.8227970638857,-659.9572139004498 +421079500.0,1736.1539826174546,-660.7678190447796 +421579000.0,1740.225350706232,-661.5789619982017 +422078500.0,1742.081583861072,-662.3896631179216 +422578000.0,1741.1000797939216,-663.1990235940051 +423077500.0,1741.8446300490198,-664.0101658063021 +423577000.0,1739.0779484305074,-664.8226166263765 +424076500.0,1739.240979950395,-665.6325171389462 +424576000.0,1736.4245498691364,-666.4438282752407 +425075500.0,1736.306203569701,-667.2569166269211 +425575000.0,1737.278842700886,-668.0686009850208 +426074500.0,1734.6277209913062,-668.880390317798 +426574000.0,1734.5518828228635,-669.692236807538 +427073500.0,1731.5130848405934,-670.502636263035 +427573000.0,1733.433942811656,-671.3148342333037 +428072500.0,1734.1760822270178,-672.126447396332 +428572000.0,1734.4944305336485,-672.9404735229268 +429071500.0,1735.1106694639104,-673.7527732366124 +429571000.0,1735.0120853165697,-674.5650479912872 +430070500.0,1732.7402910627336,-675.3772786435048 +430570000.0,1728.2964855868458,-676.1892601993846 +431069500.0,1727.530030349195,-676.9990551669842 +431569000.0,1726.6294443432312,-677.8118520942304 +432068500.0,1726.3924462979487,-678.6220804695665 +432568000.0,1727.3614015654005,-679.4344610301604 +433067500.0,1726.2392715547453,-680.2456571272617 +433567000.0,1723.8419697143881,-681.0595078688141 +434066500.0,1721.3497029216624,-681.8690301993392 +434566000.0,1721.2386430749211,-682.6810195707639 +435065500.0,1721.0726106120949,-683.4920930960714 +435565000.0,1720.7427772964259,-684.3020349874628 +436064500.0,1720.6724578883272,-685.1127438528376 +436564000.0,1721.6078453915807,-685.9230743801467 +437063500.0,1718.560624222091,-686.7350557277744 +437563000.0,1718.3336829190616,-687.5447342144554 +438062500.0,1715.793868086245,-688.3564640457471 +438562000.0,1715.756761499826,-689.1664102620879 +439061500.0,1716.114268206035,-689.9771894532503 +439561000.0,1714.6064051281166,-690.7882038873861 +440060500.0,1706.4956744639965,-691.5963526466004 +440560000.0,1709.3503892015938,-692.4080196333397 +441059500.0,1708.0660224009875,-693.2209653625457 +441559000.0,1704.3554157817232,-694.0327113439727 +442058500.0,1701.76551598307,-694.8426720326913 +442558000.0,1698.4949460237879,-695.6523293077274 +443057500.0,1701.271252604035,-696.4625858162451 +443557000.0,1701.4583069163004,-697.2752928842982 +444056500.0,1703.0880390252964,-698.0885814233749 +444556000.0,1703.5410090126466,-698.9015937796238 +445055500.0,1699.2266167077019,-699.7139764699133 +445555000.0,1696.1652350618756,-700.5276238259386 +446054500.0,1691.8218770518515,-701.3401641157888 +446554000.0,1685.5757316825116,-702.1508606345201 +447053500.0,1683.0986965619327,-702.9659330039842 +447553000.0,1681.9188269291176,-703.7789634343192 +448052500.0,1677.7398268109375,-704.5908078880478 +448552000.0,1673.5973073235277,-705.4052731889042 +449051500.0,1669.5179775635436,-706.2172204062397 +449551000.0,1671.017657228669,-707.0299439586913 +450050500.0,1667.9853006519763,-707.8440205851248 +450550000.0,1666.652751051863,-708.6593024648888 +451049500.0,1663.0194951718106,-709.470006953564 +451549000.0,1661.5276051658632,-710.2812735808399 +452048500.0,1662.0706497906992,-711.0916575492186 +452548000.0,1660.6782108160266,-711.9034722363502 +453047500.0,1661.6428261004658,-712.714443681123 +453547000.0,1660.498327774571,-713.5278146743275 +454046500.0,1659.0683804463479,-714.3397445726262 +454546000.0,1659.5877065125776,-715.1508206602708 +455045500.0,1659.7629326072154,-715.9629594164753 +455545000.0,1660.0184546008122,-716.7752672756055 +456044500.0,1662.7157926079838,-717.5877158600748 +456544000.0,1662.1685627697266,-718.3988228017295 +457043500.0,1664.5832278404396,-719.2100397301436 +457543000.0,1665.1194673781115,-720.0227311209064 +458042500.0,1665.4975605754023,-720.8328780798594 +458542000.0,1664.2223207857323,-721.6422737594283 +459041500.0,1663.7407426429693,-722.4523858560909 +459541000.0,1663.1472757255237,-723.2619899907797 +460040500.0,1661.2618155927983,-724.0713823059727 +460540000.0,1660.5339048114736,-724.881284892173 +461039500.0,1663.9160168510798,-725.691378988185 +461539000.0,1663.2066640472433,-726.50167943959 +462038500.0,1668.1479737407285,-727.3126095904893 +462538000.0,1670.7727574268793,-728.1246123722646 +463037500.0,1673.4874855730761,-728.9375343022707 +463537000.0,1674.2729490474337,-729.7499402744655 +464036500.0,1671.3710176823477,-730.559781351479 +464536000.0,1667.449988831675,-731.3699523437368 +465035500.0,1664.8357086079282,-732.1803348917018 +465535000.0,1662.972836713799,-732.9920931867866 +466034500.0,1663.063621220973,-733.8048031860887 +466534000.0,1660.862061688507,-734.6146986869308 +467033500.0,1662.2053923889384,-735.429258963964 +467533000.0,1659.57200429282,-736.2408178856225 +468032500.0,1658.1824292049887,-737.0530453173416 +468532000.0,1660.4197355457407,-737.8640556276534 +469031500.0,1657.047341867801,-738.6770496551177 +469531000.0,1653.7653406701484,-739.48565677986 +470030500.0,1655.3245995276277,-740.298334389856 +470530000.0,1654.6822245246992,-741.1087083810521 +471029500.0,1655.8698908178276,-741.9204697667825 +471529000.0,1653.6300756675894,-742.7318792514834 +472028500.0,1654.2614673851315,-743.5429525366887 +472528000.0,1653.9453466522539,-744.3539260288319 +473027500.0,1652.583990476276,-745.1632491362857 +473527000.0,1654.2560024286645,-745.972905228302 +474026500.0,1652.2081815911174,-746.7829935779971 +474526000.0,1650.8975975346304,-747.5947376321931 +475025500.0,1654.4069661003073,-748.4085653151861 +475525000.0,1650.3277823795997,-749.2186274557178 +476024500.0,1647.537932135384,-750.028571044698 +476524000.0,1645.5745003896047,-750.8391437049992 +477023500.0,1645.4358977865063,-751.6513992755425 +477523000.0,1647.7793282236073,-752.4638886522207 +478022500.0,1646.2234220233806,-753.2744417805673 +478522000.0,1645.3948028931854,-754.0857051110398 +479021500.0,1644.7872924486962,-754.8974722676994 +479521000.0,1642.2459820433214,-755.7095406808843 +480020500.0,1641.5152027541048,-756.5217779742686 +480520000.0,1639.997236706056,-757.3328804880217 +481019500.0,1638.9387652594812,-758.1462116641935 +481519000.0,1636.3275618748012,-758.9596908369311 +482018500.0,1637.6613800606683,-759.7719004449767 +482518000.0,1633.0230392912267,-760.5829666355617 +483017500.0,1631.6280220743251,-761.3960591590677 +483517000.0,1630.6801911182663,-762.2066957157316 +484016500.0,1629.0752800990601,-763.018694710035 +484516000.0,1625.096564253711,-763.8322198438052 +485015500.0,1624.3204647792536,-764.6423281181976 +485515000.0,1621.7431700215034,-765.4529317945066 +486014500.0,1618.6742408138803,-766.2622040385619 +486514000.0,1616.1774479135631,-767.0719504991051 +487013500.0,1613.6366533639157,-767.8828799460632 +487513000.0,1614.0041636604,-768.6959119980604 +488012500.0,1611.5403178074248,-769.506439908702 +488512000.0,1608.684581890942,-770.3162675475938 +489011500.0,1607.4112224584092,-771.1276330475332 +489511000.0,1608.5640397890609,-771.9405452795124 +490010500.0,1603.1016389269864,-772.7520042499262 +490510000.0,1598.3074173750545,-773.5632135332852 +491009500.0,1596.1255805567932,-774.3721040716789 +491509000.0,1594.1122828966954,-775.1835826252958 +492008500.0,1591.3483204125992,-775.9935786600502 +492508000.0,1588.3969881925616,-776.8016089913131 +493007500.0,1581.0335825591385,-777.6110140491134 +493507000.0,1576.3365186487563,-778.4210176519659 +494006500.0,1572.3938906102985,-779.2327640564739 +494506000.0,1572.366058481876,-780.0428303012973 +495005500.0,1570.9231650785434,-780.8532235559587 +495505000.0,1572.086259455759,-781.6648740053026 +496004500.0,1569.9625201454044,-782.4754994652174 +496504000.0,1572.8889671770937,-783.2867730059088 +497003500.0,1572.8075055087747,-784.1000615310462 +497503000.0,1571.4530073347423,-784.9120365113877 +498002500.0,1569.708208543128,-785.7243084550097 +498502000.0,1568.038609040089,-786.5346519856531 +499001500.0,1565.5333982858922,-787.3467208323937 +499501000.0,1564.509001973877,-788.1584639974769 +500000500.0,1561.6190026881693,-788.9725043878312 +500500000.0,1560.815070862714,-789.7846089513571 +500999500.0,1556.270625111359,-790.5972445864411 +501499000.0,1557.911422776669,-791.4095723860934 +501998500.0,1557.625312862525,-792.2227478308932 +502498000.0,1559.1088778048045,-793.0349257327205 +502997500.0,1557.6882210909946,-793.8463039180191 +503497000.0,1554.1583751022647,-794.6579538879273 +503996500.0,1553.1230583750462,-795.4682959629428 +504496000.0,1553.661230909626,-796.2838878862025 +504995500.0,1553.4068559205894,-797.0951831562656 +505495000.0,1553.1960744513065,-797.9080264776111 +505994500.0,1551.3026236659784,-798.7188514783985 +506494000.0,1549.7004181346747,-799.5316683180969 +506993500.0,1544.1362448808065,-800.3437862923772 +507493000.0,1542.2642181964354,-801.153693839295 +507992500.0,1541.576571263626,-801.9646322727808 +508492000.0,1536.5909135667296,-802.7768703388781 +508991500.0,1536.7378034772885,-803.5884416074426 +509491000.0,1534.721484953744,-804.3992891268821 +509990500.0,1531.0454066872946,-805.2102292498906 +510490000.0,1529.5837187438194,-806.0224852176245 +510989500.0,1524.2166212376321,-806.8348455525587 +511489000.0,1524.6233167560986,-807.6467630709618 +511988500.0,1524.5911277814987,-808.4574493584738 +512488000.0,1523.3307758661895,-809.2677687552335 +512987500.0,1521.329153216152,-810.0792658338125 +513487000.0,1520.0028312310012,-810.8898180342848 +513986500.0,1517.6261112358222,-811.7028213183054 +514486000.0,1514.2538667124513,-812.514301637124 +514985500.0,1509.1652899845815,-813.3267703070536 +515485000.0,1509.8741968439256,-814.1378718960615 +515984500.0,1510.4987953936766,-814.9491139793747 +516484000.0,1510.016667367208,-815.7615295045603 +516983500.0,1508.2463186486407,-816.5730455973305 +517483000.0,1509.8598989263025,-817.3860908907432 +517982500.0,1509.1830166764485,-818.197948075767 +518482000.0,1505.3945615323798,-819.0112942917618 +518981500.0,1505.9263090777004,-819.823280313923 +519481000.0,1504.1152974120337,-820.632315131696 +519980500.0,1499.3272127935572,-821.4443579807291 +520480000.0,1499.5275923870872,-822.2537449544142 +520979500.0,1501.4805327146273,-823.0658796743924 +521479000.0,1501.6008213372888,-823.8780445469794 +521978500.0,1501.3793491260571,-824.6908843146103 +522478000.0,1501.839763821281,-825.5032133749243 +522977500.0,1498.3540871149728,-826.3162762368348 +523477000.0,1498.5479631778765,-827.1299507702124 +523976500.0,1497.8169673583884,-827.9424703835865 +524476000.0,1492.0089561240918,-828.7540411016525 +524975500.0,1492.5071679728737,-829.5662825549424 +525475000.0,1492.1241367355678,-830.378623614559 +525974500.0,1490.2758329531048,-831.1921138981769 +526474000.0,1491.1562123425063,-832.0028216361229 +526973500.0,1489.616961770991,-832.8144697869424 +527473000.0,1483.9463071475088,-833.6279057207558 +527972500.0,1480.6069018468293,-834.4403414105582 +528472000.0,1481.3510918459451,-835.2539277917704 +528971500.0,1482.0838717681343,-836.0654964273165 +529471000.0,1478.9134511150219,-836.87927194129 +529970500.0,1478.1193093513696,-837.6922117679227 +530470000.0,1477.3961791117292,-838.5045108620774 +530969500.0,1479.068793622029,-839.318489329064 +531469000.0,1477.838490874261,-840.1318903030067 +531968500.0,1477.4424795973607,-840.9438584278839 +532468000.0,1479.0143674802473,-841.7571974961008 +532967500.0,1478.7694838765274,-842.5694015031949 +533467000.0,1478.326747630492,-843.3822660375503 +533966500.0,1476.1314604510765,-844.1936728918863 +534466000.0,1472.6726286558219,-845.0064041554512 +534965500.0,1473.9455927365248,-845.8181298516683 +535465000.0,1473.4072831843241,-846.6303133417007 +535964500.0,1475.6352184287198,-847.4407479964873 +536464000.0,1476.8310380403661,-848.2517233087196 +536963500.0,1475.1648139057515,-849.0623767951885 +537463000.0,1471.3939239769304,-849.8744703162486 +537962500.0,1470.7089976977952,-850.6868872611839 +538462000.0,1469.7777733221355,-851.497681430539 +538961500.0,1472.265938481899,-852.3116044213705 +539461000.0,1471.2017369557104,-853.1221576232292 +539960500.0,1470.097332165608,-853.9326475449664 +540460000.0,1466.726973307832,-854.74364642895 +540959500.0,1464.8876107581996,-855.5570292847614 +541459000.0,1463.5658240188186,-856.3685829353077 +541958500.0,1465.144543395018,-857.1776276040238 +542458000.0,1466.0237856608233,-857.9883626411992 +542957500.0,1463.094184887587,-858.8015876380441 +543457000.0,1464.2143213845807,-859.6134067285698 +543956500.0,1464.0922338518542,-860.4260516715902 +544456000.0,1461.0379990081,-861.2379621565373 +544955500.0,1457.1776601502695,-862.0510083099085 +545455000.0,1454.2541075622705,-862.862652966746 +545954500.0,1451.0943068180845,-863.6742294127392 +546454000.0,1448.3038968992603,-864.4853950856956 +546953500.0,1441.3535281308755,-865.2993747805292 +547453000.0,1435.7014954037907,-866.1112664603706 +547952500.0,1434.9358866187522,-866.9236604579839 +548452000.0,1432.5105594264617,-867.7359897529875 +548951500.0,1428.6853514880738,-868.5474328524712 +549451000.0,1427.6071110559244,-869.3598455589259 +549950500.0,1429.9444995771246,-870.1718967308002 +550450000.0,1428.1583356349165,-870.9846521378635 +550949500.0,1426.8294804161683,-871.7998074822988 +551449000.0,1426.4601710163558,-872.6127083530015 +551948500.0,1424.1041144570663,-873.4262100943572 +552448000.0,1423.634642949545,-874.2384436713342 +552947500.0,1423.694651247628,-875.050115102762 +553447000.0,1425.081187944571,-875.8617772450124 +553946500.0,1423.3160407820665,-876.673266243592 +554446000.0,1422.7255639559385,-877.4851627716793 +554945500.0,1423.7424718600578,-878.2972449574561 +555445000.0,1423.9255353351332,-879.1092439065202 +555944500.0,1422.414333351525,-879.9222799177818 +556444000.0,1423.8493055530025,-880.7339247477554 +556943500.0,1422.0253848021703,-881.5476904304908 +557443000.0,1418.95655028622,-882.3603148738068 +557942500.0,1420.6843887433636,-883.1723700343922 +558442000.0,1419.1366548588667,-883.9844410165956 +558941500.0,1417.1175902042976,-884.7968793653324 +559441000.0,1417.797077337211,-885.6063714506178 +559940500.0,1414.9945775480828,-886.4200931922553 +560440000.0,1413.4040312810043,-887.2324411235583 +560939500.0,1413.250689065477,-888.043613667437 +561439000.0,1409.55614553912,-888.8569220885441 +561938500.0,1404.7216037182511,-889.6693359479075 +562438000.0,1400.677441809162,-890.4819483456679 +562937500.0,1401.7747625408683,-891.2945176971477 +563437000.0,1397.7275467848467,-892.1083994926007 +563936500.0,1395.4540110070204,-892.9202774708103 +564436000.0,1392.9561662073243,-893.7334424920886 +564935500.0,1391.966426006151,-894.546045443426 +565435000.0,1390.2610672105025,-895.3594255122314 +565934500.0,1388.553059189665,-896.1724748730988 +566434000.0,1388.702271455725,-896.9853484732496 +566933500.0,1389.711867997068,-897.7993027399659 +567433000.0,1386.8167455343792,-898.6121896480557 +567932500.0,1383.9324920584224,-899.425577077064 +568432000.0,1380.8914071843558,-900.2385638583521 +568931500.0,1378.0065728684042,-901.0525480163324 +569431000.0,1378.7797349154755,-901.8652344845631 +569930500.0,1373.250339980346,-902.6774257720614 +570430000.0,1368.816496128774,-903.4891633900594 +570929500.0,1366.7645035196506,-904.3008828833813 +571429000.0,1363.2977135199617,-905.1150194599003 +571928500.0,1360.3866013447841,-905.9276176201652 +572428000.0,1360.2752314688514,-906.7396384605338 +572927500.0,1360.3062418686804,-907.5530159912681 +573427000.0,1358.4825220950543,-908.367828024478 +573926500.0,1354.6346914609044,-909.1809600636856 +574426000.0,1354.442698667115,-909.9933449857909 +574925500.0,1351.4431760438142,-910.807546826423 +575425000.0,1352.8685266150296,-911.6210200642038 +575924500.0,1351.9322837891107,-912.4334706649407 +576424000.0,1352.7504868316369,-913.2451918752633 +576923500.0,1352.6672642055357,-914.0603892967055 +577423000.0,1350.688374640212,-914.8747888914604 +577922500.0,1352.0062434627325,-915.6888197158149 +578422000.0,1349.330447834969,-916.5031357064361 +578921500.0,1344.0905622832477,-917.3155989836993 +579421000.0,1342.628753329151,-918.1302668090809 +579920500.0,1340.2673169579418,-918.9431061917453 +580420000.0,1338.5985010464149,-919.7587117722793 +580919500.0,1336.6883042634522,-920.5742496698776 +581419000.0,1335.1823070031194,-921.3903082661233 +581918500.0,1335.1527284585563,-922.201943721022 +582418000.0,1333.6954924008924,-923.0145571521492 +582917500.0,1331.7293168464837,-923.8280364518474 +583417000.0,1330.7970693868697,-924.6421136494849 +583916500.0,1327.8898560406728,-925.4545226409682 +584416000.0,1326.5515004935505,-926.2684086037646 +584915500.0,1324.4544819149626,-927.082451131779 +585415000.0,1322.2728930063247,-927.8983256118595 +585914500.0,1319.7773285013695,-928.7119768803058 +586414000.0,1318.375442368036,-929.5250840379764 +586913500.0,1317.6542384777713,-930.3377009973153 +587413000.0,1314.6293197353084,-931.1514145470912 +587912500.0,1311.2873775011387,-931.9655997585029 +588412000.0,1309.4633267356492,-932.7775402218317 +588911500.0,1305.6919096829126,-933.5903793351038 +589411000.0,1304.5693258113101,-934.4038772783931 +589910500.0,1302.9921517416958,-935.214718488874 +590410000.0,1301.6604948161485,-936.0285796992943 +590909500.0,1301.289960711426,-936.841904201277 +591409000.0,1298.359138906137,-937.6551502559056 +591908500.0,1298.1290804348396,-938.4686229829572 +592408000.0,1296.9214545312032,-939.2808673369968 +592907500.0,1295.7149830136934,-940.0950796835734 +593407000.0,1295.547535774021,-940.9086906894929 +593906500.0,1295.2168881232603,-941.7209673511916 +594406000.0,1294.4708024526826,-942.5357633539569 +594905500.0,1292.7451609522566,-943.3470313515692 +595405000.0,1289.3289744895203,-944.1601116313025 +595904500.0,1287.4630640750504,-944.9738523399379 +596404000.0,1284.3907876414057,-945.7848460001525 +596903500.0,1282.5844489590736,-946.5967698066419 +597403000.0,1281.0912410445296,-947.4091426193733 +597902500.0,1279.466671317095,-948.2223233341977 +598402000.0,1279.2700348640346,-949.0350242982503 +598901500.0,1276.9119227258584,-949.8495652850634 +599401000.0,1277.1222866039695,-950.6624124658368 +599900500.0,1274.9289329784747,-951.4744585529986 +600400000.0,1274.5379000157714,-952.2877816659269 +600899500.0,1274.2955049068682,-953.1007894212383 +601399000.0,1272.6252528208547,-953.9133848234068 +601898500.0,1270.6091111637986,-954.7259365227027 +602398000.0,1269.8691846940517,-955.539097717559 +602897500.0,1269.901604753974,-956.3525067283965 +603397000.0,1268.7513937944811,-957.1673270179997 +603896500.0,1267.5683871936162,-957.9787750644929 +604396000.0,1265.7971999503318,-958.7925755116647 +604895500.0,1266.049570021344,-959.6063734676923 +605395000.0,1267.4386074384688,-960.4197851277338 +605894500.0,1266.2707972331586,-961.2357738146719 +606394000.0,1264.035552089199,-962.050057544674 +606893500.0,1263.8397078467406,-962.8655114741784 +607393000.0,1261.4890084236802,-963.6805297396506 +607892500.0,1260.0787930136241,-964.4963257519183 +608392000.0,1257.4550904304128,-965.31053762528 +608891500.0,1255.947246302029,-966.1238988232762 +609391000.0,1254.066992695891,-966.9385523137581 +609890500.0,1251.938454092591,-967.7541685723754 +610390000.0,1249.8892399261474,-968.5677126571828 +610889500.0,1245.8737327223505,-969.38315554824 +611389000.0,1242.3907432667713,-970.1974112306709 +611888500.0,1238.9924420443906,-971.0136374813998 +612388000.0,1235.7367375360595,-971.8295552448219 +612887500.0,1232.1357989659955,-972.6437582171337 +613387000.0,1229.4983866181592,-973.4590361480227 +613886500.0,1228.7896994859134,-974.275798364416 +614386000.0,1227.0101137824895,-975.0914319639356 +614885500.0,1225.2395011756694,-975.9078930250354 +615385000.0,1221.1888917450613,-976.7243418522769 +615884500.0,1221.1066636292899,-977.5394750530744 +616384000.0,1216.56213140543,-978.3529246498979 +616883500.0,1214.2461564311766,-979.1673261653634 +617383000.0,1213.3657762629064,-979.982366372712 +617882500.0,1211.967061333433,-980.7968383051635 +618382000.0,1209.099057762443,-981.6118919196851 +618881500.0,1207.9672736782697,-982.4303754338988 +619381000.0,1205.632904174404,-983.2465790769314 +619880500.0,1203.6218346668247,-984.0630349791267 +620380000.0,1203.226155325509,-984.8781259832118 +620879500.0,1200.8297653635477,-985.6920658483435 +621379000.0,1197.6706441438703,-986.5071853454124 +621878500.0,1194.9865168217455,-987.3207695619277 +622378000.0,1195.160665870763,-988.1338664825562 +622877500.0,1194.1882242770866,-988.9469709692364 +623377000.0,1190.595890835018,-989.7612107985044 +623876500.0,1189.883092505831,-990.5751464014206 +624376000.0,1187.2979890771358,-991.3899671394109 +624875500.0,1184.6981031180212,-992.2069576361823 +625375000.0,1181.4823433480828,-993.0234127695188 +625874500.0,1180.3743360971885,-993.8377528151765 +626374000.0,1179.6527038837999,-994.6539211112455 +626873500.0,1178.4885881403518,-995.4687880600874 +627373000.0,1179.2535361385621,-996.2843519993977 +627872500.0,1179.39207480195,-997.0989616703371 +628372000.0,1176.4707137589735,-997.9124298796592 +628871500.0,1177.7862224685882,-998.7254862450991 +629371000.0,1174.6726528902818,-999.5384061627958 +629870500.0,1173.226095027878,-1000.3536312575208 +630370000.0,1172.807560627527,-1001.1677572277148 +630869500.0,1169.5435006976452,-1001.9822259878993 +631369000.0,1168.7972729919497,-1002.797212247983 +631868500.0,1166.478619617385,-1003.6142467000792 +632368000.0,1167.093963073777,-1004.428868493535 +632867500.0,1166.1504063295297,-1005.2454659840311 +633367000.0,1166.5342789935717,-1006.0610844117854 +633866500.0,1164.0627153558353,-1006.8759131378054 +634366000.0,1159.5992414269933,-1007.6902838727806 +634865500.0,1158.3146890437615,-1008.5058636122307 +635365000.0,1156.077501644842,-1009.3203760707725 +635864500.0,1156.423269172137,-1010.133653396283 +636364000.0,1156.1469893040075,-1010.9508657195777 +636863500.0,1155.468868224439,-1011.7661432312907 +637363000.0,1155.7719115072819,-1012.5813530630674 +637862500.0,1155.3106182327235,-1013.397478543813 +638362000.0,1151.621327906375,-1014.2129490273575 +638861500.0,1151.346283985616,-1015.0320784754304 +639361000.0,1150.4959813848238,-1015.8482358834506 +639860500.0,1149.2934200759707,-1016.6643385036047 +640360000.0,1147.876986810274,-1017.4829116968556 +640859500.0,1147.090287077921,-1018.2998429975036 +641359000.0,1145.9157608465148,-1019.1183295325266 +641858500.0,1143.8253262773508,-1019.9369415046136 +642358000.0,1146.1187778023932,-1020.7551749545652 +642857500.0,1144.118503859899,-1021.573342842735 +643357000.0,1142.5190070626022,-1022.3902749439313 +643856500.0,1142.381787194151,-1023.2086368243629 +644356000.0,1137.9824559037943,-1024.028796629204 +644855500.0,1135.0119557528944,-1024.8471186094268 +645355000.0,1131.0494148967591,-1025.6672163012777 +645854500.0,1129.862419093257,-1026.4876834080235 +646354000.0,1128.227555404924,-1027.3088730707218 +646853500.0,1124.8077154537027,-1028.1259033744582 +647353000.0,1122.5229673254034,-1028.9446796407917 +647852500.0,1120.4062907380126,-1029.7653315267469 +648352000.0,1118.7411455075219,-1030.5840063601406 +648851500.0,1115.9420162421402,-1031.402165432688 +649351000.0,1114.376728307625,-1032.2210150386363 +649850500.0,1110.95377938866,-1033.0415067874915 +650350000.0,1109.1601393604806,-1033.8594976347342 +650849500.0,1105.4697261810059,-1034.6792256341303 +651349000.0,1102.227952161551,-1035.4972210405524 +651848500.0,1098.5623847866984,-1036.3162712259057 +652348000.0,1095.6457882662378,-1037.1365992212725 +652847500.0,1092.2714796363532,-1037.9574890069068 +653347000.0,1088.405173495427,-1038.7767125444905 +653846500.0,1085.4852991514952,-1039.594898003031 +654346000.0,1084.5203503480575,-1040.4125820962806 +654845500.0,1081.7058779014312,-1041.2290907586942 +655345000.0,1077.409044328112,-1042.0453093380802 +655844500.0,1075.533222584868,-1042.861799782495 +656344000.0,1073.6502346898983,-1043.6774399187245 +656843500.0,1073.4676752268042,-1044.4960975646914 +657343000.0,1070.1995453196207,-1045.313401083969 +657842500.0,1067.675947946165,-1046.132750334745 +658342000.0,1065.183393445379,-1046.9508415213488 +658841500.0,1062.343129749985,-1047.7703772211498 +659341000.0,1059.291191859348,-1048.5885431447248 +659840500.0,1057.1279979108856,-1049.4061112571983 +660340000.0,1058.0344527213722,-1050.2246735244455 +660839500.0,1057.3317651630136,-1051.0431894464316 +661339000.0,1055.1848145676522,-1051.8622002515804 +661838500.0,1053.660336716492,-1052.6811662644623 +662338000.0,1051.7242072890394,-1053.4997498725231 +662837500.0,1047.8677000099633,-1054.3181070183869 +663337000.0,1046.0542280680745,-1055.136454458185 +663836500.0,1042.3472631111936,-1055.954919509406 +664336000.0,1038.4410684994114,-1056.7751220141697 +664835500.0,1034.1219737728247,-1057.593451442837 +665335000.0,1030.561995447033,-1058.4141292450422 +665834500.0,1028.6663372183032,-1059.234148406004 +666334000.0,1025.0907821326516,-1060.0545926382426 +666833500.0,1022.8128497144762,-1060.8758277288587 +667333000.0,1019.5659475662657,-1061.6970517696905 +667832500.0,1014.496653133246,-1062.5173936844865 +668332000.0,1008.72081378058,-1063.3377489589882 +668831500.0,1003.867360377786,-1064.1577315452046 +669331000.0,999.4471831006184,-1064.9779665272815 +669830500.0,996.3457623767121,-1065.7994497394338 +670330000.0,993.2754852368298,-1066.6200891380245 +670829500.0,988.2916793842246,-1067.44262408651 +671329000.0,983.407998649841,-1068.2610078165656 +671828500.0,978.2032777082817,-1069.081749177361 +672328000.0,971.2800344851687,-1069.9035804713255 +672827500.0,964.7207914646156,-1070.7264761296487 +673327000.0,960.4791171555058,-1071.5509413097227 +673826500.0,955.8289719305722,-1072.3722091558477 +674326000.0,949.7321882194674,-1073.1930273203684 +674825500.0,944.475443453905,-1074.0156921669327 +675325000.0,940.4022421957656,-1074.8374504386954 +675824500.0,934.5309860455725,-1075.6596742302015 +676324000.0,930.1199568472108,-1076.4830437657174 +676823500.0,926.2490500597861,-1077.3035882136505 +677323000.0,919.5033411425608,-1078.1271367169834 +677822500.0,913.9712709355758,-1078.9496366297835 +678322000.0,909.96185549555,-1079.7742795371987 +678821500.0,903.8247057592583,-1080.5975120710984 +679321000.0,899.0001111278872,-1081.4214852083167 +679820500.0,893.9297569206985,-1082.2448792338228 +680320000.0,888.7293925106226,-1083.0693555119467 +680819500.0,884.2673919322148,-1083.8907499955837 +681319000.0,879.192080788298,-1084.7125283985065 +681818500.0,876.5514658380005,-1085.5363802883335 +682318000.0,872.0212854602778,-1086.359461361058 +682817500.0,867.4617121558822,-1087.1817672853822 +683317000.0,863.0570735415959,-1088.0042004737622 +683816500.0,859.0695987167479,-1088.8277465077513 +684316000.0,852.8784082045789,-1089.6504598504876 +684815500.0,849.4088247878169,-1090.4733480070665 +685315000.0,843.8916893975565,-1091.2980295865436 +685814500.0,837.9948971948132,-1092.1220579376102 +686314000.0,832.4379960319403,-1092.9468172698378 +686813500.0,826.5009570231696,-1093.7709869174316 +687313000.0,820.7134730113869,-1094.593850433491 +687812500.0,814.3271128419345,-1095.4174521900243 +688312000.0,807.4948711586243,-1096.2424369298194 +688811500.0,801.2321461658277,-1097.0654082657668 +689311000.0,793.1931379545449,-1097.8886463148347 +689810500.0,786.2365606562189,-1098.7121756896017 +690310000.0,780.7490864457924,-1099.5356401738172 +690809500.0,774.0788285336806,-1100.3591679015215 +691309000.0,768.3191596201896,-1101.1846330716512 +691808500.0,760.6946474401428,-1102.0073271497115 +692308000.0,753.623331977509,-1102.8307456481602 +692807500.0,746.0852535306021,-1103.6525468758725 +693307000.0,739.7949939064567,-1104.4741559130075 +693806500.0,732.7925021638252,-1105.2963163883603 +694306000.0,726.6681245088856,-1106.1204882453712 +694805500.0,721.3389704377413,-1106.944318019847 +695305000.0,712.9904462228625,-1107.7684978353361 +695804500.0,704.8903991773998,-1108.5931927257243 +696304000.0,697.2455543502808,-1109.4158717524022 +696803500.0,689.5382938646433,-1110.2385440494054 +697303000.0,681.6277279383752,-1111.0621233777465 +697802500.0,673.7444574909663,-1111.8863677443117 +698302000.0,666.5076009766833,-1112.70905009065 +698801500.0,658.262291162682,-1113.5322371542961 +699301000.0,650.9263816774326,-1114.3556130449238 +699800500.0,643.8915327859285,-1115.1813631021573 +700300000.0,637.502759344876,-1116.005660106978 +700799500.0,629.4869065011902,-1116.8292050876623 +701299000.0,621.5453667310043,-1117.6537626587674 +701798500.0,613.2558087310796,-1118.4761813983703 +702298000.0,605.2734730265307,-1119.3001864956284 +702797500.0,598.1910521842675,-1120.1230640857616 +703297000.0,589.9726254776102,-1120.9453924098048 +703796500.0,581.6665663769274,-1121.7701757995758 +704296000.0,574.6061163672251,-1122.5923692119616 +704795500.0,566.8245745558937,-1123.416490531482 +705295000.0,559.3299566611962,-1124.2402708949553 +705794500.0,551.4592239143738,-1125.0628232560691 +706294000.0,543.7820333670287,-1125.8871237763055 +706793500.0,535.7403372224368,-1126.7122571178786 +707293000.0,528.0021450973861,-1127.537107155382 +707792500.0,519.3879844565749,-1128.3624440805302 +708292000.0,512.1783664475507,-1129.182574131043 +708791500.0,504.91566230819865,-1130.0049577652517 +709291000.0,498.26563251968497,-1130.8291864432113 +709790500.0,491.14222551355107,-1131.6529549239824 +710290000.0,482.94287705299735,-1132.4779407971846 +710789500.0,475.6611238015111,-1133.3031930379275 +711289000.0,468.19781469937453,-1134.1253014324739 +711788500.0,461.45232681968736,-1134.9483144394833 +712288000.0,454.67974402100873,-1135.7726245713175 +712787500.0,447.60335277903044,-1136.5971449362212 +713287000.0,439.92817825713854,-1137.4207202890013 +713786500.0,432.4216872338385,-1138.246035287477 +714286000.0,425.53564428254674,-1139.0698863826105 +714785500.0,419.2477254702895,-1139.8929376918904 +715285000.0,413.57825931615116,-1140.7152205922707 +715784500.0,407.75281506180596,-1141.5386472261014 +716284000.0,402.2753048818381,-1142.3626346810313 +716783500.0,395.92644721727765,-1143.185940142508 +717283000.0,390.7535879306404,-1144.0081958113258 +717782500.0,384.80033620421364,-1144.8307395962045 +718282000.0,379.2470953124857,-1145.6538720196238 +718781500.0,373.6913409692982,-1146.4755082998374 +719281000.0,367.8993168849219,-1147.2995444493868 +719780500.0,361.52613395586735,-1148.1238695278817 +720280000.0,355.56379552508326,-1148.9467118551902 +720779500.0,349.4848307769004,-1149.7686646473076 +721279000.0,343.82006421138516,-1150.5921738433346 +721778500.0,338.2158892693295,-1151.4154164930937 +722278000.0,331.8118816084598,-1152.2398928848138 +722777500.0,325.95880146189086,-1153.0618206801162 +723277000.0,320.7208201071343,-1153.8833986926631 +723776500.0,314.8044594888525,-1154.7053653649987 +724276000.0,309.1891369564029,-1155.5262656262696 +724775500.0,304.28436946846284,-1156.34909790205 +725275000.0,299.0189470883366,-1157.1711962133147 +725774500.0,293.38162757407645,-1157.9922168035105 +726274000.0,287.55506487683914,-1158.8134983129694 +726773500.0,282.35314992911026,-1159.634472861372 +727273000.0,276.8402357646534,-1160.4560911391263 +727772500.0,271.40808230439194,-1161.2769013754248 +728272000.0,266.00895619755727,-1162.0997720868336 +728771500.0,261.0029449414292,-1162.9216176445912 +729271000.0,255.46053538053636,-1163.7423911776336 +729770500.0,249.7381447347547,-1164.564851098152 +730270000.0,245.01021998929204,-1165.3854122867704 +730769500.0,239.57019287568136,-1166.204028504726 +731269000.0,234.86875731013072,-1167.025619270531 +731768500.0,229.83050625265392,-1167.8462699412923 +732268000.0,225.70269989747274,-1168.6671847294747 +732767500.0,221.42725153896743,-1169.4864547535058 +733267000.0,217.32090765129115,-1170.306369587016 +733766500.0,212.8775811684415,-1171.126109221075 +734266000.0,208.6909316854788,-1171.946084817413 +734765500.0,205.12094778365568,-1172.7656799462388 +735265000.0,200.4492756912944,-1173.5853063302445 +735764500.0,196.04647545175806,-1174.4053751315726 +736264000.0,191.93879086237033,-1175.2234947297134 +736763500.0,187.96042737361626,-1176.04313714941 +737263000.0,184.02207563024422,-1176.8613430190421 +737762500.0,179.57061024300646,-1177.6814688408372 +738262000.0,175.6961083331549,-1178.501911701528 +738761500.0,172.03380432528377,-1179.3229315711321 +739261000.0,168.32967716041432,-1180.1443750651633 +739760500.0,164.78220120023934,-1180.9645853855668 +740260000.0,160.83427062007593,-1181.784879430145 +740759500.0,157.3121162318661,-1182.6058307026854 +741259000.0,153.56137798445846,-1183.4267686133194 +741758500.0,150.3775336361916,-1184.2452722074395 +742258000.0,147.2619771853476,-1185.0665147021584 +742757500.0,143.985142677475,-1185.8853131561825 +743257000.0,141.0235986491288,-1186.7076853539888 +743756500.0,137.6037107087237,-1187.5291473555212 +744256000.0,134.534732812552,-1188.3498597228354 +744755500.0,131.1877814239901,-1189.1722160986587 +745255000.0,128.2584735331357,-1189.9929428253022 +745754500.0,125.24527587264446,-1190.8119854329955 +746254000.0,122.51556812118747,-1191.6323501318627 +746753500.0,119.40488766135942,-1192.455514659502 +747253000.0,116.33758213811277,-1193.276615722118 +747752500.0,113.32678542854958,-1194.0967164258823 +748252000.0,110.64690815655108,-1194.9155407474746 +748751500.0,108.03050652273106,-1195.7363852608346 +749251000.0,105.23968628578875,-1196.5546070670446 +749750500.0,102.9383273144194,-1197.374388904305 +750250000.0,100.5574764055912,-1198.1952012661493 +750749500.0,98.22263278139793,-1199.0122509395617 +751249000.0,95.83971977422685,-1199.8312961072081 +751748500.0,93.51987577146637,-1200.6495616176148 +752248000.0,91.14931760133337,-1201.4679425980767 +752747500.0,88.61508865292122,-1202.2863316329099 +753247000.0,86.29370744548042,-1203.104755643652 +753746500.0,84.14630487899758,-1203.9252780753764 +754246000.0,82.03869063964825,-1204.7450635942964 +754745500.0,79.8441250730653,-1205.562992722939 +755245000.0,77.68063586722198,-1206.3835824180323 +755744500.0,75.73328107222946,-1207.2019974009586 +756244000.0,73.55161005308389,-1208.0179267625122 +756743500.0,71.27343614441679,-1208.8333026088092 +757243000.0,69.4445572959877,-1209.6505938113971 +757742500.0,67.37773111093831,-1210.4673491370627 +758242000.0,65.34196543677992,-1211.282820106834 +758741500.0,63.62328355583271,-1212.098032369144 +759241000.0,62.043352164322805,-1212.9152663153518 +759740500.0,60.218673008931404,-1213.7308463942438 +760240000.0,58.54691903279689,-1214.5458258120973 +760739500.0,57.030896456868206,-1215.3629035244803 +761239000.0,55.266455158026346,-1216.1780597968586 +761738500.0,53.44260720315402,-1216.9924149953736 +762238000.0,51.869419622732224,-1217.808404742535 +762737500.0,50.28603859177014,-1218.6243554966213 +763237000.0,48.87135584390379,-1219.4388384575122 +763736500.0,47.377919417708746,-1220.252774287169 +764236000.0,45.88444874628601,-1221.0685930756802 +764735500.0,44.31475657104766,-1221.8845514610898 +765235000.0,42.868456390108115,-1222.70015532818 +765734500.0,41.67383472200946,-1223.5172186133266 +766234000.0,40.4277410497612,-1224.3321918186894 +766733500.0,39.28760208184816,-1225.1478710965525 +767233000.0,38.1425126898715,-1225.9629096737945 +767732500.0,36.91978822967944,-1226.7771435934467 +768232000.0,35.72964834887548,-1227.5917902728895 +768731500.0,34.482914614519686,-1228.406265159489 +769231000.0,33.38410802415823,-1229.2190036657018 +769730500.0,32.26753528052917,-1230.0324612102354 +770230000.0,31.12090467903756,-1230.8450414011916 +770729500.0,30.027157586158353,-1231.6581894319636 +771229000.0,29.06997632885369,-1232.4714542487359 +771728500.0,28.036024623112397,-1233.2835948227842 +772228000.0,26.93254585283919,-1234.0948915800298 +772727500.0,26.003949277242704,-1234.9064553632566 +773227000.0,25.129940916993142,-1235.7181271976383 +773726500.0,24.210199895987113,-1236.5285586069306 +774226000.0,23.279225762516095,-1237.3396822414043 +774725500.0,22.43469169906362,-1238.1516238229167 +775225000.0,21.68732193812123,-1238.9613445051918 +775724500.0,20.898910368702815,-1239.7697311242387 +776224000.0,20.152441001566185,-1240.5784204813942 +776723500.0,19.346236207643432,-1241.3881167756695 +777223000.0,18.59867139707601,-1242.1945676691096 +777722500.0,17.857800613564997,-1243.0033188329623 +778222000.0,17.273760321700003,-1243.8116748496004 +778721500.0,16.687215704741426,-1244.6183080734645 +779221000.0,16.09056639101147,-1245.4260093383064 +779720500.0,15.537240747071287,-1246.2320166198951 +780220000.0,14.89120253302119,-1247.0372079199044 +780719500.0,14.311586702946872,-1247.8415457677847 +781219000.0,13.664407984843018,-1248.6446784910127 +781718500.0,13.073294747293856,-1249.4480760469423 +782218000.0,12.638931275739257,-1250.2491343937604 +782717500.0,12.140862447607246,-1251.0517221031307 +783217000.0,11.694755684239405,-1251.8534165374256 +783716500.0,11.235034330551725,-1252.6520772829836 +784216000.0,10.772457587320405,-1253.4498638678867 +784715500.0,10.288185187832859,-1254.245808401281 +785215000.0,9.907894387211924,-1255.039383219548 +785714500.0,9.489934356945584,-1255.8347419776342 +786214000.0,9.067169248086403,-1256.6286272496852 +786713500.0,8.703339546649588,-1257.422310145182 +787213000.0,8.336435791388324,-1258.2156124041762 +787712500.0,7.975758927874574,-1259.008081312209 +788212000.0,7.645461461350329,-1259.7989669780297 +788711500.0,7.338470453049309,-1260.586676206187 +789211000.0,7.047822991630419,-1261.3726826706986 +789710500.0,6.769449822214936,-1262.1586756151585 +790210000.0,6.527958233664672,-1262.9417862035896 +790709500.0,6.273513314989113,-1263.7247504861841 +791209000.0,6.025558951306466,-1264.5074781043395 +791708500.0,5.796560911989793,-1265.2917312077607 +792208000.0,5.593468348982898,-1266.070041870406 +792707500.0,5.422966797451967,-1266.8492040525912 +793207000.0,5.257547418817226,-1267.6294877422226 +793706500.0,5.074842187193831,-1268.4074887610795 +794206000.0,4.903484216068243,-1269.184050082667 +794705500.0,4.756352424587254,-1269.9600680361514 +795205000.0,4.589016536314508,-1270.7375622955087 +795704500.0,4.450373620447544,-1271.5138704243384 +796204000.0,4.339650624967107,-1272.2900174527679 +796703500.0,4.2428809757897,-1273.0677372399953 +797203000.0,4.142590213782468,-1273.8421496007222 +797702500.0,4.051237851460913,-1274.617171374223 +798202000.0,3.9761702749330725,-1275.3918883657725 +798701500.0,3.9181800136794003,-1276.1692447301095 +799201000.0,3.858954498984959,-1276.9462915019074 +799700500.0,3.8142179418344586,-1277.7240396147697 +800200000.0,3.7851132506669583,-1278.5034651347953 +800699500.0,3.711945308056526,-1279.2837148454726 +801199000.0,3.6766325750528086,-1280.0629594445784 +801698500.0,3.631216984955509,-1280.844656829658 +802198000.0,3.588047862408983,-1281.6260215888765 +802697500.0,3.5486160182296134,-1282.4072345566349 +803197000.0,3.5221289121636734,-1283.1883492958007 +803696500.0,3.4972599072660833,-1283.9733251363896 +804196000.0,3.4740564936414007,-1284.7585896587802 +804695500.0,3.455559299011659,-1285.5406462075784 +805195000.0,3.4456785559449417,-1286.3280593704892 +805694500.0,3.426931413449526,-1287.112044513963 +806194000.0,3.4170927074412916,-1287.8984758893203 +806693500.0,3.4152445085457774,-1288.688959504814 +807193000.0,3.3973393114073955,-1289.479970834007 +807692500.0,3.386318504141009,-1290.2695531189352 +808192000.0,3.378558977921892,-1291.0621016049736 +808691500.0,3.3629114630566397,-1291.8553074555775 +809191000.0,3.345812941614662,-1292.6505214695107 +809690500.0,3.35337548122632,-1293.4437827487468 +810190000.0,3.346152938421341,-1294.2392382955854 +810689500.0,3.332883424781811,-1295.0348520844695 +811189000.0,3.318057271088299,-1295.8318373039788 +811688500.0,3.313689392668141,-1296.6294359213427 +812188000.0,3.303992725870965,-1297.4293843753007 +812687500.0,3.293152706198795,-1298.2262409917585 +813187000.0,3.2829673763696587,-1299.0267870923954 +813686500.0,3.277866020890828,-1299.8264293484272 +814186000.0,3.26259446861196,-1300.6246182694463 +814685500.0,3.2528409631227064,-1301.4237181871133 +815185000.0,3.2338224498652313,-1302.2226053257377 +815684500.0,3.2158555540729283,-1303.0218925667577 +816184000.0,3.203541518064863,-1303.8247478309383 +816683500.0,3.1768016769877447,-1304.6244511974983 +817183000.0,3.152320585445801,-1305.429150994951 +817682500.0,3.1339216283817293,-1306.2312093781118 +818182000.0,3.1125596043283457,-1307.0337547131774 +818681500.0,3.084772248816214,-1307.8367974203024 +819181000.0,3.0585106154426756,-1308.6390184569311 +819680500.0,3.024904574717705,-1309.4441082894841 +820180000.0,2.999454917593348,-1310.24832233649 +820679500.0,2.967438663224818,-1311.0531124604083 +821179000.0,2.9410777773394057,-1311.8575260392963 +821678500.0,2.909983592204407,-1312.662204997917 +822178000.0,2.8827036213671176,-1313.4673435741188 +822677500.0,2.84861230937288,-1314.2703256209502 +823177000.0,2.818001566550502,-1315.0752274373122 +823676500.0,2.787644437627138,-1315.881643462259 +824176000.0,2.7565960051696683,-1316.6866970582203 +824675500.0,2.722772516398336,-1317.4942020665285 +825175000.0,2.6914196334185996,-1318.3006520404826 +825674500.0,2.663275512924903,-1319.1027340131034 +826174000.0,2.6333900802440695,-1319.9110982634952 +826673500.0,2.603203943067009,-1320.715689015252 +827173000.0,2.573031792020125,-1321.5231612646269 +827672500.0,2.545655290082352,-1322.3303652375164 +828172000.0,2.506886281657559,-1323.1330529938614 +828671500.0,2.4727161308237386,-1323.9388233283926 +829171000.0,2.4384051643827704,-1324.7452363146324 +829670500.0,2.4048025491309772,-1325.549774082885 +830170000.0,2.3722870817685267,-1326.3560692142044 +830669500.0,2.341219524682552,-1327.1634849700745 +831169000.0,2.3068844779744304,-1327.9706454378156 +831668500.0,2.2723669077349338,-1328.7750879263185 +832168000.0,2.2419774694820322,-1329.5796277338295 +832667500.0,2.211985296245235,-1330.3878595528597 +833167000.0,2.171245473416529,-1331.19568662704 +833666500.0,2.134990013105309,-1332.003367941264 +834166000.0,2.0919348588848394,-1332.8114382615518 +834665500.0,2.0579007863581578,-1333.6199919883863 +835165000.0,2.0194447089978893,-1334.4284506005706 +835664500.0,1.9848536850272713,-1335.235175309366 +836164000.0,1.94953544734135,-1336.0456777571865 +836663500.0,1.911878406816963,-1336.8509319139484 +837163000.0,1.8761145090092364,-1337.6575753839004 +837662500.0,1.8404195422963663,-1338.463502520317 +838162000.0,1.8071861591899392,-1339.2709326917109 +838661500.0,1.7720118843086323,-1340.073432362092 +839161000.0,1.7372138608649594,-1340.879034036095 +839660500.0,1.7024784850968195,-1341.688542694514 +840160000.0,1.6657129703493365,-1342.4942010518432 +840659500.0,1.6264042230039406,-1343.3001331730372 +841159000.0,1.5872721765582123,-1344.106882825643 +841658500.0,1.5534835881574778,-1344.908071667436 +842158000.0,1.5245726999999416,-1345.7118715758515 +842657500.0,1.494852803574679,-1346.5176356096697 +843157000.0,1.4559227496725968,-1347.3223609559484 +843656500.0,1.424865489140085,-1348.127206196034 +844156000.0,1.3986774885653126,-1348.9278034431288 +844655500.0,1.363000491832873,-1349.733304168656 +845155000.0,1.3340413870584285,-1350.541486308697 +845654500.0,1.3022337218351339,-1351.3488088342945 +846154000.0,1.2734184368962358,-1352.1553973260093 +846653500.0,1.2490305445760863,-1352.9636693925056 +847153000.0,1.2228221810464877,-1353.7683937743168 +847652500.0,1.1951714893363834,-1354.5720710713085 +848152000.0,1.1733802870987065,-1355.3741830870244 +848651500.0,1.1493545211733989,-1356.177074687414 +849151000.0,1.1247049765395287,-1356.979071338688 +849650500.0,1.0942868881153383,-1357.7834157902257 +850150000.0,1.0700171388554842,-1358.5805814719226 +850649500.0,1.0510174053832342,-1359.3809709022855 +851149000.0,1.0258978536442005,-1360.1816805609044 +851648500.0,1.0026440173126987,-1360.986728639025 +852148000.0,0.9817834169665638,-1361.7892395674503 +852647500.0,0.9587410155469644,-1362.5901384935883 +853147000.0,0.9279697178266755,-1363.3912768953833 +853646500.0,0.9031722196568746,-1364.1899945755295 +854146000.0,0.8756506491957581,-1364.9848157125166 +854645500.0,0.853829339473446,-1365.7877215920216 +855145000.0,0.8286516606538102,-1366.5865082502844 +855644500.0,0.8036104362676176,-1367.3869006885195 +856144000.0,0.7773273161304353,-1368.1781505880779 +856643500.0,0.7536132243812381,-1368.975760208789 +857143000.0,0.7321395212179509,-1369.7733439214005 +857642500.0,0.7111573843462368,-1370.5706764783827 +858142000.0,0.6900908257164622,-1371.3646505902414 +858641500.0,0.668194672437885,-1372.1616390856766 +859141000.0,0.6484751525639998,-1372.9560913702912 +859640500.0,0.6292188954080772,-1373.7437084927653 +860140000.0,0.6133324653679408,-1374.5371650327015 +860639500.0,0.5967693210635415,-1375.3354539138782 +861139000.0,0.5844451981734518,-1376.1347522920576 +861638500.0,0.571682568272795,-1376.922724195433 +862138000.0,0.5600047672603587,-1377.7124285065415 +862637500.0,0.546263110310674,-1378.4975016595415 +863137000.0,0.5324938122998526,-1379.2861485259978 +863636500.0,0.5179102513693294,-1380.0720374782736 +864136000.0,0.5070200205468032,-1380.862947914926 +864635500.0,0.49526052347471095,-1381.6483287390624 +865135000.0,0.4803355721663909,-1382.4336407303886 +865634500.0,0.4684818758063211,-1383.2152402362972 +866134000.0,0.4553949124051252,-1384.0018155581797 +866633500.0,0.44349031854085835,-1384.788112118702 +867133000.0,0.43475340566981574,-1385.5834501583781 +867632500.0,0.4207625858656573,-1386.3646721835094 +868132000.0,0.4076070427249275,-1387.151650443448 +868631500.0,0.39587088817141314,-1387.93658769397 +869131000.0,0.38592552760928206,-1388.7245016123568 +869630500.0,0.3754609932009475,-1389.5176730388232 +870130000.0,0.3659828052037485,-1390.307255768993 +870629500.0,0.35554926113974694,-1391.0994780931612 +871129000.0,0.3472716658264986,-1391.8808050680357 +871628500.0,0.3390795869484806,-1392.6706414721746 +872128000.0,0.33245842693466215,-1393.4571113349161 +872627500.0,0.32504016273545683,-1394.2387810389228 +873127000.0,0.3158297640668524,-1395.0248039997132 +873626500.0,0.30804070638501474,-1395.8118888106774 +874126000.0,0.30150572494735617,-1396.6001820115819 +874625500.0,0.29359397735542025,-1397.3797086815987 +875125000.0,0.28544873091405865,-1398.161695695424 +875624500.0,0.2783474309873671,-1398.9451916630387 +876124000.0,0.27245435434735726,-1399.735231683674 +876623500.0,0.2685621168287062,-1400.5121015366142 +877123000.0,0.26284100005055794,-1401.2816738666663 +877622500.0,0.2577198317411962,-1402.0611575041605 +878122000.0,0.25332769299318614,-1402.840187256806 +878621500.0,0.24992400910325313,-1403.6195714726825 +879121000.0,0.2480156918986813,-1404.407719495782 +879620500.0,0.24567924282173523,-1405.19642280646 +880120000.0,0.24304708018865182,-1405.979873450072 +880619500.0,0.24071160326503507,-1406.7631060599856 +881119000.0,0.24182130787225056,-1407.5471725356183 +881618500.0,0.2397712414206233,-1408.3251727902418 +882118000.0,0.23570503725981667,-1409.1061014413501 +882617500.0,0.23357507008030018,-1409.8973664397108 +883117000.0,0.23482647045386768,-1410.679233903716 +883616500.0,0.23154989609237447,-1411.4620234621816 +884116000.0,0.2305874252265042,-1412.240847777862 +884615500.0,0.22721800267132475,-1413.018239109903 +885115000.0,0.2251586402255219,-1413.8032577949723 +885614500.0,0.22496457622293436,-1414.5966574704908 +886114000.0,0.22412771059009162,-1415.3915820809384 +886613500.0,0.2214751230172977,-1416.186820475829 +887113000.0,0.21842159702225644,-1416.9790882027798 +887612500.0,0.21556898503815244,-1417.771520925759 +888112000.0,0.21502921712867698,-1418.5610240453084 +888611500.0,0.21041356262263683,-1419.3400551726777 +889111000.0,0.20949848315644426,-1420.1333086644026 +889610500.0,0.20601936599705648,-1420.9343917273982 +890110000.0,0.20254170082705444,-1421.721757481192 +890609500.0,0.19923539163522047,-1422.5125247617402 +891109000.0,0.1961475738329096,-1423.3321642476142 +891608500.0,0.19482206795756127,-1424.1280069380716 +892108000.0,0.19189648915058952,-1424.917502495502 +892607500.0,0.18854092893482996,-1425.7210859638778 +893107000.0,0.1851106168673956,-1426.5201721298167 +893606500.0,0.18138238365034995,-1427.310584136051 +894106000.0,0.17863730728558525,-1428.1028741250118 +894605500.0,0.17769549305795543,-1428.9065615959569 +895105000.0,0.1755264022450148,-1429.6952261938163 +895604500.0,0.17382190585241847,-1430.488149130576 +896104000.0,0.1712768635481466,-1431.2607150540066 +896603500.0,0.1666982007582894,-1432.0564461271445 +897103000.0,0.16445353923376355,-1432.8344478336244 +897602500.0,0.16173199170872538,-1433.6288703708021 +898102000.0,0.15846036129724606,-1434.4108394084478 +898601500.0,0.15640935453462212,-1435.194634032762 +899101000.0,0.15449981232211651,-1435.9699579253984 +899600500.0,0.151057834498194,-1436.749819533126 +900100000.0,0.1491521511612256,-1437.5236570467277 +900599500.0,0.1468278488044645,-1438.3081141525583 +901099000.0,0.14380190476081173,-1439.0812246800979 +901598500.0,0.141065373599702,-1439.8641928282882 +902098000.0,0.1351721832479316,-1440.6322768232906 +902597500.0,0.13175905875188149,-1441.4180947814466 +903097000.0,0.12785464013989836,-1442.198347619145 +903596500.0,0.12558883495436612,-1442.9842854033639 +904096000.0,0.12207817730950973,-1443.7453886659155 +904595500.0,0.11973107990265835,-1444.5096646773438 +905095000.0,0.11640057852495629,-1445.279426019854 +905594500.0,0.11485884926730927,-1446.041769250522 +906094000.0,0.11283447532283966,-1446.814668108993 +906593500.0,0.10873650006523108,-1447.5815328023948 +907093000.0,0.10577849452338338,-1448.3477122451532 +907592500.0,0.10284165104156898,-1449.1177044738317 +908092000.0,0.09918923399826213,-1449.8911434735567 +908591500.0,0.09551597399910972,-1450.6568104391465 +909091000.0,0.0941085945007085,-1451.4255611226056 +909590500.0,0.0926473117317436,-1452.2053001683748 +910090000.0,0.08992209829355051,-1452.9747119359843 +910589500.0,0.08872805799086925,-1453.7449828705887 +911089000.0,0.08856721877017257,-1454.495078838638 +911588500.0,0.08613580720984326,-1455.2590726922353 +912088000.0,0.0856394626725257,-1456.0363340297527 +912587500.0,0.0854484724763008,-1456.7975316708082 +913087000.0,0.08642886789919549,-1457.5674556528725 +913586500.0,0.08633955741831659,-1458.3335270445787 +914086000.0,0.0860853276538506,-1459.0985372487535 +914585500.0,0.08672465112514881,-1459.8605597058415 +915085000.0,0.08806964850790111,-1460.625386859519 +915584500.0,0.09094021905786626,-1461.3966464845541 +916084000.0,0.09178042224966687,-1462.1637434339175 +916583500.0,0.09371820803870587,-1462.9310154030075 +917083000.0,0.09466661990922128,-1463.6933785659467 +917582500.0,0.09732183231085308,-1464.4525250805864 +918082000.0,0.09765983701521731,-1465.2133523844052 +918581500.0,0.09929898188703157,-1465.9821541318365 +919081000.0,0.09950441528141686,-1466.7550332481214 +919580500.0,0.10187623919210904,-1467.5293719736076 +920080000.0,0.10366150965488666,-1468.3133631856604 +920579500.0,0.10644030008198668,-1469.0953365694372 +921079000.0,0.11024144964860308,-1469.8726054279398 +921578500.0,0.11130668272039372,-1470.6481638757646 +922078000.0,0.11151860891435605,-1471.424148308738 +922577500.0,0.11363820803808057,-1472.1974637959925 +923077000.0,0.11584862899994099,-1472.974844913986 +923576500.0,0.11861119839703206,-1473.7648968897295 +924076000.0,0.12196843928548573,-1474.5607400678002 +924575500.0,0.12458746612260177,-1475.3393828480296 +925075000.0,0.1273173821371497,-1476.1384954691582 +925574500.0,0.13061386489932844,-1476.9326210565926 +926074000.0,0.1340300896618656,-1477.7082705344108 +926573500.0,0.13616949332450184,-1478.5069828742585 +927073000.0,0.13751040889513155,-1479.3073696689833 +927572500.0,0.14010486967901387,-1480.0969110668693 +928072000.0,0.14214608710569673,-1480.8892143994146 +928571500.0,0.1452864060152528,-1481.6798033984567 +929071000.0,0.1484690020092854,-1482.4743885205153 +929570500.0,0.15215900663209198,-1483.266444917795 +930070000.0,0.15356820083601233,-1484.0656762579727 +930569500.0,0.15510653053413592,-1484.8613063518035 +931069000.0,0.15615179236692256,-1485.6666377142014 +931568500.0,0.15886929822330126,-1486.4615960964309 +932068000.0,0.16073944416889097,-1487.267390787042 +932567500.0,0.16316108050951614,-1488.0576651032948 +933067000.0,0.1661493451366898,-1488.8532092877022 +933566500.0,0.1673205738754791,-1489.6505334299363 +934066000.0,0.1693341719264833,-1490.4508304834503 +934565500.0,0.1718075349646444,-1491.2507834038138 +935065000.0,0.17351361585632635,-1492.055910245948 +935564500.0,0.17420774841907075,-1492.8561506851456 +936064000.0,0.17364697824877715,-1493.6657899364045 +936563500.0,0.1752945050654851,-1494.464974567749 +937063000.0,0.17683685633099996,-1495.27713556854 +937562500.0,0.17760780649660396,-1496.071599496132 +938062000.0,0.18053278575672344,-1496.8666042961045 +938561500.0,0.1815181701544083,-1497.6477795347103 +939061000.0,0.1840467254935947,-1498.4537710428112 +939560500.0,0.1846290792634374,-1499.2602217349586 +940060000.0,0.18567599329392162,-1500.0582384638633 +940559500.0,0.18668800271599761,-1500.8575270446613 +941059000.0,0.18671046789321932,-1501.6518897023057 +941558500.0,0.18733306565271363,-1502.451798728561 +942058000.0,0.18837161254710558,-1503.253044587314 +942557500.0,0.18905432099259667,-1504.0581402880248 +943057000.0,0.18912517926260586,-1504.8581694649113 +943556500.0,0.19125232012825893,-1505.669048610183 +944056000.0,0.19067498144036713,-1506.4769300959351 +944555500.0,0.18957247294402904,-1507.271790821043 +945055000.0,0.18992102535425828,-1508.0762116707617 +945554500.0,0.18999536835625988,-1508.8710855490747 +946054000.0,0.18977870069218558,-1509.6808068283435 +946553500.0,0.19045889373095579,-1510.4849714435743 +947053000.0,0.19095055678203499,-1511.281857471021 +947552500.0,0.1909429258621425,-1512.0926033680992 +948052000.0,0.1903505438642737,-1512.892517478347 +948551500.0,0.1913931132698761,-1513.6948913436333 +949051000.0,0.1915148343241131,-1514.4996535513483 +949550500.0,0.19159185690587635,-1515.3062552171298 +950050000.0,0.1925097982916237,-1516.1074262297195 +950549500.0,0.19197414790387332,-1516.9105807424917 +951049000.0,0.1907574092666404,-1517.7068058645295 +951548500.0,0.190257205716573,-1518.5081531838805 +952048000.0,0.19069531354664612,-1519.3083987814312 +952547500.0,0.19025215688633831,-1520.1090782645135 +953047000.0,0.1893552919254461,-1520.9222036053723 +953546500.0,0.18913681987071904,-1521.7195148927995 +954046000.0,0.1902108527211287,-1522.5274092778486 +954545500.0,0.1906955506188668,-1523.3388459227665 +955045000.0,0.1905239992250165,-1524.1455189738613 +955544500.0,0.1887459730199131,-1524.9549788119764 +956044000.0,0.18505249414416425,-1525.7689710114612 +956543500.0,0.18368651215581677,-1526.5727127724126 +957043000.0,0.18330663914318943,-1527.3788622536024 +957542500.0,0.18156523021084287,-1528.1862021862632 +958042000.0,0.18145288252952296,-1528.9866969098575 +958541500.0,0.18154670690819957,-1529.7962232740408 +959041000.0,0.18075884864022465,-1530.599211116763 +959540500.0,0.17774387133688827,-1531.4080432286644 +960040000.0,0.1760573534319492,-1532.2061560768973 +960539500.0,0.17423057143369425,-1533.0114809697234 +961039000.0,0.17264010671506708,-1533.8201949971835 +961538500.0,0.1712278475565249,-1534.621211682754 +962038000.0,0.16950901305708174,-1535.4290934230576 +962537500.0,0.1678353550537421,-1536.2290452415689 +963037000.0,0.16793614441836055,-1537.0356013719816 +963536500.0,0.1675005185256126,-1537.8498560334106 +964036000.0,0.16640873989523966,-1538.6566016593233 +964535500.0,0.1640557161254272,-1539.449633585904 +965035000.0,0.16382276675868135,-1540.2504233217812 +965534500.0,0.1615318108074433,-1541.0507133965257 +966034000.0,0.16104037989145903,-1541.842897017806 +966533500.0,0.160002054078513,-1542.6404401578895 +967033000.0,0.1599440318579507,-1543.4351752835792 +967532500.0,0.15957550689957262,-1544.237585116289 +968032000.0,0.15758379040483328,-1545.041533599644 +968531500.0,0.15754965429097453,-1545.8429356777067 +969031000.0,0.15641138841335583,-1546.6357592456147 +969530500.0,0.15518090523192188,-1547.437129684222 +970030000.0,0.15299183655847262,-1548.229314371404 +970529500.0,0.15166737056720203,-1549.0312761530136 +971029000.0,0.15121850058960687,-1549.8238895024012 +971528500.0,0.15068292396077781,-1550.626132132964 +972028000.0,0.14858377759608316,-1551.419151591469 +972527500.0,0.14804169287041105,-1552.2178929035808 +973027000.0,0.14677546742811196,-1553.0053074438567 +973526500.0,0.14601980814601676,-1553.7999288038 +974026000.0,0.14423441181811497,-1554.5913670699128 +974525500.0,0.14324384971486798,-1555.3721642830428 +975025000.0,0.14157758075541463,-1556.16366601803 +975524500.0,0.1398406469961916,-1556.9536003057722 +976024000.0,0.13877590270576057,-1557.7504772809525 +976523500.0,0.1375885652017187,-1558.5392801761047 +977023000.0,0.1360315670739629,-1559.3288371423619 +977522500.0,0.1338693222619914,-1560.1179367843076 +978022000.0,0.13223604709753511,-1560.901337127838 +978521500.0,0.13055434709657862,-1561.688561622692 +979021000.0,0.12884480797630432,-1562.4717565573198 +979520500.0,0.1277156722780826,-1563.257424870606 +980020000.0,0.12611562822255526,-1564.0452969230694 +980519500.0,0.12497310185739194,-1564.8334418152801 +981019000.0,0.12380132005757395,-1565.615375265542 +981518500.0,0.12315431859942402,-1566.4005661428216 +982018000.0,0.12163691502413589,-1567.1859733720064 +982517500.0,0.12035263753787817,-1567.9559045602964 +983017000.0,0.11977353267299148,-1568.347035217298 +983516500.0,0.11867570221311316,-1569.1290726721345 +984016000.0,0.11766314310840059,-1569.9108350458037 +984515500.0,0.1167413626311044,-1570.6923510561326 +985015000.0,0.1159156263102461,-1571.47365010524 +985514500.0,0.11519095793161825,-1572.2547622795366 +986014000.0,0.11457213953778417,-1573.035718349725 +986513500.0,0.11406371142807828,-1573.8165497707994 +987013000.0,0.11366997215860591,-1574.5972886820462 +987512500.0,0.11339497854224323,-1575.3779679070435 +988012000.0,0.1132425456486375,-1576.1586209536617 +988511500.0,0.11321624680420685,-1576.9392820140624 +989011000.0,0.11331941359214034,-1577.7199859646994 +989510500.0,0.11355513585239801,-1578.5007683663184 +990010000.0,0.11392626168171086,-1579.281665463957 +990509500.0,0.11443539743358075,-1580.062714186945 +991009000.0,0.11508490771828059,-1580.843952148903 +991508500.0,0.11587691540285408,-1581.6254176477446 +992008000.0,0.1168133016111161,-1582.407149665675 +992507500.0,0.11789570572365221,-1583.1891878691908 +993007000.0,0.11912552537781917,-1583.9715726090808 +993506500.0,0.12050391646774442,-1584.754344920426 +994006000.0,0.1220317931443266,-1585.5375465225989 +994505500.0,0.12370982781523501,-1586.3212198192637 +995005000.0,0.1255384511449103,-1587.105407898377 +995504500.0,0.12751785205456356,-1587.8901545321867 +996004000.0,0.12964797772217726,-1588.6755041772333 +996503500.0,0.13192853358250453,-1589.4615019743483 +997003000.0,0.13435898332706958,-1590.2481937486557 +997502500.0,0.13693854890416757,-1591.0356260095712 +998002000.0,0.1396662105188645,-1591.8238459508025 +998501500.0,0.14254070663299745,-1592.6129014503488 +999001000.0,0.1455605339651743,-1593.4028410705018 +999500500.0,0.14872394749077394,-1594.1937140578443 +1000000000.0,0.15202896044194633,-1594.9855703432515 diff --git a/NuRadioReco/detector/RNO_G/HardwareResponses/surface_chan0_LinA.csv b/NuRadioReco/detector/RNO_G/HardwareResponses/surface_chan0_LinA.csv deleted file mode 100644 index b9001d9e1..000000000 --- a/NuRadioReco/detector/RNO_G/HardwareResponses/surface_chan0_LinA.csv +++ /dev/null @@ -1,2008 +0,0 @@ -!CSV A.01.01 -!Keysight Technologies,P5020A,MY58100190,A.14.10.03 -!Date: Monday, June 08, 2020 12:33:43 -!Source: Standard - -BEGIN CH1_DATA -Freq(Hz),S11(MAG),S11(DEG),S12(MAG),S12(DEG),S21(MAG),S21(DEG),S22(MAG),S22(DEG) -1000000,0.99709392,-7.1205082,0.0008338815,171.65002,0.029112857,7.2767472,0.95520139,-11.436144 -1499500,0.99828213,-11.081132,0.00055123848,46.674084,0.011048147,97.966331,1.0026708,-16.7328 -1999000,0.99406886,-15.085555,0.00037372892,30.919157,0.01498404,56.259075,0.96456617,-23.827827 -2498500,0.99591559,-18.359768,0.0018541599,117.65329,0.012678147,163.80347,0.98264331,-31.063223 -2998000,0.99602503,-22.196108,0.0007336518,-102.63219,0.042272288,70.089073,0.99642491,-33.233837 -3497500,0.99472004,-25.799314,0.0010782302,-88.445534,0.007391498,-46.295654,0.92292225,-41.392971 -3997000,0.99295527,-29.186163,0.00033269526,28.984457,0.018821079,-34.252308,0.91665184,-44.854694 -4496500,0.99079961,-33.048,0.00066910195,47.681293,0.03620889,-49.069748,0.91592216,-53.329342 -4996000,0.98987997,-36.631485,0.00084941788,-71.266335,0.0059751263,52.128605,0.89842188,-58.814514 -5495500,0.98868746,-40.315693,0.00029927463,95.124184,0.017043309,-85.525612,0.89307654,-64.710342 -5995000,0.98766917,-43.962955,0.0011648713,-28.150909,0.025019836,19.324551,0.88970053,-67.970291 -6494500,0.98604542,-47.520363,0.00046361855,62.451862,0.028829556,-60.887421,0.86303967,-72.11174 -6994000,0.98224199,-51.321941,0.00059124909,66.404167,0.02945393,172.15067,0.83971512,-77.829865 -7493500,0.97887617,-54.974918,0.00025536609,149.28577,0.028734064,2.7041569,0.82763004,-83.288689 -7993000,0.97695923,-58.728897,0.00030638219,117.16131,0.035200831,15.673961,0.83669686,-86.899689 -8492500,0.97319037,-62.227581,0.0015675167,-75.414009,0.029725725,37.153683,0.81124485,-89.230278 -8992000,0.9709267,-65.743462,0.00057389005,-155.89491,0.07302282,62.848198,0.8045851,-96.407852 -9491500,0.96516156,-69.199409,0.00082824152,-67.004227,0.064338192,104.21521,0.80556834,-97.871269 -9991000,0.96536291,-72.912376,0.00096632115,162.81651,0.0719845,19.327024,0.76455337,-104.66505 -10490500,0.95833707,-76.516876,0.00044003653,-171.77081,0.024328565,-114.81331,0.74586165,-109.05405 -10990000,0.95422655,-80.094887,0.00030106847,-164.11708,0.065255858,-23.666065,0.75597751,-112.31682 -11489500,0.94978672,-83.732422,0.0010874596,176.38965,0.039620694,-4.7012029,0.71483386,-115.5637 -11989000,0.94396627,-87.430588,0.00048015677,-120.17809,0.097803988,-34.146145,0.73783219,-121.43698 -12488500,0.93794835,-90.867805,0.0011726037,71.433128,0.10944888,28.878572,0.72318494,-122.31525 -12988000,0.93084574,-94.669022,0.0012025364,-155.46341,0.056528207,-51.566898,0.68532956,-126.49935 -13487500,0.92381448,-98.170097,0.00065119943,110.40598,0.087641671,25.553747,0.69935769,-129.88281 -13987000,0.91674829,-101.65998,0.00031395143,94.34211,0.11315274,1.977965,0.6612221,-133.37939 -14486500,0.90825158,-105.23972,0.00069557416,-87.800568,0.10928855,9.3036861,0.7075482,-135.71782 -14986000,0.90164751,-108.54556,0.00026430158,129.1543,0.086691529,47.929253,0.68758231,-143.20049 -15485500,0.89388841,-111.91589,0.00092527398,-73.170135,0.24152929,11.928112,0.67351234,-142.13646 -15985000,0.8855983,-115.18578,0.00090033939,-53.702229,0.19978729,-34.528381,0.6714313,-147.05347 -16484500,0.87916088,-118.51013,0.00062943459,-106.33433,0.057670891,7.3832912,0.65994138,-149.36534 -16984000,0.87267172,-121.78719,0.00067318056,167.79951,0.15205359,-35.816006,0.64976829,-149.64464 -17483500,0.86644018,-125.00679,0.00021467551,-64.894386,0.13236479,-41.93861,0.63138741,-156.34879 -17983000,0.86146349,-128.23715,0.00057195901,74.989571,0.065531507,-15.308773,0.63995624,-158.71944 -18482500,0.85405833,-131.6721,0.00056166406,-111.42059,0.25605941,-51.470791,0.60652995,-163.72585 -18982000,0.84966928,-134.74631,0.00059872773,142.55734,0.23455885,-45.559422,0.65296602,-163.04016 -19481500,0.8434971,-137.97183,0.00034132987,74.90226,0.12813711,-42.053818,0.62670451,-167.08354 -19981000,0.83897263,-141.14824,0.0018557335,31.397919,0.23193361,-40.969852,0.61239576,-166.70961 -20480500,0.83286273,-144.37906,0.00028162717,-101.3246,0.26636383,-60.812904,0.61788958,-169.92363 -20980000,0.8274672,-147.64661,0.00057215086,139.31642,0.29901516,-16.562733,0.62955993,-171.65479 -21479500,0.82274264,-150.70251,0.0012927215,48.754822,0.21624476,-55.686207,0.62565809,-174.7211 -21979000,0.81617093,-153.96289,0.0010018589,-120.59821,0.20148668,-50.840546,0.57009095,-177.56168 -22478500,0.81159121,-157.2002,0.00090613449,23.227409,0.21165343,-80.788185,0.60406226,-179.26068 -22978000,0.80722481,-160.28285,0.00017527114,-79.912407,0.32356957,-39.52742,0.60824329,175.08377 -23477500,0.80030984,-163.59341,0.00086166663,-144.59012,0.24582465,-41.475372,0.59483117,171.49779 -23977000,0.79771543,-166.63283,0.00069553504,-16.697588,0.31915414,-29.97979,0.58148563,173.86885 -24476500,0.79519391,-169.88051,0.0012571379,111.32755,0.39359352,-17.630672,0.63326234,172.65767 -24976000,0.78861749,-173.1058,0.00069202844,-78.574081,0.28488564,-74.503494,0.57566226,167.08174 -25475500,0.78388005,-176.08096,0.0010052897,-68.910995,0.34821171,-10.699757,0.61854726,166.70265 -25975000,0.77883112,-179.59482,0.0010524911,-22.137783,0.34250996,-45.684834,0.57378572,166.0361 -26474500,0.77127987,177.15393,0.00076641439,76.739761,0.51687354,-49.356792,0.60572678,161.82042 -26974000,0.76958686,174.07248,0.00092406693,105.75512,0.50779432,-36.027023,0.60162693,161.92458 -27473500,0.76936775,170.85583,0.00079736195,-2.7913108,0.57621098,-55.987789,0.58488041,158.26393 -27973000,0.75992239,167.79747,0.00015368382,166.68761,0.56653696,-43.775467,0.59244221,151.20195 -28472500,0.7569114,164.12553,0.00083358417,33.196045,0.76736665,-54.463314,0.55859441,153.76918 -28972000,0.75647336,160.84911,0.00059938419,-162.04202,0.60838246,-56.698643,0.5728398,149.80214 -29471500,0.75065011,157.51894,0.0012092609,163.71001,0.90529799,-56.106331,0.55374348,148.73512 -29971000,0.74356139,154.15068,0.0015435871,57.631493,0.93700361,-61.635715,0.59231097,144.71866 -30470500,0.73837161,151.10699,0.0012740971,45.592072,0.88970155,-65.775696,0.57386231,141.46931 -30970000,0.7368387,148.02234,0.0023160749,43.396999,1.5810481,-77.761513,0.52985793,124.80637 -31469500,0.72971284,144.03101,0.00048736433,144.10857,1.2108496,-89.284676,0.48418137,152.31972 -31969000,0.73584658,140.55365,0.00081471063,-151.89828,1.9988061,-51.914036,0.64784437,129.12729 -32468500,0.72500443,137.5851,0.00030186915,-12.890038,2.1007664,-55.34267,0.65007043,132.03806 -32968000,0.72108579,134.24423,0.0021042556,4.089684,1.5155495,-110.55727,0.62327093,117.50591 -33467500,0.7179637,131.14249,0.0015597206,-68.793816,2.2776363,-94.12886,0.52074492,135.26047 -33967000,0.70804209,127.09834,0.001138474,12.857523,3.1292748,-92.619377,0.63072455,130.74104 -34466500,0.70377129,123.46787,0.002277801,-27.168646,2.5818288,-88.47448,0.75409234,129.49733 -34966000,0.69957602,120.20838,0.0016134131,176.26822,3.3539863,-92.53331,0.60072458,131.0101 -35465500,0.69146115,116.39731,0.00077726669,-81.246391,3.8593829,-99.427368,0.6297608,126.97993 -35965000,0.6841262,112.58337,0.0013862174,112.07981,5.1508999,-104.76041,0.72105283,116.16286 -36464500,0.67465264,109.305,0.0019719431,17.490807,4.6232471,-102.44025,0.49213547,133.55394 -36964000,0.66921157,105.20329,0.0018016136,113.71169,5.8931389,-103.11609,0.48456857,136.48012 -37463500,0.65838683,101.59772,0.00031042178,16.205984,6.1698828,-108.73609,0.3927294,107.79058 -37963000,0.65176886,98.004356,0.00052123959,-103.25844,6.4669132,-121.06306,0.6157763,114.89268 -38462500,0.63681668,94.378555,0.0015506997,-66.217453,7.5634556,-119.9054,0.69557238,91.885216 -38962000,0.62394363,90.57383,0.00055252196,111.85723,7.4934201,-126.8624,0.68017334,117.80562 -39461500,0.6116854,86.743385,0.00080954388,67.712868,8.6847086,-132.09567,0.65656179,109.77155 -39961000,0.5983845,82.82399,0.001379559,90.696434,9.5264549,-132.25537,0.4486129,100.47356 -40460500,0.58882123,79.436211,5.0744165e-005,46.115231,11.067028,-139.10062,0.64390165,128.42805 -40960000,0.57045972,75.762833,0.00070971553,-120.13873,12.794737,-143.52673,0.60212457,98.90535 -41459500,0.55991906,72.526306,0.0009666406,-98.35627,13.720103,-151.87413,0.551507,105.30157 -41959000,0.54020911,68.856903,0.00093133363,-173.42961,15.090097,-159.7567,0.7503975,95.708389 -42458500,0.53148085,65.320091,0.00089856266,19.019569,16.165724,-158.80327,0.45579091,128.44975 -42958000,0.51430464,61.940037,0.0011081714,68.756248,18.418661,-164.77437,0.52933484,106.57399 -43457500,0.49974027,59.186539,0.00044712867,-76.750809,18.967943,-170.79649,0.59096676,106.13009 -43957000,0.48525015,55.180199,0.0024864401,34.983654,20.987288,-178.2316,0.46162304,98.383247 -44456500,0.47260383,52.694473,0.0011107072,-10.352939,22.929653,179.75409,0.62804818,103.18694 -44956000,0.4598428,49.569443,0.0015496318,-145.42361,24.561039,173.99371,0.51718575,92.091461 -45455500,0.44546178,46.293728,0.00076601608,-48.303631,26.113321,167.39162,0.5059973,76.207962 -45955000,0.4322857,43.753819,0.0018111343,-66.43425,27.739901,165.36372,0.63858706,81.865921 -46454500,0.41695535,40.992092,0.0011195256,-108.38736,29.494738,157.9841,0.47024643,73.171143 -46954000,0.40567493,37.513184,0.0012812124,50.318661,30.838882,157.10446,0.56175721,84.901672 -47453500,0.39206025,35.470295,0.00075399532,-103.53397,33.916569,149.65234,0.55602366,71.960083 -47953000,0.37677243,32.959938,0.00050840451,26.996262,37.179111,145.95723,0.62617922,86.784241 -48452500,0.36738849,29.904366,0.0015295217,109.69357,39.197929,141.62172,0.46292114,75.980316 -48952000,0.35692763,27.822977,0.00063486781,-49.82626,41.170071,137.27937,0.52974415,96.223869 -49451500,0.3472859,25.243759,0.00027610079,-167.23126,44.817127,133.05365,0.49359313,80.429749 -49951000,0.33562925,23.264561,0.00047763801,-60.477802,47.648281,129.43665,0.63557488,65.445351 -50450500,0.3225666,20.360613,0.0016544556,82.095337,48.575504,124.20387,0.50017864,81.165878 -50950000,0.31305483,18.912024,0.0012043703,-1.9938426,53.548779,119.42892,0.65410787,63.429955 -51449500,0.30366552,16.637602,0.0011306731,17.362442,55.71566,115.00323,0.45441672,88.831314 -51949000,0.29555365,14.761824,0.00011109717,163.91243,58.448505,112.26706,0.5804792,60.618893 -52448500,0.28678894,12.551581,0.00024650685,89.767464,62.175823,108.08458,0.65280414,64.543365 -52948000,0.27905208,9.8751068,0.0007868543,129.98788,65.693657,104.85665,0.67650801,86.803665 -53447500,0.26998803,8.0389118,0.0020544122,118.62791,69.957825,99.870491,0.60341895,64.590057 -53947000,0.26679829,6.6270785,0.0005028611,-130.90192,72.873573,96.082527,0.63100773,77.634827 -54446500,0.25591743,4.8318276,0.0014250943,108.06585,76.320267,91.651779,0.65614283,47.163651 -54946000,0.24886994,3.7441103,0.00083854562,54.348141,81.028236,87.863815,0.49709123,59.642204 -55445500,0.24733545,1.3028355,0.00033323831,154.73273,84.128967,83.915382,0.60426402,63.229698 -55945000,0.23600617,-0.74010658,0.00098221411,144.46797,90.533218,80.009964,0.720007,44.456772 -56444500,0.23297632,-2.7294104,0.0011415076,168.24776,92.509491,76.058723,0.52957004,66.079956 -56944000,0.23161128,-4.1166501,0.00087423489,-103.33697,99.005089,72.910637,0.4568499,47.544857 -57443500,0.22947203,-3.6128001,0.0026277776,-17.755751,104.03329,68.865486,0.6627019,58.063274 -57943000,0.21893287,-3.3222547,0.0021980922,25.013573,108.93739,65.350174,0.55861491,31.903379 -58442500,0.21772835,-8.586648,0.0013406682,-84.773399,113.66877,61.433624,0.51861292,53.873932 -58942000,0.21194345,-9.4954271,0.00086270145,-115.50641,118.33514,56.542774,0.34002501,16.452215 -59441500,0.20198143,-9.4358101,0.00098974514,126.09372,124.96307,53.858784,0.55249846,42.395344 -59941000,0.20581326,-9.9698772,0.0016769167,9.5302687,130.40462,50.133774,0.6392355,20.442003 -60440500,0.19484745,-14.901378,0.0010893375,-153.98662,134.90977,47.311138,0.36338404,59.846466 -60940000,0.19216526,-17.026766,0.0016504778,-123.19116,142.45865,43.516552,0.61308044,58.479984 -61439500,0.19132684,-14.754346,0.00061827095,46.079636,147.23663,39.571262,0.40796301,54.179279 -61939000,0.18489988,-15.303085,0.00048607847,131.61916,152.55054,35.599812,0.36090893,29.026669 -62438500,0.19388507,-17.75008,0.0017822211,-14.124891,160.08949,32.375748,0.48640025,35.074268 -62938000,0.17869084,-15.898992,0.0016859736,95.862663,166.94522,28.784098,0.35675025,21.557318 -63437500,0.17431565,-21.430988,0.00073849643,-156.88705,173.83788,25.318693,0.53549612,30.157225 -63937000,0.17042853,-23.106085,0.0011627281,-112.57629,181.56914,21.752758,0.61348039,29.616524 -64436500,0.18155171,-22.59017,0.0015252589,-22.328819,188.35449,18.530207,0.66786009,42.804878 -64936000,0.18258147,-23.100868,0.0020910949,31.4056,195.32854,14.446231,0.4773705,25.746586 -65435500,0.17311379,-22.746418,0.0011952374,85.166176,204.17226,11.601312,0.40978897,49.152039 -65935000,0.15584457,-21.705593,0.0014582236,155.99724,208.75851,7.5611525,0.41513336,-8.1375027 -66434500,0.16871774,-22.809526,0.0012024349,96.49498,217.87379,4.417119,0.46853223,15.100107 -66934000,0.15946181,-27.536896,0.00012373812,-108.00996,224.2834,0.77492422,0.32722682,-4.3700943 -67433500,0.14758077,-34.537487,0.0021163763,-99.163177,235.0872,-2.6190588,0.43348762,10.801038 -67933000,0.16076015,-31.42013,0.0010081177,-39.381527,242.26521,-5.4832106,0.27897248,26.767717 -68432500,0.14601356,-32.474716,0.0013567313,-108.37194,251.22029,-9.0072851,0.25304216,46.804447 -68932000,0.14439809,-34.731789,0.0014937159,-88.28833,260.02029,-13.10076,0.52836609,8.4421349 -69431500,0.16323896,-30.693371,0.00062841916,71.185745,268.57428,-16.11348,0.3835831,6.84269 -69931000,0.14317243,-33.799324,0.00064263807,-114.97629,279.21057,-20.11105,0.57829237,27.60635 -70430500,0.15083472,-35.914558,0.00064423773,14.314857,285.07605,-22.986254,0.31779227,11.196823 -70930000,0.16349009,-38.954746,0.0016842188,51.211983,296.87189,-26.287201,0.33688399,34.348808 -71429500,0.13993043,-36.257488,0.00071760616,-113.75526,303.57156,-29.582516,0.3166672,-11.332662 -71929000,0.15488681,-34.603329,0.00078406057,115.57619,312.42862,-33.265915,0.45170566,-8.7074041 -72428500,0.16109887,-44.121761,0.0015811254,33.970215,317.16306,-36.634155,0.51792312,-18.545656 -72928000,0.15065901,-36.160007,0.00074563734,128.89632,331.37881,-39.989014,0.49971163,3.7310972 -73427500,0.14262697,-35.654495,0.00073413685,-159.18201,344.36465,-43.111301,0.52987158,22.999699 -73927000,0.12374615,-39.943584,0.0013788056,-81.130653,347.69376,-46.332886,0.33478025,-3.4526155 -74426500,0.1562333,-42.213428,0.0009237859,90.462364,355.27948,-49.072697,0.34134239,-26.415541 -74926000,0.13275251,-41.849072,0.00061141909,-65.507813,364.59277,-52.410995,0.22145976,-12.37477 -75425500,0.1336426,-47.764576,0.00088104606,-2.170639,375.24008,-55.439461,0.051181063,-21.861631 -75925000,0.12170164,-36.548931,0.0013110057,-98.742722,383.96835,-59.511555,0.41860771,-5.4581618 -76424500,0.15414642,-44.850178,0.00067013054,118.61697,393.96988,-61.541084,0.02694972,-92.097069 -76924000,0.12649168,-39.090023,0.0010917586,-106.00871,402.05322,-65.496704,0.30852872,-2.5313454 -77423500,0.13130561,-40.595695,0.00071157294,-123.98293,404.90784,-68.651146,0.43818682,-29.673582 -77923000,0.13194811,-37.01532,0.0013285087,-108.96518,422.6507,-71.98539,0.33038157,31.021904 -78422500,0.14298573,-50.808895,0.00035224442,95.402725,422.14969,-75.081215,0.38194588,-19.976244 -78922000,0.15533167,-49.544952,0.00075941143,134.28009,437.93567,-78.597862,0.44072291,32.858269 -79421500,0.11415028,-60.441132,0.0014745615,10.860572,436.25595,-80.827515,0.32658312,-44.10899 -79921000,0.14678285,-49.921864,0.00053677754,158.71104,443.33472,-84.544647,0.57592595,-20.098347 -80420500,0.12633783,-48.059368,0.00053314795,-48.10709,459.95874,-86.632217,0.095860139,-13.018309 -80920000,0.15292361,-46.775211,0.00097139936,-159.07373,466.00562,-90.159889,0.17946403,-3.9017487 -81419500,0.1563697,-56.411091,0.001109332,134.85893,471.67502,-93.313004,0.36071554,4.3205543 -81919000,0.11938418,-67.10408,0.001294537,52.030632,469.46008,-95.847473,0.53644472,-46.106194 -82418500,0.13651887,-48.637306,0.00067867263,-112.22779,487.59518,-99.309219,0.22395939,20.497009 -82918000,0.1332531,-60.933838,0.00066951109,77.229355,498.36008,-101.95442,0.15224625,33.500751 -83417500,0.12241227,-47.568134,0.00068075588,-60.083733,495.68774,-105.23746,0.4271746,2.9500883 -83917000,0.14707614,-64.267784,0.001062121,126.36578,502.24805,-107.50984,0.33624592,-23.492193 -84416500,0.13324313,-60.715958,0.00055696571,105.04707,509.62973,-110.27509,0.33268335,-13.258543 -84916000,0.12574589,-61.015568,0.00049434591,67.828323,514.91309,-112.58239,0.38318905,-56.462254 -85415500,0.14124572,-63.481983,0.0006293492,141.76373,519.75049,-115.57539,0.35281181,-44.535622 -85915000,0.14775689,-71.651848,0.0012089888,125.92248,529.33777,-118.21853,0.31427115,-60.698635 -86414500,0.14714581,-53.440338,0.00065538823,-115.10276,538.42908,-120.94299,0.12581214,-58.152218 -86914000,0.13846044,-52.558193,0.00058117637,-89.781937,542.85828,-124.20321,0.18494654,15.398862 -87413500,0.11892974,-80.286118,0.0015020565,98.6203,545.3714,-126.68441,0.24461092,-13.367291 -87913000,0.15365383,-54.779514,0.00090831437,-104.49162,549.48242,-128.85899,0.25108525,-46.306877 -88412500,0.1183994,-71.71743,0.00089305855,99.031921,553.50812,-132.86017,0.4777011,19.995792 -88912000,0.12954871,-56.415569,0.00041668257,-32.223614,556.79553,-135.47119,0.45634863,17.647346 -89411500,0.13467611,-52.861347,0.00081424654,-49.477238,559.89319,-137.58238,0.43295509,4.7554936 -89911000,0.14519706,-63.191898,0.00037899578,-126.28299,572.375,-139.26357,0.19583201,-45.670525 -90410500,0.13045278,-75.077942,0.00091162598,143.0215,573.61597,-142.17944,0.33254817,-6.6871767 -90910000,0.15421478,-73.557365,0.0011758662,-165.43767,582.96136,-143.91484,0.11565424,-65.299393 -91409500,0.11217886,-64.625595,0.00054318516,71.20533,574.71936,-146.8972,0.50196922,-11.943554 -91909000,0.10849893,-68.021004,0.00066779257,87.8862,593.62457,-149.29738,0.12559406,6.1135631 -92408500,0.12037037,-95.560684,0.0019031304,137.95166,592.48065,-151.54619,0.24715403,-27.774885 -92908000,0.15635124,-71.88298,0.00091026828,-131.88527,596.70459,-153.26123,0.29713842,-69.930984 -93407500,0.13143227,-71.72683,0.00032838766,175.92778,598.89825,-156.32268,0.23853853,-10.31408 -93907000,0.084301136,-61.607384,0.0013955935,70.931313,601.28571,-158.31357,0.30484149,-38.961224 -94406500,0.065286577,-65.508553,0.0018378356,84.9562,610.72174,-161.06413,0.12453604,23.743412 -94906000,0.16098972,-69.470757,0.00084750185,-94.988152,617.51611,-163.02609,0.10846795,-70.273285 -95405500,0.11653776,-53.04192,0.0011271855,34.213646,615.1745,-165.66171,0.20035435,9.1325064 -95905000,0.15915191,-75.373772,0.00088481262,-110.78024,618.25122,-166.87288,0.41582608,-68.787468 -96404500,0.13569564,-83.252876,0.0007797415,-165.36014,631.40332,-169.76485,0.077350855,-80.753838 -96904000,0.1064836,-70.730911,0.00069822016,105.27482,632.47351,-171.92688,0.12700671,-114.05608 -97403500,0.07732705,-74.855804,0.0015910644,112.90762,632.83337,-173.25598,0.39987063,-78.563538 -97903000,0.13631469,-65.38018,0.00047046301,-0.16841884,630.47437,-177.01088,0.2496545,46.337193 -98402500,0.12206078,-67.823997,0.00031687491,76.187317,656.77319,-177.22394,0.63151687,-123.54669 -98902000,0.1467784,-69.640724,0.00050394837,-29.386192,640.21991,179.70844,0.1797674,-44.73225 -99401500,0.15479057,-76.822762,0.00068977283,-81.860771,636.62463,178.15981,0.43442282,-38.238552 -99901000,0.13986184,-71.074829,0.00032291064,-6.7133608,644.03394,175.95006,0.28846395,-54.456486 -100400500,0.14517717,-82.910583,0.00064099825,-115.22106,649.25916,173.92133,0.32098901,-70.337791 -100900000,0.13061549,-95.183998,0.0012883391,-148.75153,642.698,170.57634,0.35333392,35.393604 -101399500,0.14608103,-71.545403,0.00048561944,-9.4506292,661.42401,169.58664,0.24210702,-104.62618 -101899000,0.14684035,-74.918137,0.00039754983,-37.235622,648.57825,167.62665,0.3652308,-21.117825 -102398500,0.15323776,-80.026497,0.00065554248,-64.428307,654.00122,166.49812,0.50280017,-46.814751 -102898000,0.133837,-82.184837,0.00032277798,-126.17155,660.44611,162.9761,0.073862053,30.467087 -103397500,0.077141866,-62.649139,0.0017119527,125.72031,665.28271,161.54883,0.1343469,-66.344063 -103897000,0.11593781,-96.027405,0.0010600461,-146.07906,671.65289,160.06798,0.21529244,-73.86731 -104396500,0.14563878,-69.680801,0.0007986328,38.405861,658.93024,157.65117,0.35445914,16.053823 -104896000,0.13245384,-86.082329,0.00041869984,-123.11834,670.95532,156.09871,0.26348287,-51.825489 -105395500,0.16330513,-83.66375,0.00084897713,-43.465721,669.29437,153.19917,0.19815651,48.880169 -105895000,0.098081477,-85.69017,0.0010118646,-174.88101,682.97705,151.27107,0.074211426,150.45224 -106394500,0.11725386,-77.865089,0.00053162576,151.00473,683.16553,149.694,0.1133707,-117.25583 -106894000,0.16225424,-88.569038,0.00098064425,-48.42028,680.04089,148.9287,0.34987181,-35.570835 -107393500,0.18623473,-73.573143,0.0016124169,20.8647,683.05768,146.64377,0.18402094,-34.558323 -107893000,0.15240708,-73.127388,0.00085256429,56.285736,684.4024,144.82675,0.13464151,-27.874353 -108392500,0.14905202,-83.305252,0.00041473968,-3.9938276,685.0791,142.6862,0.11317962,23.67425 -108892000,0.15944895,-90.626389,0.00098567386,-39.858292,684.21606,140.54817,0.23083796,48.796783 -109391500,0.15898694,-85.576233,0.00070211489,-14.993115,695.26208,140.84671,0.67235273,-43.671928 -109891000,0.10520298,-58.107288,0.001658981,138.6059,709.54877,137.2672,0.35836351,-130.9877 -110390500,0.14399934,-84.56443,0.00025535325,5.0729818,693.5625,136.0593,0.23321928,-24.097208 -110890000,0.10770424,-70.686951,0.0010869114,153.73715,702.47498,134.3671,0.25087571,-57.223259 -111389500,0.1611333,-90.495316,0.0008428435,-13.369493,707.047,132.21095,0.10632526,-100.20663 -111889000,0.11129401,-60.777927,0.0015530372,150.48253,715.41119,130.03473,0.31274533,-127.42013 -112388500,0.12697209,-81.082069,0.00045021801,145.18698,713.099,128.50952,0.20785199,-140.85931 -112888000,0.1422562,-87.463631,0.00019469406,-0.47755802,701.94305,127.0516,0.1414665,32.376564 -113387500,0.19084273,-89.031113,0.0015208197,24.395788,708.96222,125.40098,0.13063185,-18.972002 -113887000,0.1341601,-94.983444,0.00051281869,-73.325233,718.5213,123.61716,0.26163924,-102.19984 -114386500,0.11410759,-87.411812,0.00061464903,-145.58372,723.94293,121.9768,0.35486165,-112.99837 -114886000,0.17346732,-80.155052,0.0012215344,77.09214,719.659,120.34969,0.21376659,-89.834145 -115385500,0.11033633,-93.338791,0.0008436967,-123.03036,709.81256,119.03118,0.12838568,23.454437 -115885000,0.15385342,-104.16212,0.0012592085,-24.269402,720.16235,116.63196,0.092811465,-127.73342 -116384500,0.13107459,-84.325386,0.00029749752,163.12234,701.8302,115.27809,0.48264784,73.106735 -116884000,0.094197035,-109.99786,0.0017264992,-92.932808,715.02948,113.78568,0.051620975,87.442955 -117383500,0.12763155,-67.018517,0.0015751774,167.57306,713.62592,112.35117,0.24235976,72.586929 -117883000,0.14247584,-100.95052,0.00080021494,-13.600038,717.72839,110.34251,0.1067017,115.31271 -118382500,0.1353011,-87.444923,0.00024345992,136.4648,732.5542,110.12191,0.43418726,-44.644558 -118882000,0.13298006,-90.811127,0.00013239415,172.14287,721.55933,108.34935,0.28413174,12.071858 -119381500,0.14545478,-104.19746,0.0010360561,-5.9370203,726.88892,105.60658,0.16379929,-123.96796 -119881000,0.14412737,-88.251511,0.00040939226,112.76785,730.20612,104.8196,0.17484298,-82.550018 -120380500,0.15353128,-96.923615,0.00070898916,39.625263,727.37909,103.15356,0.13470426,-29.211678 -120880000,0.12336795,-114.70031,0.0015720102,-31.770103,722.59521,102.01428,0.18205886,62.235886 -121379500,0.091320321,-79.644821,0.0015776998,-118.46044,720.1972,100.38409,0.30827594,93.398811 -121879000,0.13638072,-99.475792,0.00049896352,-0.94899386,745.99048,98.59742,0.26371279,-93.944283 -122378500,0.12422872,-99.061852,0.00062058173,-41.205929,739.51117,98.210297,0.33255568,-17.878031 -122878000,0.14556888,-85.327362,0.00058401132,170.22513,738.09961,96.474533,0.24078406,15.696635 -123377500,0.1461945,-77.985756,0.0012065893,-173.22749,736.51825,95.078163,0.22927308,23.081167 -123877000,0.093177803,-96.272812,0.001389762,-73.056442,748.836,93.231232,0.30799598,-47.230835 -124376500,0.18057014,-91.781487,0.0013191253,113.53902,752.90948,91.486816,0.36639133,-70.803291 -124876000,0.17819569,-95.116547,0.0012753329,106.32848,746.24707,90.256325,0.075318865,-63.802486 -125375500,0.088416629,-102.43553,0.0015921915,-53.419521,747.66498,88.533318,0.061312351,-174.22749 -125875000,0.14077067,-98.393066,0.00023264928,15.763807,747.20862,87.422417,0.056689672,-11.002409 -126374500,0.14776255,-89.313255,0.00051368319,-176.46367,748.64703,85.377724,0.17449465,-148.64333 -126874000,0.16859269,-97.87677,0.00099247985,111.48145,757.96942,84.404945,0.27565512,-40.336994 -127373500,0.14552505,-95.241814,0.00021295669,-155.19203,753.83478,83.334785,0.10854878,-0.60058469 -127873000,0.13182022,-88.422325,0.00074768986,-112.06349,757.96844,81.495407,0.18148878,-79.661896 -128372500,0.11262966,-105.92114,0.0010804664,-20.10795,759.82678,80.280319,0.15784653,-70.136604 -128872000,0.13162686,-108.80196,0.00090218108,26.212494,752.73315,78.900444,0.15671569,135.92122 -129371500,0.13306513,-101.27883,0.00040998831,-3.7178104,763.92169,77.516113,0.1439402,-59.563248 -129871000,0.14677003,-99.600616,0.00022642016,127.9454,758.43579,76.260216,0.10806461,98.261559 -130370500,0.14711456,-105.1617,0.00057477388,64.039619,761.1709,73.701973,0.50057423,-126.63007 -130870000,0.16450112,-91.195297,0.00087802921,-156.41972,752.6701,74.041809,0.36418381,114.58346 -131369500,0.15744172,-81.042328,0.0015692172,-126.43559,765.29193,71.906731,0.065332524,-105.02914 -131869000,0.15287164,-86.911568,0.0011323601,-119.85929,767.90717,71.287918,0.20948665,38.02557 -132368500,0.12249991,-101.60706,0.00069775718,-11.155326,784.28955,69.656593,0.54700214,-18.149954 -132868000,0.15152328,-91.735596,0.00070847425,-118.74962,769.87463,68.670937,0.19773462,38.822491 -133367500,0.13362692,-102.06781,0.00041562266,14.157545,764.56757,66.70929,0.1240995,178.15486 -133867000,0.15257192,-96.59465,0.0004674182,-129.92105,765.29309,66.12117,0.36612844,106.28641 -134366500,0.14540817,-89.515099,0.00092432811,-92.862076,768.10504,63.896168,0.15064701,-139.38901 -134866000,0.13128333,-124.63155,0.0017566226,61.49231,770.98267,62.909767,0.10534523,158.00902 -135365500,0.16921626,-105.38013,0.00093867088,162.34116,781.40265,61.439999,0.22842357,-22.857273 -135865000,0.15852077,-80.9039,0.0017928838,-88.252396,782.49127,60.454838,0.27296039,-1.1038364 -136364500,0.11477897,-113.4763,0.0012852281,38.807995,785.58118,59.411316,0.276375,25.668194 -136864000,0.15704049,-112.48268,0.00078592298,118.40327,794.30096,57.703377,0.50045639,-11.118977 -137363500,0.12092455,-98.574944,0.00091370137,-4.5167451,783.88733,56.315739,0.1514066,-35.87962 -137863000,0.15186408,-101.94966,0.00022517981,-116.41251,781.41547,55.486309,0.12117575,82.913269 -138362500,0.12825502,-122.95506,0.0014928975,81.523994,790.11786,54.319324,0.3231796,32.114513 -138862000,0.12484592,-107.82968,0.00066479121,35.834213,776.54059,53.246342,0.36994678,132.02623 -139361500,0.16026056,-105.73342,0.00051531428,-174.9021,789.53735,51.275745,0.25477314,-11.293032 -139861000,0.16528288,-124.41722,0.0016366272,134.77876,791.33228,50.20026,0.1241665,45.619873 -140360500,0.13551037,-115.56319,0.00082924264,100.10352,790.21436,48.818558,0.18804494,-1.777958 -140860000,0.091518223,-112.73026,0.0017042654,47.843441,791.41138,47.336506,0.17407812,-46.034058 -141359500,0.10992391,-97.836075,0.0011946207,22.573254,788.67566,46.467674,0.042185389,-40.144913 -141859000,0.16556957,-97.571518,0.00087316526,-77.978561,800.13409,45.435532,0.30789235,26.247461 -142358500,0.16557834,-99.746674,0.00061143975,-79.96096,805.47491,44.261417,0.38771465,17.503204 -142858000,0.17880332,-127.07793,0.0019361288,162.50473,795.1792,42.935169,0.094795145,77.847031 -143357500,0.19818483,-91.329872,0.0020278031,-72.228073,792.29919,41.115501,0.24576184,-81.387787 -143857000,0.17870566,-112.16505,0.0010577502,-144.44304,791.66895,41.069637,0.29753804,120.82774 -144356500,0.052930627,-106.27932,0.0028905368,62.564861,805.71313,39.089882,0.32088333,8.0339584 -144856000,0.19381115,-102.6116,0.0014033545,-91.772415,807.66461,37.405048,0.44810876,-12.459866 -145355500,0.19130988,-111.93076,0.001388185,-124.03846,795.63666,36.388741,0.1205256,-63.337791 -145855000,0.13422641,-108.99567,0.00036247465,85.680405,803.9447,35.561306,0.20329371,21.698822 -146354500,0.12066198,-93.342636,0.0012940578,30.005529,796.13983,34.090195,0.059525073,-105.84066 -146854000,0.18650609,-116.33181,0.0011483829,-133.94498,807.68585,32.577473,0.30191678,-14.934455 -147353500,0.15013054,-105.41234,0.00038956385,-11.019742,798.06909,31.712873,0.16574833,-103.18132 -147853000,0.16885692,-111.38288,0.00053087377,-105.82478,819.81256,31.007929,0.44564301,41.180027 -148352500,0.12321016,-113.66537,0.0007831644,102.09926,786.2757,30.14896,0.49260604,-145.25067 -148852000,0.15579803,-99.29232,0.00077151891,-7.5628562,808.2829,28.589632,0.19143279,18.951176 -149351500,0.14166255,-127.06962,0.0011706124,161.84682,802.12659,27.649269,0.1404766,-137.92096 -149851000,0.16228253,-110.56379,0.00026746796,-94.778122,828.24554,25.729473,0.71258801,22.905821 -150350500,0.15959421,-125.70122,0.0011253605,-162.75064,801.47321,25.378172,0.11584117,-126.20936 -150850000,0.12019282,-98.131729,0.0012755306,60.891205,824.29883,23.761042,0.45424134,49.682056 -151349500,0.15602815,-104.07619,0.00061314384,-8.4109917,806.58295,21.727171,0.51055849,-24.182985 -151849000,0.15873389,-106.28159,0.00054102083,-3.2585831,803.20514,21.314911,0.25303051,-62.874363 -152348500,0.12579055,-100.68939,0.0010666173,65.662109,811.41406,20.428543,0.079546109,-51.718613 -152848000,0.17173862,-114.04032,0.00048461679,-78.106209,807.26324,19.921143,0.14260754,-142.7626 -153347500,0.14733298,-121.60931,0.00046815388,-159.14076,799.08704,18.437212,0.23006351,-107.49456 -153847000,0.21696192,-126.25793,0.0019437028,-97.67746,821.41852,17.790859,0.24228664,102.44743 -154346500,0.17975016,-122.72298,0.0010543667,-103.73431,804.41406,15.52439,0.3971217,-42.056244 -154846000,0.15919618,-122.28552,0.00066215073,-136.76279,816.32837,15.026039,0.14011581,10.57381 -155345500,0.18080918,-110.62035,0.00093696854,-21.314383,815.47192,13.705603,0.095435232,30.798737 -155845000,0.15117535,-122.75497,0.00051886094,-141.0145,814.17957,11.756294,0.50274992,-15.096566 -156344500,0.18061912,-126.74268,0.0011384478,-102.15259,818.97803,12.120735,0.082389519,46.086674 -156844000,0.17578059,-123.96591,0.00089076196,-90.918716,810.13348,10.59543,0.20973627,-44.621662 -157343500,0.10416643,-133.19365,0.0015745454,171.82895,816.47516,10.626966,0.15715747,-170.97141 -157843000,0.16830474,-116.36667,0.00044989123,-32.207085,820.96014,8.0729198,0.30698073,16.79369 -158342500,0.17455184,-117.78641,0.00051240344,-42.06358,816.37158,8.5188169,0.25633425,-156.37065 -158842000,0.13016495,-119.45713,0.00060553051,160.08725,818.15924,6.1459961,0.19938275,-19.958357 -159341500,0.16811864,-120.8008,0.00045359877,-65.755753,821.18835,4.2833161,0.46961644,5.9663987 -159841000,0.17143165,-112.9991,0.00051045738,12.183022,833.00769,4.3988304,0.2993874,80.785576 -160340500,0.16617975,-117.23185,0.0003121887,-9.5706148,816.95801,3.8006968,0.14362541,-127.32264 -160840000,0.12144276,-115.99065,0.00081444508,156.15582,817.60461,2.0867827,0.23040122,-29.00209 -161339500,0.15219837,-133.33028,0.00086602086,-119.47901,839.55072,1.0302449,0.42492306,81.69294 -161839000,0.18607736,-118.15452,0.00069356657,-9.5389366,821.46729,0.11341736,0.1184913,-35.949791 -162338500,0.13571747,-106.38099,0.00082506239,110.61854,810.81567,0.21633895,0.42420554,-116.68382 -162838000,0.12980165,-122.75746,0.0005829393,-168.02541,824.19495,-1.663269,0.022297781,-26.982756 -163337500,0.13724248,-100.62325,0.0011698267,110.56785,830.08826,-3.8945556,0.42010805,30.951286 -163837000,0.12904397,-113.83688,0.00061106961,148.65195,813.513,-3.0667615,0.33526728,-96.923965 -164336500,0.19323739,-115.63781,0.0010492064,16.049232,821.17834,-5.1608663,0.16955224,-2.1238542 -164836000,0.14051329,-136.48279,0.0009843444,-117.97978,829.36743,-5.5067325,0.16510922,-173.01337 -165335500,0.20115505,-109.47925,0.0013087852,48.709324,817.04718,-7.1299701,0.25987864,-57.750549 -165835000,0.16945142,-113.2874,0.00070071372,66.978271,816.90491,-8.046073,0.22718845,-58.161652 -166334500,0.15482447,-127.0977,0.00026750189,-92.51442,829.19067,-8.3978691,0.22417271,-155.62215 -166834000,0.15517621,-113.88542,0.00050781545,98.823517,825.38861,-10.707882,0.25381884,10.978841 -167333500,0.15276608,-115.89649,0.00035878216,109.6275,831.36218,-10.946697,0.012341116,77.991623 -167833000,0.15132333,-135.78395,0.00085310958,-87.739151,832.61029,-12.887729,0.32451361,37.159073 -168332500,0.14975724,-137.55019,0.00091722026,-84.868652,839.37,-13.3369,0.23439746,92.169586 -168832000,0.081061378,-131.73863,0.001660357,-151.17336,830.64899,-13.670196,0.097540416,-130.73186 -169331500,0.21889453,-115.5391,0.0014768826,48.557156,842.26703,-14.085192,0.40304527,-160.9879 -169831000,0.10874852,-113.48312,0.0011594632,-174.33824,839.16309,-16.063765,0.10454687,135.16257 -170330500,0.14494237,-126.69743,0.00027279396,-106.78271,824.15021,-17.799026,0.31082246,8.5498838 -170830000,0.13323222,-128.86304,0.00048825337,-125.78246,826.6792,-17.52294,0.2052383,-102.38773 -171329500,0.16988909,-129.3658,0.00043827723,-6.172061,838.91724,-18.852503,0.15376322,166.36661 -171829000,0.1556956,-134.51096,0.00056609535,-57.319187,828.33075,-20.024897,0.1354067,-50.506577 -172328500,0.19555917,-134.87762,0.0010956664,-5.7368855,853.6994,-21.800438,0.47362605,120.51809 -172828000,0.1930774,-107.7114,0.0014227298,100.94673,830.34723,-22.145216,0.25371993,-9.7103882 -173327500,0.14328665,-117.50819,0.00050087902,154.10097,837.42627,-23.623068,0.24451403,57.506763 -173827000,0.16223378,-107.02606,0.0012582423,136.09323,833.45209,-24.622076,0.19915597,48.150864 -174326500,0.11591452,-144.25507,0.001249176,-92.374535,841.86328,-25.572157,0.19256985,81.89959 -174826000,0.1536257,-139.95189,0.00078286993,-47.708939,830.25861,-26.306961,0.24251656,1.7305653 -175325500,0.12454519,-105.32016,0.0013323259,179.49825,829.72034,-26.679695,0.1851261,-48.303886 -175825000,0.099713773,-151.51016,0.0016927799,-94.699028,830.08099,-28.445204,0.20340151,11.774589 -176324500,0.13394852,-133.30568,0.00054062932,-93.899475,858.64655,-27.787952,0.55994666,-159.53419 -176824000,0.20869702,-153.95981,0.0020497802,-11.114354,839.75562,-30.545614,0.14034155,80.267799 -177323500,0.053351689,-141.63493,0.0022861047,-110.84687,820.5094,-30.998011,0.4397383,-20.195053 -177823000,0.12915631,-129.43013,0.00055036129,-117.24469,831.79016,-31.454866,0.14621764,-49.444382 -178322500,0.082064278,-159.56831,0.002064713,-84.744156,842.39093,-33.18457,0.13932239,76.779892 -178822000,0.15974158,-142.39825,0.00078867341,-18.807676,841.7525,-33.907539,0.095717371,114.04626 -179321500,0.13121833,-130.43153,0.00044507656,-104.42763,846.3559,-34.94556,0.1753674,105.74662 -179821000,0.18768252,-120.00058,0.00097696052,119.21043,844.84064,-35.139351,0.14742269,-131.79329 -180320500,0.19663988,-129.3362,0.00091609813,78.319252,850.17816,-36.781357,0.10324283,148.00095 -180820000,0.14584033,-145.06126,0.00083638693,-26.726379,840.50531,-37.230782,0.094323814,-45.70916 -181319500,0.21189182,-136.09151,0.0013554911,60.770592,830.25726,-38.348328,0.31281316,-5.4071689 -181819000,0.19217761,-144.62273,0.0012935117,27.263828,843.78284,-40.091339,0.22056878,76.61821 -182318500,0.19453059,-121.64048,0.0010817605,122.00773,838.133,-39.361675,0.338056,-62.701897 -182818000,0.13295028,-117.14448,0.0009526668,-141.92775,830.487,-41.771503,0.32207,24.732121 -183317500,0.14511552,-136.41856,0.00028893864,-23.617315,839.64941,-42.18771,0.17868839,25.204618 -183817000,0.17802006,-134.26593,0.00054454373,71.582664,828.43958,-43.107407,0.43811092,-0.57257265 -184316500,0.16934657,-135.05243,0.00040642646,60.22649,826.33295,-44.392418,0.43091869,22.05422 -184816000,0.13873683,-160.08305,0.0015918299,-12.720152,840.92139,-44.703083,0.21361727,-8.7943821 -185315500,0.16371319,-129.60927,0.00024397345,150.13959,846.47211,-46.617008,0.20465133,95.760689 -185815000,0.11374633,-156.62138,0.0015588024,-32.631172,842.5506,-46.742447,0.17503934,-48.97768 -186314500,0.17703129,-148.97998,0.0011871556,36.692318,836.34467,-47.785847,0.24181955,-1.9987836 -186814000,0.11169958,-126.05378,0.00096304738,-87.476501,834.27032,-48.821442,0.35688764,16.82622 -187313500,0.13377406,-144.56807,0.00074771675,-15.855364,837.82507,-48.64447,0.40071583,-41.539677 -187813000,0.13294229,-127.55314,0.00062735513,-99.748611,843.96338,-49.869888,0.23265968,-55.907619 -188312500,0.24864869,-148.14192,0.002395483,81.730873,844.8869,-50.985561,0.17278714,-61.028061 -188812000,0.18175121,-136.35742,0.00068820536,106.68852,828.55963,-51.854511,0.46958795,-3.2097497 -189311500,0.12637091,-121.99539,0.00091781968,-102.51915,832.49341,-54.742809,0.64620763,73.128082 -189811000,0.11593188,-120.41294,0.0011549012,-90.321205,853.76349,-54.635204,0.1093494,152.21431 -190310500,0.18860529,-136.47643,0.0007864128,118.11691,851.9082,-55.123066,0.064968996,-122.44334 -190810000,0.14385967,-121.18848,0.00074557937,-118.99429,841.19141,-56.556992,0.25567609,48.547066 -191309500,0.16025595,-137.85956,0.00028176833,76.860023,843.8681,-56.921188,0.17049049,4.5365682 -191809000,0.16632684,-120.09958,0.00098004227,-142.69225,831.31757,-58.08091,0.41058719,29.348125 -192308500,0.12571894,-147.3795,0.0009214353,-1.191183,850.77838,-59.491974,0.23367645,113.1784 -192808000,0.22103567,-140.4631,0.0016339065,125.48925,844.23804,-59.376835,0.18405806,-2.7134075 -193307500,0.14910929,-138.53041,0.0001980391,13.697583,849.71875,-60.820942,0.0068558836,79.412788 -193807000,0.13179661,-145.84186,0.00078585703,7.3031311,841.30072,-61.767124,0.24127039,59.225754 -194306500,0.12754209,-150.21587,0.0010872777,11.491919,842.38501,-62.152538,0.20563398,5.1260986 -194806000,0.16533761,-138.35527,0.00031876785,126.87045,846.50439,-62.809799,0.23336315,-20.700249 -195305500,0.16247608,-142.42139,0.00047325215,85.874756,842.93311,-64.694748,0.23263869,85.976921 -195805000,0.16900235,-111.66289,0.0017778991,-111.21003,844.64905,-64.169968,0.36945507,-20.569534 -196304500,0.15354383,-134.92503,0.0001491677,-122.90699,829.85168,-65.627289,0.58049518,34.550545 -196804000,0.12536699,-150.95296,0.001063457,25.508219,843.83826,-66.086906,0.4037118,-5.2701654 -197303500,0.15802838,-114.96931,0.0015998223,-98.061378,844.84601,-67.527824,0.1383739,38.33387 -197803000,0.15982176,-135.38684,0.00022051271,-153.04948,845.7525,-68.314957,0.21526612,9.2034721 -198302500,0.17162164,-136.58142,0.00039387302,174.75922,844.54889,-69.064583,0.23427451,-5.4716015 -198802000,0.15535967,-129.09244,0.00059531006,-94.733444,857.71838,-69.985748,0.26663929,-72.371384 -199301500,0.14316234,-138.25804,0.00022126896,15.757883,847.86804,-71.579971,0.16184172,95.822899 -199801000,0.14495374,-147.02675,0.00071294629,62.487289,847.62439,-71.913681,0.17684099,15.748918 -200300500,0.16190432,-147.12508,0.00059708231,100.80686,850.67737,-73.417503,0.16067871,150.94298 -200800000,0.13257582,-126.61037,0.001042931,-44.031654,844.75854,-73.609192,0.21074405,45.365364 -201299500,0.1609496,-128.87105,0.00072897732,-94.326256,858.02087,-74.476768,0.25396907,-49.957642 -201799000,0.16615985,-136.97504,0.0003715386,-144.04889,845.86353,-76.098114,0.23908922,123.80045 -202298500,0.17245767,-116.08927,0.0018284287,-83.876183,858.008,-76.733505,0.14681576,-135.05959 -202798000,0.16480404,-142.4469,0.00040651893,151.37935,845.8443,-76.480675,0.35742009,11.82463 -203297500,0.17746156,-135.02716,0.00079172192,-132.09212,850.76129,-77.916443,0.11236367,22.803303 -203797000,0.13314988,-152.89561,0.001002215,69.875587,861.1048,-79.660332,0.28776041,-147.66745 -204296500,0.11483686,-147.15059,0.0010748348,40.210953,853.21332,-79.573967,0.13964991,-4.1199622 -204796000,0.13160382,-142.07472,0.00067321747,35.051872,854.45801,-80.066971,0.29228902,-10.879471 -205295500,0.16908307,-156.57292,0.0012555136,130.22878,850.54004,-81.604515,0.10978217,65.775398 -205795000,0.15938576,-126.86308,0.0010406068,-57.652241,847.95129,-82.269226,0.061781988,45.331352 -206294500,0.13872066,-143.13593,0.0003829569,54.358097,847.45929,-82.978859,0.22487858,26.640545 -206794000,0.14503609,-133.04205,0.00059753534,-37.298878,847.06024,-84.26133,0.20666648,90.770126 -207293500,0.19747722,-134.1741,0.0013309659,-110.32064,859.66425,-84.793983,0.2704744,-57.096985 -207793000,0.15027986,-132.57652,0.00063576194,-41.507206,850.48749,-85.641731,0.045407418,0.13377655 -208292500,0.19578961,-135.52373,0.0013355247,-104.37701,852.05664,-86.293877,0.15512408,5.9551382 -208792000,0.14161496,-130.18883,0.00093992375,-14.202995,854.83441,-87.131943,0.057889406,-28.789118 -209291500,0.13478282,-152.95137,0.00091277529,106.63747,864.32745,-87.616257,0.5077709,-26.09222 -209791000,0.08064732,-155.59042,0.002259355,66.164124,858.25867,-88.437485,0.35786393,-19.84285 -210290500,0.21602377,-136.36879,0.0020178899,-100.6833,860.14087,-89.842918,0.223729,-57.338566 -210790000,0.16722444,-141.07448,0.00050566799,-106.87881,850.71783,-89.727203,0.42951953,16.953905 -211289500,0.12949575,-152.4075,0.00094970682,103.47363,849.27209,-91.413292,0.052016687,1.0187017 -211789000,0.14567813,-151.81372,0.00072241796,142.88484,847.93054,-92.442627,0.094697863,61.564518 -212288500,0.19625795,-131.57037,0.0016975194,-65.298218,865.5603,-92.682648,0.54935813,-35.180298 -212788000,0.15254605,-131.47583,0.00092750409,-15.493605,851.63574,-93.998421,0.13055815,13.507452 -213287500,0.15657626,-140.71844,0.00029382628,-40.989063,855.82495,-94.64888,0.15376203,-8.4522457 -213787000,0.1526434,-147.13895,0.00026943101,175.29797,856.82861,-96.413788,0.2771154,-100.55302 -214286500,0.15065353,-157.80374,0.0010876587,168.15944,854.37244,-97.06427,0.18711847,-131.34135 -214786000,0.17650297,-141.34833,0.00077630725,-75.681984,854.71881,-96.982811,0.14985549,-0.64493686 -215285500,0.16884479,-154.32367,0.001131518,-156.53619,851.664,-97.945923,0.048462179,16.006056 -215785000,0.14498496,-134.64798,0.00068952644,26.400965,850.28369,-98.719078,0.16184372,13.744787 -216284500,0.19118953,-144.08228,0.0012936037,-80.210587,857.84827,-99.854622,0.1289259,-70.317108 -216784000,0.13559642,-159.44815,0.0011586195,159.28831,860.5318,-100.99467,0.33684582,-81.538002 -217283500,0.13680497,-153.6423,0.00095738412,162.71109,843.6214,-100.86855,0.17439628,104.92117 -217783000,0.15251637,-150.68748,0.00039628963,-155.79666,858.7511,-103.1491,0.4660055,-104.59927 -218282500,0.154681,-151.50926,0.00048919872,-152.69,868.80768,-103.3268,0.50537598,-51.663704 -218782000,0.16741033,-140.9045,0.00059184054,-35.030422,861.95471,-104.15405,0.44536039,-67.571259 -219281500,0.13199721,-153.21971,0.00064018427,156.25111,855.91602,-104.58001,0.074089386,30.543394 -219781000,0.1579791,-127.65057,0.0015254493,31.520544,855.11493,-104.95064,0.074214168,38.195461 -220280500,0.17887703,-140.03615,0.0010897175,-20.976669,867.09125,-106.40977,0.39681047,-41.847549 -220780000,0.15135211,-131.0762,0.0013732637,37.697514,864.11786,-106.99914,0.34176689,-27.828011 -221279500,0.19608377,-141.84164,0.0014580482,-35.627224,857.30914,-107.36464,0.17638408,4.481576 -221779000,0.13019547,-160.93498,0.0012903151,-178.84099,859.49609,-108.57793,0.20811355,-48.788963 -222278500,0.16650635,-164.75807,0.0016018088,-132.0717,861.28247,-109.0902,0.15783507,-15.248057 -222778000,0.1331455,-161.62207,0.0012194215,-164.94823,851.90021,-110.05946,0.086818799,-146.26187 -223277500,0.13305442,-144.48116,0.00051877141,120.69349,859.87732,-110.61076,0.16794302,35.39291 -223777000,0.13250892,-152.56252,0.00070303504,172.65193,871.91272,-112.08585,0.57967645,-33.01638 -224276500,0.14963672,-147.29767,3.9368355e-005,-175.36948,864.83557,-112.04198,0.30701634,16.685764 -224776000,0.1594917,-143.65649,0.00043948452,13.53094,852.36176,-113.19328,0.11964228,-131.38023 -225275500,0.13106351,-142.63203,0.00065751298,118.4464,872.85345,-114.06761,0.50182945,-6.7001257 -225775000,0.17342404,-160.05064,0.0011976933,-84.524231,867.83795,-114.92133,0.37325153,-15.910278 -226274500,0.21674298,-152.45319,0.0020274962,-35.258904,869.06653,-116.19714,0.4970355,-32.990215 -226774000,0.19536859,-158.62788,0.0015655723,-56.351303,868.62793,-116.84969,0.4114641,-33.383663 -227273500,0.15319884,-135.69971,0.00093110662,74.425484,844.44995,-117.58451,0.47131264,-123.08101 -227773000,0.20225504,-141.85847,0.0016975366,12.383128,863.25214,-116.96583,0.37849995,82.132416 -228272500,0.13469374,-139.32248,0.00069307873,108.93853,860.57001,-119.41656,0.42280558,-48.619514 -228772000,0.15474275,-165.79832,0.0013128951,-101.46853,859.02679,-119.61433,0.17175825,-73.591713 -229271500,0.16505858,175.47462,0.0027599109,-102.88583,872.8479,-120.13039,0.3742618,9.0540257 -229771000,0.17223281,-165.85632,0.0014097807,-73.771698,867.08594,-120.23232,0.31768519,80.8255 -230270500,0.1080673,-155.23524,0.0011638884,-164.84563,866.7392,-122.54156,0.42845744,-35.871883 -230770000,0.16343294,-143.83862,0.00067221146,58.079353,861.44287,-122.38896,0.0033192968,-86.194168 -231269500,0.16225949,-142.82436,0.00054319453,59.891014,849.88434,-123.04161,0.31486517,-142.22728 -231769000,0.19032672,-139.15831,0.0015067911,50.668537,857.95886,-124.01411,0.086200975,-106.4562 -232268500,0.12352628,-127.8368,0.0015320529,141.22815,855.08398,-124.52312,0.20747374,-157.62747 -232768000,0.14845479,-150.31,0.00013154361,-58.577316,865.74207,-125.47598,0.097384296,6.2536325 -233267500,0.12816483,-158.79445,0.00076530926,-115.46889,869.61896,-126.89462,0.28981322,-14.148385 -233767000,0.1754946,-136.80109,0.0010888296,81.55162,863.94897,-127.48508,0.23720352,-50.49963 -234266500,0.15604216,-130.85011,0.0013245491,117.04895,857.97815,-127.62295,0.20156528,-146.51239 -234766000,0.17848231,-177.14653,0.0021700177,-54.56852,895.23077,-129.0748,0.83089459,32.591164 -235265500,0.12006206,-161.56541,0.00092309696,-112.18702,873.71906,-130.33887,0.40750474,-5.9110451 -235765000,0.21063349,-139.67081,0.0017676308,68.511467,855.31085,-130.22441,0.28370631,-123.13204 -236264500,0.16432349,-173.98074,0.00163289,-49.00288,869.55273,-131.27193,0.17183316,17.353954 -236764000,0.15240829,-156.198,0.00032157975,-43.691666,866.71405,-132.06689,0.1070986,-55.314396 -237263500,0.10344967,-155.01244,0.0011367998,-127.19772,869.34552,-133.61003,0.40354276,-19.797853 -237763000,0.23809345,-157.17371,0.0022418688,26.568476,867.44836,-132.30569,0.32433277,160.53548 -238262500,0.1876585,-152.17992,0.00090997986,43.99654,856.4408,-135.15274,0.47078446,-57.960732 -238762000,0.14704992,-142.93607,0.00066310278,147.41042,866.7052,-135.19943,0.084357522,-70.177254 -239261500,0.059708148,-146.32022,0.002141787,-132.14148,879.88281,-136.61368,0.39188796,16.697813 -239761000,0.22530803,-162.34279,0.0018457561,26.732752,882.06268,-136.81436,0.30719516,46.867519 -240260500,0.15043212,-148.11295,0.0002900073,152.02364,874.13531,-137.75194,0.21240468,10.75282 -240760000,0.19387566,-165.65848,0.0013117739,15.309195,852.77655,-138.15039,0.38753876,-104.06755 -241259500,0.18435568,-118.50693,0.0025080419,152.81497,868.99805,-138.51814,0.17736793,-157.55312 -241759000,0.13236602,-161.4021,0.00055009883,-67.782784,882.71613,-140.56319,0.44382364,33.356274 -242258500,0.20167863,-151.65723,0.0012374474,75.697105,855.88983,-141.41872,0.45060688,-48.016212 -242758000,0.095466733,-149.66791,0.001204934,-114.8853,868.74231,-140.64624,0.10240819,-145.25011 -243257500,0.1547865,-159.60431,0.00039270936,14.234532,869.94952,-141.84181,0.033645261,113.94404 -243757000,0.11312982,-157.33141,0.00078860368,-93.926407,866.28369,-142.34412,0.18068974,-128.52225 -244256500,0.11393577,-157.79088,0.00072226283,-96.347923,863.91754,-143.20901,0.15665804,-114.92143 -244756000,0.14012074,-137.09575,0.00091517251,-179.3831,840.49023,-144.78648,0.68527347,-70.311981 -245255500,0.11422534,-167.49113,0.00090879848,-61.283878,865.69757,-145.20807,0.086084135,-23.806162 -245755000,0.18165702,-174.88515,0.0014950641,15.089211,883.75238,-146.28215,0.35525647,56.320465 -246254500,0.16538173,-149.75598,0.00055281422,122.80463,853.5257,-147.50475,0.48637861,-42.350246 -246754000,0.18855192,-162.95567,0.0010429907,61.760506,870.00989,-147.87099,0.22637425,8.9690094 -247253500,0.15295555,-175.25339,0.0010737149,-2.3048773,869.88464,-149.30818,0.39710855,-3.659481 -247753000,0.05169867,178.21603,0.0021846602,-74.885468,868.19202,-149.90582,0.36115175,-3.1462202 -248252500,0.088645458,-166.06918,0.0012218454,-68.433334,864.88202,-149.6394,0.11946413,-60.518497 -248752000,0.13639849,-127.69629,0.0014516823,-152.51355,849.84973,-151.22577,0.57342225,-40.764309 -249251500,0.18308794,-148.73119,0.00094175624,130.06824,853.95117,-152.52136,0.59875423,-24.918074 -249751000,0.16561651,-131.78224,0.001407313,-175.60399,862.54498,-152.45956,0.32749781,-31.031622 -250250500,0.11971679,-169.68303,0.00079831202,-25.288094,849.56097,-152.06255,0.4743093,-87.958282 -250750000,0.11748829,-158.54514,0.00057017757,-66.456329,882.22559,-152.74861,0.21660906,161.72765 -251249500,0.12294837,-178.00624,0.0010664917,-10.854331,865.37793,-154.54723,0.25088948,-25.056345 -251749000,0.24199677,-153.48082,0.0020856927,118.55252,867.5498,-153.69014,0.33167222,-133.0983 -252248500,0.12213595,-169.70447,0.00075180572,-13.376776,858.9292,-154.98962,0.3295885,-83.524246 -252748000,0.12178541,165.55716,0.0017664864,-4.1550879,869.13617,-155.76285,0.21340607,-105.70266 -253247500,0.2158888,-179.83083,0.0020408903,64.618172,860.73999,-156.27632,0.30751207,-96.381126 -253747000,0.13396087,-144.45259,0.00061671954,-132.86757,871.04443,-158.75714,0.28805211,13.327347 -254246500,0.14265542,-161.73175,0.00018524402,68.389084,858.65216,-158.395,0.25264478,-62.533451 -254746000,0.14989744,-168.5295,0.00062852947,53.063602,868.29926,-159.10555,0.12682454,-78.197685 -255245500,0.2029563,-158.11632,0.0012720899,124.6665,865.87335,-160.19044,0.19631039,-45.919521 -255745000,0.12971698,-141.85823,0.00081475941,-122.43359,877.83014,-161.85417,0.34408861,53.635937 -256244500,0.099720761,-154.16272,0.00073925726,-59.554798,862.11768,-162.33186,0.36700711,-4.7110782 -256744000,0.17741811,-170.15077,0.00098611414,87.460373,836.32513,-162.68042,0.76742142,-43.746513 -257243500,0.077272058,-129.564,0.0015445414,-69.903938,877.85681,-162.9864,0.017432636,145.47923 -257743000,0.13831341,175.10185,0.0012416247,34.299774,865.40405,-163.84242,0.19547932,-56.468555 -258242500,0.17881235,177.99156,0.0015755591,70.511162,868.88031,-164.7471,0.19683923,-38.18644 -258742000,0.15805992,-159.73975,0.0004861331,140.20035,864.94812,-164.49489,0.28875101,-87.965485 -259241500,0.19299093,-157.16841,0.001158155,149.09048,853.81116,-166.27237,0.48256123,-29.852968 -259741000,0.086331077,-108.84805,0.0019937712,-72.14386,855.27997,-166.95988,0.45755473,-29.233231 -260240500,0.13988498,-147.79907,0.00057602592,-121.30883,878.04626,-167.63802,0.051920433,131.44444 -260740000,0.08929266,-178.00319,0.0011807068,5.842567,856.73199,-169.58612,0.61718547,3.3818505 -261239500,0.18500179,-153.68517,0.0010249831,173.30568,871.4917,-169.77641,0.23480338,23.05909 -261739000,0.1379177,-125.63577,0.0015364662,-98.064644,877.1203,-169.87189,0.026677778,40.661827 -262238500,0.098374113,-158.97955,0.00071755523,-21.290443,860.13861,-169.82861,0.43465844,-59.953659 -262738000,0.10636374,-153.6373,0.0005609931,-38.458031,860.55103,-170.19406,0.46553835,-71.809929 -263237500,0.099597424,-153.28786,0.00073151127,-30.654095,861.09204,-173.1572,0.45373717,13.404118 -263737000,0.15782557,167.60713,0.0018143422,76.615158,869.17267,-173.13269,0.2416099,-13.448404 -264236500,0.1282104,-179.23906,0.00097292883,64.016266,870.32007,-174.68188,0.44033286,28.80267 -264736000,0.20686913,-158.86266,0.0014059456,171.93011,872.47308,-174.50694,0.10101843,-31.479916 -265235500,0.11696855,-153.87212,0.0003121694,-42.113281,908.81976,-175.58716,0.59524548,137.65573 -265735000,0.16944624,-146.76314,0.0009021571,-134.07103,875.95264,-175.79474,0.11289141,-62.966721 -266234500,0.10896578,-167.07207,0.00058185443,38.924171,875.73712,-176.59236,0.11552282,-9.4985895 -266734000,0.15050171,-151.16191,0.00056586566,-122.80336,844.01404,-176.36937,0.70955193,-39.297604 -267233500,0.16500568,-161.72656,0.0006801798,170.67896,882.68958,-176.99757,0.37379616,-115.67741 -267733000,0.12799706,-152.91884,0.00029805038,-67.355042,857.80658,-178.04979,0.48170412,-40.325161 -268232500,0.14083332,-150.31731,0.00046146289,-100.77893,872.78003,-179.18083,0.20135356,-59.394226 -268732000,0.11981037,-139.40186,0.00089015759,-58.158112,867.22266,-179.89001,0.29097223,-35.444569 -269231500,0.15625623,-138.58324,0.0011356637,-92.083015,876.96747,179.50568,0.25361791,-93.780502 -269731000,0.1430005,-145.11327,0.00064342818,-82.840881,856.83881,179.62093,0.67752087,-53.986774 -270230500,0.1670025,-159.53032,0.0007528307,-168.13222,882.43695,177.28677,0.052547898,143.0497 -270730000,0.19644514,-169.82271,0.0015445206,172.79495,873.5036,177.46082,0.25842661,-54.938503 -271229500,0.105017,-130.15762,0.0013233926,-28.163931,868.47845,176.22665,0.25260842,-26.304153 -271729000,0.075979635,179.59657,0.0013145033,49.802189,863.21783,175.97188,0.38475662,-36.608978 -272228500,0.16361296,-154.5703,0.00077119702,-129.51089,888.96863,174.36324,0.2488531,174.12669 -272728000,0.16751389,-179.3615,0.001349709,142.76968,863.55524,173.67082,0.24380286,6.769084 -273227500,0.23170415,-170.13071,0.0023289665,-170.2753,873.98199,173.74588,0.20699188,-60.573399 -273727000,0.19743942,-159.12044,0.001438621,-145.24403,870.66443,172.9147,0.3427566,-47.276733 -274226500,0.15367499,-163.77824,0.00062900461,-169.16031,883.87036,172.99797,0.45021689,-84.088814 -274726000,0.17104687,-162.44859,0.00091279147,-153.06606,865.96674,172.26534,0.51431865,-55.256115 -275225500,0.10727252,159.94542,0.0019015881,98.744354,861.41882,170.42555,0.40213758,-18.034575 -275725000,0.16496015,-140.84416,0.0013574825,-73.412155,867.7832,170.27243,0.42499897,-44.457546 -276224500,0.088354871,177.72775,0.0013478367,82.581741,878.01825,168.31996,0.088354915,141.18111 -276724000,0.14321943,-172.87459,0.00078296126,158.72025,891.51984,167.81599,0.27450305,-167.94101 -277223500,0.10551882,176.35083,0.0011974975,108.87933,882.763,166.98729,0.12726235,-165.47266 -277723000,0.2117334,-162.09799,0.0018805827,-132.16501,865.72876,166.39931,0.25475222,7.0428805 -278222500,0.11890844,-150.92542,0.00048757781,-2.769506,867.39471,165.91692,0.26511151,5.8832393 -278722000,0.12003335,-157.03345,0.00024695869,21.92856,883.92358,165.69698,0.26936409,-104.57935 -279221500,0.13698274,-156.371,0.00028454707,-62.019764,874.20911,164.82155,0.18615347,-41.65657 -279721000,0.11848249,-137.48624,0.0011079685,0.55963552,862.72205,165.29948,0.73355746,-38.177876 -280220500,0.16329956,-165.33351,0.00092005765,-137.76767,889.88733,163.24373,0.35759947,-122.76111 -280720000,0.13378797,-154.90211,0.00030572072,-53.719372,868.44769,163.4933,0.60058838,-37.488388 -281219500,0.071611248,-154.33917,0.0012966288,64.925529,873.37671,162.67842,0.49293959,-48.742321 -281719000,0.14031236,-163.5256,0.0003629367,-144.01627,869.81934,161.91455,0.4532131,-31.202795 -282218500,0.12453616,-176.62666,0.00085075106,153.38857,875.42987,159.94968,0.046368182,-74.74633 -282718000,0.14105061,-155.98824,0.00044017669,-70.773727,880.02936,159.28616,0.091534771,-93.816177 -283217500,0.14925826,-140.93097,0.001158947,-26.403488,874.22961,159.18597,0.36105046,-45.336342 -283717000,0.05110953,-164.09752,0.0018958484,89.784927,873.39417,159.19766,0.52645695,-43.914967 -284216500,0.16619922,-152.27194,0.0011361026,-58.75555,888.02344,158.02571,0.452463,-87.674225 -284716000,0.12093389,-161.96802,0.00017024786,155.58359,872.43024,156.99722,0.30636829,-32.327801 -285215500,0.14269611,-166.90491,0.00056009978,-131.61082,874.11023,156.72299,0.39270103,-41.908558 -285715000,0.12826948,-176.12997,0.00093886949,-174.37375,870.42157,155.26006,0.13336042,-0.83839321 -286214500,0.13220611,-166.87428,0.00046130246,-154.88409,875.97388,154.98636,0.33075491,-57.235504 -286714000,0.12736936,-155.20079,0.00034909204,7.1584024,875.94891,154.16721,0.17860404,-42.961258 -287213500,0.17880557,-142.72652,0.0019236909,-27.6458,894.396,153.95775,0.69701087,-77.375748 -287713000,0.13107163,-145.76363,0.00087638036,16.551636,879.51929,152.94342,0.39525673,-55.218895 -288212500,0.14261696,-155.39594,0.00060676347,-43.375515,861.38892,151.85083,0.39449739,29.979944 -288712000,0.12234364,-148.21861,0.00072054821,31.722586,874.39478,151.33434,0.25858006,-30.85705 -289211500,0.1649179,-142.80424,0.0016493724,-7.3613434,878.29761,151.20914,0.545407,-39.602146 -289711000,0.11342109,-172.62064,0.0008258092,-176.56998,864.95618,149.89861,0.34875298,11.238917 -290210500,0.11737514,-150.84023,0.00060246547,61.795078,877.48706,148.94646,0.26368764,-71.830162 -290710000,0.11237342,-161.41995,0.00039113127,146.0103,882.48285,147.23743,0.4863956,-142.5152 -291209500,0.080791332,-175.81142,0.0014440513,154.83508,875.39624,148.14293,0.41630775,-24.215578 -291709000,0.098785736,-177.9247,0.0013200823,174.29321,875.61322,146.29237,0.18901061,-145.76965 -292208500,0.19064024,-160.87239,0.0020021829,-49.640205,877.43726,146.23051,0.28546983,-52.702446 -292708000,0.14484295,-159.46512,0.00075263734,-39.17561,878.59912,144.83627,0.1712576,-126.48819 -293207500,0.095959686,-141.10181,0.0012521954,101.67403,876.42401,144.93867,0.37272069,-46.671505 -293707000,0.16238777,-158.64912,0.0012336688,-32.861233,872.87335,144.16589,0.24797568,-14.644615 -294206500,0.15656357,-158.26566,0.00097083719,-27.575171,870.67908,143.73961,0.29275891,3.0574505 -294706000,0.12531979,-170.49379,0.00075527601,-120.35101,874.31982,143.16528,0.42343703,-18.742964 -295205500,0.1629803,-170.19913,0.0015063642,-66.32988,881.05048,141.89622,0.389898,-58.308308 -295705000,0.13333847,-148.47107,0.00085234409,47.958931,884.02838,141.18936,0.42986104,-68.824646 -296204500,0.084565803,-165.49709,0.0012880736,176.59006,869.62512,140.72365,0.22061479,1.04899 -296704000,0.079746097,-175.84012,0.0016497772,-172.30618,879.05853,139.80229,0.28792331,-51.14706 -297203500,0.12632787,-170.79626,0.00083341455,-95.936897,875.9812,138.83023,0.14894173,-77.001747 -297703000,0.11092752,-143.42853,0.0010482586,107.75622,881.65613,138.50798,0.46428484,-55.934261 -298202500,0.1335426,-150.24373,0.00072101981,64.28978,881.08795,138.07481,0.45855594,-34.503448 -298702000,0.11024724,177.39447,0.0015280496,-124.20454,878.50006,137.26524,0.33081263,-39.088947 -299201500,0.13277166,-153.80705,0.00044333635,56.42852,872.22491,136.33647,0.10051739,-29.212343 -299701000,0.10626841,-161.02954,0.00053183641,-172.50549,869.36169,135.65744,0.11540852,50.795715 -300200500,0.13466124,-153.02341,0.00049825286,70.943092,876.98059,134.77396,0.29073772,-85.185776 -300700000,0.15625416,179.36116,0.0020137585,-60.085625,881.58118,133.80521,0.52048725,-90.95977 -301199500,0.11810216,-164.60503,0.0005323487,-110.30233,883.82397,134.09816,0.56892145,-16.186155 -301699000,0.11095253,-149.68811,0.00073978724,142.24036,868.92853,132.6729,0.057719797,139.01311 -302198500,0.073469967,-166.40353,0.0017768355,-151.23381,876.99054,132.56409,0.34185013,-3.5317121 -302698000,0.13571446,-176.23343,0.0013412929,-58.161949,884.66071,131.44412,0.44551814,-52.862324 -303197500,0.12746969,-156.57158,0.00016103235,62.227131,871.04541,131.2289,0.19459242,25.271023 -303697000,0.15053006,-137.38658,0.001971069,103.99097,878.66492,130.1922,0.24136163,-36.378849 -304196500,0.15849312,-156.71904,0.0011531146,41.007202,866.10632,129.69612,0.14001916,116.7691 -304696000,0.11955639,-152.92203,0.00052974542,156.36047,875.54956,128.50049,0.25944987,-72.406357 -305195500,0.096714266,-154.53725,0.00096962019,-148.58107,870.00098,127.37103,0.38992262,-126.2367 -305695000,0.13535094,-160.69484,0.00043567133,23.011858,877.76721,127.26974,0.26672536,-57.857208 -306194500,0.1075165,-172.1794,0.0010413253,-76.978111,872.9632,126.74677,0.097320557,0.68870223 -306694000,0.14828923,-171.14517,0.0013776615,-7.8050313,871.21674,126.06893,0.082328252,-38.545147 -307193500,0.15065187,-170.0574,0.0013077667,5.7606268,873.41284,124.98631,0.14983498,-101.65863 -307693000,0.095926575,-177.2303,0.0014150618,-77.345428,876.09351,124.8168,0.13149063,38.870293 -308192500,0.15384209,-151.87321,0.0011376136,92.465034,868.91498,123.31783,0.32733458,-117.50523 -308692000,0.11433696,-157.24742,0.00034456569,-132.04651,881.98651,123.1328,0.30906692,-29.110588 -309191500,0.11055189,-152.92033,0.00052154576,-153.17444,874.89508,121.62702,0.36589664,-81.762154 -309691000,0.129724,-168.4326,0.00071676122,-5.8024955,880.15576,122.0573,0.22795908,23.451012 -310190500,0.11464345,-163.33255,0.00044537958,-55.992466,889.83362,120.07677,0.70568138,-52.710758 -310690000,0.12570702,-150.28754,0.00048481449,167.84035,891.98773,120.54444,0.63673031,-7.9872103 -311189500,0.16348498,-171.60529,0.001546327,36.700958,870.60785,120.24493,0.27181637,129.23508 -311689000,0.12709412,-143.39322,0.001090848,-177.49635,886.1239,119.26341,0.26406088,-11.783508 -312188500,0.10917822,-128.79053,0.0020494773,-150.47897,874.27203,118.67529,0.11281021,151.864 -312688000,0.083608456,-164.97459,0.0013143932,-69.867935,879.72729,117.12518,0.37303117,-66.177574 -313187500,0.090768434,-164.05026,0.0010818726,-61.132114,863.06799,116.38905,0.52456599,-123.15665 -313687000,0.15060568,-155.84619,0.00075235701,102.4419,888.62396,116.59871,0.46840525,3.9256806 -314186500,0.13238929,-168.29315,0.0006762495,34.632233,869.56451,113.93233,0.78609163,-93.198311 -314686000,0.12159108,-150.92476,0.00041724253,-137.50006,868.77332,114.42391,0.47675759,-113.30173 -315185500,0.12457192,-169.58272,0.00081769057,10.677365,888.4668,114.20892,0.29161382,-13.457088 -315685000,0.095110811,-146.64732,0.0010539053,-95.835175,869.65277,112.25826,0.6543076,-86.531776 -316184500,0.12707005,-141.06145,0.001041189,-154.25967,886.065,113.36159,0.25552922,64.519478 -316684000,0.12349875,-150.62851,0.00045063903,-164.02222,879.99188,112.72707,0.19382299,107.82101 -317183500,0.16597709,-164.41713,0.0011524126,94.945442,883.24323,110.51494,0.47446394,-51.588615 -317683000,0.15588558,-157.64091,0.00089632854,118.99572,870.3479,109.68999,0.59320581,-86.697754 -318182500,0.10385451,-147.6763,0.00068376341,-91.985092,881.56122,110.46381,0.15714104,93.861191 -318682000,0.16361828,-148.70575,0.0012137328,168.0502,891.87683,109.01085,0.27523959,0.38865966 -319181500,0.13027696,-163.19598,0.00043926228,51.903301,878.84167,108.37096,0.24914017,-79.319107 -319681000,0.14310904,-156.42737,0.00048647911,132.86848,881.59052,108.69332,0.14617278,119.78056 -320180500,0.14284237,-150.69907,0.00056686392,-170.82474,888.05219,106.68015,0.2899048,-28.744219 -320680000,0.11079501,-143.61258,0.00078951882,-87.790688,888.80145,106.42252,0.20278539,-5.8870378 -321179500,0.13669562,-144.9557,0.0007437506,-144.58667,882.10498,105.25255,0.28063953,-40.911346 -321679000,0.10323431,-161.71373,0.00057448918,-2.4797015,886.51385,104.83734,0.23848794,-10.931459 -322178500,0.10293888,-147.41562,0.0006893067,-60.176773,886.60199,104.01778,0.25954032,-27.469065 -322678000,0.088940546,-167.50262,0.0010028566,1.1546841,877.95593,104.50605,0.26221004,177.00281 -323177500,0.16100916,179.46861,0.0017612536,87.491737,880.27081,103.28958,0.076915599,-115.05479 -323677000,0.16271864,-176.26411,0.0013885429,92.626328,883.08551,102.15894,0.16308351,-85.065529 -324176500,0.096614942,-162.64896,0.00070286868,5.3083034,879.02081,100.63469,0.42291063,-40.974243 -324676000,0.15470687,-140.89525,0.0010532524,-133.22659,891.68195,100.71012,0.17901789,13.845057 -325175500,0.12357299,163.74098,0.0019612501,55.099819,883.64813,100.34312,0.10171035,-130.47369 -325675000,0.13556363,-142.85098,0.00071833911,-108.91679,889.60626,99.917061,0.10735431,132.84254 -326174500,0.15684895,-172.00798,0.0011516459,111.0648,863.00946,99.058357,0.56321585,-115.27936 -326674000,0.094781026,-149.51599,0.0008047251,-24.228735,898.95795,98.243156,0.21891522,76.719482 -327173500,0.22082287,-169.12239,0.0023482826,149.18398,890.00165,97.603714,0.097515561,68.09613 -327673000,0.091240168,-149.33017,0.00080876501,-14.490353,888.50995,96.617279,0.067024894,-8.4857607 -328172500,0.10633922,-156.44878,0.00040440739,17.994795,880.36469,95.729607,0.23487826,-60.189671 -328672000,0.12209805,-149.70198,0.000201727,-59.014603,888.09436,95.311386,0.060318254,-13.554176 -329171500,0.036658794,-165.62105,0.0018655093,14.693354,884.95178,94.512268,0.099641345,-60.066624 -329671000,0.16145322,-169.74825,0.0011215481,136.6983,887.97058,93.348457,0.23138036,-12.007873 -330170500,0.10043463,-137.68513,0.00092211179,-27.582254,880.81433,93.092583,0.1913387,-82.719032 -330670000,0.067498237,-173.32265,0.0013189868,34.897388,864.75775,92.987015,0.52041256,-112.07516 -331169500,0.13262247,-162.60323,0.00038597465,121.71145,866.89624,91.835541,0.45538282,-93.843231 -331669000,0.16984025,-157.84692,0.00088046707,-172.6689,872.59125,90.670952,0.38394564,-66.402779 -332168500,0.11115973,-122.74574,0.0013419634,-33.911175,881.99585,90.804108,0.22025512,-125.60358 -332668000,0.12351429,-156.49945,0.00010437911,76.79451,874.6839,89.370636,0.31010431,-77.958313 -333167500,0.16875862,-147.75397,0.0008590644,-123.82744,889.70892,88.320442,0.20874782,4.0160623 -333667000,0.13310501,-124.53779,0.0014160535,-45.066189,870.28418,87.569916,0.44712421,-65.49958 -334166500,0.088685162,-134.57895,0.0010885685,-3.3550575,876.6394,87.591385,0.24623819,-97.441284 -334666000,0.16496024,-158.11218,0.00072143553,-162.93999,883.81042,86.995071,0.16213541,-100.95483 -335165500,0.20940389,-141.67453,0.0015845839,-107.10416,881.82874,85.64872,0.22994782,-54.83728 -335665000,0.085024789,-121.19807,0.0013627927,0.3258622,868.10944,85.123505,0.42597288,-66.470467 -336164500,0.18551081,-136.79636,0.001367568,-90.146255,874.07709,85.99691,0.45025036,-128.65921 -336664000,0.18979777,-145.12819,0.0012192784,-110.61213,879.89209,84.192871,0.19974193,-86.168961 -337163500,0.12554893,-148.84924,0.00022149662,-36.758629,861.05066,84.202408,0.57633978,-101.4213 -337663000,0.16356307,-161.45775,0.00074346678,-161.95374,869.59009,82.702225,0.3863191,-79.257713 -338162500,0.11009059,-146.64235,0.0003943897,27.315493,859.94543,81.842148,0.56907666,-66.010399 -338662000,0.099190913,-146.50793,0.00059463736,33.361988,871.92102,81.237411,0.28283128,-70.608414 -339161500,0.032012079,-150.07921,0.0017596956,56.431438,862.63147,80.533203,0.48563719,-76.432541 -339661000,0.12895711,-129.19579,0.00097727054,-20.749828,876.65729,79.557457,0.20908423,-40.748322 -340160500,0.14700733,-148.51939,0.00033891739,-89.401535,884.08649,78.767784,0.15781109,-36.113586 -340660000,0.12637696,-126.04286,0.001054369,-8.9606953,888.68591,78.293671,0.041679423,-50.499886 -341159500,0.17631258,-146.59016,0.00082449848,-87.278427,899.69794,78.012672,0.18941234,167.98679 -341659000,0.044463493,-148.87326,0.0015469985,68.654198,872.49048,76.19574,0.34849066,-40.954372 -342158500,0.17683062,-175.29747,0.0012602463,-172.60944,908.99438,75.74588,0.32862404,114.95793 -342658000,0.14289826,-131.8298,0.00090048718,-16.821795,889.30121,76.181534,0.22598134,-144.92493 -343157500,0.14153311,-150.90034,0.00020490837,-81.691643,875.04047,76.787422,0.59891289,-121.49112 -343657000,0.11490513,-140.87825,0.00051082019,25.947403,875.09167,75.54158,0.48318818,-114.45346 -344156500,0.12815177,-139.07172,0.00057426089,1.1565907,862.45471,74.067612,0.50365102,-76.174744 -344656000,0.19375923,-152.75345,0.0010359226,-97.103416,893.92969,73.661858,0.32254156,-149.52733 -345155500,0.095398806,-97.547874,0.0018102082,39.446545,881.96759,71.729012,0.12964296,-27.252012 -345655000,0.12843925,-143.40799,0.00034303541,9.1893921,887.57379,71.290771,0.047690857,-112.59201 -346154500,0.16011389,-150.18217,0.00044332366,-87.844353,887.87628,71.171661,0.20343311,-113.07452 -346654000,0.17754795,-126.55188,0.0013206069,-21.010189,891.55597,69.714256,0.069643915,-13.343892 -347153500,0.13745528,-167.01694,0.00057352736,-176.22189,903.58936,70.006538,0.35232955,-174.95203 -347653000,0.15444301,-156.91876,0.00041140092,-115.30716,882.75397,68.777168,0.22054757,-95.489517 -348152500,0.12660719,-151.65332,0.00014145349,68.334297,875.66071,67.298904,0.16572545,-13.76455 -348652000,0.13812231,-165.85587,0.00055480312,-167.29529,884.51398,66.332367,0.14169885,31.969347 -349151500,0.17388099,-173.23726,0.0011746195,-140.64833,858.08813,66.135941,0.45889845,-38.921535 -349651000,0.14794269,-148.50247,0.00028125092,-37.220428,897.17932,65.900093,0.23934186,175.25948 -350150500,0.13640283,-171.38438,0.00079167844,-170.5806,901.70557,64.874527,0.23042345,154.95909 -350650000,0.10303102,-134.40195,0.00075633638,66.06617,885.51544,64.674934,0.13084227,-124.10801 -351149500,0.17334379,-147.82861,0.00065653853,-50.042717,868.27771,64.264816,0.39240462,-75.213158 -351649000,0.11506416,-179.41379,0.0010902019,172.93468,861.6745,63.482681,0.48689568,-62.302704 -352148500,0.14872377,-148.66859,0.00029304341,-32.204666,857.31732,61.922756,0.50354165,-29.063002 -352648000,0.16772494,-147.90019,0.00066518231,-47.818134,887.6673,60.79483,0.17926373,67.388123 -353147500,0.19210812,-162.67474,0.0010923354,-93.541519,890.81647,60.565159,0.076798841,170.01195 -353647000,0.11783604,-137.87059,0.00063276087,66.193695,867.43207,60.615143,0.37216172,-67.633583 -354146500,0.17505713,-123.49064,0.0014386821,22.635592,880.46143,59.157349,0.07174094,-47.471363 -354646000,0.15849136,-179.60959,0.0012824599,-138.3587,874.24896,60.287369,0.48234898,-93.663193 -355145500,0.048246797,153.44121,0.0019914594,147.71176,893.43384,57.980335,0.20533739,-176.38817 -355645000,0.073973268,-156.12215,0.0011018423,135.64555,885.33044,56.93961,0.041071575,163.33482 -356144500,0.15284631,-151.33252,0.00030989299,-36.009262,870.18048,57.316311,0.34034175,-75.13205 -356644000,0.10593559,-169.24594,0.00081595621,-179.22801,867.3208,54.983532,0.33969018,12.257184 -357143500,0.085129946,-139.77144,0.00095723174,115.7047,877.50214,55.017082,0.076016255,-11.149565 -357643000,0.17144643,-145.22566,0.0007380165,-7.4675117,885.01379,55.561932,0.38080871,-119.70162 -358142500,0.12893687,-106.97731,0.001805905,77.287987,882.56189,55.228348,0.47158769,-105.62299 -358642000,0.1361109,-158.94235,0.00030072394,-136.02168,872.92816,53.629337,0.28039652,-70.53318 -359141500,0.15659431,-158.87244,0.00046111035,-78.890205,868.49658,51.945999,0.21908002,10.177181 -359641000,0.17748922,-150.49741,0.00068563526,-25.877523,870.83704,52.174213,0.28474575,-62.829697 -360140500,0.12200461,-132.82127,0.00084124162,88.066963,873.29797,51.723587,0.28296611,-73.803513 -360640000,0.15460892,-130.45372,0.00096766761,55.385509,875.87775,50.578518,0.21259923,-69.174187 -361139500,0.15142114,-126.07635,0.0012616398,68.066597,877.48358,50.451317,0.33281711,-94.311226 -361639000,0.16201018,-129.08066,0.0011747257,56.6931,870.17456,49.390556,0.28262949,-53.778446 -362138500,0.16879357,-140.11113,0.0008159834,30.576504,886.96252,48.530781,0.21305722,-130.59264 -362638000,0.15741214,-171.25778,0.00099382002,-100.33312,892.53931,47.384163,0.25769326,-171.22745 -363137500,0.17909651,-145.15981,0.00084417773,11.171022,887.31775,47.137623,0.2160304,-133.39053 -363637000,0.15554,-163.90486,0.00070280855,-81.208687,878.63977,47.004288,0.32181558,-81.008743 -364136500,0.13674191,-154.64423,0.00018047186,-122.15327,873.64014,45.072609,0.088347219,0.23643279 -364636000,0.13580674,-148.08707,0.00024322326,100.97226,883.8233,46.562119,0.62492919,-97.822449 -365135500,0.11382649,-135.01744,0.00094869093,127.55549,871.64288,43.880749,0.088201635,-59.643028 -365635000,0.12551755,-155.84071,0.00040994867,-160.47002,877.66632,43.926765,0.3108364,-93.563049 -366134500,0.23360559,-149.08563,0.0018506112,2.8714027,879.15741,42.592308,0.11428501,-114.65915 -366634000,0.13699754,-130.99385,0.0010277143,101.674,883.85388,42.551971,0.31535143,-110.32777 -367133500,0.2090811,-127.69111,0.0020456503,58.704063,877.49982,42.090729,0.32885247,-81.916367 -367633000,0.19415429,-131.90791,0.0016120367,62.240009,879.14807,39.582432,0.27517655,133.56068 -368132500,0.16605867,-158.942,0.00059588626,-39.793774,866.54364,39.832642,0.18243432,-12.830432 -368632000,0.15359414,-112.09317,0.0021711378,108.34947,895.62177,39.852596,0.49425963,-134.88995 -369131500,0.17986198,-146.55136,0.00088522088,32.798466,874.4848,39.982529,0.57862335,-73.426117 -369631000,0.11244884,-163.84912,0.0008527998,-137.81732,863.01648,39.361401,0.6051138,-50.275822 -370130500,0.12812385,-160.22447,0.00053942611,-115.37115,876.50122,38.470005,0.56719315,-74.851959 -370630000,0.16033836,-171.65152,0.0011710444,-72.470901,881.74982,36.51313,0.28617972,-127.82973 -371129500,0.18764818,-145.63864,0.001097466,44.785843,880.2807,36.340691,0.28994313,-90.137024 -371629000,0.14237645,174.97876,0.00179377,-88.844742,883.03931,36.008327,0.42844966,-94.247009 -372128500,0.13989776,-154.60823,0.0001375237,-102.26505,879.45239,35.034637,0.37956223,-82.183464 -372628000,0.16480325,-141.96196,0.00090024655,83.51442,873.84381,34.381184,0.25219759,-67.321014 -373127500,0.11972295,-166.15674,0.00092439103,-115.65226,872.24872,33.869171,0.32999739,-68.155373 -373627000,0.15340748,-134.57771,0.0011657043,118.74529,865.86609,32.402905,0.18696415,-9.3938847 -374126500,0.15155108,-147.15738,0.00038560992,109.32178,871.16925,32.074902,0.25559729,-67.810471 -374626000,0.13147664,-148.45441,0.0004625408,-174.24969,869.49915,30.627642,0.048714403,-6.9527836 -375125500,0.1927443,-142.0334,0.0014227357,78.119965,873.62878,30.304173,0.14543837,-72.143074 -375625000,0.16292383,-173.59534,0.0013630911,-43.20615,861.74896,29.619772,0.26217133,33.378075 -376124500,0.15898283,-146.60703,0.00058324874,99.905479,885.99994,29.382469,0.47749171,-104.02573 -376624000,0.12533133,163.02376,0.0027776666,-81.602173,867.09448,28.085501,0.0929811,-44.350384 -377123500,0.083974011,-164.6965,0.0018105765,-119.0965,857.6795,27.428612,0.26256374,35.141212 -377623000,0.1301879,-146.20529,0.00066616171,176.36896,877.99884,27.597599,0.42131278,-60.025513 -378122500,0.12931809,-144.6232,0.00069691037,-170.11993,873.49756,26.256851,0.33719501,-81.410477 -378622000,0.15131551,-156.40117,0.0002918535,-2.126709,875.8714,24.473827,0.35182163,-177.45648 -379121500,0.17318027,-149.17737,0.00088194595,89.143311,868.34534,25.043257,0.12773082,13.711841 -379621000,0.13902251,-137.34447,0.001252184,168.92909,876.80988,23.965776,0.30694997,-112.94706 -380120500,0.1825105,-151.6806,0.0010398908,73.527351,865.47839,23.637768,0.27498999,-9.6552372 -380620000,0.1208287,-149.05731,0.00095994223,-142.34306,875.25372,22.812197,0.19883791,-84.296814 -381119500,0.13792466,-157.13939,0.00042515731,-89.138214,864.31274,22.558468,0.22595838,-10.60231 -381619000,0.16553782,-153.13651,0.00056726963,74.289436,876.52997,21.557106,0.35974857,-82.45948 -382118500,0.15151533,-163.36044,0.00081621681,-13.811152,873.57281,20.548096,0.24307574,-99.323837 -382618000,0.1414392,-153.94017,0.00033110738,-86.495239,872.37036,20.34771,0.38852438,-71.229317 -383117500,0.17694978,-148.47627,0.0010821562,113.00568,877.73932,19.264013,0.36976242,-103.03644 -383617000,0.1507704,-171.10439,0.0014117995,-15.002127,866.86768,18.348907,0.039258875,131.98305 -384116500,0.12974562,-144.31728,0.0011757392,-146.07773,875.22095,18.386551,0.43862978,-52.351955 -384616000,0.18082871,-158.93221,0.0010685212,58.447338,859.77557,17.125139,0.17512871,71.828217 -385115500,0.13588606,-166.7421,0.0013131737,-31.940174,859.82617,16.842014,0.37588009,28.224194 -385615000,0.15032151,-138.41959,0.001468331,-170.09769,863.2735,15.711635,0.087216116,-19.520605 -386114500,0.14758259,-145.57872,0.001057626,-149.44034,873.7337,15.117661,0.34746072,-92.271202 -386614000,0.11721066,-143.03955,0.0018066467,-110.56105,865.25983,14.670422,0.16872841,-9.8322182 -387113500,0.15946259,-158.70485,0.00046800292,35.596127,878.65686,13.185536,0.66361612,-120.68941 -387613000,0.14876133,-166.85509,0.001313161,-2.4828224,870.60889,13.413333,0.33372676,-48.701515 -388112500,0.16718286,-147.7885,0.001091057,174.29826,874.64972,12.732872,0.49071091,-41.213428 -388612000,0.15363687,-148.83345,0.00078609743,-144.53252,872.15509,11.074141,0.50979775,-122.3698 -389111500,0.15407366,-162.9301,0.00098873698,18.563147,872.95203,10.561389,0.55760115,-106.68856 -389611000,0.14268577,-165.08835,0.0012996311,1.0881667,866.30475,10.237139,0.23974051,-95.583855 -390110500,0.15067527,-153.85899,0.00039682866,-93.86895,869.49133,8.9647503,0.48794255,-126.94164 -390610000,0.19563828,-160.66589,0.0018658898,106.42226,857.91937,8.7002583,0.24582057,152.15024 -391109500,0.17719227,-154.57545,0.00094095699,136.59286,857.26813,8.1602955,0.17705299,142.97618 -391609000,0.13289204,-150.56567,0.0013453135,-64.265511,864.53009,7.5343356,0.20829223,-88.296669 -392108500,0.20307548,-146.87592,0.0025293618,-178.32718,858.78461,6.8835196,0.1566067,161.00169 -392608000,0.15989707,-162.04878,0.00075051491,68.876511,864.52979,6.4997563,0.28434697,8.1576605 -393107500,0.14418179,-153.25534,0.00078169908,-49.99432,859.4682,5.5697417,0.095209435,76.37043 -393607000,0.17542401,-152.53842,0.00099470722,-164.35362,860.23535,4.5770855,0.22514497,-171.12971 -394106500,0.15812509,-162.82335,0.0011411043,64.785706,864.54639,3.8042772,0.43448973,-87.444649 -394606000,0.17403053,-161.99646,0.0010922721,115.57064,861.16278,2.7958765,0.44045529,-127.7121 -395105500,0.15628158,-154.67172,0.00041654526,-84.138481,862.58459,1.9883776,0.54459655,-124.07091 -395605000,0.15353428,-154.65073,0.00032964037,-47.311375,858.14386,1.9331073,0.089477077,176.64781 -396104500,0.16553865,-170.17381,0.0018949949,93.339142,863.75677,1.3978515,0.18546377,4.1544385 -396604000,0.15986881,-160.44701,0.00042661067,90.927856,867.23285,0.2089058,0.41399738,-66.216591 -397103500,0.154172,-166.16481,0.0010970118,77.576477,862.39227,-0.15880474,0.051182244,-102.02168 -397603000,0.14741611,-155.4227,0.00067315903,-4.5165024,858.75732,-0.81588274,0.097966798,-109.14735 -398102500,0.15000692,-157.79301,0.00059540267,25.505615,865.75378,-1.9508506,0.44066328,-63.958965 -398602000,0.13467714,-157.53003,0.0011949243,27.530121,858.47119,-2.966888,0.5467912,-93.210411 -399101500,0.19006366,-148.70766,0.001733301,-109.5385,860.62927,-3.0022523,0.15755169,-75.062126 -399601000,0.15708666,-163.03552,0.00074262603,99.174538,862.15228,-3.4492545,0.21017145,24.521383 -400100500,0.18281066,-167.98732,0.0017972151,148.18365,858.16107,-4.5396285,0.28074574,-81.320137 -400600000,0.14730686,-156.28839,0.000712412,33.279026,852.5509,-5.4464931,0.43759429,-118.99799 -401099500,0.17962104,-165.23671,0.0010466423,159.70807,856.61536,-6.0402117,0.29998967,-119.31272 -401599000,0.17064869,-164.92708,0.00099849899,153.50092,852.11023,-6.2957425,0.27789024,170.48903 -402098500,0.14300454,-165.07329,0.0011540876,81.267929,859.87549,-7.6116109,0.36991549,-62.668884 -402598000,0.18569991,-157.10295,0.00085918681,-129.73779,860.16681,-8.0306988,0.30054435,-53.69994 -403097500,0.19264124,-150.21217,0.0013535459,-83.30146,858.59906,-8.6923351,0.32115278,-55.644318 -403597000,0.1635747,-162.93668,0.00049228186,137.4761,855.17645,-9.7581606,0.38246801,-81.813599 -404096500,0.17481388,-148.82936,0.0010814496,-47.866505,854.48102,-10.277165,0.42232445,-83.083687 -404596000,0.1904092,-167.69366,0.0013576028,-170.71281,861.78351,-10.408008,0.14655635,7.1712699 -405095500,0.14574492,-159.57458,0.00073313701,66.711685,850.85876,-11.568475,0.36480567,-106.83604 -405595000,0.15744901,-154.35764,0.00054039026,32.537182,855.40424,-12.159736,0.31570637,-62.441132 -406094500,0.16993274,-157.73453,0.00016030288,-69.635399,851.40393,-13.247538,0.3844642,-72.408485 -406594000,0.15878929,-172.33232,0.001370284,146.79494,853.30133,-13.736382,0.24524258,-60.300365 -407093500,0.14963584,-154.09425,0.0007119595,52.204472,852.03534,-14.036243,0.18293719,-94.921333 -407593000,0.14462775,-162.59106,0.00076040538,99.013756,857.38464,-14.779474,0.13430528,0.22163586 -408092500,0.21224821,-150.57162,0.0017660041,-65.082771,850.71521,-15.080448,0.084471263,-155.03946 -408592000,0.14367688,-167.61441,0.0011292018,127.97977,862.0719,-15.761393,0.31394759,55.605854 -409091500,0.16533346,-156.92647,9.8135308e-005,56.249332,853.04352,-17.145241,0.26154435,-41.937607 -409591000,0.21668185,-147.75008,0.0019523414,-44.07851,862.99518,-17.743378,0.36413985,27.185934 -410090500,0.1393792,-153.21352,0.0010680837,71.601028,840.31238,-17.915218,0.36548352,-119.64948 -410590000,0.16710298,-156.11172,0.00034319327,34.466919,851.25781,-18.423391,0.14910245,-162.98077 -411089500,0.15761504,-162.08923,0.00041225867,131.15079,848.72205,-19.403053,0.06917192,-111.78854 -411589000,0.11756942,-159.76294,0.0016035161,105.66524,855.03973,-19.458399,0.2121129,123.94963 -412088500,0.23579785,-149.84583,0.0021401132,-45.56752,849.65576,-21.201916,0.2633619,-49.75185 -412588000,0.17494683,-148.7363,0.00092353544,17.308922,846.36884,-21.533455,0.17222485,-105.82622 -413087500,0.21000029,-151.71922,0.0012454231,-33.465084,837.74347,-22.790102,0.50741488,-80.659058 -413587000,0.1832245,-147.6664,0.00097968406,5.367733,848.92285,-22.88125,0.076231033,-56.079468 -414086500,0.1687234,-156.17206,0.00026845129,43.222824,842.48999,-23.211819,0.27544191,-131.5153 -414586000,0.15419489,-152.96455,0.00070175662,73.595871,847.88684,-24.662735,0.21417396,-41.766586 -415085500,0.21446803,-150.67737,0.0014316264,-22.562855,851.32263,-25.14212,0.16562299,-11.997576 -415585000,0.19761428,-144.01984,0.0014277108,14.166298,840.36688,-25.200525,0.26180503,-118.22925 -416084500,0.15303397,-137.35677,0.001862837,63.731903,853.9762,-26.787745,0.16896404,-10.444031 -416584000,0.16785473,-144.18668,0.0012784175,52.528236,849.21588,-26.709227,0.12151677,-171.93806 -417083500,0.24031392,-169.07056,0.0018268898,-83.018478,838.71228,-27.502165,0.29056406,-98.846191 -417583000,0.19116619,-176.21771,0.0012450755,-130.65657,851.9823,-28.268978,0.075187296,-179.83583 -418082500,0.15470746,-145.96024,0.0010758563,78.912682,833.65643,-28.38731,0.39011136,-120.94946 -418582000,0.15175612,-151.64565,0.00081820466,93.051399,852.09686,-29.982708,0.14045675,43.267307 -419081500,0.15808108,-164.73972,0.00053109217,167.25493,834.84186,-31.03554,0.41836196,-61.49509 -419581000,0.25920245,-156.73531,0.0020283312,-26.860661,836.80121,-31.830923,0.34004331,-50.154716 -420080500,0.20856519,-154.4845,0.00099728093,-0.0013511467,845.09674,-31.65988,0.096814103,-146.29291 -420580000,0.19528374,-160.81241,0.0004010656,-35.516739,843.8089,-31.91573,0.18220773,-152.09512 -421079500,0.20919974,-162.8623,0.00076690171,-42.492638,836.92419,-32.967182,0.24871509,-109.97061 -421579000,0.15518321,-156.80469,0.0005418298,116.91302,840.28033,-34.478661,0.26382071,-32.244614 -422078500,0.18033819,-177.38956,0.0011494351,-123.4753,844.24414,-33.885586,0.27436799,-161.30304 -422578000,0.21627936,-173.56241,0.0013078721,-78.44117,839.63715,-35.669712,0.15935014,-41.656578 -423077500,0.15696466,-143.89633,0.001306915,94.671799,838.40442,-36.269428,0.18269661,-70.496513 -423577000,0.14582755,-141.80135,0.0014339914,105.52698,848.07886,-36.960487,0.11858351,67.036964 -424076500,0.18104507,-150.05818,0.00076727808,65.311333,839.80286,-37.103497,0.14876367,-106.84554 -424576000,0.16781503,-158.82965,0.0003390343,123.82113,845.00604,-37.426537,0.2192442,-165.44408 -425075500,0.21103862,-149.55309,0.0010432459,47.810669,852.83075,-38.571602,0.14900284,133.95561 -425575000,0.25489664,-145.00391,0.0022044347,36.570847,831.02484,-39.785004,0.27572179,-60.976772 -426074500,0.17386535,-160.65533,0.00020265112,158.10797,849.51538,-39.412804,0.21464024,-172.57713 -426574000,0.20442601,175.47649,0.0016844154,-95.611816,828.35266,-40.60965,0.39336771,-81.75544 -427073500,0.17040972,-157.36676,0.00042716335,118.87733,826.81628,-41.70245,0.348409,-68.465599 -427573000,0.20677397,-155.88931,0.00071622484,40.950272,833.22137,-42.398571,0.23732522,-62.066059 -428072500,0.17558247,-151.78111,0.00074320525,95.088135,835.14282,-42.017769,0.34052292,-133.6254 -428572000,0.23686166,-162.2845,0.0012000367,-1.6285805,838.5495,-43.815079,0.096257672,-28.642603 -429071500,0.2086861,-160.95685,0.00060976,14.566272,836.72931,-43.913704,0.17050841,-117.25443 -429571000,0.11712218,-158.77736,0.0013444881,176.51451,844.26074,-44.667599,0.14483379,-159.91272 -430070500,0.17604581,-161.33167,0.00023904409,172.63911,836.74969,-44.782566,0.40432543,-120.10323 -430570000,0.17091264,-154.83646,0.000499802,122.49388,848.04675,-45.799824,0.23306927,178.38989 -431069500,0.20824002,-179.02179,0.0011648991,-62.19545,849.23566,-48.080326,0.28023133,74.511795 -431569000,0.17765442,-142.01115,0.0013722755,118.03508,835.53998,-47.371025,0.20909372,-102.68446 -432068500,0.22081806,-177.63612,0.0012413792,-48.838703,844.54993,-48.88467,0.085379191,105.34625 -432568000,0.14435829,176.63658,0.0013222182,-116.85701,841.06781,-48.890739,0.12953526,-157.08531 -433067500,0.21960045,-152.50394,0.0010904513,74.098488,834.66095,-49.315544,0.27729535,-114.31915 -433567000,0.1538468,175.38162,0.0014052258,-105.03586,851.62708,-50.631866,0.21100271,139.05582 -434066500,0.18102863,-173.25404,0.00055215362,-75.252495,844.17615,-51.685795,0.15316346,104.57265 -434566000,0.20286314,-173.44498,0.00076566008,-41.026081,841.65839,-51.676918,0.12945969,-140.94606 -435065500,0.17414176,-165.02335,0.00021864507,-142.81293,838.28912,-52.674728,0.084059305,-132.00397 -435565000,0.227971,-169.6243,0.0009007203,0.055656657,828.24365,-53.709583,0.17084894,-37.995201 -436064500,0.27522403,-164.40579,0.001745828,30.331669,844.71027,-54.219357,0.12767997,152.97424 -436564000,0.22505194,-174.35059,0.0010039659,-11.375621,849.07727,-55.754246,0.2988646,112.51542 -437063500,0.16278642,-158.15141,0.00067146099,171.90292,822.05042,-56.172115,0.27513185,-6.6967478 -437563000,0.22426876,-158.14619,0.00089981523,70.709229,829.51752,-55.235729,0.39231324,-104.08805 -438062500,0.13596533,-169.08321,0.0010936633,-130.92018,817.7168,-56.726967,0.40564656,-57.193653 -438562000,0.19991244,-167.01714,0.0002943507,1.6016566,838.26312,-56.953533,0.28145787,-126.36821 -439061500,0.18497072,-152.03276,0.00087296485,142.90173,822.02075,-56.920555,0.51622576,-94.514473 -439561000,0.19108014,-170.04019,0.00028434113,-37.351746,840.19775,-59.074196,0.10277936,171.69652 -440060500,0.21491453,-174.85526,0.00084173842,-3.8815086,821.31519,-58.849968,0.38435143,-82.556374 -440560000,0.15314886,-152.9715,0.0010623451,-172.69734,832.2782,-61.110367,0.09645965,77.75248 -441059500,0.14687909,-177.09135,0.0010157097,-93.132469,828.01624,-61.297771,0.074975565,-26.504265 -441559000,0.16404074,-174.05775,0.00063543575,-85.79245,842.41559,-61.668488,0.28667423,-167.95207 -442058500,0.23784032,176.7997,0.0015750095,-4.1586504,838.9964,-62.197861,0.24875186,-150.51772 -442558000,0.19832715,-170.41336,0.00036980447,8.3366566,830.93805,-63.817593,0.085141107,41.385826 -443057500,0.18363327,-139.73859,0.0016334095,162.87558,832.68787,-63.161095,0.24159381,-105.83134 -443557000,0.1283696,-161.06113,0.0012510832,-129.92107,811.84882,-63.74947,0.47035784,-59.739548 -444056500,0.23180175,-150.98279,0.0013592956,123.04795,834.52307,-65.362907,0.09472394,-135.36131 -444556000,0.11613312,167.92601,0.0019215115,-84.440506,830.35242,-66.163597,0.074696861,-138.77835 -445055500,0.25246465,-160.39276,0.0013386697,93.314575,836.17908,-66.606216,0.19177689,-148.78429 -445555000,0.17486349,167.79462,0.0016659176,-41.586613,845.46399,-66.733345,0.3934772,-140.72073 -446054500,0.17790855,-151.94035,0.0009826069,-174.20543,827.23065,-66.944107,0.54235339,-94.329231 -446554000,0.20812185,-151.18744,0.0011298137,154.28036,837.24792,-69.395172,0.1456829,169.07245 -447053500,0.27978718,-163.51799,0.0018962122,88.436081,816.0199,-69.105515,0.28015521,-49.022488 -447553000,0.29287589,-159.60812,0.0022205105,100.68017,822.85498,-70.798454,0.10547124,43.932407 -448052500,0.17850086,-156.22243,0.00077738287,-167.74133,828.2688,-71.992126,0.23128588,102.64319 -448552000,0.2359798,-154.58734,0.0014163898,136.87131,827.6969,-71.695435,0.10122222,-139.71544 -449051500,0.11924656,-171.42555,0.001434129,-91.615517,815.73901,-71.917015,0.29944637,-52.043465 -449551000,0.20909454,175.18396,0.0012534244,7.7375312,827.44507,-71.905998,0.40560099,-92.005104 -450050500,0.17182976,-172.4256,0.0004321468,-62.097179,825.96667,-73.209641,0.26222596,-102.39568 -450550000,0.12035757,-171.5029,0.0014157236,-84.53405,827.2309,-74.102211,0.21673571,-95.522476 -451049500,0.17447746,170.4288,0.0014217574,-21.5756,812.89117,-75.700188,0.19929945,27.510244 -451549000,0.17362434,176.96983,0.00098868844,-20.897833,820.49823,-76.521957,0.076830208,90.735641 -452048500,0.22446769,-163.97365,0.00085948687,126.99559,812.83759,-76.037018,0.31349751,-52.621742 -452548000,0.20354252,-164.04164,0.00046705257,159.9071,810.30762,-77.200409,0.23148862,-27.486523 -453047500,0.22217014,-179.73972,0.0010992183,48.78371,840.57092,-77.349663,0.4980202,-130.42711 -453547000,0.25148964,-176.36655,0.0014877463,77.325554,829.01062,-78.948326,0.18092676,-154.99973 -454046500,0.11318775,-160.31888,0.0017110141,-85.870163,820.72198,-79.508675,0.09959583,-115.15276 -454546000,0.18840417,-169.35931,7.7406148e-005,-159.18216,833.81805,-80.269753,0.35489714,-154.677 -455045500,0.19210036,-165.83282,0.00031469465,-172.25163,817.01837,-81.278809,0.056576271,52.466835 -455545000,0.17249344,-170.44218,0.00034889244,-56.165119,819.41364,-82.500771,0.17405175,121.19947 -456044500,0.13987343,-152.55363,0.0014985936,-104.51218,820.21802,-81.309837,0.38805595,-73.381866 -456544000,0.15993772,-168.8938,0.00068540196,-66.701721,835.10437,-83.37513,0.4646208,-154.61794 -457043500,0.23222871,176.54131,0.0014383702,63.487408,810.47241,-82.722717,0.38837641,-51.627514 -457543000,0.17430167,175.40651,0.0010965092,5.0986104,821.72803,-84.384895,0.20431246,-110.84502 -458042500,0.15002152,-166.18619,0.00094850617,-72.094673,812.81079,-85.301498,0.060520101,-41.243935 -458542000,0.20757063,-165.89639,0.00052286393,170.26361,820.27338,-85.283905,0.36446884,-97.773117 -459041500,0.19802779,-166.66504,0.00042162667,-178.3891,813.57251,-85.856873,0.31567758,-62.076374 -459541000,0.178259,-173.54274,0.00023196811,-22.721313,817.59436,-88.082672,0.27559635,144.96866 -460040500,0.17963171,-177.29698,0.00055027928,10.824266,809.78094,-86.972321,0.41599593,-53.766438 -460540000,0.19673537,-178.29202,0.00064689753,56.981625,823.55334,-89.169334,0.3100583,-154.79558 -461039500,0.21853919,-166.58559,0.00073984772,169.7755,819.57983,-89.783157,0.25126892,-144.89265 -461539000,0.13576226,-166.12798,0.0013144821,-56.649086,806.81384,-89.954025,0.15402348,-0.46746188 -462038500,0.21321107,-166.04895,0.00087112433,-174.35692,810.35889,-90.831543,0.022406684,-163.85364 -462538000,0.19829829,-156.25175,0.0013500713,-131.15268,808.52197,-91.028572,0.26449621,-34.688328 -463037500,0.18736911,-173.70984,0.00021016769,8.3913965,803.95709,-91.519318,0.33809575,-33.904369 -463537000,0.19272825,-160.81561,0.0010300586,-120.83127,801.27618,-92.805992,0.19707897,12.081741 -464036500,0.13293217,-160.32256,0.0016639846,-51.768814,807.67883,-92.982666,0.37678987,-39.432278 -464536000,0.1561019,-168.97009,0.00084040413,-43.250271,818.29877,-95.115959,0.31266746,-160.77312 -465035500,0.23577179,-165.24049,0.001432079,-170.78282,805.60339,-95.410896,0.078175902,123.15185 -465535000,0.16979493,-161.88382,0.0010504902,-79.398071,807.78119,-94.153496,0.67396438,-38.060379 -466034500,0.18031675,172.24051,0.0012889071,50.782413,811.22968,-95.553795,0.38421869,-55.467415 -466534000,0.17539746,-161.34737,0.0010863786,-77.114624,799.8941,-97.865143,0.20834707,131.34065 -467033500,0.18533333,169.49718,0.0015650563,64.625023,797.32788,-97.616859,0.27556244,22.119131 -467533000,0.18206026,-165.16646,0.00078500446,-84.986542,817.59674,-98.384186,0.44626713,-100.9108 -468032500,0.22268224,-170.04066,0.0010142004,-165.47415,811.59692,-99.433342,0.27597424,-116.33179 -468532000,0.22225343,176.0352,0.0013907601,119.29969,802.78113,-99.62886,0.21824895,-35.293541 -469031500,0.19867805,-164.29807,0.0010165444,-106.38305,805.2312,-100.74332,0.059418261,-32.450081 -469531000,0.24391739,-172.76331,0.0016930028,-176.14398,801.7951,-101.17802,0.10967219,-30.103205 -470030500,0.22311981,-174.86256,0.00095567113,175.61813,801.18115,-102.40018,0.15764832,-165.03275 -470530000,0.15966934,179.01703,0.0011719911,37.036114,796.03088,-102.77989,0.14447568,10.220705 -471029500,0.18889697,-166.23764,0.00087378745,-77.440582,802.52856,-103.75063,0.17062436,-132.12544 -471529000,0.2253744,175.15636,0.0017069683,133.64462,799.86005,-104.11637,0.18935907,-47.051876 -472028500,0.15157583,-171.69302,0.0012670838,-0.94739807,801.82874,-104.55023,0.27430817,-48.271858 -472528000,0.20772646,-174.43585,0.00058815512,-153.95192,800.76031,-106.49982,0.30613175,179.67554 -473027500,0.16387573,-167.50351,0.001132174,-20.27667,804.13953,-106.18302,0.28303072,-77.310043 -473527000,0.21884835,-163.69086,0.0016649634,-102.3238,803.00696,-107.02695,0.27896914,-70.893738 -474026500,0.21996713,-174.17638,0.001172234,-151.41447,796.76508,-108.26915,0.18116046,-141.87289 -474526000,0.16712216,-178.85648,0.00086703902,43.654049,797.14606,-108.57289,0.13149379,-168.89148 -475025500,0.20348611,-178.4028,0.00065919565,-178.55756,800.15924,-108.55209,0.36189455,-12.703638 -475525000,0.19449115,-177.61542,0.00035670106,166.97617,803.69287,-110.41425,0.39173126,-123.10249 -476024500,0.17845741,-175.4006,0.0004317362,28.979103,798.56647,-110.23895,0.22543271,-37.411053 -476524000,0.18283656,-175.74814,0.00035879223,23.496185,796.39203,-111.41056,0.11958897,-120.10199 -477023500,0.21840695,178.10847,0.0013678343,-176.41263,792.75177,-112.16095,0.099070899,-158.16153 -477523000,0.16277283,-179.20612,0.0008980342,60.850449,795.35168,-112.45732,0.20295738,-22.133276 -478022500,0.25433895,-177.66185,0.0023906548,-138.16455,798.53174,-113.09567,0.23072858,-52.904942 -478522000,0.20745404,176.94823,0.00097736507,-179.11838,804.77802,-114.34966,0.44751009,-97.85276 -479021500,0.19469705,-176.97302,0.00013597931,-99.483963,795.07611,-114.87588,0.1041967,-148.00529 -479521000,0.17164442,177.61691,0.0009347095,101.47154,805.15729,-115.56153,0.55752736,-62.370312 -480020500,0.23062369,-179.33072,0.0015987286,-127.87739,788.08636,-116.20946,0.10083742,148.37251 -480520000,0.16355272,175.65993,0.0013686562,102.30598,797.10608,-116.81367,0.18595852,-39.180588 -481019500,0.20548561,-170.26804,0.001212867,-49.559505,798.52393,-117.86919,0.33878893,-94.00473 -481519000,0.18709172,-172.99698,0.00075858139,-7.4740415,787.74866,-119.14581,0.52361929,-156.48709 -482018500,0.19320545,-166.17578,0.0015563765,-19.180325,790.05865,-119.3661,0.18644117,-121.45409 -482518000,0.14280227,-175.44873,0.0019317162,68.512825,796.28967,-119.62041,0.20068946,-33.545151 -483017500,0.18354394,-176.98946,0.00042646858,53.643948,794.24445,-120.82489,0.36559755,-109.17013 -483517000,0.21260975,-170.16852,0.0014630898,-38.144909,790.28394,-121.48702,0.28914264,-104.97168 -484016500,0.20248626,-171.9814,0.0010249201,-28.691551,782.38635,-121.65624,0.26277789,134.52255 -484516000,0.20961572,-176.51041,0.00085686293,-56.43581,790.19507,-122.85285,0.19122344,-119.36261 -485015500,0.19489038,-179.21468,0.00021826572,-72.826195,791.80096,-123.36362,0.2036995,-85.659271 -485515000,0.18458089,177.05399,0.00054669613,164.57126,785.35999,-124.5448,0.43236411,-125.3369 -486014500,0.22761871,174.23856,0.0019409889,-110.41341,788.06482,-125.55556,0.5664804,-103.93965 -486514000,0.18391965,-179.56206,0.00021533613,93.874092,784.17682,-125.9481,0.38506666,-132.74934 -487013500,0.20333213,179.04225,0.00062456698,-87.68103,788.48175,-126.82316,0.41332459,-102.15225 -487513000,0.19796777,-175.88127,0.00064046879,-0.7528671,787.55804,-127.54548,0.4330624,-104.33315 -488012500,0.21658181,170.10512,0.0018262597,-114.51937,789.31116,-127.59803,0.094037957,-26.193153 -488512000,0.19920212,-175.87834,0.00075799698,2.2437775,784.73138,-128.40108,0.13419406,-138.22844 -489011500,0.21354347,177.70988,0.0010683753,-65.327156,787.85474,-129.71722,0.37137705,-85.739731 -489511000,0.19407229,-169.89413,0.0014867734,38.468815,789.89288,-129.73477,0.12873563,-37.685646 -490010500,0.17928647,-172.51544,0.0012258933,66.263443,787.65564,-130.62274,0.099758036,-89.427193 -490510000,0.16280276,-170.50272,0.0016193257,87.149368,783.48035,-131.0732,0.091665447,165.03133 -491009500,0.18816423,-176.81152,0.00061845005,51.644764,783.41687,-132.28465,0.28823528,-108.01517 -491509000,0.22321975,-179.24658,0.0014147274,-23.069651,790.38373,-132.63651,0.14293031,12.786721 -492008500,0.14805493,-175.78812,0.0015997981,131.69867,782.41284,-133.92897,0.36200318,-92.304825 -492508000,0.15130414,-175.12791,0.0014593698,127.1358,779.94977,-134.24327,0.22452211,-118.4362 -493007500,0.17251654,-174.7774,0.0010265458,100.64765,790.65149,-135.0322,0.21183342,-28.249983 -493507000,0.15409006,-176.66045,0.0014898734,135.22833,784.77484,-135.20978,0.14570448,168.85432 -494006500,0.21347386,166.58086,0.0017846848,-81.715164,785.99109,-136.99374,0.37558436,-57.540112 -494506000,0.20930468,-179.42056,0.00084545917,-3.66344,780.24078,-137.00642,0.17698669,-112.028 -495005500,0.21447204,-169.98308,0.0016942623,51.23735,790.1521,-137.74484,0.19476782,-4.9183054 -495505000,0.22218056,-178.71342,0.0012186125,8.6967831,780.35876,-138.70236,0.25486022,-105.13566 -496004500,0.18585135,-174.39539,0.00085243257,80.164993,787.07092,-139.14223,0.12630089,25.890381 -496504000,0.17173989,168.95566,0.001115575,-130.18973,787.51434,-140.03267,0.16326766,-42.765057 -497003500,0.22015552,167.71745,0.0015274937,-52.56004,790.68115,-141.41562,0.3965469,-28.174309 -497503000,0.20882024,167.7213,0.0013275115,-60.29517,783.34515,-141.46422,0.087703153,-106.02902 -498002500,0.19557983,-176.63625,0.00081566628,72.766624,787.8479,-142.20032,0.10919932,23.776237 -498502000,0.17043439,164.108,0.0013713376,-108.97776,783.32343,-142.48138,0.13634872,153.79356 -499001500,0.17907919,173.66003,0.00041716566,-104.649,773.64801,-143.99696,0.37829569,-100.0247 -499501000,0.17276916,170.73294,0.00058415072,-113.53848,776.43866,-145.05128,0.36937195,-81.528305 -500000500,0.1815923,174.93103,0.00023169929,-105.32161,784.60626,-145.46019,0.20618629,-25.224508 -500500000,0.16410692,-179.36392,0.00073617318,177.8213,783.63733,-145.74196,0.044292845,-45.982555 -500999500,0.21658422,171.01584,0.0010792657,-13.51646,784.77002,-146.3638,0.063021563,151.77344 -501499000,0.17334713,176.41962,0.00036882792,-168.99219,784.06799,-147.86304,0.17129448,-42.346355 -501998500,0.20438632,172.56133,0.00063293608,2.2106302,778.09021,-148.52647,0.21646805,-82.662758 -502498000,0.2185035,178.86549,0.0010200408,45.343796,774.69019,-149.05797,0.26994473,-98.223595 -502997500,0.18049534,170.814,0.00055089151,-84.687241,773.09125,-149.44299,0.38439745,-121.54274 -503497000,0.11546951,150.68977,0.00244065,-113.5941,775.87524,-151.20116,0.28201586,-49.889507 -503996500,0.1835223,152.11804,0.001999713,-62.503418,781.92987,-151.64742,0.19545332,-10.356546 -504496000,0.15936258,160.79248,0.0012631413,-86.129616,779.67786,-152.54463,0.18061523,-18.203728 -504995500,0.16728523,167.48209,0.00073454023,-79.218536,773.92755,-153.5201,0.36708578,-44.277977 -505495000,0.16178432,178.52803,0.00072288292,-157.63367,770.71466,-153.23079,0.32793409,-119.68343 -505994500,0.15089701,156.37444,0.0015542198,-85.39167,781.46631,-154.80458,0.17865917,-16.449474 -506494000,0.20236352,-174.27821,0.0010353699,116.57675,769.13226,-155.28812,0.36795509,-85.707794 -506993500,0.22036901,176.87219,0.00098403241,55.750248,771.27124,-155.44675,0.28505546,-102.30211 -507493000,0.19657938,-177.39468,0.00073610124,122.01212,779.34961,-156.44133,0.096778654,-133.89185 -507992500,0.23644409,171.1684,0.0014851391,40.128326,771.48303,-156.39378,0.29820734,-149.42648 -508492000,0.14003113,-173.1674,0.0013760914,-156.52539,773.64709,-158.11104,0.19656767,-86.974693 -508991500,0.16191398,177.25735,0.00048034627,-144.51286,762.73871,-159.04268,0.39265606,-83.55938 -509491000,0.1680284,-171.04553,0.0011388267,175.82858,777.29242,-158.93808,0.20824131,-163.75615 -509990500,0.17229396,-165.56339,0.0016170727,176.36263,768.19659,-160.50034,0.32115641,-85.72052 -510490000,0.14256839,-170.14034,0.0013499685,-155.56302,766.08832,-160.62071,0.30609381,-112.06297 -510989500,0.18739997,174.15413,6.7647859e-005,73.100754,769.29279,-162.58165,0.32093298,-52.163986 -511489000,0.18305886,179.36351,0.00037713116,152.78337,772.02637,-162.35461,0.17233066,-91.445351 -511988500,0.19804768,176.87422,0.00055686175,103.42441,783.73254,-163.89073,0.19652082,57.711628 -512488000,0.1668158,-178.79871,0.00059150963,-162.65883,773.18005,-164.92683,0.21326736,-13.784585 -512987500,0.24364488,-175.6772,0.0017167149,115.8546,762.12823,-165.24969,0.36253682,-64.34153 -513487000,0.20090559,174.64426,0.00066876429,96.769844,760.68195,-165.7448,0.27435449,-76.717964 -513986500,0.19741213,174.09535,0.00046292832,82.786049,759.65466,-166.7807,0.37359709,-58.054729 -514486000,0.15333219,-167.31128,0.0012646627,-149.37675,767.10236,-167.04674,0.19635439,-84.344246 -514985500,0.15888743,169.08797,0.00042628151,-57.612778,775.69305,-168.22664,0.062622279,43.073364 -515485000,0.15377688,-171.62904,0.0011013868,-140.32097,779.9129,-168.02269,0.27476814,174.24727 -515984500,0.20838721,170.00912,0.0008233586,74.323608,761.78979,-169.06665,0.26304302,-103.98766 -516484000,0.17846406,-178.85442,0.00055584538,-173.86095,765.86469,-169.47476,0.34400114,-126.00411 -516983500,0.24735859,168.36928,0.0016672841,82.429543,762.8208,-170.85402,0.20358889,-72.093788 -517483000,0.13254052,163.32121,0.0010926769,-55.858822,769.25238,-171.78526,0.14792004,-133.97157 -517982500,0.19515778,-173.48468,0.0010228935,173.35692,759.12402,-173.27037,0.29165843,-39.065334 -518482000,0.13845821,-173.2803,0.0010946766,-113.39409,754.31207,-173.38797,0.32297394,-62.568535 -518981500,0.15720829,171.82278,0.00037251032,-59.585506,774.77728,-173.43961,0.27724412,-168.70384 -519481000,0.20952031,157.49701,0.0014063979,44.90464,759.58209,-173.76843,0.42591941,-120.14964 -519980500,0.15704174,166.97354,0.00045603723,-22.015697,755.82745,-175.86974,0.25037974,-55.549175 -520480000,0.25066724,-173.5526,0.0019730595,153.46922,756.23743,-176.13881,0.28630719,-79.179741 -520979500,0.14356302,174.26636,0.00060741371,-63.317383,770.49329,-177.14507,0.064738147,-159.97798 -521479000,0.15832292,-170.20872,0.0010826074,-125.779,765.00714,-177.49283,0.19512495,-140.87518 -521978500,0.24756473,-179.18292,0.0016645679,145.65738,758.06335,-178.57974,0.20989735,-78.161591 -522478000,0.11972904,151.97939,0.001510112,-19.53606,752.26404,-177.95955,0.51511264,-106.85791 -522977500,0.16218796,159.92264,0.00079634885,21.689938,747.60364,179.56509,0.34918758,-48.580532 -523477000,0.15655407,178.07684,0.00041153486,-102.74307,746.17743,179.58449,0.41337246,-80.039452 -523976500,0.16421677,157.38113,0.00098079816,30.700537,750.7597,178.58296,0.32826412,-70.270233 -524476000,0.20265384,-163.15625,0.0017858739,-147.02547,758.69055,177.62668,0.15928805,-105.84526 -524975500,0.18321179,177.64,0.00049146678,176.20744,748.5061,177.21716,0.33042169,-79.950539 -525475000,0.13981034,162.38393,0.00079519814,-2.4900224,761.82068,177.05066,0.37486428,-134.65308 -525974500,0.22847869,157.72115,0.001712214,89.695648,765.27411,174.84114,0.065593794,154.68654 -526474000,0.085300393,160.02876,0.0018223571,-23.538187,756.6571,175.01431,0.30197388,-109.7608 -526973500,0.16563918,-171.29364,0.0009704929,-116.87068,741.73572,173.63843,0.35311037,-48.057919 -527473000,0.16474125,167.18726,0.00037348346,47.274025,748.43756,173.40234,0.33753932,-89.308235 -527972500,0.18940848,168.03638,0.00059738744,114.88931,769.32935,172.82362,0.39034328,-158.34689 -528472000,0.17080337,169.6319,0.00029577044,81.850403,742.21942,170.92999,0.32880548,-33.143566 -528971500,0.15934545,-179.88889,0.00044646556,-98.003052,759.19543,169.63202,0.14059797,93.812286 -529471000,0.23480274,-179.90129,0.0015309927,178.44847,751.80884,170.33525,0.31522733,-101.37673 -529970500,0.16249184,175.41101,8.9573354e-005,-80.632843,744.86115,169.08394,0.27460578,-59.963387 -530470000,0.17147382,173.91846,0.0002125059,171.76488,749.89038,168.37518,0.16948809,-83.069389 -530969500,0.17260103,-178.2235,0.00053208548,-129.91042,754.95319,167.92,0.2382113,-117.01368 -531469000,0.22007969,178.01103,0.0011604973,-173.993,738.15485,166.44896,0.28679937,-39.809155 -531968500,0.13588119,162.95358,0.00083958427,26.883654,731.43542,165.73755,0.42885056,-36.612579 -532468000,0.18296275,177.6131,0.00042676806,-151.63318,740.67334,165.03632,0.24580933,-55.733318 -532967500,0.18420835,170.06685,0.00047735113,144.31317,744.12592,164.40862,0.22344595,-76.58873 -533467000,0.23049612,-178.0226,0.0015355633,-156.12584,738.23529,162.56961,0.24852762,13.437023 -533966500,0.16332704,177.8667,0.00026244845,-103.00771,747.36249,162.68845,0.10134337,-89.124939 -534466000,0.15387772,146.64539,0.0015424074,72.327652,743.04938,162.04602,0.15978917,-65.884224 -534965500,0.067946263,170.95418,0.0019570577,6.0536404,740.4538,162.27516,0.4427503,-79.429779 -535465000,0.17617206,-179.20882,0.0005703175,-120.71786,744.35834,160.56905,0.17604934,-87.242264 -535964500,0.17807497,-167.78183,0.0012281225,-89.841179,751.74878,159.68224,0.22611213,-145.02095 -536464000,0.18174618,179.56458,0.00052613753,-125.17823,743.59247,158.06073,0.033549827,146.7133 -536963500,0.21252465,-178.7677,0.0012069554,-141.80136,743.65167,158.13916,0.16366372,-98.72715 -537463000,0.09157984,151.05072,0.0017907099,39.429966,747.23309,158.47147,0.49208701,-111.23441 -537962500,0.21426314,156.73557,0.0016991829,144.31654,735.09363,157.02097,0.29379854,-63.92598 -538462000,0.20199877,179.37042,0.0010648631,-133.56641,747.17108,156.18399,0.28652841,-127.27712 -538961500,0.13379174,-170.86835,0.00094455213,-23.797804,729.42072,155.92296,0.47284624,-59.759239 -539461000,0.19975799,-157.11269,0.0021846064,-76.196312,757.0899,154.44565,0.46310827,-150.79648 -539960500,0.17429905,-172.58168,0.00084709789,-80.780037,754.65674,154.09756,0.49374801,-127.38428 -540460000,0.21179362,166.93938,0.0012566501,179.51608,735.1933,152.69862,0.21050103,-76.518509 -540959500,0.14820333,-168.92464,0.0010215368,-38.332325,740.93018,152.81494,0.42276502,-104.033 -541459000,0.16437559,-177.67274,0.00047382852,-70.114937,748.75677,150.26869,0.33743477,-175.16484 -541958500,0.16841172,172.31728,0.00032637376,-178.72446,731.02057,150.21545,0.18105309,-39.689304 -542458000,0.14678937,168.51498,0.00050217984,99.210472,740.4942,149.82803,0.29477966,-105.4408 -542957500,0.17782681,158.40199,0.0012190189,149.98531,727.93256,148.80757,0.17297305,-64.019089 -543457000,0.19094422,173.89278,0.00076684583,-142.08272,747.76282,147.93294,0.37141606,-142.59435 -543956500,0.1766108,159.3698,0.0012221102,154.27881,744.44769,147.05109,0.32530281,-136.2599 -544456000,0.21855707,-179.40468,0.0015513772,-111.64318,736.77606,146.33046,0.19523284,-114.24402 -544955500,0.12066237,175.91353,0.00068687362,54.197132,726.72437,145.29747,0.12366398,-25.613308 -545455000,0.16439582,-178.26363,0.00045361757,-54.13567,734.07843,144.87357,0.26684013,-113.91238 -545954500,0.18164803,166.24052,0.00095104065,-171.5379,740.64392,144.40038,0.38159227,-112.53037 -546454000,0.13811892,179.54433,0.00040414339,34.057037,726.61316,143.99687,0.35897008,-64.474869 -546953500,0.15967773,169.97253,0.00048052287,175.68317,741.26215,141.43234,0.40229422,-165.07521 -547453000,0.1587055,-167.06223,0.0010984706,-29.188866,730.37622,142.25188,0.2910935,-70.316536 -547952500,0.1699996,163.23755,0.00096440659,178.21213,735.75323,140.40982,0.2772243,-138.9196 -548452000,0.14079909,-170.9644,0.00077625306,5.2334137,726.70209,140.74953,0.35823402,-70.167839 -548951500,0.16285889,177.36545,0.0002328944,-68.202065,718.98236,139.75116,0.25799999,-45.246563 -549451000,0.15273137,-164.3791,0.0011889081,-5.1856346,721.59076,138.48254,0.16290958,-62.805256 -549950500,0.16040352,-177.25055,0.0004216957,-37.338867,720.47632,137.16443,0.037166838,-16.612684 -550450000,0.17192608,-178.27579,0.00066999637,-62.777145,724.23584,137.35814,0.25399071,-64.13768 -550949500,0.13763198,-165.20213,0.0011614601,18.907591,725.65808,135.60658,0.19914535,-143.86958 -551449000,0.13856125,-156.25833,0.0017418691,19.923346,720.8927,135.87219,0.277852,-58.083702 -551948500,0.093202479,166.7648,0.0015131232,110.53569,720.17462,134.86275,0.33933607,-57.751865 -552448000,0.20703697,165.2863,0.0018057566,-129.46654,728.25659,134.543,0.53923512,-77.021126 -552947500,0.14537084,177.05815,0.00013024698,160.85306,723.23383,131.65207,0.27949181,-177.05682 -553447000,0.18639299,155.4514,0.0020067487,-152.95825,717.22241,131.47102,0.1177375,-153.13258 -553946500,0.17320076,-167.68863,0.0012208106,-12.138855,724.22827,130.91275,0.29020625,-113.48328 -554446000,0.13941507,179.10733,0.00027604843,104.37214,720.38196,130.66243,0.27173468,-86.074875 -554945500,0.096610039,169.62061,0.0014566263,124.36555,728.54199,130.19254,0.52202511,-89.149315 -555445000,0.1396949,171.04601,0.00063933496,178.35378,722.66083,128.16614,0.34722912,-137.84856 -555944500,0.10751992,160.14427,0.0016796171,151.19196,721.54456,128.57719,0.41104805,-77.696556 -556444000,0.18670407,168.2261,0.0013142007,-109.28626,714.80945,126.96626,0.16423476,-122.43439 -556943500,0.14470868,178.80127,0.00017090744,-169.34138,710.21497,125.92419,0.030180734,-135.98724 -557443000,0.14566407,179.38281,8.883483e-005,176.65782,715.7489,125.48282,0.21240808,-104.00576 -557942500,0.16001974,-175.26302,0.00051416055,-7.1442037,720.49652,124.52029,0.31905717,-113.6463 -558442000,0.15013595,-170.46442,0.00066522247,39.124397,712.72949,122.88216,0.39647931,-169.33926 -558941500,0.19162709,179.0602,0.0012402284,-52.598835,721.06311,123.95324,0.5052312,-69.966743 -559441000,0.18347107,167.58124,0.0014914174,-98.260704,717.31342,122.41243,0.34854302,-89.50621 -559940500,0.10783862,-169.05133,0.0014667776,110.02538,716.89825,121.9727,0.36170748,-81.364761 -560440000,0.20085905,179.81039,0.001488555,-42.607407,705.01007,121.24616,0.17973228,-24.087564 -560939500,0.16444477,-164.13092,0.001140082,38.692013,708.15155,119.72518,0.2163299,-101.88813 -561439000,0.13922313,168.4077,0.00094667514,-143.7571,706.76141,118.9957,0.1024057,-110.39215 -561938500,0.12091022,-173.46759,0.00081049523,129.71172,715.75232,117.47385,0.49400598,-123.90043 -562438000,0.15349707,-176.1765,0.00023717343,37.489136,712.94556,117.11541,0.40150961,-121.61392 -562937500,0.13492435,176.62575,0.00063756801,-162.20178,703.50696,117.02703,0.17200536,-48.415894 -563437000,0.14088751,-147.37254,0.0023154798,91.621376,713.06287,115.74678,0.43683812,-100.87033 -563936500,0.1531225,-177.28362,0.00014172049,1.1621388,707.34912,114.53094,0.30294815,-130.79085 -564436000,0.11557368,-160.58607,0.0015762396,125.46915,707.67004,113.87592,0.31416002,-111.36772 -564935500,0.12397939,-168.22284,0.0010510045,129.28409,710.38617,113.17159,0.37579361,-97.856148 -565435000,0.18379517,-177.34604,0.0010933285,-7.8124394,703.68549,112.42149,0.22640194,-107.60494 -565934500,0.15020604,178.88361,0.00041027946,-71.804306,692.60852,111.48103,0.20523417,146.81111 -566434000,0.14542563,178.47632,0.00039148622,-98.924232,710.75543,110.8835,0.42225897,-81.077332 -566933500,0.16337483,174.6723,0.00088011951,-59.285488,701.77618,109.86256,0.22263359,-131.95016 -567433000,0.17846902,-179.88881,0.0010935399,-18.776783,702.49799,109.1825,0.26803991,-91.679024 -567932500,0.19038412,172.80647,0.0017581207,-33.766632,698.61346,108.62537,0.1217545,-82.485313 -568432000,0.19277516,-173.6041,0.001506518,19.921654,698.5705,107.75582,0.12747985,-76.676285 -568931500,0.10565218,172.39243,0.0017341066,-137.76572,700.11121,106.52036,0.25084624,-108.22349 -569431000,0.15693484,169.99089,0.0013471907,-73.236916,694.91992,106.28884,0.075280309,-125.68108 -569930500,0.1737221,-178.00877,0.00081875763,6.2274852,702.11328,104.68387,0.4231402,-103.34808 -570430000,0.13480903,172.1799,0.0012452231,-92.699448,691.09924,104.65934,0.067075402,110.35295 -570929500,0.19099934,-173.24156,0.0014301143,35.404015,692.53662,103.59233,0.097607546,-150.90352 -571429000,0.18491185,-170.98795,0.0010570504,54.934467,687.68176,103.11005,0.092499696,151.17409 -571928500,0.16044655,-165.47643,0.00090940174,109.50201,701.06854,101.58157,0.38269413,-75.418594 -572428000,0.099533312,-174.98035,0.0019017537,-137.72696,701.38373,100.62488,0.51412117,-84.805183 -572927500,0.1688268,-165.314,0.0010291291,106.11887,691.99005,100.2719,0.14487652,-95.525574 -573427000,0.15626106,-174.83575,0.00024012725,48.789684,693.17236,99.525337,0.12790304,-79.871933 -573926500,0.19681427,-162.03415,0.0019499002,96.188568,685.74933,98.192673,0.40430036,-143.73499 -574426000,0.14105736,-171.17128,0.00042297033,-146.10623,686.19061,97.318321,0.3111755,-135.84154 -574925500,0.16414137,-171.0058,0.00047533502,98.044479,690.38727,96.349213,0.30677095,-110.13487 -575425000,0.15719447,-178.46281,0.00042110594,-15.460618,693.71802,95.697105,0.39362004,-84.411865 -575924500,0.13560708,-171.65358,0.00069059164,-126.28403,691.4751,94.949654,0.3640525,-90.691551 -576424000,0.1187607,-163.85632,0.0013757747,-140.86011,693.37579,94.314346,0.28831279,-45.490768 -576923500,0.12777004,-162.44519,0.0014242434,-146.55524,686.97034,93.611343,0.065104753,-164.90111 -577423000,0.13330373,-155.33446,0.0018093194,-158.15054,689.23767,92.862961,0.13932253,-76.757599 -577922500,0.1274126,-172.35129,0.0009814126,-101.8414,689.22931,91.604134,0.27843389,-85.185585 -578422000,0.16201508,172.6833,0.0016547489,-9.5020866,683.45862,90.667953,0.32235917,-107.15427 -578921500,0.14226395,173.16896,0.0014275613,-27.780752,679.25879,90.045151,0.23157625,-150.05551 -579421000,0.15449883,-178.29884,0.00067784655,-19.621622,684.75586,89.169312,0.22769903,-101.845 -579920500,0.13797182,-178.91289,0.0010294747,-62.056129,677.28003,88.683228,0.36729789,-163.90358 -580420000,0.14262813,175.89615,0.001271163,-30.415068,682.724,87.187019,0.37103683,-94.739296 -580919500,0.17700458,-167.32893,0.00087783148,138.25879,680.81757,86.089218,0.39037898,-102.79683 -581419000,0.22551616,-175.14938,0.0023200894,89.52076,677.58478,85.889412,0.222408,-119.44953 -581918500,0.17188963,-164.99286,0.00063547603,164.10892,671.87811,85.149963,0.27472979,-160.50394 -582418000,0.16878588,-174.2455,0.00032560615,88.450562,682.63959,83.895164,0.23693871,-78.289894 -582917500,0.16547753,-176.8363,0.00052349648,38.938549,679.36963,82.997612,0.27319244,-90.925026 -583417000,0.16166772,-167.08063,0.00036769934,-145.29485,678.63367,82.267319,0.24629387,-87.615547 -583916500,0.21569553,-169.90672,0.0017432868,123.77969,677.80249,81.704582,0.17265843,-102.04084 -584416000,0.18293311,176.68532,0.0013958705,51.173855,672.42493,80.10379,0.48731899,-102.22119 -584915500,0.17372374,-144.08157,0.0026068676,-135.40147,674.4267,79.815414,0.21862757,-100.12164 -585415000,0.17185585,-173.05283,0.00037498164,76.40062,669.99084,78.822578,0.30608663,-118.2153 -585914500,0.16584677,178.43654,0.0010087863,40.044956,668.21704,77.927826,0.39556271,-129.54477 -586414000,0.19618565,-162.27165,0.0011866018,-178.72838,670.55322,77.372162,0.23199187,-115.25112 -586913500,0.16248176,-177.73524,0.0006451371,27.445908,663.90283,76.355324,0.45421413,-138.48006 -587413000,0.17865916,-171.90959,0.00032086894,98.676994,673.48511,76.010376,0.11597907,-144.58478 -587912500,0.13915405,-170.82944,0.0010300137,-28.242151,670.29791,74.685776,0.21734494,-101.95435 -588412000,0.17554788,-167.93967,0.00030153844,-162.58696,667.7337,73.793854,0.25053996,-112.8081 -588911500,0.18178874,-167.99866,0.00043170905,-174.4986,667.98834,72.623993,0.21952754,-98.114067 -589411000,0.19305371,-167.23924,0.00078804593,-174.97394,667.85785,71.963646,0.21776122,-106.94939 -589910500,0.20268223,-170.22672,0.00094391441,157.68669,662.83502,71.253792,0.33324885,-118.22009 -590410000,0.12477959,-168.23532,0.0014898462,-20.853476,667.38086,70.104889,0.19800173,-92.478455 -590909500,0.23956014,-171.01065,0.001986552,164.36937,671.33105,70.135582,0.22448847,150.04108 -591409000,0.20225544,-161.71065,0.0012110468,-141.61127,662.32013,68.208305,0.35212159,-99.909836 -591908500,0.18821301,173.49158,0.0017365691,82.757843,671.26117,67.971329,0.012944867,-156.49861 -592408000,0.17564231,-167.60132,0.00018427023,-75.000725,665.88031,66.393562,0.25472134,-69.497284 -592907500,0.16806486,-161.3416,0.00080652878,-65.919846,653.57367,65.904152,0.4910779,-118.78188 -593407000,0.21371202,178.96823,0.0014833544,129.6754,665.758,64.446609,0.22850256,-60.673527 -593906500,0.15604821,-164.42592,0.00075707672,-22.85445,653.48352,63.443745,0.50199246,-83.773308 -594406000,0.18971421,-173.88512,0.00039749462,110.03954,662.3761,62.720268,0.31609443,-72.774361 -594905500,0.19327338,-174.09006,0.00045890856,146.97887,665.20477,62.574436,0.11665494,179.41595 -595405000,0.1241725,177.39128,0.0019941875,36.19202,654.59137,60.578178,0.44889206,-73.544991 -595904500,0.17385887,-171.59486,0.00027055223,57.613983,658.7439,60.847595,0.16215366,-149.64131 -596404000,0.15350688,-162.41969,0.0011147211,-20.120842,652.89465,59.690403,0.28871268,-119.6624 -596903500,0.18650252,-153.97397,0.0016109805,-63.2467,650.94196,58.975018,0.3729507,-126.06613 -597403000,0.20187843,-157.64853,0.0012928633,-81.079346,651.29913,57.301697,0.3680194,-77.784088 -597902500,0.19860944,-159.56905,0.0012289071,-78.907478,646.47723,56.880684,0.38650155,-111.70403 -598402000,0.1845184,-171.10258,0.0001776852,72.809319,642.07977,55.699879,0.54278547,-92.127419 -598901500,0.19701563,-167.53969,0.00029679545,-84.270218,655.01617,54.879044,0.17474493,-88.891792 -599401000,0.16537587,-171.11433,0.00069995498,39.362782,657.50458,54.605621,0.15796229,-162.40511 -599900500,0.18660234,174.02715,0.0013646967,116.4172,644.87823,53.926399,0.40456888,-132.35368 -600400000,0.25960901,-163.93921,0.0020286541,-114.29552,645.5199,52.917675,0.37928703,-126.17805 -600899500,0.21815047,-170.73015,0.00065396575,-144.64337,643.95978,51.395775,0.35132766,-98.455864 -601399000,0.23284324,-175.11125,0.0012558328,-162.4221,649.35681,51.4617,0.29033625,-161.53105 -601898500,0.23139153,-175.59691,0.0010718083,-160.82906,652.84998,49.64006,0.068410724,-115.29745 -602398000,0.2353421,-175.21252,0.0012065489,-156.17857,650.00208,49.056591,0.14256209,-145.60645 -602897500,0.19494189,-167.25851,0.00039135088,-25.914804,631.33032,47.557579,0.5407058,-87.565971 -603397000,0.20158631,-172.06847,0.00014314734,-156.55659,644.51733,47.062084,0.22683574,-116.05512 -603896500,0.14092031,-179.10854,0.0016945442,78.181206,646.15509,46.542095,0.21846983,-130.10025 -604396000,0.17576377,-150.88219,0.0019170153,2.2988088,634.58398,44.997551,0.46458936,-92.79612 -604895500,0.19987106,-166.06961,0.00060808094,-14.921047,642.74115,44.175198,0.21881425,-115.6362 -605395000,0.22649604,-179.19334,0.001028271,-167.21484,631.51599,43.490555,0.39346284,-93.664139 -605894500,0.20780434,-165.37856,0.00054866285,-26.749836,640.14404,42.314468,0.22065732,-102.17256 -606394000,0.21516973,-163.01247,0.00081570784,-34.851616,645.1377,41.733593,0.16756111,-148.89545 -606893500,0.11867101,-160.23555,0.0023500994,59.720089,631.40985,40.341801,0.35179806,-73.005203 -607393000,0.22043414,-169.39168,0.00037963956,-61.626225,632.9115,39.63636,0.31561932,-94.616631 -607892500,0.19467743,-171.8076,0.00041702468,75.011246,626.2254,38.74078,0.50795722,-87.227501 -608392000,0.18542022,-155.37965,0.001548016,20.301968,629.56207,37.993439,0.35077673,-98.617233 -608891500,0.21665022,-172.72591,0.00016884266,-98.97538,637.93787,37.42421,0.29463336,-145.12201 -609391000,0.27742374,-160.84753,0.0020508608,-52.462341,628.8905,35.880581,0.33099517,-85.788033 -609890500,0.22525284,-170.60133,0.0003766095,-62.688988,627.21619,35.679386,0.40830681,-109.39284 -610390000,0.17482157,-173.35538,0.00094702409,93.146759,617.39801,34.329739,0.50302756,-88.331528 -610889500,0.15601823,-168.75951,0.0014858485,81.850922,624.74152,33.641811,0.4139086,-106.09103 -611389000,0.24054071,-164.92215,0.0012046193,-34.683689,627.91418,32.139282,0.12960187,-111.70116 -611888500,0.23087612,-178.77174,0.00061967806,-139.36852,625.43457,31.311272,0.26718411,-99.614418 -612388000,0.29743722,-169.91211,0.002078962,-64.549759,626.10712,29.848146,0.1501575,-66.673126 -612887500,0.22580506,-169.27963,0.00037848455,-11.007132,619.83301,29.440578,0.36249238,-77.909508 -613387000,0.2489184,168.45941,0.0018813133,-150.30119,626.72192,28.230257,0.1204133,-132.37724 -613886500,0.20500822,179.87415,0.00067013502,169.61026,621.79492,28.109152,0.32971531,-109.85439 -614386000,0.27405599,-164.8499,0.0017064832,-28.663961,625.29797,27.470373,0.40685004,-130.58247 -614885500,0.23944078,172.32173,0.0014398536,-143.02383,629.23798,26.132721,0.27237248,-151.86998 -615385000,0.19855487,-177.80151,0.00070990942,141.38028,626.49487,24.640503,0.14621726,-136.8671 -615884500,0.17070577,167.03906,0.0020539549,162.9883,612.66003,24.303101,0.36856082,-85.790817 -616384000,0.25841913,-176.73401,0.00094313099,-78.523087,624.56946,22.948734,0.18476123,-137.22942 -616883500,0.20453808,-172.57744,0.00062450214,96.991005,609.95099,22.546661,0.45953485,-94.677856 -617383000,0.22056259,174.12117,0.0010101174,-158.77286,617.31256,21.475496,0.32731181,-114.6537 -617882500,0.20166801,173.67952,0.0011913966,-179.57391,619.76154,20.558779,0.33301356,-125.80157 -618382000,0.23759565,-178.1185,0.00043733086,-99.820946,615.92053,19.277956,0.23566656,-118.68729 -618881500,0.23596087,179.09161,0.00055871275,-125.95839,617.6734,18.484617,0.32423934,-135.76048 -619381000,0.25043553,-178.8295,0.00058335136,-64.570282,605.71692,17.793659,0.39816737,-98.549438 -619880500,0.20628539,179.32463,0.0007392579,166.52007,602.05072,16.533833,0.40232477,-77.226051 -620380000,0.2279717,-177.08516,0.00018149256,159.56357,608.36816,15.208071,0.23867914,-85.532051 -620879500,0.26188478,-161.6398,0.0018268005,32.961937,600.95587,15.507581,0.56549323,-89.77916 -621379000,0.18065847,-179.99767,0.0013608465,157.03862,610.60535,13.593434,0.2499813,-113.49674 -621878500,0.21971764,175.82378,0.00083433883,-153.77016,601.95905,12.697528,0.34723198,-80.936523 -622378000,0.27486074,-172.73991,0.0011413352,-2.2228613,601.78009,11.46758,0.25985667,-73.984901 -622877500,0.2027401,-177.72508,0.00080068631,150.5632,597.84692,11.446273,0.50001967,-86.273949 -623377000,0.21778113,-167.79607,0.0011057933,97.388672,609.12018,9.1673584,0.13441318,-134.59093 -623876500,0.20375563,-165.20868,0.0015619413,107.11,610.13123,9.1995678,0.42313761,-129.48355 -624376000,0.28172174,-176.75365,0.0011953128,-19.436886,608.53088,8.5036421,0.4332256,-115.90927 -624875500,0.22467072,-175.28131,0.00038908402,124.70845,601.71008,7.3928995,0.40722665,-95.177124 -625375000,0.23535706,-175.52744,0.00033151996,81.117714,598.28949,5.5223975,0.15963371,-75.14875 -625874500,0.19108531,-178.72298,0.0011963885,166.55157,598.99579,5.0365434,0.27126479,-85.720459 -626374000,0.23675425,-175.66618,0.00043955326,92.707214,592.62207,4.0786257,0.34335345,-75.943954 -626873500,0.22852755,176.94553,0.00053251116,-143.83842,598.75018,2.879411,0.25461897,-105.75981 -627373000,0.21349314,-167.93765,0.0015002198,120.40675,600.30084,2.003993,0.30262497,-120.72462 -627872500,0.25757715,-174.41455,0.00074502116,57.056561,607.32306,0.75708228,0.38284358,-152.12077 -628372000,0.27112111,172.90044,0.0011571449,-52.367039,602.69873,-0.45369986,0.21151464,-154.83475 -628871500,0.22989233,174.29688,0.00075246824,-125.45604,600.05188,-0.93629003,0.32098183,-120.35169 -629371000,0.23087564,171.10207,0.00094283832,-114.96894,594.32269,-1.5579604,0.36240137,-103.55976 -629870500,0.22624645,170.49031,0.0010282533,-116.4921,591.42139,-2.9046826,0.24438792,-97.84594 -630370000,0.20863353,-173.95601,0.001265327,152.2579,598.58124,-3.483418,0.44396955,-118.33871 -630869500,0.2449441,-175.15103,0.00079390308,106.62006,592.20258,-4.8898668,0.28447059,-109.91189 -631369000,0.26700661,-174.51578,0.0010637989,71.659294,586.04919,-6.0223064,0.2467078,-114.74519 -631868500,0.26989353,172.80885,0.00096211466,-36.538792,582.77612,-7.541801,0.072393596,-72.155777 -632368000,0.2315432,169.60606,0.00099624868,-107.17323,579.91937,-8.3569279,0.1353585,-77.252899 -632867500,0.24918731,-179.25546,0.00046839842,115.49944,588.23962,-8.5903397,0.43100417,-113.28888 -633367000,0.26531312,-179.32007,0.00065781787,64.483772,589.61902,-10.101779,0.34944814,-125.30313 -633866500,0.23695621,176.70131,0.00044446788,-168.14931,581.55676,-11.124657,0.20927194,-112.93434 -634366000,0.28777817,-177.62259,0.0013693214,66.504715,584.37665,-12.47442,0.24162488,-140.11687 -634865500,0.30354148,-177.24911,0.0018371867,61.527439,593.96814,-13.67302,0.47954777,-157.60362 -635365000,0.29218003,177.1389,0.0012296077,39.927174,597.34845,-14.719633,0.60791039,-160.07945 -635864500,0.28026113,178.47745,0.00094426615,64.229279,584.54193,-14.737518,0.42556283,-106.04189 -636364000,0.26035658,167.22768,0.0010622701,-40.730885,591.60449,-15.682752,0.55883384,-121.22713 -636863500,0.23107903,174.55807,0.00063222495,-148.62094,574.84283,-17.359385,0.11421437,-111.08762 -637363000,0.24640509,-171.51683,0.0018044566,143.98334,582.49841,-18.149599,0.34954315,-106.76051 -637862500,0.26308018,163.99557,0.0014868273,-36.215225,587.59143,-19.80014,0.4493466,-156.20686 -638362000,0.26022437,175.88829,0.0003761212,111.34758,580.80042,-19.616219,0.52170885,-110.97854 -638861500,0.25139669,175.98943,0.00029320517,145.60718,580.80597,-21.068066,0.37088209,-110.00887 -639361000,0.23656474,-176.93042,0.0014286765,167.16071,580.24725,-21.955488,0.40288749,-111.96116 -639860500,0.19776228,166.79468,0.0019222338,-104.45273,575.60327,-24.001534,0.20428444,-150.89304 -640360000,0.24941269,-176.73988,0.0015404193,155.46593,575.62549,-24.337349,0.37748209,-110.77393 -640859500,0.25777009,173.57195,0.0002384478,114.38044,581.888,-25.373676,0.47177666,-119.00449 -641359000,0.25295189,168.47011,0.00044542074,-42.623039,572.03381,-26.756767,0.28608543,-127.86841 -641858500,0.22241284,171.45886,0.0010530592,-113.75176,568.55481,-27.73955,0.21623601,-125.49387 -642358000,0.23383725,158.67215,0.0018833362,-47.540104,571.09698,-29.050882,0.28712976,-118.70663 -642857500,0.2226903,167.31055,0.0011556882,-91.70623,569.54712,-29.705286,0.25542384,-127.73225 -643357000,0.26571187,171.59261,0.00050341839,94.53994,575.5929,-30.554766,0.5436393,-106.8614 -643856500,0.25695726,172.09668,0.00032274239,172.62794,569.1347,-31.700438,0.35459334,-113.32214 -644356000,0.24453032,167.79446,0.00040753841,-61.648968,568.80176,-33.146004,0.29155895,-123.74783 -644855500,0.23783784,164.52409,0.00080030138,-56.203106,569.0163,-34.12323,0.36374652,-126.18275 -645355000,0.23586331,173.0197,0.00095338322,-143.4913,561.98029,-34.931961,0.17070282,-97.922859 -645854500,0.23598567,176.64037,0.0013831732,-150.04689,566.50269,-36.400532,0.41424179,-126.83791 -646354000,0.22529824,171.67401,0.0011970669,-116.73556,561.55847,-37.636688,0.276997,-138.58537 -646853500,0.26477078,164.79124,0.00056838314,43.387432,562.12286,-39.044094,0.36470073,-156.62711 -647353000,0.27551469,165.14883,0.00096088409,77.36393,563.93579,-39.615662,0.33806953,-123.21221 -647852500,0.23955028,165.91977,0.00048399408,-71.951118,561.46063,-40.061104,0.33176184,-84.941231 -648352000,0.25339285,164.60553,0.00027579296,15.125277,554.90131,-41.670181,0.14608097,-128.99638 -648851500,0.28324917,172.91731,0.0016199906,151.12712,555.4245,-43.293774,0.28375903,-156.71722 -649351000,0.24399382,157.43068,0.0012721439,-4.5274453,553.69843,-43.851089,0.19338374,-131.22134 -649850500,0.24348076,164.79625,0.00031110525,-25.869791,551.737,-45.269245,0.19773567,-140.72556 -650350000,0.25949392,161.40659,0.00059851352,48.064503,554.03192,-46.312054,0.27667794,-148.93338 -650849500,0.26282433,165.42685,0.00043177756,130.9973,556.65375,-47.219299,0.39772192,-114.07307 -651349000,0.27340266,166.0134,0.0010106706,139.22865,553.09485,-48.177189,0.25495207,-105.53214 -651848500,0.23893008,161.3524,0.00055934262,-25.312574,551.43024,-48.909935,0.23200525,-81.216568 -652348000,0.2415933,162.16226,0.00026629082,-34.255646,555.50812,-50.7785,0.44875717,-117.35803 -652847500,0.25707197,153.34369,0.0016635988,50.245415,549.82306,-51.817173,0.22947817,-118.40917 -653347000,0.22414511,158.38763,0.0011314285,-12.937172,550.04535,-53.037949,0.35248846,-119.62399 -653846500,0.22316945,162.92189,0.0009484581,-54.142635,543.37946,-53.941788,0.14222768,-149.99387 -654346000,0.25379112,171.33856,0.0017611138,-135.8548,544.43732,-55.472786,0.33438474,-147.82765 -654845500,0.25622258,166.49316,0.00092098722,-153.07379,545.32288,-56.561295,0.35404903,-125.63491 -655345000,0.25804213,157.54634,0.00080729899,102.06522,538.23358,-57.248165,0.091734931,160.17308 -655844500,0.25664222,165.03371,0.0010240113,-153.7419,543.52942,-58.98695,0.35967061,-130.90485 -656344000,0.28109127,163.95961,0.0017102581,175.94716,545.1236,-60.179424,0.45565942,-116.22588 -656843500,0.215241,151.25475,0.0015606816,19.761639,543.91516,-61.171215,0.36414039,-113.07248 -657343000,0.23979636,153.66939,0.00081587408,69.664612,536.67969,-61.976624,0.15196218,-142.31929 -657842500,0.21378717,165.5784,0.0014837489,-65.688004,536.76294,-63.717751,0.34297103,-141.90976 -658342000,0.22946197,156.35033,0.00040490544,39.815807,536.50464,-65.063583,0.42377475,-128.60793 -658841500,0.24534087,165.01904,0.0011906706,-118.09091,535.18134,-66.429741,0.50695157,-133.34003 -659341000,0.22406702,157.31885,0.00050481502,20.821165,534.11469,-67.155571,0.37535366,-115.22091 -659840500,0.27217835,157.62173,0.0015634854,172.39264,534.164,-68.656372,0.49256411,-114.34312 -660340000,0.24561113,162.4827,0.0011324127,-115.90903,536.24658,-69.767357,0.43943977,-116.09067 -660839500,0.22751676,167.87318,0.001893278,-82.850319,528.50092,-71.155296,0.42140338,-135.33713 -661339000,0.18354914,154.57568,0.0016377714,14.306485,531.73737,-71.936295,0.34028527,-89.363892 -661838500,0.24251446,149.12265,0.0011280444,124.1776,527.00702,-73.424568,0.3975912,-133.67776 -662338000,0.23478274,148.30318,0.0010285573,110.02312,528.29144,-73.966187,0.18449809,-97.063004 -662837500,0.25549275,147.57742,0.0016607466,145.9039,521.47888,-76.110977,0.45632613,-134.89444 -663337000,0.22404525,152.08534,0.00032157789,101.71735,526.60437,-77.352951,0.5031113,-106.41212 -663836500,0.21008208,162.86699,0.0013623942,-50.962967,519.65601,-77.949989,0.27727914,-151.3912 -664336000,0.22729762,157.26724,0.00063591066,-96.733688,518.51453,-79.652977,0.35442719,-122.99571 -664835500,0.24086457,153.45612,0.00081477943,-157.58643,513.90424,-80.179108,0.31701893,-165.18329 -665335000,0.18402188,163.474,0.0017902708,-14.436529,514.67676,-82.071022,0.41740689,-127.79519 -665834500,0.22520909,152.54074,0.00027422662,-147.73518,516.8111,-83.421974,0.43355012,-113.87274 -666334000,0.20349269,149.01344,0.00068109058,83.225105,513.4577,-84.156776,0.29618785,-113.22649 -666833500,0.22175719,145.75235,0.00091010402,141.42006,513.14172,-85.033081,0.19317549,-136.19489 -667333000,0.20204394,153.98227,0.00052392489,-17.171227,507.017,-87.094437,0.39055577,-150.87238 -667832500,0.22209942,153.33278,0.00053533388,-88.495033,511.05069,-88.529396,0.46171024,-115.6333 -668332000,0.18441553,145.76128,0.00083344622,79.446053,508.11505,-90.019844,0.38455737,-117.44794 -668831500,0.18690568,145.41339,0.0007342273,89.450111,502.2038,-91.122375,0.43704599,-136.50656 -669331000,0.20245872,148.97589,0.00019180149,116.64378,508.08109,-91.802696,0.23683053,-87.449554 -669830500,0.20902553,150.63515,0.00043582791,-108.33839,499.45996,-93.341278,0.32181284,-134.26093 -670330000,0.20297395,147.53233,0.00030695173,-154.53786,495.99585,-94.423637,0.34448329,-152.48338 -670829500,0.17932035,144.87671,0.00076427468,95.880302,495.98553,-96.483147,0.49180588,-124.95384 -671329000,0.1916814,141.83206,0.00074421742,151.22717,495.40662,-97.580757,0.39671957,-121.66915 -671828500,0.19817649,150.51668,0.00045278287,-55.197456,494.18713,-98.459496,0.25944734,-146.77429 -672328000,0.20140806,151.94232,0.00074365089,-45.198574,493.93661,-100.08449,0.35917556,-126.13365 -672827500,0.23279613,144.62398,0.0018341658,-120.47786,488.80084,-101.14527,0.3085236,-129.88646 -673327000,0.1939795,139.60269,0.00096746127,-177.39085,487.95856,-102.29687,0.29340196,-139.83897 -673826500,0.18758528,141.90988,0.00051969558,-168.53658,483.71063,-103.98867,0.41164896,-136.45528 -674326000,0.17960155,142.62619,0.00048205291,-166.93712,487.76135,-104.39706,0.12696819,161.86757 -674825500,0.16475227,138.12155,0.00083677669,150.25508,481.92105,-107.11647,0.37315857,-114.74342 -675325000,0.15296745,153.09749,0.00095874391,40.37035,479.89148,-108.14098,0.26812613,-127.55833 -675824500,0.18676892,141.73491,0.00077441207,-119.13899,477.8208,-109.43958,0.30583024,-127.67545 -676324000,0.14708108,155.87947,0.0011271149,42.813908,471.29846,-110.76581,0.43623269,-140.05157 -676823500,0.19672021,135.72775,0.0014952392,-130.58871,476.29276,-112.02175,0.21335359,-123.82927 -677323000,0.17396109,151.92593,0.00077999965,-8.8885126,470.40485,-113.54491,0.36427569,-134.04477 -677822500,0.18106568,136.73616,0.0012668745,-124.50835,467.44608,-115.08714,0.34701836,-123.68539 -678322000,0.12373265,138.65387,0.0010513094,127.803,462.02603,-116.14504,0.38828552,-142.30931 -678821500,0.16706361,155.15004,0.0010780144,-5.6118975,463.34991,-117.28735,0.30857971,-147.10219 -679321000,0.2005333,139.18361,0.001910836,-87.150467,462.71405,-118.66258,0.21140438,-156.69218 -679820500,0.1587671,145.11552,0.0005572082,-54.741261,454.42181,-120.77229,0.45515195,-125.94656 -680320000,0.13704066,135.11856,0.00083346636,-165.07481,455.57626,-122.02664,0.35479936,-125.89324 -680819500,0.14217512,144.82904,0.00011810853,-120.22841,451.90643,-123.03076,0.39448437,-142.46295 -681319000,0.15071417,153.47404,0.00076093647,3.8641338,449.63852,-124.07816,0.37351549,-154.5854 -681818500,0.1457945,153.70917,0.00074732187,13.569081,448.45541,-125.64374,0.32631138,-153.6682 -682318000,0.10479578,138.71086,0.00098237908,162.78041,445.202,-127.49709,0.36979592,-136.98172 -682817500,0.12968275,137.63023,0.0006782299,-120.96995,443.30533,-129.23083,0.30372354,-116.88625 -683317000,0.084787257,156.54996,0.0012724758,120.11021,436.3967,-130.53996,0.43107706,-128.81941 -683816500,0.083119147,134.00417,0.001423215,172.06178,436.99893,-132.24481,0.34907043,-114.94366 -684316000,0.11574809,148.2916,3.106015e-005,-72.201843,433.59201,-133.04671,0.35746744,-139.77356 -684815500,0.10896951,134.7688,0.00088883395,-134.2659,429.13184,-134.87794,0.42990041,-121.79248 -685315000,0.13383281,140.86172,0.0009360924,-60.727943,429.99045,-135.67024,0.32080942,-159.6132 -685814500,0.070503183,135.28954,0.0014577539,-170.23904,427.11206,-137.43535,0.28490636,-135.85541 -686314000,0.090353779,146.10953,0.00046270381,-157.9982,420.78021,-139.01608,0.37323549,-129.98085 -686813500,0.12026452,135.4319,0.0012131813,-79.274719,419.95181,-140.35995,0.36071205,-143.68227 -687313000,0.071887419,134.81975,0.0011604242,-150.05795,420.12814,-142.35754,0.17432617,-124.96127 -687812500,0.13167371,169.16048,0.0015028125,44.17651,416.00522,-143.02313,0.29686835,-153.93001 -688312000,0.057740841,122.18975,0.0018053775,-141.6517,410.07495,-145.02893,0.35142162,-131.07988 -688811500,0.091698751,171.9729,0.00066707592,91.838585,408.62302,-146.05162,0.28931746,-143.79941 -689311000,0.055335112,165.53629,0.0012239082,-177.47249,404.80399,-147.71477,0.32200179,-139.78267 -689810500,0.12125042,172.93135,0.0013743838,46.129177,396.12326,-148.76115,0.51398331,-138.9003 -690310000,0.089058213,154.23689,0.00058418588,-41.426651,396.29794,-150.82153,0.34069073,-131.68285 -690809500,0.064759433,178.76086,0.00070488726,177.13007,393.88364,-152.29144,0.30860725,-127.47584 -691309000,0.1335174,178.23994,0.0019785569,58.598911,389.6459,-153.85139,0.36132246,-129.44208 -691808500,0.092306584,-168.92169,0.0011249731,119.93875,385.68982,-154.78947,0.47380459,-141.6828 -692308000,0.087424032,-178.58472,0.00047577539,96.979485,383.83862,-156.68181,0.34829968,-134.67914 -692807500,0.072276123,-152.37578,0.0013306063,161.36133,380.65146,-157.85805,0.37120378,-146.90825 -693307000,0.07687249,169.24925,0.0004940136,-28.67655,376.96408,-159.35408,0.38774976,-142.71243 -693806500,0.084324099,174.01546,0.00054813712,-0.86900103,372.7601,-161.31718,0.34615451,-130.01549 -694306000,0.084492996,-159.27666,0.00075381488,133.35754,367.90225,-162.31694,0.4139348,-135.81772 -694805500,0.11880804,178.44244,0.0017232556,48.946144,366.0307,-163.92651,0.37897441,-140.83502 -695305000,0.080751166,-152.99133,0.00063627324,171.00191,362.1423,-165.1217,0.42939857,-143.8278 -695804500,0.096397266,-166.23024,0.00058008579,77.380226,361.54446,-167.06003,0.30244428,-143.31903 -696304000,0.055138215,167.01714,0.0015770134,-48.19416,353.34326,-169.12593,0.36944887,-120.16819 -696803500,0.10846019,-151.51419,0.0011145892,126.32162,353.02615,-170.1187,0.29015148,-138.11899 -697303000,0.058367278,-132.46933,0.0014784822,-103.15475,350.28241,-171.57079,0.29704109,-139.86176 -697802500,0.07430277,-141.14697,0.00069512497,-111.93548,344.07117,-172.60191,0.40682456,-141.87607 -698302000,0.073112197,-149.99385,0.00067088829,-77.933357,341.25134,-174.14066,0.41991302,-144.50282 -698801500,0.12072447,-142.24548,0.0011985342,157.90735,338.89694,-175.6219,0.42762789,-152.49141 -699301000,0.080762669,-135.35426,0.00099945324,-102.2936,334.19876,-177.90392,0.3125557,-131.37335 -699800500,0.085426643,-140.86452,0.00072459539,-73.80304,333.08624,-179.26695,0.27745089,-148.93619 -700300000,0.076270908,-136.23697,0.0012595145,-67.884674,326.32037,179.49927,0.39870512,-137.22955 -700799500,0.12297429,-149.22502,0.00084552058,99.246231,324.61987,177.83664,0.2746543,-141.77084 -701299000,0.095399283,-140.45453,0.00061569409,-44.734356,321.01297,176.60294,0.3350513,-151.62373 -701798500,0.10968857,-122.8977,0.0015350544,-97.158195,314.43713,175.04985,0.40258542,-130.27417 -702298000,0.1305625,-145.11206,0.00061056676,119.61794,314.07825,173.27539,0.30676937,-153.97031 -702797500,0.12835136,-153.08228,0.0011571622,69.083351,310.29373,171.86971,0.30795398,-150.43152 -703297000,0.11866103,-143.49355,0.00052096392,35.180988,304.65479,170.40953,0.31302959,-140.4687 -703796500,0.13009344,-133.58276,0.00051015412,-95.007401,301.65964,169.19167,0.37965265,-148.35353 -704296000,0.13927223,-141.13701,0.00029359304,80.85804,297.29004,167.1571,0.30041447,-137.18872 -704795500,0.15515789,-134.53409,0.00063625845,-150.9118,295.70755,166.13087,0.36877289,-152.40947 -705295000,0.099498332,-150.32385,0.0025511899,15.214581,290.99557,163.70433,0.19305356,-135.91144 -705794500,0.15608066,-137.21465,0.00024954768,149.45392,288.04269,163.22595,0.38176686,-156.19781 -706294000,0.16389571,-144.19888,0.001079211,116.39784,282.68048,161.43549,0.33500397,-145.48332 -706793500,0.15581232,-140.92433,0.00051722262,72.168335,279.272,160.3609,0.44569901,-146.94884 -707293000,0.15884687,-134.32912,0.00043753811,-32.297943,274.95978,158.40254,0.32539281,-141.37102 -707792500,0.19570486,-133.41116,0.0014488578,-141.71771,270.97079,156.92874,0.35858393,-142.96994 -708292000,0.14979859,-146.81778,0.00171113,63.123497,267.97955,155.56624,0.3543129,-150.75786 -708791500,0.17940424,-137.36763,0.00010279779,-55.65593,264.63733,153.92798,0.34992254,-149.79405 -709291000,0.15773354,-134.43439,0.0012997562,-0.94167662,259.56125,152.22443,0.27947214,-139.09305 -709790500,0.19472253,-135.69633,0.0004723224,-125.72885,256.14502,151.18098,0.38953766,-137.15828 -710290000,0.18538593,-143.25987,0.0010642229,97.63633,252.82832,149.19319,0.26563632,-145.41435 -710789500,0.20773396,-142.16148,0.0010680478,141.83057,249.79924,148.25777,0.37569302,-142.19818 -711289000,0.20262852,-132.94948,0.0009789227,-53.353535,245.54955,146.89676,0.42926386,-141.12012 -711788500,0.18463115,-132.14333,0.0017386714,-7.8367481,240.65865,144.6582,0.27322501,-130.30882 -712288000,0.23217036,-137.85513,0.001182451,-140.37184,239.10419,143.56305,0.32935047,-149.61646 -712787500,0.21960127,-142.97563,0.0011847153,137.96083,235.45671,142.62009,0.412218,-142.29892 -713287000,0.2417465,-138.95718,0.0011951181,-146.28262,231.66284,141.00198,0.40657312,-144.60533 -713786500,0.25216964,-136.56544,0.0017081876,-119.03972,228.9577,139.83998,0.45562193,-146.24426 -714286000,0.2247359,-144.79874,0.0015349125,118.16522,224.11938,137.53354,0.26498067,-136.79849 -714785500,0.22742432,-132.96091,0.0015053918,-29.29365,220.33119,136.62178,0.34690431,-137.28174 -715285000,0.239205,-143.33569,0.00066703756,130.61389,217.72891,134.80913,0.34622294,-147.81012 -715784500,0.24949272,-143.28046,0.00099339592,-174.88344,213.265,133.80521,0.37493998,-139.041 -716284000,0.23669185,-145.82613,0.001657624,113.13947,211.89561,131.90863,0.35142449,-152.83081 -716783500,0.24138135,-144.64398,0.0012551319,103.30591,207.09949,130.49203,0.34713399,-143.03278 -717283000,0.23496658,-143.99246,0.0016321801,82.292824,203.70232,128.75874,0.29153749,-142.53345 -717782500,0.25119609,-137.1732,0.0014541612,5.2051196,201.04442,127.5899,0.30761594,-143.20178 -718282000,0.26847813,-137.42201,0.0016364431,-19.408592,198.20612,126.07251,0.3382349,-148.35786 -718781500,0.2708194,-145.02623,0.00075355091,151.12984,194.62395,124.74054,0.32329535,-147.98711 -719281000,0.26089197,-144.0957,0.001315402,95.176445,191.99791,123.39272,0.37374324,-150.11995 -719780500,0.26776138,-140.75082,0.0011586125,26.267891,189.59332,121.92864,0.40191835,-161.78516 -720280000,0.29036289,-144.8676,0.00063517736,-148.71165,185.6588,120.48361,0.3508265,-149.76741 -720779500,0.26576841,-143.92529,0.0016634457,77.373001,181.87701,118.98959,0.33331919,-148.94266 -721279000,0.30245662,-143.82295,0.0012583119,-61.43792,177.31839,117.90896,0.36764073,-137.61115 -721778500,0.29775289,-146.96072,0.000606974,-167.05247,175.47835,116.24265,0.36634162,-151.1138 -722278000,0.29292268,-145.17488,0.00052403117,27.303196,172.31418,115.36071,0.39651203,-141.7538 -722777500,0.306164,-147.53221,0.00072876585,-176.86795,170.28343,113.51935,0.35355699,-147.20578 -723277000,0.3019051,-139.84856,0.0033905746,10.406232,166.52631,112.30737,0.39028105,-139.94615 -723776500,0.3116869,-144.76515,0.0013795636,11.019624,163.72557,110.56365,0.36491591,-147.65721 -724276000,0.31666699,-149.68948,0.001039334,-168.44194,161.00346,109.20245,0.37081474,-147.63828 -724775500,0.30658612,-147.56653,0.0011690984,81.667015,157.9427,108.01691,0.37239277,-146.81256 -725275000,0.32249919,-149.91838,0.000751129,-163.80812,155.08475,106.52661,0.32809815,-147.35608 -725774500,0.33241567,-150.21768,0.0010896222,-98.090584,152.75941,105.41437,0.38821384,-151.82567 -726274000,0.33109611,-147.57979,0.0013716683,2.4899879,149.68484,103.96266,0.35774177,-148.01599 -726773500,0.34654087,-150.73567,0.0015983378,-95.520302,147.04877,102.48238,0.31675452,-149.80608 -727273000,0.3430903,-151.02722,0.00061523408,-75.42984,143.77805,101.1209,0.37918729,-143.86067 -727772500,0.34015247,-151.22653,0.00014244988,48.227367,141.2323,99.754898,0.3835642,-146.77068 -728272000,0.34869084,-152.1199,0.00057127548,-129.26236,139.40451,98.033661,0.40385309,-155.82605 -728771500,0.34834421,-153.16081,0.00088774657,-166.05016,136.40381,96.773827,0.36081591,-151.04007 -729271000,0.36912534,-152.07845,0.0017105227,-53.857761,134.23891,95.242439,0.37315533,-157.08537 -729770500,0.35574132,-153.03146,6.7637528e-005,8.2335835,131.61519,94.325165,0.41525441,-147.4007 -730270000,0.36058298,-154.85074,0.0009909455,-142.74118,128.95905,92.848763,0.3775233,-150.72292 -730769500,0.35531697,-154.11336,0.0010706348,124.20347,126.22575,91.464691,0.37533161,-154.60666 -731269000,0.36977288,-155.40982,0.0011524477,-101.28026,124.42878,90.269104,0.41823035,-148.64592 -731768500,0.37056869,-154.08565,0.0012199891,12.891545,121.73412,89.070152,0.40069228,-154.4418 -732268000,0.37184975,-155.00078,0.0005140244,20.463722,119.4258,87.861,0.39898357,-144.21643 -732767500,0.37055081,-156.60664,0.0010550461,-169.08379,116.92525,86.442413,0.40101925,-140.98811 -733267000,0.3853974,-157.02446,0.00091658649,-52.792694,114.30692,84.825256,0.3759422,-152.86061 -733766500,0.37786183,-157.0282,0.00042076601,150.86787,112.54971,83.659683,0.37968028,-148.16187 -734266000,0.37833756,-156.7523,0.00075274362,83.139297,110.15472,82.163147,0.34541735,-151.28131 -734765500,0.38608849,-158.60751,0.00096699037,-138.53723,107.79558,80.928787,0.36677951,-150.73331 -735265000,0.38620707,-158.39241,0.00070697366,103.50856,105.96211,80.065109,0.37933719,-148.24574 -735764500,0.39061567,-159.56131,0.00070654001,-153.07939,103.64161,78.406303,0.38274828,-147.28807 -736264000,0.40221179,-158.66808,0.0019747918,13.946434,101.8606,76.926529,0.41655537,-153.86124 -736763500,0.39618912,-159.77795,0.00025674535,89.144684,99.485161,75.852074,0.388504,-149.4238 -737263000,0.40109918,-160.1998,0.00024554238,94.271004,97.096268,74.424423,0.36483634,-149.36845 -737762500,0.40245745,-161.8226,0.0013202378,-138.77481,95.32132,73.088341,0.35212153,-151.8139 -738262000,0.40230179,-162.51385,0.001650126,-118.65839,94.082108,71.937836,0.36691535,-150.57437 -738761500,0.40883607,-161.60542,0.00055114093,47.711826,91.908585,70.466995,0.38577092,-152.86955 -739261000,0.4114801,-163.29289,0.001022247,-72.056282,90.06002,69.24173,0.42232203,-153.52119 -739760500,0.4181461,-163.44708,0.00074642891,-63.890507,88.030708,67.887444,0.37912548,-156.65118 -740260000,0.41569284,-164.25816,0.00054243952,-61.704079,86.679512,66.479912,0.41565984,-155.74216 -740759500,0.42424241,-163.99489,0.00081852759,-31.633646,84.161606,65.443657,0.40558562,-153.70348 -741259000,0.4231368,-164.65579,0.000221856,-147.58066,82.375206,64.349251,0.43733624,-155.56754 -741758500,0.41950762,-164.8284,0.0013775941,-139.13329,80.566902,62.833015,0.39127338,-153.97087 -742258000,0.42700332,-165.60936,0.00054611609,-85.677574,79.222771,61.454731,0.43282029,-151.85587 -742757500,0.43036824,-165.87126,0.00088502787,47.320034,77.505417,60.306759,0.40748796,-155.21835 -743257000,0.42947406,-166.47311,0.00050687545,-145.60469,75.646629,59.101929,0.40212247,-151.71072 -743756500,0.43392295,-166.27907,0.0010237603,123.57666,74.086609,57.74427,0.3970063,-151.05788 -744256000,0.43516681,-167.15048,0.00097676239,-123.89111,72.367516,56.544556,0.3975569,-151.79242 -744755500,0.44147387,-167.82434,0.0011783211,42.304855,70.918823,55.288383,0.43522781,-155.9897 -745255000,0.44013116,-167.5959,0.0016392191,150.91887,69.552742,53.917603,0.44554815,-154.11906 -745754500,0.44525075,-168.55157,0.0010669677,63.545982,67.860123,52.878788,0.43585429,-156.03976 -746254000,0.44712317,-169.03798,0.0011113387,49.709244,66.612869,51.668011,0.42764425,-156.10716 -746753500,0.4472903,-169.63268,0.00091098063,-79.43895,64.667549,50.205589,0.39825365,-156.49605 -747253000,0.45129871,-170.2704,0.0015968001,12.687207,63.399761,48.855446,0.4243792,-154.08411 -747752500,0.45421797,-170.35925,0.00091897248,-4.5576663,61.889286,47.709667,0.42377156,-157.31161 -748252000,0.45709383,-170.29643,0.0017589158,79.122864,60.799953,46.688702,0.43663403,-158.53534 -748751500,0.45806041,-171.04372,0.0008499875,-152.03693,59.340813,45.791233,0.41625223,-154.60979 -749251000,0.45930585,-171.79692,0.00139515,-24.083643,57.784321,44.021801,0.42198893,-156.46577 -749750500,0.46027151,-172.68193,0.0016095786,-65.990997,56.763695,42.908173,0.44566283,-156.52626 -750250000,0.46198246,-172.59488,0.0011286502,-161.95796,55.44585,41.49715,0.44424018,-157.73003 -750749500,0.46686909,-172.88797,0.00018299183,145.94391,54.000206,40.533333,0.43042973,-155.69257 -751249000,0.46610457,-173.74805,0.0010750373,-85.486336,52.756702,39.33028,0.44936651,-159.31801 -751748500,0.46816656,-174.15546,0.00068467413,120.54548,51.887836,37.901688,0.45721933,-155.91373 -752248000,0.46985352,-174.43788,0.00061614852,-26.392481,50.508076,36.827221,0.44701302,-158.37575 -752747500,0.47117034,-174.96248,0.00047488435,55.061928,49.395176,35.450512,0.45636994,-157.06299 -753247000,0.47097662,-175.37585,0.0011902486,-32.4729,48.000923,34.110752,0.41827017,-157.54091 -753746500,0.4716419,-175.23351,0.0018198615,-100.10796,46.987186,32.969807,0.45454293,-155.99919 -754246000,0.47555044,-176.15822,0.00059317413,-39.033676,45.576893,31.909227,0.44404051,-160.533 -754745500,0.47923458,-176.345,0.001463938,-150.76126,44.808537,30.777515,0.46129754,-161.37741 -755245000,0.48049608,-177.17627,0.00059890578,-21.031477,43.624065,29.434301,0.45503086,-161.26929 -755744500,0.48335689,-177.50066,0.00054236298,78.102074,42.644363,28.111738,0.44469684,-164.64195 -756244000,0.48308802,-177.41121,0.0009107783,45.918064,41.540283,27.125456,0.47794938,-159.32025 -756743500,0.48795858,-177.93373,0.0011109774,170.92285,40.607265,26.17964,0.44529876,-160.74448 -757243000,0.4871318,-178.61823,0.0007076303,38.766083,39.556141,25.231037,0.46263772,-163.47037 -757742500,0.4898665,-178.77672,0.00083458674,144.48216,38.636768,23.321518,0.45082593,-164.84601 -758242000,0.49360996,-179.22032,0.00082665042,32.696968,37.564011,22.53618,0.46926895,-163.03134 -758741500,0.49321723,-179.88428,0.00018869776,-59.106949,36.866249,21.25605,0.45626843,-164.8112 -759241000,0.49505669,-179.80353,0.00099983939,97.12764,35.769268,20.128597,0.49342966,-163.51549 -759740500,0.49546188,179.18825,0.0015391492,53.79047,34.943222,18.787132,0.4632577,-160.90309 -760240000,0.49904698,179.00877,0.00038452359,139.08571,33.913929,17.931276,0.47076711,-159.36838 -760739500,0.50000393,178.23566,0.001728838,40.440407,32.92979,16.799509,0.48346278,-166.12811 -761239000,0.50107151,178.2222,0.00058780768,160.81168,32.066483,14.975839,0.48056403,-164.03452 -761738500,0.50261784,177.9276,0.0009309075,-54.661594,31.607765,14.164351,0.45506206,-163.95406 -762238000,0.50169522,177.14201,0.00068994256,-74.127243,30.55047,12.894324,0.48185891,-164.01018 -762737500,0.50588357,176.42867,0.0017875188,116.17588,30.055483,11.774487,0.48916608,-165.77176 -763237000,0.50554371,176.96516,0.0014371203,-122.55766,28.775513,10.44294,0.50637525,-166.42223 -763736500,0.51011825,176.48044,0.0021505281,-110.81264,28.217113,9.8005095,0.4936423,-167.0437 -764236000,0.51337779,175.76572,0.00069158577,-174.93646,27.760471,8.5200844,0.45313433,-167.20187 -764735500,0.5082016,174.81255,0.00083313097,108.81441,26.660265,7.4927621,0.49724913,-166.75525 -765235000,0.51363474,174.72002,0.00037533429,-149.48802,26.39246,6.6868272,0.49593145,-168.03793 -765734500,0.51626903,174.29741,6.7674111e-005,149.09779,25.309977,5.0971351,0.49458963,-172.27261 -766234000,0.51334906,173.47458,0.0014573029,53.961613,24.88833,4.4232235,0.46893269,-167.44089 -766733500,0.51206005,173.76286,0.0015421471,55.081646,24.090687,2.4749289,0.47978231,-167.58005 -767233000,0.51751113,173.10878,0.00021214402,-164.15834,23.414127,1.3048371,0.49786398,-168.76813 -767732500,0.51808894,173.01015,5.932468e-005,-173.6881,22.782583,0.36170599,0.4888052,-168.94135 -768232000,0.51851583,172.47302,0.00016449462,66.96492,22.156063,-0.57857025,0.50301903,-172.186 -768731500,0.51875848,171.44203,0.0011304147,-77.014999,21.703817,-1.6396432,0.5024935,-169.94438 -769231000,0.52138841,171.73038,0.0017153103,-1.0807241,21.079056,-3.0274549,0.50249928,-171.10861 -769730500,0.52416247,170.85197,0.0011826942,-31.428082,20.297194,-3.8742037,0.49671164,-175.03601 -770230000,0.52697498,171.11783,0.0015038049,-170.44295,19.768511,-4.455472,0.47873095,-170.58014 -770729500,0.52761215,170.34428,0.00080050854,54.365265,19.304499,-6.1013622,0.5178594,-173.01048 -771229000,0.52509367,170.38968,0.0021416075,-82.384056,18.666834,-7.196723,0.50470722,-170.0446 -771728500,0.52296382,169.96124,0.00048273092,-72.612831,18.000565,-7.8784885,0.49487904,-173.22723 -772228000,0.52999884,169.48824,0.0009772958,-97.782326,17.726702,-9.3442183,0.51661056,-174.21616 -772727500,0.52740926,168.76506,0.0011315413,141.76289,16.948502,-10.130728,0.53174371,-171.84717 -773227000,0.52759415,168.63275,0.00033321301,78.089714,16.694077,-11.843052,0.4892883,-175.98657 -773726500,0.53127718,168.13989,0.0021527428,137.1362,16.106411,-12.342195,0.50067836,-176.57826 -774226000,0.5308103,167.47751,0.0019772777,177.60362,15.554503,-13.02882,0.51588833,-177.36909 -774725500,0.53305626,167.64941,0.0010998254,105.30194,15.164252,-14.863312,0.52347982,-175.11633 -775225000,0.53461015,166.63667,0.0018458501,-121.62264,14.921933,-16.352312,0.52648163,-178.93146 -775724500,0.52948868,166.7628,0.00057735608,71.427757,14.14133,-16.916645,0.47324422,-177.146 -776224000,0.53847784,166.28511,0.001307988,-121.29851,13.626882,-18.318703,0.5169788,-175.46794 -776723500,0.5341152,165.96304,0.00071421912,24.847618,13.287722,-19.051107,0.50895929,-178.20576 -777223000,0.5372901,165.38991,0.00061275368,159.96924,12.966062,-19.564598,0.51975363,-179.13216 -777722500,0.53640008,165.29514,0.0012921457,-11.766429,12.410467,-20.684732,0.53407681,179.15179 -778222000,0.53923768,164.75345,0.00040131551,32.134048,12.188946,-21.057024,0.51073289,-178.14694 -778721500,0.53752702,164.383,0.0015762188,-96.918671,11.672696,-22.262354,0.53488064,179.06857 -779221000,0.53781623,164.40912,0.00131861,167.21774,11.415698,-22.608601,0.51556379,179.6235 -779720500,0.53996897,163.26773,0.0013426945,-97.363785,10.876524,-25.429306,0.51674455,177.99155 -780220000,0.53893524,163.12358,0.0011275448,96.210114,10.52944,-26.934666,0.50937957,177.83049 -780719500,0.54348731,163.28381,0.00082220533,-72.041397,10.465369,-24.353535,0.51320291,176.87982 -781219000,0.53945094,162.12761,0.00045945091,-173.51143,10.118803,-27.47645,0.52774668,174.03856 -781718500,0.54068762,162.03326,0.0020384146,-41.672268,9.8507776,-29.432772,0.53633446,175.63023 -782218000,0.54675138,161.84375,0.00030002266,-75.186325,9.2798405,-29.991764,0.52807844,175.60396 -782717500,0.54773289,161.1096,0.00036870144,-156.39696,9.1680927,-31.741871,0.52738601,176.07748 -783217000,0.54337418,161.20929,0.0006829417,85.426514,8.8324623,-31.091209,0.50675553,176.31404 -783716500,0.5438512,160.65056,0.00057055632,9.2137985,8.6628466,-32.929218,0.53000921,174.24431 -784216000,0.54569131,159.97357,0.00059105799,-110.20291,8.181632,-33.933743,0.52537727,175.7458 -784715500,0.54990405,160.38019,3.9019193e-005,171.27577,7.990231,-33.697643,0.53829372,174.46092 -785215000,0.55229479,159.6888,0.00054391677,123.03548,7.4151435,-35.614216,0.51652008,177.16843 -785714500,0.55617291,159.8712,0.0024721469,-21.306692,7.3499961,-35.416897,0.55522782,173.70735 -786214000,0.55118322,159.00418,0.0010369427,-104.42218,7.1485376,-36.6478,0.53890455,171.46747 -786713500,0.5470593,159.14922,0.0013157208,-169.22385,6.9601402,-37.446724,0.52138549,170.99515 -787213000,0.55200344,158.30338,0.0019482224,-145.97256,6.7415462,-37.781639,0.55501419,170.89948 -787712500,0.55159742,157.86987,0.00083994045,1.3226731,6.2827487,-39.486073,0.54251528,171.2579 -788212000,0.5567733,157.00969,0.0012494053,-75.434212,5.9712801,-40.398952,0.5438534,171.43863 -788711500,0.55353838,156.81667,0.0021415949,42.073143,5.883563,-39.714088,0.53052026,169.15814 -789211000,0.55579317,157.22713,0.0004080674,45.069817,5.7578378,-42.505772,0.52679425,170.58847 -789710500,0.5523622,156.74063,0.00059097941,70.935043,5.4517713,-42.890835,0.54654485,170.47231 -790210000,0.55486441,156.03664,0.00065038708,-40.233475,5.3671508,-44.015896,0.55488014,170.20436 -790709500,0.54891342,155.58797,0.00031694546,88.515617,5.0772276,-43.323711,0.53882605,170.84433 -791209000,0.5550828,155.15898,0.00088515982,-87.346962,4.8833632,-43.483082,0.54861015,167.50554 -791708500,0.56034207,155.09918,0.00077193836,-52.229481,4.6137781,-45.372635,0.53663689,167.24768 -792208000,0.55513227,154.63188,0.0014061668,42.250641,4.4779968,-45.686943,0.56336761,168.10352 -792707500,0.55832863,154.60637,0.00056930876,150.95912,4.3335261,-46.865646,0.53904212,168.15315 -793207000,0.55754668,154.2937,0.0017820605,-29.759548,4.1384969,-49.656311,0.5469023,165.88148 -793706500,0.5597623,153.37781,0.0012552942,85.260147,3.9990947,-45.934937,0.53211737,165.50883 -794206000,0.55770224,153.19798,0.00026588244,-47.003426,3.9182143,-46.589432,0.55425614,162.75554 -794705500,0.55770248,153.03624,0.0014242326,61.182068,3.6631413,-49.420307,0.51867628,166.04671 -795205000,0.55948609,152.49191,0.00035677481,169.55721,3.5190947,-52.113892,0.52199602,161.75424 -795704500,0.56507909,152.39513,0.0011235542,32.075603,3.2651682,-52.713852,0.54429543,161.45447 -796204000,0.56331056,152.39049,0.001867793,-98.337318,3.1879129,-49.699974,0.53326523,162.67725 -796703500,0.55699617,151.73325,0.00080339867,153.53789,3.0268102,-47.264301,0.5616377,162.11755 -797203000,0.55647629,151.63478,0.0021041688,100.68832,2.9372671,-52.307182,0.54220259,161.37227 -797702500,0.56157047,151.1678,0.0011249528,123.27003,2.7596648,-57.318756,0.54519075,161.48735 -798202000,0.56231916,151.11621,0.00097529398,28.356722,2.8517699,-50.346409,0.52754402,159.98825 -798701500,0.56449479,150.43684,0.0006123964,-85.820969,2.5904484,-58.250675,0.54890639,158.95302 -799201000,0.56486034,149.94608,0.00046604563,-25.820522,2.5347455,-53.998756,0.55327642,158.47447 -799700500,0.56851411,149.45157,0.00042376408,-91.763695,2.3261633,-57.309292,0.53384107,159.84091 -800200000,0.56587571,148.9762,0.0011023224,-129.52478,2.2443819,-49.071114,0.55741042,159.79366 -800699500,0.56376052,149.21098,0.0012985345,-14.510167,1.9995079,-54.814972,0.55127358,157.68019 -801199000,0.56558162,148.58842,0.0020066323,134.50362,1.9560525,-55.924328,0.54415268,155.62759 -801698500,0.56917006,148.32436,0.00056121737,99.433441,1.8031758,-56.758839,0.52206612,157.66344 -802198000,0.56749207,147.91832,0.0010536346,0.77421749,1.9118674,-50.547421,0.55917937,155.45578 -802697500,0.56546426,147.78212,0.00063929346,-155.68555,1.8205689,-56.132042,0.54504126,156.7184 -803197000,0.56538695,147.13329,0.0013376158,115.35978,1.6914011,-58.723999,0.53882402,155.60905 -803696500,0.56607467,147.08054,0.00021337024,78.599617,1.6856009,-58.49221,0.52674264,154.70407 -804196000,0.56966364,146.87994,0.0005311945,-134.25542,1.7678626,-50.653584,0.55429739,153.40181 -804695500,0.56351191,146.16411,0.0018368313,142.84669,1.6548191,-51.107262,0.53535336,154.52924 -805195000,0.56721425,145.99925,0.0017167849,-111.51031,1.3935887,-57.083366,0.53845578,151.21507 -805694500,0.56707263,145.72804,0.0011324746,-90.053612,1.2983671,-55.76569,0.52842933,153.80664 -806194000,0.56886089,145.15501,0.0021077492,69.371788,1.1180859,-50.16148,0.56444287,152.81209 -806693500,0.56789207,144.82585,0.00076849241,-24.66143,1.304289,-55.184902,0.53682971,152.01506 -807193000,0.56904942,144.76482,0.0023870927,-150.45012,1.2015256,-54.421146,0.54802412,151.09406 -807692500,0.56843871,144.37025,0.001698655,98.042931,1.2679585,-58.771389,0.53683871,150.45738 -808192000,0.56933838,144.04411,0.0029947688,37.710098,1.1955949,-44.151558,0.54106045,149.7951 -808691500,0.56778163,143.79585,0.00065008027,40.553223,0.91971767,-42.24839,0.53805232,147.8873 -809191000,0.56949294,143.36885,0.00062897964,12.82367,0.88518214,-57.713406,0.54117197,149.7903 -809690500,0.57014859,143.26405,0.0013973205,2.3697245,0.91000134,-54.864643,0.53319669,148.28134 -810190000,0.5687865,142.92728,0.00077065005,8.6847601,0.90184808,-37.085358,0.52632713,147.66849 -810689500,0.56913024,142.36391,0.0016301989,-119.00289,0.71543723,-36.370121,0.53818929,148.03056 -811189000,0.56833208,141.95966,0.00092425372,-17.319021,0.80474418,-50.35463,0.52246988,145.06732 -811688500,0.56738186,141.73077,0.0015074362,32.655643,0.71559703,-43.389072,0.533912,145.948 -812188000,0.57111508,141.56776,0.0004343242,20.302446,0.53871346,-49.475319,0.54077697,146.18802 -812687500,0.57118201,140.94591,0.00076365552,-41.855713,0.90464967,-44.153584,0.55275536,146.83089 -813187000,0.56972897,140.49852,0.00018372211,-120.17398,0.63608682,-30.219603,0.52817798,146.46117 -813686500,0.57410061,140.44112,0.0012350708,40.045628,0.75304043,-34.195499,0.52341151,144.28075 -814186000,0.57135326,140.10773,0.0014159137,-137.2643,0.67393446,-39.805645,0.5417816,144.49374 -814685500,0.56760043,139.85423,0.0014102387,151.90268,0.66846967,-39.848713,0.52953142,140.48846 -815185000,0.57140952,139.61281,0.00042092206,29.597471,0.56618851,-45.920563,0.54095948,143.29008 -815684500,0.57145184,139.18997,0.0021739211,-171.56335,0.64418465,-36.289482,0.52178407,144.4538 -816184000,0.57126749,138.61856,0.00098111574,-7.6353488,0.6777541,-30.62258,0.52570683,143.20355 -816683500,0.56913799,138.48959,0.00056398113,-22.381536,0.67567843,-40.086796,0.54615664,143.66432 -817183000,0.57449055,138.15865,0.0010300623,38.201508,0.44173753,-23.460711,0.51319695,142.15291 -817682500,0.57014507,137.74011,0.0011344213,-142.83311,0.41156679,-22.109102,0.53055221,139.67451 -818182000,0.57075089,137.53101,0.00087924761,-57.882507,0.64894599,-14.234015,0.51199293,141.26555 -818681500,0.56986433,137.31364,0.00042937871,-25.958994,0.60132903,-24.599066,0.54985332,138.05656 -819181000,0.56994581,137.0983,0.0025556143,-92.324364,0.65383857,-29.492693,0.54202616,138.84573 -819680500,0.57047307,136.38615,0.00024771449,-34.691055,0.5695132,-14.98565,0.49562773,136.86528 -820180000,0.57032281,136.69806,0.0012424752,-160.92334,0.37782949,-27.81815,0.52285677,137.66927 -820679500,0.57287008,135.98387,0.00073369459,-50.342472,0.63995552,4.3784623,0.52244008,138.78609 -821179000,0.56993061,135.63724,0.0007211208,-97.311813,0.47449619,-15.272554,0.51720679,137.32011 -821678500,0.56954896,135.38675,0.0028531228,-171.32803,0.45678195,-13.44135,0.52773064,136.01984 -822178000,0.57025665,135.17368,0.0010917258,-13.188754,0.59695393,-19.415869,0.52088225,139.37283 -822677500,0.57087511,134.46642,0.0019669579,-178.8273,0.54449868,-10.236989,0.530967,135.60803 -823177000,0.57207918,134.37936,0.00045934279,37.928516,0.55063349,-25.953163,0.5075345,132.68231 -823676500,0.57235849,133.90964,0.00038607657,-52.559795,0.4683007,-20.554201,0.51177746,130.82069 -824176000,0.57167238,133.81874,0.0014595083,-17.737261,0.35328561,6.5464244,0.51564676,134.74324 -824675500,0.56877965,133.37602,0.0009544983,106.37669,0.5652771,-6.2499938,0.4941673,134.18623 -825175000,0.57318634,132.73024,0.0011249277,15.658084,0.51804823,-9.0251026,0.49655688,134.0303 -825674500,0.56814867,132.68005,0.0014809639,143.78865,0.49504173,-10.450283,0.49134606,133.64018 -826174000,0.56757414,132.46216,0.00038018476,-5.5104747,0.53585088,0.79500592,0.52599418,129.85077 -826673500,0.5686878,132.28577,0.0021951534,63.088642,0.37420794,-10.417683,0.51838762,128.72951 -827173000,0.5709849,131.94682,0.00084693026,-81.437813,0.41772708,-11.994438,0.52945703,129.44023 -827672500,0.56714028,131.42892,0.00017753057,-8.1149454,0.49720383,9.8852625,0.50260693,128.65906 -828172000,0.57246196,131.27756,0.0013126681,157.52597,0.53348762,-3.7059515,0.49756038,127.87394 -828671500,0.57087672,130.77953,0.00040816551,-99.167458,0.52129948,-13.121892,0.51937735,126.96528 -829171000,0.5709551,130.42493,0.0011223435,98.569801,0.46029133,-2.626147,0.50670016,126.95693 -829670500,0.56799793,129.96841,0.00076759781,31.386229,0.32344943,1.0627578,0.49515787,128.19089 -830170000,0.56834483,129.79539,0.00071059319,143.95287,0.43285522,1.5798547,0.51749593,127.67286 -830669500,0.56670415,129.46365,0.00060191104,-104.18354,0.39687803,2.4190257,0.48309287,124.508 -831169000,0.5695067,129.61926,0.0023900929,24.90189,0.41226456,1.9072292,0.50601017,128.49756 -831668500,0.57050866,129.01729,0.0018652901,-40.914688,0.41154736,13.99805,0.47851673,126.97086 -832168000,0.57029361,128.67564,0.001895584,29.303253,0.48200768,5.8355007,0.48099864,124.46184 -832667500,0.5703916,128.49927,0.0016373213,-125.65608,0.40248269,2.6996956,0.48895919,125.06179 -833167000,0.57224607,128.00371,0.00051343098,119.93146,0.44822717,-3.0021443,0.47810197,122.76344 -833666500,0.56561822,127.43894,0.00092989131,157.21941,0.518601,4.845293,0.48570332,122.87527 -834166000,0.56610495,127.4043,0.00092164759,52.330299,0.42939147,26.145483,0.47967044,123.74648 -834665500,0.57250297,126.78162,0.0021322654,160.98528,0.35073787,-16.014402,0.47635984,124.08935 -835165000,0.56890929,127.05566,0.00082797674,5.5369473,0.43068832,0.44731215,0.48468676,122.95155 -835664500,0.56822294,126.3174,0.0017956992,25.090839,0.3705782,-1.276721,0.48154929,120.04906 -836164000,0.568973,125.6732,0.00087304675,158.73715,0.3486734,0.72414714,0.48730123,119.83317 -836663500,0.56284606,125.88141,0.0015037457,38.304592,0.37509045,10.356062,0.47141144,120.21954 -837163000,0.56680918,125.72403,0.0017692138,-25.281872,0.33119336,-5.1300917,0.4905591,119.12291 -837662500,0.56588602,125.36744,0.00099982903,82.6576,0.40722233,-11.614699,0.46830225,120.00914 -838162000,0.56903976,124.65678,0.00047457183,79.302078,0.27019942,-10.65291,0.47699672,117.60434 -838661500,0.56889218,124.74541,0.00031353245,-116.74033,0.5251146,1.6468906,0.49226519,115.44843 -839161000,0.56641012,124.15085,0.00092921947,173.39272,0.35653335,-24.943323,0.48794505,118.18163 -839660500,0.56195867,124.15495,0.0012780639,-179.97456,0.40803406,7.9920001,0.46955481,118.80524 -840160000,0.56567246,123.43025,0.00022511059,-158.30576,0.29831964,-6.1953025,0.49882355,116.32771 -840659500,0.56969923,122.75622,0.00050395069,25.374529,0.31310242,1.1199362,0.49081075,118.14279 -841159000,0.56462741,123.216,0.00053975719,-89.06897,0.44461727,-1.1644696,0.4554525,117.69759 -841658500,0.56654823,122.68212,0.00065016584,-11.332535,0.29345343,1.2737262,0.45672372,116.56382 -842158000,0.56823725,122.14325,0.00076427357,-90.413971,0.30720213,10.107422,0.45191118,114.59828 -842657500,0.56146896,122.76702,0.0016864976,142.17014,0.35541031,-8.4585295,0.47171739,116.26218 -843157000,0.56197768,121.65366,0.00047381828,23.200243,0.35087457,-8.6208496,0.49886054,113.14071 -843656500,0.56278253,121.14603,0.0007682296,120.01186,0.32286507,3.1147892,0.45604196,112.6941 -844156000,0.5652377,121.11208,0.00072558667,87.72509,0.41617796,-9.6719408,0.4665277,112.84869 -844655500,0.56384635,120.71424,0.0002474763,169.83434,0.2997205,-1.212519,0.45206329,110.57218 -845155000,0.56021321,120.76111,0.0010845928,110.95107,0.3036887,-2.158468,0.45633519,112.64774 -845654500,0.56256509,120.29755,0.0002862782,-145.44284,0.25338688,-2.500648,0.45773649,111.89323 -846154000,0.55924273,119.96008,0.0016098423,165.27808,0.17306052,-26.425468,0.43477523,108.49414 -846653500,0.56242967,119.68994,0.00176656,7.4458504,0.26217747,-6.1077051,0.47460309,108.15665 -847153000,0.56206608,119.2044,0.00097113708,-170.16183,0.32704508,-2.8536692,0.44547415,111.60041 -847652500,0.56172562,118.83972,0.001072044,66.86171,0.29536393,-12.383088,0.45388857,111.15434 -848152000,0.56450891,118.26128,0.0012706759,43.099442,0.31206036,-4.7712789,0.43770689,108.66622 -848651500,0.55932802,118.15452,0.0029053425,155.94197,0.28204554,-17.523918,0.44316339,106.22977 -849151000,0.55619305,117.7305,0.0022774565,85.114662,0.20824151,10.313021,0.44364694,108.95527 -849650500,0.55885541,117.58393,0.00074401125,-157.41241,0.18624309,-14.869002,0.41949862,105.24645 -850150000,0.56233448,117.07418,0.00071331218,-160.73981,0.16018972,18.226435,0.44021061,104.66999 -850649500,0.55838203,116.66592,0.0015825606,-167.83217,0.18372892,7.5402141,0.44367841,104.29838 -851149000,0.55428565,117.08653,0.002569637,146.33803,0.33257297,-15.170598,0.46696621,106.18029 -851648500,0.55803627,116.46925,0.0018061085,-137.76862,0.15824802,-3.3389316,0.44638938,105.24657 -852148000,0.55621117,116.08169,0.00052870432,6.9140654,0.21227239,-1.7591326,0.42971772,104.38595 -852647500,0.55764192,116.06159,0.0013143037,-117.42323,0.051814791,-58.803741,0.44135478,103.49422 -853147000,0.55301327,115.08472,0.0019373961,17.260862,0.21986069,9.2905817,0.43744847,104.29345 -853646500,0.55848116,115.0135,0.00049319229,-112.63345,0.32127389,13.303997,0.44570509,101.92693 -854146000,0.55699217,114.88433,0.00062711688,-112.67891,0.2110436,-0.47692961,0.42904526,102.65614 -854645500,0.55693001,114.29522,0.0014038493,4.0033665,0.16251798,-33.272255,0.42896777,100.53725 -855145000,0.55274647,114.3546,0.00027791987,51.358112,0.23724084,-15.595078,0.42672673,100.70544 -855644500,0.55725616,114.04929,0.00033891638,24.145388,0.20640549,-7.539916,0.4347114,96.563232 -856144000,0.55585748,113.47496,0.00090494135,99.206535,0.19677934,-6.322866,0.41522613,97.493332 -856643500,0.55445147,113.25836,0.00075182819,-116.05826,0.19497268,13.197108,0.43460727,98.009155 -857143000,0.55424678,113.32693,7.0028516e-005,-118.53674,0.19814949,-14.361168,0.42210114,99.036316 -857642500,0.55511677,112.26532,0.0011265487,-57.021427,0.30578682,-4.3363137,0.42428735,98.821777 -858142000,0.55576783,112.65741,0.0017297956,50.864391,0.21498105,-5.6645107,0.4036465,96.636932 -858641500,0.5527066,112.08973,0.0010470605,-98.034386,0.19873615,-1.8664575,0.44312999,94.753311 -859141000,0.55060035,111.37981,0.00071824441,-49.836094,0.1311118,0.69256383,0.43392351,92.858223 -859640500,0.55462497,111.25726,0.00042604175,-155.82533,0.11373192,5.0250235,0.44378999,94.90271 -860140000,0.55156678,111.19389,0.00027421067,19.346598,0.17942822,-12.039492,0.40633181,95.228981 -860639500,0.55095321,110.66458,0.0011366997,122.82426,0.15429679,-14.001909,0.41429812,94.416924 -861139000,0.55586165,110.25083,0.0014333356,-18.483459,0.12188271,-48.183002,0.42765903,93.867943 -861638500,0.5500015,109.58504,0.00087380607,-108.72192,0.14858672,2.2704377,0.41228074,91.729439 -862138000,0.54876834,109.3571,0.0019770791,121.79003,0.10327012,14.111242,0.40714654,94.398193 -862637500,0.54244232,109.11646,0.00074019202,-32.76646,0.12680176,39.441963,0.40324327,94.264442 -863137000,0.54433173,108.64307,0.0013214146,-59.053162,0.074184828,-42.837551,0.40234038,89.57428 -863636500,0.5489406,108.52918,0.0021430231,150.2068,0.18155205,2.0795286,0.39736608,94.364624 -864136000,0.54904985,108.65086,0.00015532323,-127.65385,0.093007289,14.71951,0.3976472,91.295883 -864635500,0.54225129,107.82465,0.0016946549,143.92218,0.069274224,-27.156471,0.41090325,92.299805 -865135000,0.54204237,107.98227,0.0009596204,73.041016,0.084618755,-5.1590648,0.41652301,86.210091 -865634500,0.54331917,107.76292,0.00078814651,164.85025,0.13409285,37.656765,0.37703699,86.144508 -866134000,0.54217356,107.28947,0.00024683203,-173.41331,0.1705042,-31.402912,0.40023118,89.096611 -866633500,0.53949487,107.27271,0.0010605243,-45.206444,0.11187818,-54.537952,0.40288019,89.018501 -867133000,0.53915578,106.35084,0.0013200077,-43.844395,0.067743696,-2.5022006,0.39286575,88.603485 -867632500,0.54215765,106.38634,0.00074660656,48.742466,0.17261003,26.355246,0.38900733,88.006973 -868132000,0.54134345,105.67495,0.00039311551,-93.69577,0.15360756,15.185932,0.40608513,84.308708 -868631500,0.53700101,105.00661,0.00081500638,-101.35213,0.075241148,7.2438111,0.39529705,83.154198 -869131000,0.54087049,105.71288,0.00063565635,-96.20034,0.10616954,42.081844,0.39257741,85.299438 -869630500,0.54253364,104.91502,0.0016037596,22.203976,0.10385609,30.595884,0.40815985,86.520569 -870130000,0.53229976,104.74336,0.0014683768,-105.66123,0.13494724,12.739464,0.37714633,85.846611 -870629500,0.53715301,104.1808,0.0013454573,-36.956516,0.088608213,-4.6848388,0.39677742,85.168045 -871129000,0.53675169,104.20055,0.001265864,-111.26117,0.02788057,107.18377,0.38499883,81.158432 -871628500,0.54075766,103.50657,0.0010552831,135.23619,0.0093516773,37.415424,0.37549564,82.812149 -872128000,0.53529185,103.7124,0.0010913141,175.18553,0.091213949,40.661053,0.3669889,84.872688 -872627500,0.53442305,103.0486,0.00042393219,111.31549,0.0094804075,-161.97992,0.37807405,80.059875 -873127000,0.5317257,102.86301,0.00056783459,-37.63784,0.071213625,16.016998,0.3676292,82.369049 -873626500,0.53284615,102.44323,0.00072012242,-162.28424,0.034428794,-2.257127,0.3522003,79.838531 -874126000,0.53149897,102.35107,0.0017624772,-121.03619,0.085388601,39.44976,0.35933143,81.19915 -874625500,0.52922535,102.09612,0.00064452155,20.557238,0.083963364,-3.809015,0.35163298,75.647163 -875125000,0.53282815,101.42358,0.0020702358,95.625153,0.093692012,-0.036072809,0.3672097,82.302101 -875624500,0.53237975,101.25334,0.00045406455,34.907089,0.070950896,4.3419428,0.3716732,79.557579 -876124000,0.52628195,101.07983,0.0015845355,49.656406,0.14065593,-2.4939053,0.37938628,78.621506 -876623500,0.52439743,100.40278,0.00072136923,-53.200226,0.099993885,-34.065346,0.36369002,80.145157 -877123000,0.52825671,100.45979,0.001287138,-36.407825,0.098628916,15.332755,0.38511598,76.05999 -877622500,0.52589971,99.415932,0.00086326333,25.545364,0.057757519,8.2576532,0.37835386,77.736053 -878122000,0.52528644,99.797897,0.00057212118,110.78645,0.092232138,19.085245,0.3711504,75.491203 -878621500,0.52602917,99.324249,0.00065258867,-43.786224,0.169816,24.165926,0.36175126,74.670601 -879121000,0.52430904,99.169174,0.00055002584,-96.410011,0.089377336,-0.33509505,0.36647287,72.709206 -879620500,0.52352166,98.394348,0.00042683588,-85.875275,0.13815704,-5.4227071,0.35530853,73.567741 -880120000,0.5222975,98.022926,0.0021841822,74.747169,0.060969286,-12.698473,0.37642038,73.236923 -880619500,0.52314138,97.831757,0.00098708074,-10.944459,0.08430592,9.1856976,0.35610998,74.600082 -881119000,0.52234441,97.715927,0.0016499193,125.32237,0.10249068,45.978481,0.3755289,76.761475 -881618500,0.52257699,97.40696,0.00093806948,45.087048,0.039692715,177.52319,0.33705738,71.252724 -882118000,0.5211156,96.959335,0.0019767447,-67.755882,0.10757747,-39.509113,0.35399839,70.229607 -882617500,0.52035105,96.591003,0.0012190259,55.109329,0.049216121,129.52898,0.35436505,72.374916 -883117000,0.51984823,96.434967,0.00064200204,-19.338638,0.061500564,59.077278,0.37251854,72.32679 -883616500,0.51884997,96.385864,0.0015510854,59.065025,0.063919924,-9.4714098,0.37467858,70.643372 -884116000,0.51629829,95.917458,0.0018332344,8.5031872,0.15243678,84.396294,0.36307645,70.418297 -884615500,0.51993322,95.31562,0.00064260623,-59.618687,0.057040378,92.286278,0.35801131,71.876015 -885115000,0.51531053,95.174133,0.0011090194,-86.836403,0.08372996,0.023064118,0.35375598,67.445793 -885614500,0.51632363,94.545326,0.0012385376,31.706814,0.074172944,15.684906,0.3481735,67.07074 -886114000,0.5128907,94.622963,0.0019397496,67.01786,0.060177349,22.003073,0.34279794,66.187866 -886613500,0.51111364,93.998703,0.0016453388,147.68947,0.11481668,56.474396,0.34141749,67.393562 -887113000,0.50976068,93.816711,0.00073416083,79.46846,0.064453423,-8.6441174,0.3373661,66.091476 -887612500,0.50982034,93.539192,0.00083904021,148.4194,0.050058816,40.05806,0.32688406,62.939995 -888112000,0.50908244,92.93692,0.00015281333,152.39458,0.045962643,-13.549099,0.34340385,64.44828 -888611500,0.50914878,92.682106,0.0010751778,-47.047749,0.02281067,38.019974,0.33330554,63.920864 -889111000,0.50824946,92.262962,0.0011259922,28.268265,0.052775137,55.267517,0.33092317,65.712646 -889610500,0.50846905,92.232201,0.0014063413,-31.293724,0.086588025,21.56089,0.34535217,62.764713 -890110000,0.50423986,91.544586,0.00038880401,156.97406,0.032013647,2.1637666,0.35376745,64.583443 -890609500,0.50330454,91.099777,0.00057934655,-40.321384,0.093259707,8.0013037,0.36147299,64.161591 -891109000,0.50572067,90.944656,0.0011121975,156.03482,0.029066212,74.251015,0.34114125,65.201576 -891608500,0.50519466,90.78611,0.00097049621,-150.23038,0.043708395,-26.429516,0.33447653,60.321705 -892108000,0.50322682,90.190109,0.0012265957,21.788925,0.081007496,10.828805,0.32151476,59.643219 -892607500,0.50322318,90.221893,0.00068570743,82.746674,0.096620426,-8.3974438,0.32808569,62.711594 -893107000,0.49990121,89.540115,0.0011062949,109.57283,0.016861055,-42.392143,0.33644712,60.220093 -893606500,0.49800536,89.32589,0.0007898219,163.68919,0.089194,48.352684,0.32309365,59.72205 -894106000,0.4978174,89.183678,0.00017134026,-4.2189341,0.084711708,-12.237297,0.32219705,58.978016 -894605500,0.49728766,88.649567,0.00023354341,-106.85493,0.015407672,42.106796,0.31850007,59.871651 -895105000,0.49797511,88.11338,0.0010404091,118.67776,0.096328013,20.232256,0.34191149,60.123158 -895604500,0.49611875,87.775017,0.0010974279,-96.526566,0.037968401,45.471935,0.30846924,59.62846 -896104000,0.49354598,87.692696,0.0014305556,-104.61309,0.028828153,26.022715,0.3395358,57.940323 -896603500,0.4923704,87.50988,0.00091681193,17.889984,0.025072284,12.207273,0.33230826,54.809177 -897103000,0.49361914,87.299446,0.0023417592,-22.88184,0.0047201272,91.537956,0.31926858,56.448814 -897602500,0.49054956,87.099243,0.00068248477,-175.41434,0.050249912,77.816696,0.33298293,55.835621 -898102000,0.4896799,86.274986,0.00036668728,-105.89215,0.040615682,40.557423,0.31574893,54.830662 -898601500,0.48623753,86.103104,0.00046074789,5.8788891,0.013058632,32.168285,0.31613487,57.815952 -899101000,0.49080253,85.563751,0.0019262767,67.51004,0.036837101,25.991486,0.31099296,53.963654 -899600500,0.48666117,85.577141,0.0007690792,33.4841,0.066892058,93.231033,0.3134774,52.664997 -900100000,0.48650891,85.15918,0.00081460731,31.251001,0.060058869,110.13248,0.33361253,53.29845 -900599500,0.48617768,84.64238,0.00097107206,-67.363686,0.035378419,68.149002,0.32021329,49.915138 -901099000,0.48682952,84.582359,0.00064013794,37.925625,0.051377889,-19.000921,0.32276663,51.197945 -901598500,0.48100436,83.992592,0.00016050163,152.97946,0.15377434,7.7186937,0.32341594,50.239643 -902098000,0.48173091,83.852867,0.0014677396,56.286774,0.061675504,-24.093534,0.29061106,48.618927 -902597500,0.48040971,83.607964,0.00069714186,-142.7659,0.048682436,36.316391,0.30144453,50.131691 -903097000,0.47981146,82.905075,0.00095277827,179.78523,0.051742315,34.941711,0.31875217,50.276608 -903596500,0.47788334,82.669029,0.00024381479,20.916346,0.074069642,13.754478,0.3238045,50.587528 -904096000,0.48216096,82.10112,0.0019620629,15.401051,0.044122994,78.458511,0.32392234,49.388466 -904595500,0.47723627,82.077644,0.0012571225,150.96037,0.044453476,3.3254771,0.2899738,50.45776 -905095000,0.47918531,81.683128,0.00014539664,-70.752579,0.09140043,71.356728,0.31585017,50.222385 -905594500,0.4751173,81.610268,0.0017581285,151.49394,0.091898203,33.445316,0.30560896,45.762985 -906094000,0.47344387,81.034302,0.00050212309,-71.573021,0.02836049,31.912113,0.29455993,47.384155 -906593500,0.47253752,80.814163,0.0014200609,-54.731792,0.024571221,-28.57918,0.30390933,42.966423 -907093000,0.47074381,80.624741,0.00085413054,-33.086418,0.063605584,-14.381607,0.31493941,45.122627 -907592500,0.46950713,80.167648,0.0021065129,-167.71974,0.037371628,-25.169556,0.29959404,43.392036 -908092000,0.46880412,79.77861,0.00088715996,96.389618,0.012907089,63.516285,0.31296146,45.953609 -908591500,0.46726361,79.663597,0.0011327339,-7.7101207,0.034839321,-3.2750001,0.28471568,44.297443 -909091000,0.46514624,78.822571,0.00045877334,142.86716,0.038748242,120.85947,0.29480925,48.510612 -909590500,0.46532252,78.826164,0.0013212636,114.05772,0.07202176,31.353018,0.3134357,40.009987 -910090000,0.46392903,78.248657,0.0016784207,123.24727,0.065995999,81.699524,0.29725584,41.820305 -910589500,0.46254057,77.634544,0.0003506371,123.48153,0.026281686,163.75389,0.31282195,42.147362 -911089000,0.46422014,77.667427,0.0013365841,119.59668,0.047663882,26.887785,0.29444042,41.013599 -911588500,0.4623051,77.38018,0.00063175173,-69.684204,0.012702134,-77.341331,0.27404022,40.31678 -912088000,0.46038613,76.859299,0.0028810787,117.30537,0.034683928,35.330555,0.28803715,41.345921 -912587500,0.46146685,76.768547,0.0008651017,-106.95388,0.054804493,10.39968,0.29034579,41.536774 -913087000,0.45953,76.371246,0.0017075796,-82.344482,0.02442861,-27.575891,0.29166412,40.497612 -913586500,0.45673299,76.164818,0.0011482849,60.472855,0.038379945,24.541334,0.27922231,38.354713 -914086000,0.45339546,75.68779,0.0023449243,-161.30742,0.017133893,100.91727,0.2991612,41.901573 -914585500,0.45290732,74.747047,0.0025766084,80.448074,0.11299362,53.560066,0.28035411,39.290802 -915085000,0.45354676,74.925003,0.0015156858,-128.85019,0.072587259,83.573097,0.2882075,36.702892 -915584500,0.45259288,74.483246,0.0011519177,41.715931,0.067270756,57.463017,0.29057211,40.001507 -916084000,0.44823825,74.37812,0.000545991,44.26997,0.048820049,58.064537,0.29297647,37.974159 -916583500,0.44560117,73.632492,0.0014034508,24.611933,0.050934173,55.780865,0.2773391,34.593616 -917083000,0.45040411,73.17794,0.0013407796,156.3103,0.051782422,108.06561,0.29963773,38.572598 -917582500,0.44701669,72.653053,0.0018095722,173.21391,0.10529372,76.243271,0.30175069,34.521938 -918082000,0.44598165,72.766167,0.0017492749,81.50956,0.053135533,54.844761,0.28420609,32.933853 -918581500,0.4471761,72.464996,0.0012042978,-139.5565,0.023792302,148.9201,0.27464461,37.490971 -919081000,0.44656888,72.203125,0.001028353,164.2123,0.0013838898,-51.152229,0.2991505,31.838995 -919580500,0.44372782,71.775841,0.0012702065,-95.998047,0.054845963,153.57845,0.28905535,31.064995 -920080000,0.44250229,71.007309,0.0014406155,-63.88063,0.022857966,41.467934,0.29875919,33.90889 -920579500,0.43977827,71.749474,0.00016619763,39.359726,0.092620142,-6.0300717,0.27341306,29.733463 -921079000,0.44085154,70.8508,0.0015494333,-97.304665,0.06668783,41.848202,0.27277258,31.779497 -921578500,0.43599382,70.287872,0.00048816335,99.902306,0.039037213,64.525963,0.30310288,31.870865 -922078000,0.43813616,70.124001,0.00064379413,19.964336,0.01724809,52.85677,0.30160168,28.979673 -922577500,0.43415517,69.823029,0.0010732724,23.947315,0.046610303,112.78097,0.25770727,25.768187 -923077000,0.43240148,69.256287,0.0011068218,10.885129,0.024910145,-135.46736,0.25525653,27.962925 -923576500,0.42904338,69.000267,0.00025192837,-175.5377,0.084683277,34.441986,0.29402965,30.526199 -924076000,0.42825752,68.693314,0.00099850073,29.389112,0.027924094,136.66351,0.2493813,27.324093 -924575500,0.42924964,68.601898,0.0010035506,-126.94926,0.038008261,4.0485249,0.28942525,24.154928 -925075000,0.42657894,68.326691,0.0013150931,131.56377,0.057178415,125.31258,0.27953678,24.85438 -925574500,0.42839074,67.441833,0.0011222938,31.081425,0.078746893,55.507111,0.28787628,24.789381 -926074000,0.42254853,67.066689,0.001281181,28.888945,0.027760699,129.63739,0.2735675,24.805948 -926573500,0.42258066,67.383682,0.00073788641,91.767334,0.024304813,175.81316,0.26455745,24.841766 -927073000,0.41976428,66.260834,0.0015074166,122.84769,0.066965364,79.972229,0.26434234,23.0835 -927572500,0.41843542,66.084625,0.00030255321,-95.57766,0.076184586,70.353828,0.26788291,27.068253 -928072000,0.41624177,65.387756,0.00030017263,110.55019,0.027394291,158.4073,0.2716133,23.197191 -928571500,0.41921481,64.823479,0.0012387765,69.884201,0.069215089,-83.343224,0.27003983,21.760832 -929071000,0.41782597,64.602211,8.5163127e-005,26.696835,0.029518291,179.88168,0.26972383,20.839174 -929570500,0.41208398,64.123108,0.002941634,-36.529377,0.086707488,147.67101,0.28285196,20.992521 -930070000,0.41796476,64.154884,0.0013792788,128.01273,0.040104184,144.21568,0.25472099,22.862194 -930569500,0.40955392,63.53809,0.00040502936,-159.50127,0.025917284,75.610603,0.25497994,20.644093 -931069000,0.4083859,63.414742,0.0015899729,117.89648,0.047091246,-64.901787,0.28277454,20.96143 -931568500,0.40650779,63.016529,0.0012971698,125.09519,0.052281316,167.11937,0.27403149,16.133612 -932068000,0.40902165,62.275944,0.0012440728,-38.560268,0.017171506,133.8214,0.28187439,19.111343 -932567500,0.40215626,61.905994,0.00052859331,17.343651,0.085216098,-3.6347463,0.24235395,17.369848 -933067000,0.40815708,62.292194,0.00087578682,-147.6564,0.042279258,87.686661,0.26602373,16.571592 -933566500,0.40436134,61.119469,0.00064387138,-78.605743,0.01265284,-85.614182,0.28177592,22.387089 -934066000,0.40160468,60.870605,0.001524648,-90.081978,0.017630586,-74.551628,0.29348838,18.917025 -934565500,0.40018216,60.76318,0.0017156793,-158.39201,0.060095344,154.64578,0.28034115,16.418381 -935065000,0.40093905,60.132065,0.00087618589,-122.88169,0.046165004,38.323097,0.26856253,13.016212 -935564500,0.40214786,60.235321,0.00029804971,-78.367912,0.053518847,105.40482,0.24967168,11.682972 -936064000,0.39528769,59.918449,0.0018903372,26.859209,0.017715488,-13.387149,0.26857531,13.233127 -936563500,0.39964408,59.363293,0.0012963075,-81.238724,0.075440481,82.159241,0.28262794,10.658707 -937063000,0.39329636,58.627914,0.00037859654,-36.32946,0.059849538,70.122169,0.27319977,12.374528 -937562500,0.39185339,57.28595,0.00027691294,-60.38224,0.020163637,107.59315,0.26178917,13.867354 -938062000,0.39283058,57.879448,0.0016912575,-151.44601,0.052158885,-20.77409,0.26338252,10.883179 -938561500,0.38965598,58.386044,0.0016034822,-66.314178,0.01430267,86.69725,0.24206823,12.388817 -939061000,0.38748333,57.566475,0.0012155264,111.78187,0.0024771788,-148.67516,0.26604876,9.3904476 -939560500,0.39201063,57.131161,0.00078860583,-70.069359,0.076986685,-44.814594,0.2757619,11.095356 -940060000,0.38434437,56.35722,0.00023438316,162.53629,0.012486196,122.51966,0.26615533,7.6910586 -940559500,0.38697615,56.441147,0.0013833272,140.27675,0.031032665,-92.060669,0.265854,11.481621 -941059000,0.37975374,55.875622,0.00075857865,-137.67931,0.034257408,22.805893,0.2651912,9.4830112 -941558500,0.38290408,55.006577,0.0017747969,71.897057,0.080086961,114.09525,0.27188846,7.5306211 -942058000,0.37657949,55.105511,0.0011302225,-168.20396,0.0428355,-38.25589,0.25750843,8.5492764 -942557500,0.37760568,54.292713,0.00070019678,24.379404,0.063067019,85.430397,0.25473124,9.1449327 -943057000,0.37516177,54.274498,0.0019778961,176.59776,0.11192466,39.573097,0.24531807,5.4552946 -943556500,0.37618425,53.505302,0.00075518433,-84.559326,0.021053871,-140.1107,0.24374916,5.9439673 -944056000,0.37720275,53.286694,0.00068841729,-172.81715,0.0093336133,177.59001,0.26764482,2.0726035 -944555500,0.37175,53.157738,0.0013809105,137.88568,0.065444671,26.458755,0.23492783,8.3680487 -945055000,0.36405402,52.367661,0.00065658224,-75.360039,0.021860352,177.92888,0.26537055,3.8900497 -945554500,0.36972457,51.602154,0.0011377032,113.77577,0.055526763,43.470085,0.26738966,3.6471772 -946054000,0.37062895,51.886612,0.00079724297,135.48184,0.082741983,12.89389,0.26677915,1.03721 -946553500,0.36768386,51.181236,0.00099026167,5.692934,0.027025845,-77.31488,0.25179958,4.8902717 -947053000,0.36929128,51.186256,0.00052622275,-83.713142,0.055290304,125.50619,0.26088646,-0.64502192 -947552500,0.3649773,50.227844,0.00060453953,-128.28242,0.043305326,32.154613,0.2636283,-1.8456541 -948052000,0.361938,50.279758,0.00024991232,131.79019,0.040675767,-25.794611,0.27389172,4.9827728 -948551500,0.35690179,49.949947,0.00049450027,-128.30469,0.02355369,-77.928314,0.25058898,0.090265743 -949051000,0.35606924,49.321125,0.00059565296,-161.00929,0.054396987,3.1167269,0.25873893,-0.68089449 -949550500,0.35642126,48.636608,0.0008024454,-130.49696,0.028191248,-27.264057,0.2598711,0.26595983 -950050000,0.35424453,47.574299,0.00050346181,-114.81215,0.025863146,117.67394,0.25849241,2.627079 -950549500,0.3556059,48.600609,0.00089222816,-19.920216,0.035625223,121.82642,0.27186495,1.0566229 -951049000,0.35178599,47.804432,0.00077739719,-28.879898,0.069928482,170.01221,0.28950247,-7.1649537 -951548500,0.34929764,47.175331,0.0013805962,-5.506928,0.038556423,-3.710135,0.26556087,0.14382344 -952048000,0.34787461,47.326012,0.00096297602,-70.991051,0.0081618065,11.30052,0.25563419,-3.7677305 -952547500,0.34942654,46.34692,0.00088325021,138.57961,0.072728291,-35.065311,0.25463715,0.74379086 -953047000,0.34465736,45.73209,0.0010891644,-179.73163,0.088757254,116.94833,0.2560589,-8.3961496 -953546500,0.34758642,45.590954,0.00093437691,59.945778,0.060133658,-179.39857,0.26889813,-5.5733027 -954046000,0.34074748,44.930527,0.0001110235,-121.63728,0.019463869,157.52403,0.26485753,-1.7402132 -954545500,0.34194535,44.822357,0.0016002628,145.43269,0.076680131,-134.16238,0.271671,-4.6536207 -955045000,0.33819062,43.75692,0.0005993924,-156.23373,0.017778458,145.36833,0.25657073,-3.9344685 -955544500,0.34148204,44.113342,0.0011039173,-122.8764,0.013145044,67.643517,0.25364995,-5.594718 -956044000,0.33844364,43.658104,0.0013907877,-125.58695,0.048007317,-178.9382,0.26129472,-2.230171 -956543500,0.33257115,43.141705,0.0017782749,117.42854,0.087377556,-47.764324,0.25941697,-9.1677761 -957043000,0.33071566,42.490887,0.0013203243,-68.048561,0.05180477,-59.541046,0.24306259,-6.6920419 -957542500,0.33216381,42.564785,0.00055283506,-41.703747,0.029233724,-90.054779,0.27776214,-6.9751983 -958042000,0.33132061,41.968487,0.0010357238,-115.05007,0.047789935,-57.821194,0.24953733,-12.660403 -958541500,0.32869008,41.650627,0.00099760643,87.133064,0.015368626,114.97445,0.28524211,-9.518465 -959041000,0.32800004,40.261543,0.0010906715,-107.65758,0.021574685,58.920921,0.26179188,-4.6187787 -959540500,0.32537064,40.205036,0.0016341873,-3.2631338,0.01738975,-99.123161,0.26660055,-14.128264 -960040000,0.32049513,40.182571,0.001070002,-36.435833,0.053791355,-134.89294,0.26168182,-8.2511902 -960539500,0.3237738,40.117569,0.00086577161,160.33427,0.050216191,79.502258,0.26701093,-12.666009 -961039000,0.32378066,39.403278,0.00093479961,162.40547,0.044213694,-84.113106,0.24614373,-10.657074 -961538500,0.32113668,38.505726,0.0010915623,-175.60518,0.078027681,171.713,0.28741884,-12.733604 -962038000,0.31883228,38.473717,0.00079750817,37.245041,0.033848859,-15.571573,0.26472765,-11.791433 -962537500,0.3144975,37.602001,0.00065996969,-59.865917,0.094436511,-82.549767,0.25731415,-9.7032547 -963037000,0.31767991,37.19883,0.0011979328,-23.959814,0.080765732,133.77818,0.27086717,-10.366998 -963536500,0.31260911,36.959484,0.00060179859,149.23267,0.060628366,-67.63533,0.26121223,-11.483668 -964036000,0.31005612,36.615845,0.0013534104,61.85627,0.085779987,-110.90442,0.28774041,-16.872921 -964535500,0.30930918,35.782494,0.0015498903,126.81979,0.041347831,60.658714,0.26361144,-12.274259 -965035000,0.31276202,35.716267,0.00091283821,172.08392,0.022671016,-22.760342,0.27429849,-14.576889 -965534500,0.30660853,34.954575,0.00081866607,138.64079,0.071788535,-49.920815,0.27435422,-14.499177 -966034000,0.30303928,34.686974,0.00059505523,-120.58154,0.14719532,-141.34303,0.26457494,-16.580345 -966533500,0.30450827,33.903404,0.00073020981,-82.684372,0.050124131,-173.29614,0.25506839,-18.259203 -967033000,0.30317706,33.615444,0.00057996629,-140.409,0.084485874,-118.0517,0.28032219,-17.982689 -967532500,0.30411375,32.837975,0.0011790057,-100.7878,0.02899689,-106.60964,0.28123909,-18.783487 -968032000,0.30101246,33.392597,0.00076172431,-139.58685,0.0988473,-49.768707,0.26089686,-23.707432 -968531500,0.29851329,32.542145,0.00059581071,67.061226,0.065301359,-61.102074,0.2536422,-15.257779 -969031000,0.29644725,31.432493,0.00021196627,116.71474,0.11290425,-109.23832,0.27534732,-19.600557 -969530500,0.29896295,31.244768,0.001021646,-13.317749,0.06772662,-78.095016,0.26772577,-17.710361 -970030000,0.29550415,30.868498,0.0011517319,-66.028999,0.096247703,27.653067,0.26415652,-20.159014 -970529500,0.29323786,30.327091,0.0030469135,37.880768,0.015845727,58.08009,0.25114384,-20.43334 -971029000,0.28869858,29.83637,0.0017741396,58.765438,0.072356589,-114.40513,0.26649928,-18.207125 -971528500,0.28979766,29.392538,0.00081382843,-70.763336,0.019952841,169.75461,0.27315316,-22.560646 -972028000,0.28912157,29.306423,0.00087511312,-175.23053,0.030099915,-131.79137,0.24905555,-17.196453 -972527500,0.28794453,27.984856,0.00083023281,55.428799,0.046629824,-62.932327,0.27876788,-19.48398 -973027000,0.28678066,27.329079,0.00079063087,-162.3141,0.018545665,25.318876,0.25929889,-23.250553 -973526500,0.28322154,27.241459,0.0015189374,-143.16527,0.075141482,162.07561,0.26976508,-25.773603 -974026000,0.279778,27.244164,0.00060875446,175.47043,0.013632785,120.97114,0.26156375,-23.228498 -974525500,0.27918792,25.98263,0.0012069487,-124.59464,0.044634011,18.044321,0.28998771,-23.142214 -975025000,0.27890715,25.819508,0.0015481259,-160.27524,0.095070705,-138.95396,0.27787891,-22.465775 -975524500,0.27831039,25.235323,0.00068179215,-145.5984,0.12211592,-108.20656,0.27170169,-22.232454 -976024000,0.2738688,24.756952,0.0010404709,-120.4846,0.057203345,106.87952,0.27222633,-22.176617 -976523500,0.27268732,24.554962,0.00053785549,117.73107,0.059684608,-73.020432,0.2607092,-23.873875 -977023000,0.27333769,24.238766,0.00055097684,-175.52751,0.022670731,77.472862,0.2554712,-26.789532 -977522500,0.27163988,23.108891,0.0012270613,-152.24142,0.016112594,-66.165726,0.26730418,-23.521839 -978022000,0.27217647,22.857794,0.0013411694,79.032005,0.11462296,-135.68335,0.26273489,-25.894966 -978521500,0.26925996,22.593328,0.0012137772,110.65257,0.045028042,118.32697,0.27089432,-29.671564 -979021000,0.26441133,22.230068,0.002650626,-53.528622,0.071044482,172.61696,0.2721976,-29.449888 -979520500,0.26778644,21.102161,0.0014518601,77.963364,0.06231308,-72.243149,0.25926423,-28.085115 -980020000,0.26535344,21.062984,0.00027902593,-166.50221,0.038427319,-60.470509,0.27159673,-26.726219 -980519500,0.26202694,20.773384,0.00030473777,-111.0583,0.083496578,-48.172401,0.25745258,-24.748251 -981019000,0.26101965,19.87067,0.00022327639,54.263107,0.042385384,-91.938347,0.27679175,-29.187475 -981518500,0.25456402,19.381554,0.00096611987,33.515621,0.023284702,-166.688,0.26143447,-26.748875 -982018000,0.25917515,18.613523,0.00084744213,32.652058,0.023006886,-87.801399,0.27244306,-27.687166 -982517500,0.25546712,18.588724,0.00059981679,-53.880367,0.00775233,-30.816713,0.26636514,-29.266098 -983017000,0.25560808,17.879978,0.0010489455,-67.873154,0.03495359,-135.46863,0.26482108,-34.000362 -983516500,0.25116265,17.577671,0.00061527995,-96.257561,0.06083389,-128.87796,0.25852025,-32.118641 -984016000,0.25273752,16.816545,0.00098459667,-116.86703,0.053277433,-158.60733,0.26724827,-30.925406 -984515500,0.2491881,15.602903,0.00090511813,-35.780098,0.031507958,-138.1868,0.25365627,-29.617426 -985015000,0.25016549,15.204425,0.00088990695,-68.462753,0.0094035277,161.73619,0.27558261,-30.998468 -985514500,0.24595958,14.86992,0.00027417147,-85.191681,0.01181055,-96.14286,0.26238778,-33.237675 -986014000,0.24394323,14.497029,0.0014294664,-37.610054,0.14416185,-83.29393,0.26905784,-27.185087 -986513500,0.24607836,13.124209,0.0012073681,-4.5580096,0.030388305,-142.36253,0.25795195,-32.160229 -987013000,0.24817157,13.134916,0.0012770813,-132.14957,0.046402473,-47.980789,0.28774592,-33.776493 -987512500,0.24149096,13.073371,0.00061348872,84.041542,0.026743092,90.359657,0.26093367,-30.34375 -988012000,0.24266894,12.520083,0.0011225708,33.859913,0.022377113,-94.175018,0.28391814,-37.226944 -988511500,0.23860951,11.136173,0.00036135819,128.15881,0.062366713,-150.68044,0.28768417,-30.66802 -989011000,0.23738731,11.927414,0.00039713565,117.91953,0.054350503,-79.292572,0.26653528,-32.417839 -989510500,0.23446633,10.14677,0.00073302572,10.798918,0.069273904,-38.46273,0.27402046,-41.674507 -990010000,0.23587717,9.4306059,0.00034052395,162.14403,0.017045127,-3.5411224,0.27781889,-30.39414 -990509500,0.23245475,9.0421658,0.00095253234,-44.573547,0.058504336,34.021877,0.26483893,-35.143497 -991009000,0.22955929,8.6627235,0.00072847964,76.432785,0.088812344,-61.259457,0.28149238,-38.270798 -991508500,0.23103438,8.2468166,0.00078780437,92.380219,0.054243606,-129.61479,0.27645606,-39.451218 -992008000,0.2282064,7.9801464,0.0013765396,8.9814749,0.032989964,16.084629,0.27579561,-36.751026 -992507500,0.22584382,5.8003125,0.00050647667,11.59365,0.060594011,-97.523087,0.27708617,-40.470226 -993007000,0.22375549,6.6299667,0.00095807982,169.56577,0.14519012,-90.524338,0.25913078,-39.94986 -993506500,0.22088501,5.7968459,0.00035517092,123.38379,0.042090025,-130.24551,0.28608638,-38.335503 -994006000,0.22322632,5.1580443,0.00057854404,52.725224,0.044117473,38.784222,0.29291585,-39.573692 -994505500,0.22370125,3.9917467,0.0013922774,115.84106,0.065123901,-71.745857,0.27490652,-38.425125 -995005000,0.22069712,4.1888213,0.0012526239,7.3495526,0.040141508,150.08714,0.26546505,-41.361797 -995504500,0.21694104,2.6661367,0.0010922595,147.49225,0.11847453,-71.103394,0.26262039,-39.420914 -996004000,0.21524253,2.586164,0.00090151548,-100.66746,0.15047668,-89.946663,0.26927549,-44.39513 -996503500,0.21361074,1.4817642,5.1734631e-005,119.71759,0.082623608,-133.2823,0.28516805,-43.8955 -997003000,0.21243185,2.150722,0.0013949376,-124.04468,0.040011261,-107.11515,0.29166615,-41.513432 -997502500,0.21368277,0.12715475,0.00083265337,-61.538994,0.081548475,-171.2894,0.26128134,-44.425129 -998002000,0.20982304,0.26638258,0.0011736884,-22.585285,0.049146008,29.636246,0.26695433,-43.460152 -998501500,0.21167189,-0.54980969,0.00065299263,47.183773,0.11435036,-72.77153,0.25480455,-41.825668 -999001000,0.2100348,-0.85889405,0.0011117188,-8.2854328,0.057663504,-73.928307,0.29371104,-42.359329 -999500500,0.20962173,-2.0188639,0.0009900853,65.533829,0.113084,-97.634308,0.27406198,-40.071312 -1000000000,0.20922679,-2.1851594,0.00027592323,-122.05688,0.037588976,-105.46671,0.26902422,-42.439438 diff --git a/NuRadioReco/detector/RNO_G/HardwareResponses/surface_placeholder.csv b/NuRadioReco/detector/RNO_G/HardwareResponses/surface_placeholder.csv new file mode 100644 index 000000000..beac75cdd --- /dev/null +++ b/NuRadioReco/detector/RNO_G/HardwareResponses/surface_placeholder.csv @@ -0,0 +1,2002 @@ +Frequency [Hz],Gain,phase [rad] +1000000.0,-0.03858090873551004,-3.7029683013217505 +1499500.0,-0.01988934423570643,-3.451323398796027 +1999000.0,-0.004054949156231696,-3.2016821721105497 +2498500.0,0.00916996058401566,-2.9548629762093683 +2998000.0,0.020025250112358874,-2.711647090300872 +3497500.0,0.028742965602342935,-2.4727787178577865 +3997000.0,0.03554733427373458,-2.2389649866171766 +4496500.0,0.040654764392522275,-2.0108759485804453 +4996000.0,0.044273845270916226,-1.789144580013333 +5495500.0,0.0466053472673484,-1.5743667814459186 +5995000.0,0.047842221786472516,-1.3671013776726202 +6494500.0,0.04816960127916396,-1.1678701177521922 +6994000.0,0.04776479924251999,-0.977157675007728 +7493500.0,0.04679731021985943,-0.7954116470266599 +7993000.0,0.04542880980072313,-0.6230425556607568 +8492500.0,0.04381315462087333,-0.46042384702612704 +8992000.0,0.04209638236229429,-0.3078918915032167 +9491500.0,0.040416711753191864,-0.1657459837368096 +9991000.0,0.03890454256799375,-0.03424834263602872 +10490500.0,0.03768245562734922,0.08637588862566625 +10990000.0,0.036865212798129626,0.19593864261047633 +11489500.0,0.03655975699342763,0.294288927616265 +11989000.0,0.03686521217255799,0.3813128276765556 +12488500.0,0.03787288334105683,0.4569335025605388 +12988000.0,0.039666256550682566,0.5211111877730601 +13487500.0,0.042320998899414874,0.5738431945546325 +13987000.0,0.045904958531455264,0.6151639098814257 +14486500.0,0.05047816463722733,0.6451447964652774 +14986000.0,0.05609282745337596,0.6638943927536816 +15485500.0,0.06279333826276787,0.6715583129297973 +15985000.0,0.07061626939449211,0.6683192469124442 +16484500.0,0.07959037422385849,0.6543969603561037 +16984000.0,0.08973658717239882,0.6300482946509187 +17483500.0,0.10106802370786766,0.5955671669226974 +17983000.0,0.1135899803442402,0.5512845700329057 +18482500.0,0.13168700332389804,0.38448053847187325 +18982000.0,0.14078881068347437,0.2360247906396199 +19481500.0,0.17300016813822205,0.07641351761659018 +19981000.0,0.1916152515882193,-0.04246981469960799 +20480500.0,0.20684807798791216,-0.13236717035705423 +20980000.0,0.23838014140094616,-0.15433235243041313 +21479500.0,0.2615104391101257,-0.24634528880547327 +21979000.0,0.27394182724380484,-0.3656177372500009 +22478500.0,0.293036189007597,-0.5880663717201364 +22978000.0,0.30163438548838073,-0.7705927863048 +23477500.0,0.3424547696456124,-0.8703126070560957 +23977000.0,0.36452618699472444,-0.9255301440510322 +24476500.0,0.396202293523021,-0.9493518053680703 +24976000.0,0.42762422418749546,-0.9892860414681843 +25475500.0,0.4498920933164634,-1.077784716182977 +25975000.0,0.4554847489860676,-1.1181410958881313 +26474500.0,0.47799593832364584,-1.159871974847625 +26974000.0,0.496361845059092,-1.2118067203188376 +27473500.0,0.5095782517248794,-1.2764306841914101 +27973000.0,0.5355831512457153,-1.3343602419993306 +28472500.0,0.564809019322561,-1.4558228268972244 +28972000.0,0.5985776418563097,-1.5093341543923853 +29471500.0,0.6272785210279141,-1.5704469597669757 +29971000.0,0.6524914443633568,-1.6442334995764607 +30470500.0,0.6626821082869951,-1.6992342062908854 +30970000.0,0.6929223222962196,-1.770936823408124 +31469500.0,0.7071388687049159,-1.8485639326880041 +31969000.0,0.7082660367939843,-1.9424084710804843 +32468500.0,0.7258289551683319,-1.9873386754079512 +32968000.0,0.7676652140032677,-2.021485708443338 +33467500.0,0.7998498769471456,-2.0833431966722307 +33967000.0,0.8003985047234489,-2.1437467270532333 +34466500.0,0.7968705298443451,-2.194473236822028 +34966000.0,0.8398944749535743,-2.2384383950487927 +35465500.0,0.8440419560241719,-2.273141567162988 +35965000.0,0.8720576810441893,-2.3100927101183775 +36464500.0,0.945636342921818,-2.3366996004800247 +36964000.0,0.9995703510625326,-2.3693189190326134 +37463500.0,1.0251230404812999,-2.3927848760836463 +37963000.0,1.0489420136747256,-2.4213940624946284 +38462500.0,1.096776082847608,-2.463990542648828 +38962000.0,1.1717695523473273,-2.4963172831769205 +39461500.0,1.2562689944120573,-2.5212041679676895 +39961000.0,1.346814907092915,-2.556520716391965 +40460500.0,1.4804794641114423,-2.6045656393905485 +40960000.0,1.5827835343431134,-2.6371538724081587 +41459500.0,1.7196940566432817,-2.67534518617386 +41959000.0,1.865838320936123,-2.710942951812148 +42458500.0,2.0637932859431194,-2.7585394361144107 +42958000.0,2.26380411153532,-2.8119592109011853 +43457500.0,2.491446511167467,-2.8720572279490115 +43957000.0,2.6909281044331235,-2.9269268572449643 +44456500.0,2.988945154397416,-2.9951262472053943 +44956000.0,3.3258706744927258,-3.06521279117248 +45455500.0,3.6565393276542184,-3.1395256786280203 +45955000.0,4.012767538020684,-3.220739871180423 +46454500.0,4.454021242931656,-3.304259799455562 +46954000.0,5.042360016102483,-3.394112128779241 +47453500.0,5.508576621779305,-3.4839906320251623 +47953000.0,6.029901743881814,-3.5820986251067084 +48452500.0,6.667384490280892,-3.6335143368472917 +48952000.0,7.535428855205621,-3.701482975620699 +49451500.0,8.27500822817475,-3.7924361532681434 +49951000.0,8.978071375412412,-3.865652591566391 +50450500.0,9.727895464338024,-3.956093123097567 +50950000.0,10.61863929118676,-4.036991141253959 +51449500.0,11.54418718051269,-4.083538359792424 +51949000.0,12.544272843745322,-4.171634081388468 +52448500.0,13.770052151643569,-4.269700004636316 +52948000.0,14.958404162855748,-4.340964513754483 +53447500.0,16.21919395845716,-4.4135711311060275 +53947000.0,17.54905141131863,-4.531178304739694 +54446500.0,19.064246847177657,-4.6077141970701 +54946000.0,20.642206316203136,-4.683344812991941 +55445500.0,22.361590495577076,-4.767409804040998 +55945000.0,23.996061349343364,-4.856987253341595 +56444500.0,25.905008961357783,-4.932238165651171 +56944000.0,28.12512000830116,-5.0153919963411795 +57443500.0,30.123170974794498,-5.084536588977324 +57943000.0,32.31442457612586,-5.154516765624801 +58442500.0,34.526659278029456,-5.2112405544426945 +58942000.0,37.0107827720514,-5.296893665805938 +59441500.0,39.77919724788945,-5.372797044975143 +59941000.0,42.295513575967384,-5.452381779238745 +60440500.0,45.13502633353742,-5.540579241204128 +60940000.0,48.15169636623189,-5.621862258545676 +61439500.0,51.38670219289172,-5.699428820654275 +61939000.0,54.354449471006376,-5.775296121007575 +62438500.0,57.689356421172825,-5.848994098911934 +62938000.0,61.422152053706995,-5.921077122570361 +63437500.0,65.22083309663688,-5.997848695236687 +63937000.0,69.33609039940418,-6.073707079887983 +64436500.0,73.59267574267648,-6.145336826682969 +64936000.0,78.13990911604412,-6.216361478602752 +65435500.0,83.10228300660559,-6.288666469596762 +65935000.0,87.40593172067803,-6.360369624420218 +66434500.0,92.84271848882699,-6.434465345929988 +66934000.0,97.98179987327975,-6.502520171483587 +67433500.0,103.75431087522823,-6.575331277378061 +67933000.0,109.77422828562648,-6.6463331054275185 +68432500.0,115.78600819207762,-6.719846097728422 +68932000.0,122.5681074385639,-6.787825358766463 +69431500.0,129.80015071446059,-6.857063536497582 +69931000.0,137.0021308217366,-6.927217978709224 +70430500.0,144.36534350532273,-6.995967399812288 +70930000.0,151.9429503308116,-7.064849898642626 +71429500.0,159.72756495485254,-7.132707336931547 +71929000.0,167.25956637559048,-7.200614388936406 +72428500.0,175.24873249351123,-7.26904368042838 +72928000.0,184.11419823128685,-7.337755345450925 +73427500.0,193.26669058860938,-7.406705672063622 +73927000.0,203.31991833035067,-7.4746869218800365 +74426500.0,212.84089467088577,-7.542704198349783 +74926000.0,222.50441866646617,-7.611582929391717 +75425500.0,232.81639300316849,-7.679683200938578 +75925000.0,242.9661650755837,-7.749450505337593 +76424500.0,253.323767712516,-7.818920029552164 +76924000.0,264.21116694551176,-7.888131799669355 +77423500.0,275.74244713722186,-7.957247704486088 +77923000.0,287.18664977323505,-8.026707005410568 +78422500.0,298.34670243164857,-8.096779810815692 +78922000.0,310.9344294628474,-8.166976507574951 +79421500.0,322.82221266458066,-8.236753809659804 +79921000.0,334.73706631851746,-8.30633732890157 +80420500.0,346.54527951105206,-8.376369465252067 +80920000.0,358.77998600617684,-8.447036435340552 +81419500.0,371.12804991492504,-8.515430821682058 +81919000.0,383.24671770839905,-8.585125363614273 +82418500.0,395.88460396765436,-8.655116376382626 +82918000.0,407.9043273731175,-8.72467031806571 +83417500.0,420.30093720380154,-8.792259063228645 +83917000.0,431.87380550766187,-8.861433395877832 +84416500.0,443.4640196727783,-8.930291846422344 +84916000.0,455.4663695003206,-8.996460871653875 +85415500.0,466.6399882219092,-9.065120488446551 +85915000.0,477.26742016617413,-9.13266899832768 +86414500.0,488.047081005849,-9.199952520475613 +86914000.0,498.3257787009838,-9.26619935614556 +87413500.0,508.6234432325267,-9.332325929908627 +87913000.0,518.1003974947514,-9.397305261367775 +88412500.0,527.4827289711411,-9.463047191584934 +88912000.0,535.5794907478277,-9.527743952115443 +89411500.0,543.9793105485946,-9.59208841419937 +89911000.0,552.9463805985495,-9.65481202172417 +90410500.0,561.2562248107374,-9.71660882436815 +90910000.0,569.1416769350236,-9.777648342952283 +91409500.0,576.1422488268632,-9.838755845616832 +91909000.0,583.0656125042699,-9.89794473157876 +92408500.0,589.7717507770902,-9.957772763385224 +92908000.0,596.7557847998985,-10.017507232414484 +93407500.0,603.2289170299352,-10.075655665510705 +93907000.0,609.3778722914968,-10.133675504483683 +94406500.0,616.2826733327248,-10.190577184934636 +94906000.0,622.7104631114461,-10.247659450774371 +95405500.0,627.4369082957713,-10.302576753355988 +95905000.0,633.1433702840706,-10.35755998899222 +96404500.0,639.2537921287015,-10.411412877449298 +96904000.0,646.0724967340377,-10.464230247148182 +97403500.0,651.3136555340891,-10.515169722250818 +97903000.0,656.0248960422896,-10.566274178921189 +98402500.0,661.2331425150421,-10.616635380980375 +98902000.0,665.4094576533527,-10.664965966721963 +99401500.0,670.104290058992,-10.713411824920597 +99901000.0,673.9959114781349,-10.76140655809968 +100400500.0,678.4904620979696,-10.810162348958931 +100900000.0,683.6262997255271,-10.857617484264381 +101399500.0,687.8969526095885,-10.905620226837783 +101899000.0,692.736867102202,-10.952739828860121 +102398500.0,697.5951662233593,-10.998410482078377 +102898000.0,701.7110107807126,-11.044714997433074 +103397500.0,706.4772599179652,-11.089475126505723 +103897000.0,710.6487274365824,-11.133948850404757 +104396500.0,714.3437808317959,-11.177884725842208 +104896000.0,718.0679176304704,-11.221696182781587 +105395500.0,720.6154146094038,-11.266318600903956 +105895000.0,723.1792679344437,-11.308159886052259 +106394500.0,726.6340140236205,-11.351252137004689 +106894000.0,728.5431009886726,-11.393241018655106 +107393500.0,731.994157697985,-11.436200116127047 +107893000.0,734.8361812531248,-11.478323057115936 +108392500.0,737.4668278098533,-11.51932921185738 +108892000.0,738.8180757302798,-11.560616670380288 +109391500.0,740.5929352171586,-11.60282107173368 +109891000.0,742.0547083507556,-11.643749866047852 +110390500.0,743.1358945173295,-11.68447577435992 +110890000.0,744.7677127251037,-11.721661248970099 +111389500.0,747.2607936701093,-11.759053103000419 +111889000.0,749.414219247749,-11.797448703372638 +112388500.0,751.3208221374908,-11.836624995556798 +112888000.0,753.588791366327,-11.876478268659026 +113387500.0,755.2367567911588,-11.914390959623768 +113887000.0,756.5340454756913,-11.952400666034567 +114386500.0,758.2388976868575,-11.991549878696587 +114886000.0,759.6272573790255,-12.032237129536396 +115385500.0,762.2719788638622,-12.070279547344395 +115885000.0,764.0107430080158,-12.105881947245283 +116384500.0,767.0330276813926,-12.143760906039038 +116884000.0,770.5288509521371,-12.180471554966589 +117383500.0,773.8284332450571,-12.21540082554961 +117883000.0,777.0410754604512,-12.251012414613866 +118382500.0,780.2550208797694,-12.286195947836081 +118882000.0,783.0115313287215,-12.319382598996297 +119381500.0,786.6093091207521,-12.35429224420428 +119881000.0,789.2310593618944,-12.388631667704145 +120380500.0,793.516552528087,-12.420347237302398 +120880000.0,796.8400750312486,-12.454278877802683 +121379500.0,800.9695196862814,-12.486539306282534 +121879000.0,803.577654528505,-12.517769445987215 +122378500.0,806.4708045671819,-12.54981956877694 +122878000.0,808.9608917726205,-12.581673222492821 +123377500.0,811.331942471713,-12.613641273635427 +123877000.0,812.82651857336,-12.644173350722754 +124376500.0,814.5538408566082,-12.67459104872098 +124876000.0,816.359685796666,-12.7055676072685 +125375500.0,818.1334882314283,-12.73669728897435 +125875000.0,819.7333912455181,-12.766633164593252 +126374500.0,821.4055026677942,-12.796380004907135 +126874000.0,822.6894294226671,-12.827833503269655 +127373500.0,825.0418402726548,-12.857638819613976 +127873000.0,825.8507837236708,-12.888496589966993 +128372500.0,827.5831918832058,-12.919103285186495 +128872000.0,830.3122095823034,-12.949789300143772 +129371500.0,831.4057181998883,-12.98179251026522 +129871000.0,833.5614213735914,-13.010945729702566 +130370500.0,837.4834817810283,-13.041162852458095 +130870000.0,840.2094818675581,-13.070727844319414 +131369500.0,842.5010401490381,-13.098959456486726 +131869000.0,842.0748488948619,-13.12611297846197 +132368500.0,843.560548015845,-13.155297191195025 +132868000.0,845.1022106236924,-13.18305421530032 +133367500.0,845.8223609951337,-13.211609345762556 +133867000.0,847.6255710513213,-13.240523558362584 +134366500.0,848.7426009193424,-13.268746853705373 +134866000.0,851.3362454627105,-13.29761906803545 +135365500.0,853.1822753791179,-13.32685972832282 +135865000.0,855.3974930462416,-13.354730583661215 +136364500.0,857.4202591251114,-13.382282394460837 +136864000.0,859.8138225922158,-13.411628840925706 +137363500.0,862.1150666564653,-13.43784340740475 +137863000.0,865.7928398607379,-13.464941029765239 +138362500.0,866.8313958856313,-13.492617988481275 +138862000.0,869.3287543250191,-13.519292575389347 +139361500.0,872.4046028927836,-13.546631316470185 +139861000.0,874.1405658001919,-13.57333714769865 +140360500.0,876.1234514728282,-13.598047801797446 +140860000.0,878.3304365922204,-13.624364263462462 +141359500.0,879.6043087461849,-13.649666797745901 +141859000.0,882.3883342608597,-13.67731414572199 +142358500.0,884.1876279814517,-13.70385812882781 +142858000.0,885.7530188322497,-13.729534362333522 +143357500.0,887.9364932216375,-13.756522700483341 +143857000.0,889.6749642167593,-13.78145983335437 +144356500.0,889.5423270822939,-13.805416283211823 +144856000.0,890.9949561667836,-13.830075020376258 +145355500.0,893.7665263130993,-13.853957824298192 +145855000.0,895.5131247561018,-13.877928684401278 +146354500.0,897.3498926989207,-13.902940921638637 +146854000.0,897.0075215487836,-13.927087412726712 +147353500.0,896.9546101136591,-13.952153243232843 +147853000.0,896.6886627968435,-13.975934929305641 +148352500.0,897.1675148237827,-14.001091530957313 +148852000.0,897.2965367821663,-14.027314005995551 +149351500.0,897.6273408300631,-14.050528213289695 +149851000.0,899.3017994471013,-14.072670978882078 +150350500.0,901.178163853583,-14.09738912403618 +150850000.0,903.2820613358457,-14.121486616469317 +151349500.0,904.0585419821444,-14.144009049263575 +151849000.0,904.81858990511,-14.16875034556991 +152348500.0,905.1308214722923,-14.193479315226183 +152848000.0,906.2529849285373,-14.217582806254697 +153347500.0,906.9924062351962,-14.24080416082114 +153847000.0,909.964490476556,-14.264530027937477 +154346500.0,913.0809748375392,-14.286137270151519 +154846000.0,915.6007028859199,-14.310217157769797 +155345500.0,917.5381364207726,-14.335687390315451 +155845000.0,920.6930389380284,-14.358414438658217 +156344500.0,921.9849210335343,-14.38108894263577 +156844000.0,925.3505709069997,-14.404175841078798 +157343500.0,926.5313461931298,-14.426884914827584 +157843000.0,927.4727548694735,-14.449540741719591 +158342500.0,928.3347570768536,-14.47432687486588 +158842000.0,931.8141286746754,-14.497474783634502 +159341500.0,934.6255004302838,-14.520221023823783 +159841000.0,936.0089654335915,-14.541870481573149 +160340500.0,937.0847537652162,-14.562688728589361 +160840000.0,938.3401735827101,-14.585456155063637 +161339500.0,940.2799184695454,-14.607924712563218 +161839000.0,943.1317131544823,-14.630783707977688 +162338500.0,945.0454875075181,-14.654291682056098 +162838000.0,948.2388426516161,-14.676491258950636 +163337500.0,950.8289572658606,-14.698376791147753 +163837000.0,953.192064354525,-14.721704256868954 +164336500.0,956.172932397943,-14.742445696730009 +164836000.0,958.5833674577715,-14.766241860432658 +165335500.0,958.6563093610955,-14.786393452172497 +165835000.0,958.7585257403914,-14.80814665731878 +166334500.0,958.7461954570699,-14.829126325685893 +166834000.0,961.3437106995603,-14.850179014598991 +167333500.0,962.0671264923408,-14.87065106852743 +167833000.0,963.0819718353565,-14.89182829466141 +168332500.0,963.5936669171733,-14.913120875620217 +168832000.0,962.8245972553107,-14.936475881038415 +169331500.0,963.5860280584876,-14.957821889195843 +169831000.0,963.4427222261039,-14.979519161205047 +170330500.0,963.5991408548983,-15.000427830567027 +170830000.0,964.3081355517858,-15.02095515543732 +171329500.0,964.8419554624575,-15.04236162968174 +171829000.0,963.8270880968228,-15.062875204404612 +172328500.0,963.3624802633037,-15.081954736650506 +172828000.0,961.0903913712447,-15.102990201614958 +173327500.0,963.5863406144223,-15.122822301984298 +173827000.0,963.498822527294,-15.143312916515482 +174326500.0,962.9226390193003,-15.162746939790717 +174826000.0,961.6200339055563,-15.1812130246887 +175325500.0,962.0645770808698,-15.20096437408737 +175825000.0,962.8465428350091,-15.221152663364794 +176324500.0,962.7834975611694,-15.240726471132751 +176824000.0,962.668490546036,-15.26104621220932 +177323500.0,964.0261606202582,-15.280420739201608 +177823000.0,964.6750548279551,-15.30157405359693 +178322500.0,964.5600478205166,-15.320500947754951 +178822000.0,964.3076114170963,-15.340300238646202 +179321500.0,966.0180144342122,-15.360826431316 +179821000.0,969.3171053959841,-15.380763399562515 +180320500.0,969.9032221046905,-15.400508580004457 +180820000.0,970.5304461592671,-15.421420182583413 +181319500.0,971.0237024618368,-15.43854185237687 +181819000.0,972.3738171591884,-15.459253735671105 +182318500.0,973.4202510289988,-15.477660322269653 +182818000.0,975.6638204415098,-15.496301856754291 +183317500.0,976.6724507808628,-15.51622248430239 +183817000.0,977.5963228748333,-15.535108053646049 +184316500.0,977.7275487534055,-15.554813449684596 +184816000.0,976.9257499715475,-15.576808723833956 +185315500.0,977.1582531585918,-15.596410119887075 +185815000.0,977.181566397553,-15.616736751798813 +186314500.0,977.8531525232265,-15.638309041533542 +186814000.0,978.1028937799069,-15.658294784826696 +187313500.0,977.7150734716383,-15.677899431804402 +187813000.0,978.5369087952122,-15.698156554246928 +188312500.0,980.4604158947243,-15.71736959039775 +188812000.0,981.6036416460495,-15.737567195101054 +189311500.0,982.3627663408124,-15.758293766800733 +189811000.0,984.8686709711471,-15.778177933472332 +190310500.0,984.0166095466807,-15.796255218025303 +190810000.0,983.646927202937,-15.815703632218092 +191309500.0,983.8399506543551,-15.834122322426806 +191809000.0,983.6998196914052,-15.852559785279594 +192308500.0,984.1205942900339,-15.87196399598876 +192808000.0,985.7406569200224,-15.892444093453017 +193307500.0,986.5923071285398,-15.910066395153175 +193807000.0,985.7301644253216,-15.928805641501626 +194306500.0,984.9446778904642,-15.947387441497414 +194806000.0,985.3138608601928,-15.965320077748487 +195305500.0,985.0585382917362,-15.982975517214971 +195805000.0,985.0868310710415,-16.001330169985433 +196304500.0,985.5410903737048,-16.019820906164583 +196804000.0,986.4792638505228,-16.038449032769606 +197303500.0,985.6677382405787,-16.057040945566587 +197803000.0,986.3903755100104,-16.07535788522623 +198302500.0,984.9577436147683,-16.09469117221009 +198802000.0,985.8521276359701,-16.11164542195987 +199301500.0,985.3517438603247,-16.128594655890478 +199801000.0,984.0843451224828,-16.147096982319873 +200300500.0,983.9005920776954,-16.166082002385917 +200800000.0,985.2076417061651,-16.182893339440394 +201299500.0,986.8846852205285,-16.20070164988203 +201799000.0,985.8915770418453,-16.21947222168834 +202298500.0,986.6983335592336,-16.237711596849433 +202798000.0,986.5575891387938,-16.256142194539173 +203297500.0,986.7939633649744,-16.275392434771188 +203797000.0,988.1053796337029,-16.291847846671036 +204296500.0,988.2225863398297,-16.309554470222952 +204796000.0,988.2608088362723,-16.32558660593839 +205295500.0,988.9630961056639,-16.342262845971163 +205795000.0,988.2913583286631,-16.36030416952508 +206294500.0,987.051213562097,-16.377988028529177 +206794000.0,987.5421464269734,-16.391119280362854 +207293500.0,986.4908744894839,-16.40989936538537 +207793000.0,988.594044995123,-16.426222330836254 +208292500.0,988.0842746120588,-16.443613479062094 +208792000.0,988.6184441051813,-16.460743829041604 +209291500.0,988.703440718298,-16.4779137230535 +209791000.0,988.7044638889993,-16.49529674039202 +210290500.0,989.2865952779553,-16.512204028521577 +210790000.0,989.4350096010712,-16.528658647435805 +211289500.0,988.2992538188225,-16.545844300593192 +211789000.0,989.688292338494,-16.56140052568386 +212288500.0,990.8605893317817,-16.579913851978997 +212788000.0,991.2475004660447,-16.594829158967812 +213287500.0,993.007083805086,-16.61072838383891 +213787000.0,995.2130385706895,-16.627488040686195 +214286500.0,999.5397412271637,-16.64433219473827 +214786000.0,1001.7256191562926,-16.659591603187696 +215285500.0,1001.9795978371158,-16.67540199934952 +215785000.0,1004.5795924438614,-16.688131450096968 +216284500.0,1006.5234329012341,-16.705064183308753 +216784000.0,1007.6210683706388,-16.719203253081833 +217283500.0,1007.5534191962845,-16.73517347388293 +217783000.0,1005.6883432938289,-16.751106072751746 +218282500.0,1004.6391509316263,-16.76572677129065 +218782000.0,1004.4703825557636,-16.780795610051864 +219281500.0,1004.0731097672301,-16.79734493960988 +219781000.0,1004.6810746233973,-16.813918002644826 +220280500.0,1002.9553765353913,-16.830165180902846 +220780000.0,1001.6281692193581,-16.847799831795452 +221279500.0,1000.3615164287647,-16.863474271952683 +221779000.0,1001.3946000059993,-16.879514539600656 +222278500.0,1001.3557303425223,-16.895762398079864 +222778000.0,1001.148590190226,-16.910886792860136 +223277500.0,1000.9532077958975,-16.927816599119705 +223777000.0,1001.0151117296795,-16.944158597025833 +224276500.0,999.3348560497147,-16.959761954543637 +224776000.0,996.3583463874884,-16.974831100440998 +225275500.0,996.2820636326991,-16.98950226787782 +225775000.0,998.4386934921013,-17.004894695978624 +226274500.0,1000.193986424677,-17.021094440260637 +226774000.0,1000.980284756277,-17.038792340064195 +227273500.0,1001.2804812893683,-17.055473627307087 +227773000.0,1000.0548854581539,-17.071963032223675 +228272500.0,999.867648088269,-17.089024197845028 +228772000.0,999.9974250848882,-17.104036303698713 +229271500.0,1000.5993963906986,-17.11960368408189 +229771000.0,999.766422266242,-17.135580894600622 +230270500.0,1001.0577608235365,-17.15253943598492 +230770000.0,1001.7424462488518,-17.168636149456127 +231269500.0,1002.1801098250182,-17.184945807106057 +231769000.0,1001.96923905662,-17.200094270180536 +232268500.0,1004.6555551076157,-17.21438489310137 +232768000.0,1003.0986007738521,-17.229771698503804 +233267500.0,1005.8652671908403,-17.245546111594777 +233767000.0,1006.7944921653162,-17.261077542171208 +234266500.0,1008.5128015570233,-17.277965317642366 +234766000.0,1008.626742585558,-17.293653958708404 +235265500.0,1010.6576626215989,-17.310457801743965 +235765000.0,1012.3464388663131,-17.32755442405485 +236264500.0,1013.0926955258884,-17.34408592597265 +236764000.0,1015.5764118867843,-17.359378303102503 +237263500.0,1015.9527446994459,-17.376726745580513 +237763000.0,1016.7403815247491,-17.39482733866388 +238262500.0,1016.4889538150014,-17.409548470936603 +238762000.0,1015.8906574227437,-17.424559103112955 +239261500.0,1017.3790574742319,-17.437964844052985 +239761000.0,1017.2544727885918,-17.45230509453904 +240260500.0,1017.696160673766,-17.465248463558993 +240760000.0,1019.2277155988007,-17.478832677812765 +241259500.0,1019.725167287677,-17.491711173520176 +241759000.0,1019.1407872774554,-17.50814875319322 +242258500.0,1020.2278651935914,-17.523007804358507 +242758000.0,1020.4350931223271,-17.538266136892815 +243257500.0,1019.5789017091772,-17.552862927309754 +243757000.0,1019.5609457069609,-17.5686238625078 +244256500.0,1018.4330340919707,-17.58424128371136 +244756000.0,1017.8097824593174,-17.598127926711413 +245255500.0,1015.5329418126444,-17.612623390451 +245755000.0,1014.0908305900765,-17.626135263400904 +246254500.0,1014.6659768266925,-17.64032081818553 +246754000.0,1014.5456424893931,-17.655387095833753 +247253500.0,1014.6863678092527,-17.668266614611632 +247753000.0,1016.1171331551528,-17.683495236796322 +248252500.0,1017.6648085476932,-17.699909698834077 +248752000.0,1019.0041947002215,-17.71471161156587 +249251500.0,1018.7907952116726,-17.730326800541814 +249751000.0,1018.8181775165558,-17.745763231266086 +250250500.0,1020.9878370877718,-17.75995490200823 +250750000.0,1021.0603080744473,-17.77453572496964 +251249500.0,1020.6181381827761,-17.79016373237948 +251749000.0,1020.0889679411154,-17.804728300621395 +252248500.0,1019.5430636015619,-17.82020834563621 +252748000.0,1020.1017937414058,-17.835518585514812 +253247500.0,1018.9235375166544,-17.851596363391632 +253747000.0,1017.4170149542831,-17.86682870869086 +254246500.0,1018.4955603442685,-17.883427006838282 +254746000.0,1017.7119458316262,-17.89956950376894 +255245500.0,1018.7467102871356,-17.914233476953502 +255745000.0,1020.136398603385,-17.928442934165243 +256244500.0,1022.944689832595,-17.942590975691292 +256744000.0,1020.4419218000838,-17.956423938534613 +257243500.0,1020.715416279674,-17.971657467674383 +257743000.0,1021.3831625498691,-17.985677055647947 +258242500.0,1021.3942279767443,-17.99954133663462 +258742000.0,1021.2037074964541,-18.012825742353808 +259241500.0,1022.1150998115946,-18.026630144554442 +259741000.0,1023.8987345754527,-18.041310954434426 +260240500.0,1025.910498485952,-18.05679582353448 +260740000.0,1024.4842910016055,-18.072978543837394 +261239500.0,1024.491008750006,-18.088536108929674 +261739000.0,1023.0199040503194,-18.103915486756613 +262238500.0,1022.547067347447,-18.11853796835644 +262738000.0,1024.0517430813786,-18.133986929465358 +263237500.0,1022.9057354210919,-18.14811929197526 +263737000.0,1022.9820309002373,-18.16393871537885 +264236500.0,1022.4747401509559,-18.177649786894268 +264736000.0,1023.1049120211624,-18.191995657147668 +265235500.0,1022.3243778763435,-18.206123693698977 +265735000.0,1023.6825890405175,-18.21976284358655 +266234500.0,1023.9058451795471,-18.23208408730748 +266734000.0,1023.6193178785397,-18.246268358840204 +267233500.0,1023.1640028947411,-18.26082595272651 +267733000.0,1024.8583117866408,-18.274248322052294 +268232500.0,1023.8878142607051,-18.28653015966011 +268732000.0,1024.3057478639926,-18.302196359053234 +269231500.0,1023.3143466189405,-18.31784220497227 +269731000.0,1023.0970136968357,-18.3322153352443 +270230500.0,1022.2120316333351,-18.34710227224754 +270730000.0,1021.3813585860385,-18.36081352904966 +271229500.0,1021.1144455466332,-18.375238897684948 +271729000.0,1018.4787975779765,-18.389402389087962 +272228500.0,1018.2290103090625,-18.403701390635238 +272728000.0,1018.385079835329,-18.41476899341303 +273227500.0,1018.1627325405552,-18.42752078812992 +273727000.0,1019.3510903403782,-18.43829076879044 +274226500.0,1018.37414911921,-18.450883239421824 +274726000.0,1020.4809625040159,-18.46329470668901 +275225500.0,1021.8353761392439,-18.477938505562054 +275725000.0,1020.4903496805433,-18.49100264830127 +276224500.0,1021.0420669275819,-18.503020754183208 +276724000.0,1022.3780553855515,-18.51550612551225 +277223500.0,1024.071970227987,-18.528604816543663 +277723000.0,1024.2947353350264,-18.542151978489528 +278222500.0,1024.2746378975578,-18.555983150723716 +278722000.0,1023.6022014536326,-18.56719672372752 +279221500.0,1022.2980497585199,-18.580332389310442 +279721000.0,1022.9288184694065,-18.593459711165565 +280220500.0,1022.7358894876651,-18.60628898812967 +280720000.0,1023.1802086400364,-18.619237898032512 +281219500.0,1022.5186057799625,-18.634008445749217 +281719000.0,1021.4043543577025,-18.647213749594986 +282218500.0,1020.8123438412513,-18.66256712769906 +282718000.0,1020.8220668345917,-18.678042591531973 +283217500.0,1020.4335068110358,-18.69397722941444 +283717000.0,1020.6110676586883,-18.708917850192762 +284216500.0,1021.034303787413,-18.722253096628478 +284716000.0,1021.8178610846735,-18.73730067297059 +285215500.0,1021.3654888583577,-18.75205661493889 +285715000.0,1021.7565623900132,-18.767859144796443 +286214500.0,1021.5258234419564,-18.78204705542471 +286714000.0,1021.4562292380516,-18.797389430381635 +287213500.0,1023.0379639172359,-18.811384798116183 +287713000.0,1022.5827764036843,-18.82696788649502 +288212500.0,1023.9307044108,-18.84269517577971 +288712000.0,1025.0465431589344,-18.85912274924731 +289211500.0,1025.5827450457398,-18.87381527439682 +289711000.0,1028.010149007374,-18.887472773683015 +290210500.0,1029.9743249802848,-18.902275178427608 +290710000.0,1031.8305750228722,-18.914654831754028 +291209500.0,1031.5165272597494,-18.92934348347248 +291709000.0,1031.5429920426786,-18.944339260021547 +292208500.0,1032.3429402186193,-18.95829861171261 +292708000.0,1032.3513351558147,-18.97192034528185 +293207500.0,1032.7243717093097,-18.98597438617451 +293707000.0,1031.9513278028712,-19.0006668242299 +294206500.0,1032.1053912037605,-19.015725510622534 +294706000.0,1031.9406347823003,-19.030998281825934 +295205500.0,1031.1500435902324,-19.045726982271844 +295705000.0,1032.58887858486,-19.05895457891488 +296204500.0,1031.4474058664082,-19.07275146840548 +296704000.0,1031.413016701288,-19.084791229090442 +297203500.0,1030.2870879602108,-19.098259708137768 +297703000.0,1028.1848565832775,-19.111469303776566 +298202500.0,1028.165621157109,-19.1249018802083 +298702000.0,1028.4312907750564,-19.13749220918801 +299201500.0,1027.365457644954,-19.151290145060663 +299701000.0,1027.46774533536,-19.164204402060264 +300200500.0,1028.2658729878174,-19.17672152952075 +300700000.0,1028.3045060882607,-19.190740443632823 +301199500.0,1027.7792253694226,-19.204896487149174 +301699000.0,1028.735733948706,-19.217743031987933 +302198500.0,1028.1918584281175,-19.23156732799647 +302698000.0,1025.8758128388095,-19.246197280478203 +303197500.0,1025.9070086251945,-19.2600271366149 +303697000.0,1024.0838153827794,-19.272609915365475 +304196500.0,1023.3182919104402,-19.287205782604644 +304696000.0,1022.1072828558075,-19.301511010081168 +305195500.0,1022.4076996818837,-19.315184422581865 +305695000.0,1021.9621249498306,-19.3300485459173 +306194500.0,1020.3694747055821,-19.342913483192227 +306694000.0,1020.0972309477223,-19.355692258976173 +307193500.0,1019.1794434989806,-19.36946161381637 +307693000.0,1018.6680954003757,-19.383363340613595 +308192500.0,1020.0428556921215,-19.39662523248562 +308692000.0,1020.7369255716576,-19.410940883189557 +309191500.0,1020.3698599367407,-19.423025251974018 +309691000.0,1019.8668421681332,-19.437119211627515 +310190500.0,1020.3610573733775,-19.44875284299555 +310690000.0,1022.2363745669935,-19.46124810747312 +311189500.0,1020.9026872791212,-19.473309415271792 +311689000.0,1021.6327304973117,-19.48676486858015 +312188500.0,1021.2294077067047,-19.499171052698287 +312688000.0,1021.6984478493823,-19.5118328487688 +313187500.0,1024.6627128525738,-19.523798408029553 +313687000.0,1025.2123659774506,-19.538478306170347 +314186500.0,1027.075149408556,-19.549528019763926 +314686000.0,1025.9962153051667,-19.563143230125156 +315185500.0,1024.815575629323,-19.574465187081177 +315685000.0,1021.5929348869026,-19.58823435909874 +316184500.0,1019.7274931296323,-19.59932448355254 +316684000.0,1018.7626761612045,-19.61339795401067 +317183500.0,1018.1866516019826,-19.626816008613776 +317683000.0,1016.8306797172115,-19.640662610774886 +318182500.0,1014.161704309167,-19.651567998867808 +318682000.0,1013.7037219002498,-19.664643417493135 +319181500.0,1013.1784270099723,-19.677751539602067 +319681000.0,1010.4844217403174,-19.68986376555605 +320180500.0,1010.0805826127347,-19.70368163683597 +320680000.0,1009.6558920959035,-19.716082998833812 +321179500.0,1009.1609015243115,-19.727699959608923 +321679000.0,1009.0764881517132,-19.740735660753543 +322178500.0,1009.3416190270992,-19.753446256629786 +322678000.0,1008.3635435109428,-19.765789465329025 +323177500.0,1008.9082525036871,-19.778132466627465 +323677000.0,1009.7990724418455,-19.791286998011753 +324176500.0,1010.3511199462882,-19.802513956946886 +324676000.0,1010.7108992817363,-19.814675390901552 +325175500.0,1011.8036275696361,-19.82838519310699 +325675000.0,1011.8577969899285,-19.842414087414294 +326174500.0,1011.7956615015408,-19.85461661818136 +326674000.0,1014.036379358763,-19.8669719313199 +327173500.0,1014.8932271301417,-19.88030558279585 +327673000.0,1016.5851268365831,-19.89262918025328 +328172500.0,1018.209294318044,-19.906805658729713 +328672000.0,1019.7494962101541,-19.920034413142833 +329171500.0,1020.9161614116907,-19.932255782195643 +329671000.0,1022.339656663161,-19.942904443571173 +330170500.0,1024.6516849327427,-19.956233703738388 +330670000.0,1023.8860122636177,-19.97002112259918 +331169500.0,1023.9868901397833,-19.982316859885046 +331669000.0,1023.4763939021367,-19.995464385724688 +332168500.0,1024.6629221516846,-20.008480719112526 +332668000.0,1024.7730193032528,-20.021673567021853 +333167500.0,1027.391642730227,-20.03413176532217 +333667000.0,1024.5838741714183,-20.045874437351827 +334166500.0,1024.8105507219525,-20.057858831241926 +334666000.0,1024.5176468327886,-20.07179855774567 +335165500.0,1025.2715517774973,-20.084720584914113 +335665000.0,1023.8539889810774,-20.0968215489892 +336164500.0,1024.2067416355067,-20.109286195184307 +336664000.0,1022.9715292879403,-20.1238797893952 +337163500.0,1021.8775670596103,-20.135769604304343 +337663000.0,1021.7579855971455,-20.14722714363887 +338162500.0,1022.82444975983,-20.16152777798354 +338662000.0,1021.9779745825571,-20.174285865908438 +339161500.0,1022.0067924194105,-20.18652118967587 +339661000.0,1022.6296309776924,-20.198675566213577 +340160500.0,1021.4509777549979,-20.21138237294082 +340660000.0,1021.0396453521302,-20.22251344749459 +341159500.0,1020.034237268359,-20.23514891059126 +341659000.0,1020.1032663864971,-20.249880895105242 +342158500.0,1020.3998828389299,-20.26214220751086 +342658000.0,1020.6644789065602,-20.27566858917287 +343157500.0,1018.9543613955142,-20.288716923664797 +343657000.0,1016.760758177705,-20.301693005392355 +344156500.0,1016.0736297233562,-20.31573043142133 +344656000.0,1015.2329872808704,-20.328276615152415 +345155500.0,1015.1521396992215,-20.34080127296147 +345655000.0,1014.6587636621847,-20.353419744620325 +346154500.0,1016.1129448433217,-20.369066141742778 +346654000.0,1016.8793229871037,-20.383041820026744 +347153500.0,1018.3414952953635,-20.39648184380998 +347653000.0,1019.0483086150525,-20.409524218820437 +348152500.0,1018.8903913750712,-20.425484295639578 +348652000.0,1020.6909897960772,-20.438710573617804 +349151500.0,1020.1384939820466,-20.452932189435696 +349651000.0,1020.3032749016369,-20.465586626590873 +350150500.0,1021.2735365803431,-20.47814660723985 +350650000.0,1020.8813107514751,-20.490573317734164 +351149500.0,1020.0463885667452,-20.50511243821823 +351649000.0,1021.6830221478709,-20.519398110546728 +352148500.0,1020.7336315731092,-20.53233103764263 +352648000.0,1021.0693506900421,-20.54480506535448 +353147500.0,1021.7599063342007,-20.558061576194017 +353647000.0,1021.9653566240492,-20.569379134664608 +354146500.0,1020.6475087070993,-20.581899569841998 +354646000.0,1022.0355444572987,-20.59489023025765 +355145500.0,1021.3575949989162,-20.607986674527186 +355645000.0,1020.671822068477,-20.61943803998543 +356144500.0,1021.3424745571184,-20.632260871013475 +356644000.0,1021.9602801972244,-20.644287067188287 +357143500.0,1019.6938468955503,-20.659650973417186 +357643000.0,1018.2192719234312,-20.673797732381516 +358142500.0,1017.605307879106,-20.68805145573897 +358642000.0,1016.8198380136595,-20.699598710073683 +359141500.0,1016.4028871863796,-20.712594320174436 +359641000.0,1017.1602964622548,-20.726247186754524 +360140500.0,1017.1325409723469,-20.737586210773756 +360640000.0,1018.0928074368506,-20.74877707973898 +361139500.0,1018.9254724422316,-20.761113646954506 +361639000.0,1020.0039892778384,-20.774081046835423 +362138500.0,1019.7740343190749,-20.78435380935331 +362638000.0,1020.3983648010717,-20.79760969617997 +363137500.0,1021.0569827691265,-20.8093753097748 +363637000.0,1023.5308774766091,-20.8216631282366 +364136500.0,1025.4381094168957,-20.83559834611765 +364636000.0,1025.9143930924185,-20.849778593326413 +365135500.0,1025.1663146223282,-20.864584327297973 +365635000.0,1028.0585242991192,-20.87657184637229 +366134500.0,1029.9585251908406,-20.889047461860788 +366634000.0,1031.3154033013016,-20.903390365678334 +367133500.0,1030.9948060942643,-20.91710909762862 +367633000.0,1032.6676085669571,-20.929541151639008 +368132500.0,1029.708192979304,-20.94210981478251 +368632000.0,1029.4990767317865,-20.95612387641331 +369131500.0,1029.026145841829,-20.969619780843786 +369631000.0,1028.7869548475137,-20.981329322229964 +370130500.0,1029.3603682988005,-20.99477397100832 +370630000.0,1029.4407297549278,-21.0092530345037 +371129500.0,1029.6468153593169,-21.02412974358036 +371629000.0,1030.005879330481,-21.036482796583336 +372128500.0,1029.575086750183,-21.05029330071166 +372628000.0,1032.1766451966676,-21.064185716562882 +373127500.0,1030.9791723536266,-21.077892806845718 +373627000.0,1032.2259886594284,-21.091931541693413 +374126500.0,1032.824306490697,-21.104327342072075 +374626000.0,1031.1795290576358,-21.119095495874028 +375125500.0,1028.4659338639362,-21.134508497105045 +375625000.0,1026.5547095388154,-21.148888035573194 +376124500.0,1025.4303294208053,-21.161598254365597 +376624000.0,1024.8350528217964,-21.173812237058595 +377123500.0,1023.3298412485433,-21.1866838918963 +377623000.0,1021.6068610465587,-21.197955331365 +378122500.0,1020.8022013054439,-21.20906503251851 +378622000.0,1019.4182039894523,-21.220173375885675 +379121500.0,1018.4979191027271,-21.232032519366975 +379621000.0,1018.5671219964927,-21.244379442116376 +380120500.0,1017.8753812480132,-21.25815395663763 +380620000.0,1017.3837986719877,-21.27158359676337 +381119500.0,1015.8571289067012,-21.282669959037612 +381619000.0,1014.5376227775475,-21.294248253496534 +382118500.0,1014.048835540266,-21.30823875694642 +382618000.0,1015.6952107322627,-21.32301918646985 +383117500.0,1017.5225662799379,-21.335146115459114 +383617000.0,1016.7952179874328,-21.349078529373738 +384116500.0,1017.0314668049493,-21.361267192866947 +384616000.0,1015.4872313579275,-21.3732089637298 +385115500.0,1013.8525734729832,-21.38779471645259 +385615000.0,1013.8793966188149,-21.39992447216542 +386114500.0,1015.0822964619398,-21.412629231619643 +386614000.0,1015.1431372221883,-21.423796444341516 +387113500.0,1015.732644036099,-21.43798051757768 +387613000.0,1015.4343422200875,-21.448872648125622 +388112500.0,1015.3858731634324,-21.460042237922462 +388612000.0,1013.2762389669465,-21.473173334457268 +389111500.0,1014.6031649637594,-21.485165134470712 +389611000.0,1013.1589605674062,-21.49804784367965 +390110500.0,1011.6652085611641,-21.509099404937267 +390610000.0,1012.1593152980174,-21.52216695158706 +391109500.0,1012.2169797363199,-21.535738272415188 +391609000.0,1010.9416232780545,-21.549873539639236 +392108500.0,1010.5598835286747,-21.561679732307496 +392608000.0,1011.7372958340513,-21.573897369706543 +393107500.0,1009.2008403002659,-21.585849485909925 +393607000.0,1008.5560555048991,-21.598166816752748 +394106500.0,1008.3373414156457,-21.611462368539506 +394606000.0,1007.3151703213439,-21.62222475037076 +395105500.0,1006.9923320759528,-21.63438405005291 +395605000.0,1006.0891386860667,-21.64652187442222 +396104500.0,1005.4923321121934,-21.6591795419941 +396604000.0,1005.5064609288493,-21.671728668206057 +397103500.0,1006.370371226464,-21.68457040877226 +397603000.0,1004.6682585227942,-21.698701920297783 +398102500.0,1003.9156566871737,-21.712801591862192 +398602000.0,1003.095596229068,-21.72783721570988 +399101500.0,1001.7490225005058,-21.740548653823957 +399601000.0,1002.8657421792835,-21.755146873284698 +400100500.0,1003.5329606049331,-21.769173127426292 +400600000.0,1003.7583702768089,-21.78357516670868 +401099500.0,1002.0089089065541,-21.797231742387353 +401599000.0,1001.9601164096853,-21.810728988808904 +402098500.0,1002.1304348518365,-21.824756553777743 +402598000.0,999.8551701698299,-21.837384859640043 +403097500.0,1000.2712681621564,-21.849346286064026 +403597000.0,1000.7431652296065,-21.861565179673804 +404096500.0,1000.1513834535189,-21.874492235101005 +404596000.0,1002.31986469177,-21.888127526491633 +405095500.0,1000.1968701821723,-21.89984575707965 +405595000.0,1001.0197783636369,-21.911487399078066 +406094500.0,1001.0539614895188,-21.924241126738096 +406594000.0,1000.9100821344812,-21.93658296686987 +407093500.0,1003.807215975491,-21.949278259081122 +407593000.0,1002.040287081833,-21.96238647778929 +408092500.0,1002.2157841299887,-21.97447898476555 +408592000.0,1000.9575559473458,-21.987666858233144 +409091500.0,997.2964570938046,-22.002103567018747 +409591000.0,996.441348209348,-22.01577458360879 +410090500.0,997.4253149381275,-22.027274595975946 +410590000.0,995.6582703980272,-22.039341440170716 +411089500.0,994.4128408760745,-22.051775133646096 +411589000.0,993.5833551417559,-22.062987435561798 +412088500.0,993.141458575076,-22.07321211603774 +412588000.0,991.5610335123193,-22.086972563249997 +413087500.0,988.5325302001881,-22.099669440642447 +413587000.0,987.3217445749667,-22.112741157574956 +414086500.0,987.2743291592171,-22.12582033996351 +414586000.0,987.0627765127307,-22.13876276909608 +415085500.0,986.2859417781615,-22.149795601198022 +415585000.0,983.2679138344535,-22.16136009310614 +416084500.0,983.8488911881793,-22.172394326289176 +416584000.0,983.6468271313179,-22.185721372467306 +417083500.0,984.382487020194,-22.1973822687544 +417583000.0,984.0136880836128,-22.20957739877715 +418082500.0,982.9384376028304,-22.221645173527033 +418582000.0,981.5886764429092,-22.232851935292917 +419081500.0,981.5778315838808,-22.24606251434766 +419581000.0,980.7330495686797,-22.259003353876444 +420080500.0,980.5548958083918,-22.271682326102507 +420580000.0,979.5808729261967,-22.28470547386226 +421079500.0,978.5009752621293,-22.297385277587313 +421579000.0,978.7874280147844,-22.309241417776786 +422078500.0,978.1871980178912,-22.319031247200385 +422578000.0,977.6411881968071,-22.33147172800834 +423077500.0,977.8299857716669,-22.342960944704004 +423577000.0,979.6463290680744,-22.355402138190307 +424076500.0,979.4257799636612,-22.36735340445404 +424576000.0,980.2657383686059,-22.37948147030375 +425075500.0,981.6685966390276,-22.392301486300592 +425575000.0,983.1449563819571,-22.404425188417026 +426074500.0,983.6552774600677,-22.417711419194447 +426574000.0,982.910899119894,-22.43135946999088 +427073500.0,982.8156181648512,-22.445119404559097 +427573000.0,982.4495774012189,-22.458164997698656 +428072500.0,984.0107184265386,-22.469888601272885 +428572000.0,984.2347516166825,-22.482813324822477 +429071500.0,984.5438816141632,-22.495418488586093 +429571000.0,984.5617576712701,-22.508561269371906 +430070500.0,984.8785183016637,-22.521203071960773 +430570000.0,986.2690226523168,-22.53450105533067 +431069500.0,986.5386840425814,-22.547058025887306 +431569000.0,985.1224679556155,-22.560311346731883 +432068500.0,985.8420003976436,-22.574946207030422 +432568000.0,986.8402575199935,-22.588696270670127 +433067500.0,986.4687492412417,-22.60198727578549 +433567000.0,986.9688329691788,-22.614975200026095 +434066500.0,987.5683493075368,-22.62967416860684 +434566000.0,985.7710977857005,-22.6443431083547 +435065500.0,987.6676701087703,-22.65688196167378 +435565000.0,987.2124375164583,-22.670099602549723 +436064500.0,986.904046721603,-22.68438706297574 +436564000.0,986.8239150367283,-22.699207361996695 +437063500.0,987.0730203091437,-22.71224190619306 +437563000.0,988.0335918053387,-22.726944142188877 +438062500.0,987.1149824023736,-22.74131653119241 +438562000.0,986.881828928755,-22.75540483536372 +439061500.0,986.5388055301075,-22.76811836800195 +439561000.0,985.2620810554905,-22.779558086715575 +440060500.0,985.5745405360652,-22.794377772194547 +440560000.0,984.8886832535715,-22.806942236455264 +441059500.0,984.2390288071922,-22.819372602259865 +441559000.0,983.8911155991749,-22.83150551323649 +442058500.0,983.2776601920833,-22.842846149145416 +442558000.0,983.2955095940117,-22.85498935742477 +443057500.0,982.197571311655,-22.86557611164568 +443557000.0,981.1334036461864,-22.87906679359207 +444056500.0,979.8326467401088,-22.891786878380874 +444556000.0,978.2453095834614,-22.90290613881466 +445055500.0,976.7709123332974,-22.91460608114681 +445555000.0,977.7264749667778,-22.926203953988765 +446054500.0,977.1175584613097,-22.936260394431322 +446554000.0,974.2754204803306,-22.948782629580506 +447053500.0,975.1017867876501,-22.962146934732786 +447553000.0,973.1999949447086,-22.97445771910013 +448052500.0,972.1886371405241,-22.989040084811045 +448552000.0,972.337504671614,-23.002280552025866 +449051500.0,970.5333987653034,-23.015860211616037 +449551000.0,969.431906777825,-23.027984889718805 +450050500.0,968.3410529677993,-23.04090992397991 +450550000.0,968.6705631508942,-23.05443705841612 +451049500.0,967.0806152480559,-23.069210768320797 +451549000.0,967.9104092984179,-23.08198600700501 +452048500.0,966.9292105085472,-23.096426577831284 +452548000.0,966.8016397413627,-23.110256330138522 +453047500.0,964.3819967579865,-23.126761770937268 +453547000.0,963.8749112006716,-23.140599552913436 +454046500.0,962.2156375390388,-23.153206970681588 +454546000.0,962.0066351454354,-23.1673651838629 +455045500.0,960.6979017211889,-23.17972249282093 +455545000.0,961.2960706791814,-23.192297141613174 +456044500.0,963.7427050741861,-23.205095291851812 +456544000.0,962.6923848588372,-23.217764548353998 +457043500.0,962.7544565776583,-23.230580714101553 +457543000.0,962.7446141100784,-23.244053222287626 +458042500.0,962.9777508639271,-23.257814431200792 +458542000.0,962.5729275512372,-23.26923619067161 +459041500.0,961.5441984361745,-23.28144056784266 +459541000.0,960.9938900929969,-23.294168870751786 +460040500.0,961.5172612540506,-23.30642437427071 +460540000.0,961.7023833964698,-23.320062909496972 +461039500.0,959.9340552133152,-23.332755742194802 +461539000.0,959.298978093174,-23.34443823400808 +462038500.0,957.7651139104008,-23.356377661558447 +462538000.0,956.1974446600442,-23.369679173861975 +463037500.0,954.7307375417911,-23.382238895060453 +463537000.0,953.8277081302971,-23.39454904212839 +464036500.0,951.6912097478313,-23.4076678949599 +464536000.0,951.8621446607548,-23.419628744159326 +465035500.0,950.680899441269,-23.430635386898757 +465535000.0,949.8894367883665,-23.44196550115043 +466034500.0,950.8503458111742,-23.454800242134496 +466534000.0,951.0883707124599,-23.46702802136631 +467033500.0,948.7509913695595,-23.478926319965108 +467533000.0,948.5709979121832,-23.490487194957545 +468032500.0,948.738323610704,-23.502592532135264 +468532000.0,947.8532305748606,-23.514220148369265 +469031500.0,947.1135211599178,-23.525892256754 +469531000.0,947.4131059916705,-23.536391582941228 +470030500.0,945.8507780425675,-23.548665843954197 +470530000.0,945.0226987834592,-23.562712682139473 +471029500.0,945.5173550513408,-23.577451519514653 +471529000.0,944.5518055996736,-23.590437318134054 +472028500.0,945.246679646159,-23.60473237153353 +472528000.0,947.5868535131185,-23.619209405436248 +473027500.0,946.9107537597222,-23.63386268038808 +473527000.0,946.3475910441799,-23.648847870421903 +474026500.0,947.2283742756574,-23.66343709944004 +474526000.0,948.3118074801047,-23.678435818525028 +475025500.0,949.6112224625466,-23.69056261794206 +475525000.0,949.8866629425943,-23.705795363934953 +476024500.0,949.1655043089264,-23.718741388427418 +476524000.0,949.6259397667991,-23.732906511761723 +477023500.0,948.980190604412,-23.747316251585097 +477523000.0,947.8792554183259,-23.760034088134127 +478022500.0,947.1264125166707,-23.776815668286666 +478522000.0,947.6131367353763,-23.791269395592685 +479021500.0,948.9941193112879,-23.804577401106407 +479521000.0,950.6820103555922,-23.81994869881592 +480020500.0,952.6683990697526,-23.834497305351572 +480520000.0,952.1316836477678,-23.84816429203171 +481019500.0,952.2578564214739,-23.86270889531015 +481519000.0,954.6095498376883,-23.87610637055805 +482018500.0,952.1585094107637,-23.890087878224058 +482518000.0,951.8296680807852,-23.90502472898539 +483017500.0,952.370819205167,-23.91862832551057 +483517000.0,951.6117983998512,-23.933302690875216 +484016500.0,950.4670081535443,-23.94624117030991 +484516000.0,949.8692701396368,-23.96082427377368 +485015500.0,948.021725521429,-23.975153019618563 +485515000.0,947.1870730474217,-23.988635861577926 +486014500.0,946.6902363863854,-24.001373249601855 +486514000.0,945.711331839576,-24.01389045247633 +487013500.0,945.4554380966198,-24.026866977218273 +487513000.0,942.2549160945742,-24.03894543352459 +488012500.0,940.13648121343,-24.050506902678233 +488512000.0,938.2095928415571,-24.062728617543396 +489011500.0,936.711247934842,-24.07564631420516 +489511000.0,936.0943449187189,-24.087045215381494 +490010500.0,936.0336901724907,-24.100377066809692 +490510000.0,933.0056746796863,-24.11231534451311 +491009500.0,929.0094853570694,-24.125606235154322 +491509000.0,928.6084139377731,-24.14023935904687 +492008500.0,927.0580833031029,-24.15326422364363 +492508000.0,926.2268687547993,-24.166146515990537 +493007500.0,925.6618635084336,-24.178485673743435 +493507000.0,924.4001353874814,-24.190929108631558 +494006500.0,925.3266456549808,-24.20251296210218 +494506000.0,926.175244348923,-24.21514404635315 +495005500.0,924.3305222605784,-24.229051896353447 +495505000.0,923.1870848104953,-24.243312438210967 +496004500.0,922.656304853626,-24.256817602648173 +496504000.0,922.633851346141,-24.270003739050253 +497003500.0,923.256555415518,-24.282001521046745 +497503000.0,922.8772742941803,-24.29396087909491 +498002500.0,922.355462390657,-24.30760739715438 +498502000.0,922.1356381253647,-24.32070516518537 +499001500.0,921.4032063338226,-24.333084302844124 +499501000.0,921.2937352878799,-24.346452535553958 +500000500.0,921.6743793855825,-24.360031758378145 +500500000.0,921.8975415216121,-24.373141716046597 +500999500.0,921.1180086973818,-24.387208170216002 +501499000.0,919.7482018668892,-24.400546837066106 +501998500.0,920.8525628115211,-24.41406322754288 +502498000.0,919.8704950403762,-24.427538106807305 +502997500.0,919.0313599350966,-24.44027677413735 +503497000.0,917.181014497302,-24.452590357553127 +503996500.0,915.3717564879269,-24.46643354743441 +504496000.0,914.4451057853257,-24.48064991431018 +504995500.0,913.2922723403358,-24.49508731453623 +505495000.0,911.0985531010117,-24.50835606475027 +505994500.0,909.1200777941726,-24.521575180665813 +506494000.0,909.868567570178,-24.536433617432852 +506993500.0,908.7173493824541,-24.550479896754524 +507493000.0,905.2859061503564,-24.564410263062005 +507992500.0,905.4857958736934,-24.577659860575302 +508492000.0,904.770873558857,-24.589755418863042 +508991500.0,903.8615158534972,-24.602355294505383 +509491000.0,902.030793239202,-24.614104020069885 +509990500.0,899.1853392667824,-24.628554655767548 +510490000.0,896.3661885381574,-24.640682070574375 +510989500.0,893.8822773905487,-24.654094333237747 +511489000.0,892.2815909123208,-24.667369461613376 +511988500.0,891.3086604164326,-24.680544116782446 +512488000.0,890.2761703920988,-24.69663087968076 +512987500.0,889.2653095396573,-24.710316264321253 +513487000.0,887.4775109894861,-24.72320077205909 +513986500.0,885.7772649123663,-24.737533213631608 +514486000.0,884.4845012277577,-24.751759665004133 +514985500.0,882.0170436796208,-24.765260875452917 +515485000.0,879.8074527809206,-24.778882824777067 +515984500.0,879.2969112655699,-24.793567547633025 +516484000.0,878.7708912346823,-24.807552089388327 +516983500.0,879.0780923590557,-24.82275972381451 +517483000.0,878.8611810285257,-24.83914175168332 +517982500.0,877.7157665837123,-24.85371823695215 +518482000.0,877.3086013849614,-24.866930598236728 +518981500.0,877.5347302428179,-24.880860522567986 +519481000.0,877.1960353176804,-24.89550945407458 +519980500.0,877.4024089413984,-24.908163737500583 +520480000.0,877.819691449717,-24.919705410650103 +520979500.0,877.701026032232,-24.932355682972435 +521479000.0,877.2254695794913,-24.94602354337811 +521978500.0,875.7021902338845,-24.95813189740767 +522478000.0,875.7376672578333,-24.971807116938596 +522977500.0,875.8966413385875,-24.983340037051345 +523477000.0,876.2989458874288,-24.994711787012502 +523976500.0,875.6205594608202,-25.007654837220404 +524476000.0,874.4678615463306,-25.021893404973735 +524975500.0,871.7813454689046,-25.03651299350359 +525475000.0,869.751635601491,-25.050693337207125 +525974500.0,870.8047522889937,-25.06321787523855 +526474000.0,869.8359762405805,-25.07587099981874 +526973500.0,869.3699730086158,-25.089689449618472 +527473000.0,868.1640735526738,-25.102699850882576 +527972500.0,867.9837707953715,-25.116304732666226 +528472000.0,867.5665863946816,-25.128995864523844 +528971500.0,866.6822294348169,-25.143577947753062 +529471000.0,865.533598477829,-25.1593277297912 +529970500.0,866.1732680224395,-25.174419436190465 +530470000.0,865.225761359703,-25.186790420268387 +530969500.0,865.405369843888,-25.19902959059365 +531469000.0,864.4915800799228,-25.212537591476625 +531968500.0,864.5794681903495,-25.226482380781842 +532468000.0,864.2702836549262,-25.23993845969594 +532967500.0,862.6217879921893,-25.254234093599162 +533467000.0,862.4452713805084,-25.26893364318556 +533966500.0,862.401125116722,-25.28327510529783 +534466000.0,862.2411677512641,-25.298345636464095 +534965500.0,862.5156466980021,-25.31111629177375 +535465000.0,862.0041466482422,-25.32560717359817 +535964500.0,860.9460795218727,-25.339123090397695 +536464000.0,862.3167775964957,-25.35240385519777 +536963500.0,860.6102577352061,-25.366130513401913 +537463000.0,859.4092708568086,-25.38101034062816 +537962500.0,858.7730826688162,-25.395657536137374 +538462000.0,858.0870441476694,-25.412278663624495 +538961500.0,857.1907344835295,-25.425849028119405 +539461000.0,855.8974766834917,-25.440837209676346 +539960500.0,853.8929736774777,-25.455333466464907 +540460000.0,852.4410002896409,-25.46984736865838 +540959500.0,851.7157424512617,-25.483295295919646 +541459000.0,850.6933882074633,-25.497066554431708 +541958500.0,849.3323904066127,-25.51000295849184 +542458000.0,849.3845851079907,-25.52400079418032 +542957500.0,847.6975818751667,-25.535746160916407 +543457000.0,846.3388701049569,-25.549430854942397 +543956500.0,846.8893917721518,-25.56231595200106 +544456000.0,846.0507476379851,-25.57665715634381 +544955500.0,845.2442797022784,-25.58852269912366 +545455000.0,843.6147525418677,-25.602189331450738 +545954500.0,843.1429865732864,-25.616794488210036 +546454000.0,843.1219177375143,-25.6296652592397 +546953500.0,842.158412409498,-25.644643541469797 +547453000.0,840.8862374710118,-25.656301553400546 +547952500.0,839.4693501278433,-25.668410197679204 +548452000.0,838.2477004350814,-25.6823886937222 +548951500.0,837.4982877375452,-25.696424881738245 +549451000.0,836.4615075078276,-25.70943989099005 +549950500.0,834.627731343853,-25.72431679565519 +550450000.0,834.9199157614989,-25.737813850588807 +550949500.0,833.9462211489091,-25.750773908268407 +551449000.0,832.5279735126699,-25.764488134102482 +551948500.0,831.7744073341024,-25.78027427415223 +552448000.0,830.4650811269055,-25.794370524693388 +552947500.0,830.4639473412502,-25.807875186328985 +553447000.0,829.200652155599,-25.823338153618298 +553946500.0,827.9488915598979,-25.83859355651312 +554446000.0,826.1363690686035,-25.851384581534944 +554945500.0,825.5176217410345,-25.86602409639103 +555445000.0,824.8744945781438,-25.880577056184404 +555944500.0,823.6105886387339,-25.89386337396268 +556444000.0,823.4577194598409,-25.90741423284153 +556943500.0,822.253317867358,-25.922175841909805 +557443000.0,822.1596170838133,-25.935473087552587 +557942500.0,821.2276415666046,-25.94868682696775 +558442000.0,821.0445499467061,-25.963498351994307 +558941500.0,820.0750548627783,-25.97783170143705 +559441000.0,819.3656948022175,-25.992223039004802 +559940500.0,819.138800664284,-26.005212617690677 +560440000.0,819.585682365896,-26.01853812498624 +560939500.0,819.877667181492,-26.031504524341173 +561439000.0,818.5074488085037,-26.044279754986484 +561938500.0,817.8126595032726,-26.058816338755726 +562438000.0,817.6837521362918,-26.07453000663603 +562937500.0,815.7927401265115,-26.088593774086927 +563437000.0,816.582297911865,-26.1041029522498 +563936500.0,815.7892534273332,-26.119954414790154 +564436000.0,814.568299717284,-26.134688863864977 +564935500.0,813.735496405482,-26.148240025360824 +565435000.0,812.6737970332061,-26.163086466521214 +565934500.0,811.0310009381899,-26.177543401472068 +566434000.0,809.6533002048991,-26.190646535869675 +566933500.0,807.0771737285252,-26.204651811893676 +567433000.0,805.1816146440419,-26.219451812973578 +567932500.0,804.9270674382784,-26.23474553110516 +568432000.0,802.4318094970578,-26.250170116384645 +568931500.0,801.2739346692568,-26.26436903532557 +569431000.0,798.833733480099,-26.276579293588732 +569930500.0,796.6134256048124,-26.28989860863691 +570430000.0,794.5637134153862,-26.305113209232584 +570929500.0,793.5009988389008,-26.318242355378093 +571429000.0,791.9619090897645,-26.333458081543004 +571928500.0,791.274577710907,-26.349333074562093 +572428000.0,790.2944426859348,-26.364412067570157 +572927500.0,789.1193138530457,-26.37763696770454 +573427000.0,787.3067957408107,-26.39110183471111 +573926500.0,785.9701349608843,-26.406401814536405 +574426000.0,783.6743107384684,-26.419895498164824 +574925500.0,782.3345355628676,-26.433582159774033 +575425000.0,782.0251995660838,-26.44763132913367 +575924500.0,781.2379322091439,-26.462486076224057 +576424000.0,778.8082494622074,-26.47568774061063 +576923500.0,777.3956778663493,-26.49135115102305 +577423000.0,775.9970729476145,-26.503617916614203 +577922500.0,774.7946511441801,-26.520754519241194 +578422000.0,774.5808810064194,-26.53498298789503 +578921500.0,772.9935929504862,-26.550292753211522 +579421000.0,770.6852979486607,-26.565095232798566 +579920500.0,768.7739426226357,-26.580230160865927 +580420000.0,767.5799537845667,-26.5958698024816 +580919500.0,766.05876041524,-26.609720737003578 +581419000.0,766.1844117886569,-26.625956381930052 +581918500.0,763.875472483222,-26.640543390732088 +582418000.0,763.7550137048622,-26.65649619929041 +582917500.0,762.7227180413529,-26.67410280224817 +583417000.0,761.2438675252536,-26.68892574717473 +583916500.0,760.4156334216893,-26.70263216762262 +584416000.0,758.7899822390966,-26.717523629816284 +584915500.0,758.0265555335899,-26.732130112905285 +585415000.0,757.1323204132407,-26.747269597704797 +585914500.0,756.4073233078628,-26.762048844129517 +586414000.0,756.255023527674,-26.778244811314085 +586913500.0,755.2320736921367,-26.792435967173503 +587413000.0,754.2700064954466,-26.80525840119261 +587912500.0,752.2114887017345,-26.82021365602657 +588412000.0,750.0036319231759,-26.8357151292649 +588911500.0,748.2817116685713,-26.851525263860797 +589411000.0,746.8436285454395,-26.867433859515508 +589910500.0,744.2730615318684,-26.88206036181244 +590410000.0,741.1067156993181,-26.89767753460511 +590909500.0,741.7141877359431,-26.913367855932787 +591409000.0,740.6137428197359,-26.929450998716092 +591908500.0,739.7916206679158,-26.943381685225983 +592408000.0,737.3677556588628,-26.95814597512908 +592907500.0,736.7352680271883,-26.97347074220504 +593407000.0,735.1570644810654,-26.98724281192599 +593906500.0,735.0428740270781,-27.001377778494508 +594406000.0,733.2382774661095,-27.015461700703373 +594905500.0,730.803961531686,-27.028366846026646 +595405000.0,730.9556904882759,-27.041910632078853 +595904500.0,729.1491794023977,-27.055766116118537 +596404000.0,728.7385436439928,-27.070217522150173 +596903500.0,728.6095345949568,-27.086590806327653 +597403000.0,729.1043463206878,-27.099409168422287 +597902500.0,728.778299678664,-27.11317315127143 +598402000.0,726.408500865033,-27.12861140426832 +598901500.0,726.3920709227984,-27.142301178019853 +599401000.0,725.2857675394724,-27.15627057835979 +599900500.0,723.6248139128935,-27.17106005318611 +600400000.0,722.4995963661127,-27.184930687091338 +600899500.0,721.5000154154048,-27.200582916982388 +601399000.0,720.3817870899293,-27.215478859413672 +601898500.0,719.4594708049352,-27.231342178953255 +602398000.0,717.2571367195934,-27.246909951878816 +602897500.0,716.1197529701393,-27.260582656927898 +603397000.0,715.0575964200362,-27.27484488763747 +603896500.0,712.929096322785,-27.289152886721673 +604396000.0,712.2727544980285,-27.30466478193606 +604895500.0,711.4241515442208,-27.320750267254226 +605395000.0,710.3071495550065,-27.334780802158956 +605894500.0,709.2966613317839,-27.35272507685673 +606394000.0,707.870663394658,-27.366895895882973 +606893500.0,706.7744005676846,-27.382455395021818 +607393000.0,707.4617751465615,-27.39708890077062 +607892500.0,706.3444049568552,-27.41251557161643 +608392000.0,705.7970001726363,-27.426698328398324 +608891500.0,704.5579245440723,-27.440657788708627 +609391000.0,704.990627360575,-27.45618015424909 +609890500.0,705.632534446525,-27.47211540596318 +610390000.0,705.7747513168183,-27.48850494346514 +610889500.0,704.8682693079091,-27.50352443674745 +611389000.0,704.5428443742898,-27.519889760337314 +611888500.0,704.0001386267398,-27.535594823543025 +612388000.0,702.6507304670557,-27.550437781030535 +612887500.0,702.5120941501013,-27.56502410931488 +613387000.0,702.7136535535003,-27.581573239061164 +613886500.0,700.8064774773692,-27.59629766738194 +614386000.0,700.0105183439715,-27.610513977574886 +614885500.0,698.8732487683658,-27.626299377065678 +615385000.0,697.5921162732208,-27.64231312131834 +615884500.0,697.1110913531705,-27.659285307580042 +616384000.0,694.9858757551978,-27.67656736093985 +616883500.0,695.3631693953124,-27.693833374351428 +617383000.0,693.5312255345215,-27.70945989525435 +617882500.0,691.9586095996716,-27.724424497847274 +618382000.0,690.2720313027755,-27.74119802728279 +618881500.0,689.5546748878334,-27.758712357987605 +619381000.0,688.3488551328622,-27.776077967508275 +619880500.0,686.6635361364789,-27.793210057394703 +620380000.0,684.7081883033824,-27.810061467579885 +620879500.0,684.0847807638993,-27.825510935927767 +621379000.0,683.8922086489137,-27.840303265856676 +621878500.0,682.7797658624454,-27.855190730305885 +622378000.0,681.8395695197202,-27.87234711775018 +622877500.0,680.4782746003606,-27.890546130508515 +623377000.0,680.1772438572659,-27.908126026159398 +623876500.0,678.3933415708069,-27.925980198972496 +624376000.0,677.5096430462044,-27.943896318706926 +624875500.0,677.9321528049073,-27.962194885418615 +625375000.0,677.8291581720229,-27.97777584950094 +625874500.0,677.2889634899703,-27.995849784434707 +626374000.0,676.0445328772422,-28.012859572098645 +626873500.0,675.2746973947234,-28.030944319711303 +627373000.0,675.2859425784554,-28.047662650273857 +627872500.0,675.2052310638705,-28.063398449642968 +628372000.0,675.2750768850793,-28.080095800611417 +628871500.0,674.6250865579443,-28.097164993146553 +629371000.0,674.5191330183397,-28.113673501504717 +629870500.0,674.9956418437482,-28.12957636015139 +630370000.0,675.4267893640326,-28.14582531156164 +630869500.0,676.4768153857024,-28.161608830347127 +631369000.0,676.708334972956,-28.178714473643325 +631868500.0,676.8699949706627,-28.194084762635963 +632368000.0,677.2937623733272,-28.21137929834037 +632867500.0,677.4647781045752,-28.22860544440515 +633367000.0,678.0504069804076,-28.24364032197287 +633866500.0,676.6454715258309,-28.260401729931058 +634366000.0,676.9697206817754,-28.277836822407664 +634865500.0,676.3723866790068,-28.295149459802193 +635365000.0,676.2734616582275,-28.312244285234346 +635864500.0,674.8818502407518,-28.326366977129453 +636364000.0,674.3620813067448,-28.341875671664347 +636863500.0,673.9712702995363,-28.357445799713897 +637363000.0,674.218904259806,-28.373150043827863 +637862500.0,672.4597217822301,-28.39112752458893 +638362000.0,671.1214632857888,-28.408726914750453 +638861500.0,669.4625679568951,-28.426432527919054 +639361000.0,667.5167318887555,-28.443947297893885 +639860500.0,665.8226252316088,-28.462803675126768 +640360000.0,664.0080607966328,-28.4824649570526 +640859500.0,661.4499385453726,-28.497359910280526 +641359000.0,660.4877842212984,-28.517089779795764 +641858500.0,659.1967317298261,-28.53568468060479 +642358000.0,655.7804768252902,-28.553806131354452 +642857500.0,652.6365094180697,-28.572148482211077 +643357000.0,650.8453805954599,-28.590269785851245 +643856500.0,649.6517405779149,-28.611738700267527 +644356000.0,648.176284345043,-28.63038070579408 +644855500.0,646.7354979055091,-28.64958027391331 +645355000.0,644.424559903329,-28.666470452869564 +645854500.0,642.1544119137662,-28.6856428055567 +646354000.0,641.5663327933273,-28.704594132427935 +646853500.0,640.5347852258308,-28.72300823922473 +647353000.0,639.7643063150905,-28.74308844938269 +647852500.0,638.3059823393371,-28.761757609752294 +648352000.0,635.5248121763364,-28.779541933081124 +648851500.0,634.3674566425046,-28.79734152517079 +649351000.0,631.8969790189626,-28.815889594770848 +649850500.0,630.0336002309132,-28.835307013211516 +650350000.0,628.9476593727325,-28.853417238746566 +650849500.0,627.8361038140004,-28.872870659576595 +651349000.0,627.0266283649958,-28.8924521975166 +651848500.0,625.3323745599425,-28.911097421354963 +652348000.0,623.46725914898,-28.9315936848044 +652847500.0,622.6707785643785,-28.95162297764406 +653347000.0,622.0328082453177,-28.972818908609074 +653846500.0,620.2473111437714,-28.9937557806879 +654346000.0,618.9323693685287,-29.014647978132032 +654845500.0,619.017819362565,-29.033335385985488 +655345000.0,618.5860551444189,-29.05225179109099 +655844500.0,618.4527883242835,-29.071208980430303 +656344000.0,617.3469984504394,-29.089779226450773 +656843500.0,616.090626168161,-29.110373031229706 +657343000.0,614.3092878131537,-29.13118418615799 +657842500.0,613.5906383535741,-29.152339750312393 +658342000.0,611.9828467098006,-29.173541702135207 +658841500.0,612.2181376292149,-29.193709026578183 +659341000.0,611.3423093542085,-29.213215393832833 +659840500.0,610.0255263717629,-29.2343636488618 +660340000.0,609.4413004371321,-29.256808143153098 +660839500.0,607.6463232993444,-29.276529425803076 +661339000.0,606.2289577104931,-29.296779729347417 +661838500.0,604.9360050367603,-29.317745911622595 +662338000.0,603.9219355855538,-29.337189493945864 +662837500.0,602.2236425849914,-29.357253034422726 +663337000.0,600.5440378391263,-29.378910017287744 +663836500.0,598.131231444006,-29.399348054391155 +664336000.0,596.9891280600624,-29.42118396775844 +664835500.0,594.2405707722943,-29.44283152352662 +665335000.0,592.9196271917106,-29.462724039547386 +665834500.0,590.6353322746354,-29.484677567482056 +666334000.0,589.182481610605,-29.505479376941096 +666833500.0,587.2605729834712,-29.527849634963573 +667333000.0,585.0262914042786,-29.549417075016763 +667832500.0,583.3578010600583,-29.571769602168374 +668332000.0,581.0024330718699,-29.594507790436527 +668831500.0,580.0780141927194,-29.618262093552378 +669331000.0,577.4250949015909,-29.64147163844578 +669830500.0,575.5073510211647,-29.662344894125276 +670330000.0,573.0317219978377,-29.683189352388155 +670829500.0,571.2267598603016,-29.705857645057122 +671329000.0,568.9473567382963,-29.729464228182252 +671828500.0,566.2453484507444,-29.75188961164919 +672328000.0,563.7774507819281,-29.774185945638024 +672827500.0,561.7065703551426,-29.795984895092673 +673327000.0,558.7500549753114,-29.820079418049016 +673826500.0,557.0003574556696,-29.844318300096173 +674326000.0,555.3032160242261,-29.866261342940458 +674825500.0,552.1546517604927,-29.89024646336816 +675325000.0,550.0893867098428,-29.913585378028955 +675824500.0,548.0373577992742,-29.939222182926855 +676324000.0,545.2318158096001,-29.964056166686944 +676823500.0,542.5777232695141,-29.988429901055223 +677323000.0,540.453434249274,-30.0119093821806 +677822500.0,539.2896082912905,-30.037321541346916 +678322000.0,537.0067392657846,-30.062156869329897 +678821500.0,534.9915986618666,-30.083786969573687 +679321000.0,532.9869231305806,-30.107531483233494 +679820500.0,530.7292986204268,-30.131201630252107 +680320000.0,528.4003019758522,-30.155246195116437 +680819500.0,526.3167082750766,-30.179911379781128 +681319000.0,523.2281622415666,-30.203546703924236 +681818500.0,520.2677639671397,-30.228446497994305 +682318000.0,516.8081272925982,-30.251323696243247 +682817500.0,513.3594497648392,-30.276245650326484 +683317000.0,510.0531133412849,-30.299644283622044 +683816500.0,506.5211549368882,-30.32180635830446 +684316000.0,503.32658949954606,-30.34357421335731 +684815500.0,500.4573936308769,-30.36652860333355 +685315000.0,497.3998940021181,-30.390041918519902 +685814500.0,494.31958341384603,-30.414292997038086 +686314000.0,490.6207934180087,-30.436774129164764 +686813500.0,486.309047953318,-30.460133457935445 +687313000.0,483.07565592689014,-30.483090866210553 +687812500.0,478.8035542777832,-30.508086299350406 +688312000.0,475.2665801097921,-30.53167321117153 +688811500.0,471.94209144308894,-30.553643892510166 +689311000.0,468.8573339667713,-30.57763303149177 +689810500.0,464.8359216027101,-30.603360602591025 +690310000.0,461.3356837151586,-30.627097279566268 +690809500.0,457.0264638383832,-30.6521426086469 +691309000.0,452.790635636148,-30.678925856829345 +691808500.0,448.59699678151605,-30.70515742886198 +692308000.0,445.0959630487269,-30.730096475680174 +692807500.0,441.8606625192348,-30.756290309190106 +693307000.0,438.08187143346794,-30.781849512535643 +693806500.0,433.995928362992,-30.807711683439397 +694306000.0,430.01765439551554,-30.834436096534606 +694805500.0,426.05100985512223,-30.85960065057905 +695305000.0,421.7931882932748,-30.885001513792787 +695804500.0,417.6302521677409,-30.91080975407842 +696304000.0,413.21151173965194,-30.937179185358318 +696803500.0,409.22042846171587,-30.961297447950866 +697303000.0,404.6457301374204,-30.987393630167084 +697802500.0,400.5343226863922,-31.011473783373447 +698302000.0,395.7227419442648,-31.03590709238569 +698801500.0,391.58336424081494,-31.06011365611389 +699301000.0,386.8643018969364,-31.08504064431253 +699800500.0,383.75560700813537,-31.10937004512071 +700300000.0,379.4055277285945,-31.134518452105738 +700799500.0,374.9889833229163,-31.159235197050517 +701299000.0,370.84853381282124,-31.18641668867202 +701798500.0,367.71974942476703,-31.210729931691866 +702298000.0,363.24539062672693,-31.236815648812147 +702797500.0,358.73914491761343,-31.262141218826624 +703297000.0,354.54126684720205,-31.288369443496432 +703796500.0,349.83548503014856,-31.31206688373559 +704296000.0,344.9967653337645,-31.335590383557243 +704795500.0,340.2562836555106,-31.35953819664529 +705295000.0,335.8166355569925,-31.384605595073513 +705794500.0,331.5036684476604,-31.408519516526823 +706294000.0,326.83034444438766,-31.43193208258313 +706793500.0,322.3358466518078,-31.45549947719273 +707293000.0,317.5944323233059,-31.478175371556233 +707792500.0,312.9385378653359,-31.501506101773575 +708292000.0,308.68118160128716,-31.523699451466005 +708791500.0,304.46503057218956,-31.545355077778968 +709291000.0,299.8960657170404,-31.57131415114049 +709790500.0,295.95397902356376,-31.594799769795443 +710290000.0,291.4491375891214,-31.61869193839104 +710789500.0,287.87414717922417,-31.64297393749458 +711289000.0,284.2275507194275,-31.666305349880616 +711788500.0,280.46098885866706,-31.6888182457527 +712288000.0,276.3025946235764,-31.711328927576464 +712787500.0,272.2672738256318,-31.73331845457753 +713287000.0,268.43802443669546,-31.756477473524036 +713786500.0,264.8705968921064,-31.780720529379348 +714286000.0,261.082943411582,-31.802314469417905 +714785500.0,257.2801073659147,-31.826038279826264 +715285000.0,253.22509647163957,-31.850398204083803 +715784500.0,249.7757216573493,-31.87425300953946 +716284000.0,246.07084099981572,-31.898765510114206 +716783500.0,242.2071957521087,-31.921161873267064 +717283000.0,238.38534151613547,-31.94556882018906 +717782500.0,234.88942085921894,-31.96766830599209 +718282000.0,231.15023119376409,-31.98954524997541 +718781500.0,227.501078997128,-32.01338738845987 +719281000.0,224.3368299980077,-32.036739684732865 +719780500.0,220.97158521458763,-32.0593320176879 +720280000.0,217.02753433056517,-32.081327800109825 +720779500.0,213.05088204737768,-32.10243692151879 +721279000.0,209.3221288388301,-32.123618552206175 +721778500.0,206.32604194388594,-32.14572104767844 +722278000.0,202.9657913901757,-32.16875003059872 +722777500.0,200.00474692538035,-32.19096795959267 +723277000.0,197.17207685283162,-32.21191865657144 +723776500.0,194.15384768563098,-32.23524536107396 +724276000.0,190.92694354796882,-32.258051758868454 +724775500.0,187.95203377346067,-32.28034031492754 +725275000.0,184.7906127325187,-32.302737458182804 +725774500.0,181.95778236330162,-32.3248623234893 +726274000.0,178.83961017744826,-32.34599285370789 +726773500.0,175.93892877583437,-32.36766535706789 +727273000.0,172.97506711182638,-32.391261274988544 +727772500.0,169.58896181712933,-32.41481427737598 +728272000.0,166.80896662584425,-32.43835613212854 +728771500.0,163.86832919989547,-32.46148313519499 +729271000.0,160.9012992098252,-32.48445730104404 +729770500.0,157.8388966252871,-32.50766971055733 +730270000.0,154.9222674395334,-32.529356918172866 +730769500.0,152.02959786915582,-32.550892774533146 +731269000.0,149.16558576709838,-32.57123075297364 +731768500.0,146.2022095027139,-32.59308278687388 +732268000.0,143.7336558693184,-32.614394807112404 +732767500.0,140.89412236476895,-32.63705123983736 +733267000.0,138.33749110221018,-32.65714832088042 +733766500.0,136.04037617329757,-32.679182811136215 +734266000.0,133.5181710026502,-32.70039222287022 +734765500.0,131.0347802816599,-32.71965742783448 +735265000.0,128.49719917685798,-32.74127560910488 +735764500.0,126.24279970646853,-32.76081202576784 +736264000.0,123.90959506236923,-32.78145478323381 +736763500.0,121.31064502380609,-32.80325812988249 +737263000.0,118.9846058223311,-32.824666212330214 +737762500.0,116.81837294491885,-32.8457919606596 +738262000.0,114.8084465463897,-32.865491534781576 +738761500.0,112.64371744515482,-32.886380692064535 +739261000.0,110.6068668428457,-32.906634204114276 +739760500.0,108.45211398190521,-32.92710200680336 +740260000.0,106.24204958581794,-32.94815764862924 +740759500.0,103.94330360748047,-32.967606353594576 +741259000.0,101.98317159682183,-32.987773521867595 +741758500.0,99.95336766375225,-33.005432263045805 +742258000.0,97.96167691931224,-33.02505756074141 +742757500.0,96.09491357963253,-33.0443022319134 +743257000.0,94.0252440434938,-33.063324471153294 +743756500.0,92.24021071757751,-33.083142692869416 +744256000.0,90.45190524211185,-33.10264194664609 +744755500.0,88.8096400146735,-33.12375328896987 +745255000.0,87.00841331984915,-33.143087828596336 +745754500.0,85.22583604033998,-33.161642960580025 +746254000.0,83.43146941040636,-33.18103438509787 +746753500.0,81.74394925362681,-33.200730398851384 +747253000.0,80.14284535741466,-33.21904878931125 +747752500.0,78.57201760280479,-33.23770822798249 +748252000.0,77.02362703544787,-33.25617973008411 +748751500.0,75.29756577763368,-33.273843900171336 +749251000.0,73.62909903086528,-33.2937687148239 +749750500.0,72.12099032661406,-33.31420850282269 +750250000.0,70.60353890425957,-33.33367230783319 +750749500.0,69.02475556245345,-33.35205901583256 +751249000.0,67.46883445749694,-33.371432313197545 +751748500.0,65.9294557967565,-33.39165942740958 +752248000.0,64.61327188379231,-33.410708079213116 +752747500.0,63.170692149007,-33.42986061978766 +753247000.0,61.872686528655194,-33.44856476090908 +753746500.0,60.44710046740651,-33.46719493225619 +754246000.0,59.102640935749626,-33.486152582293784 +754745500.0,57.66122939429956,-33.50463050525678 +755245000.0,56.318431094819125,-33.52323387333609 +755744500.0,55.093382311448956,-33.5419354555017 +756244000.0,53.79632600993064,-33.562561621005194 +756743500.0,52.622064152466024,-33.58274556315016 +757243000.0,51.352017899308684,-33.601050944527834 +757742500.0,50.20031932163014,-33.61838593196848 +758242000.0,49.04643296186367,-33.63611751680496 +758741500.0,47.864663429588234,-33.65387300121037 +759241000.0,46.78090868237238,-33.67254382297702 +759740500.0,45.70532250440848,-33.6894542295429 +760240000.0,44.671357080631246,-33.70793104479934 +760739500.0,43.53799488509224,-33.72709898794145 +761239000.0,42.565129937075774,-33.74709282763576 +761738500.0,41.701118155715925,-33.76654411489521 +762238000.0,40.67450962916451,-33.78639186141282 +762737500.0,39.62380268465625,-33.80457143132433 +763237000.0,38.70643110602426,-33.82250793522712 +763736500.0,37.76574343734237,-33.84139346780762 +764236000.0,36.8822853843457,-33.86066858873787 +764735500.0,36.00235353263217,-33.87626529841476 +765235000.0,35.09960940106709,-33.89284339005849 +765734500.0,34.235096630453135,-33.910359467268044 +766234000.0,33.43754274129731,-33.92860423305341 +766733500.0,32.62350791700693,-33.94523635208985 +767233000.0,31.82000422829119,-33.96039474145464 +767732500.0,31.08720662505887,-33.97574265990055 +768232000.0,30.207667887614395,-33.992073652692156 +768731500.0,29.52519803995611,-34.008396543638675 +769231000.0,28.798111390744438,-34.024295480294505 +769730500.0,28.049995110443948,-34.04223297508693 +770230000.0,27.282594118837185,-34.058363235577005 +770729500.0,26.557226425785903,-34.078375433002954 +771229000.0,25.829719267816575,-34.09638704452533 +771728500.0,25.19816136080054,-34.114475710231375 +772228000.0,24.53923541832097,-34.129875985193785 +772727500.0,23.903204156266195,-34.14592701836436 +773227000.0,23.274811131968608,-34.16272138661716 +773726500.0,22.6275228232951,-34.17868637102295 +774226000.0,21.967592125477083,-34.195815244731754 +774725500.0,21.37862990611682,-34.21265358602734 +775225000.0,20.76769327338664,-34.22825222522716 +775724500.0,20.230186952116647,-34.24584391307312 +776224000.0,19.70737752227887,-34.260456282370995 +776723500.0,19.137300415591703,-34.27611877801422 +777223000.0,18.554382689937025,-34.29048276945624 +777722500.0,17.98857749970456,-34.30523962990346 +778222000.0,17.44610145848784,-34.321264219993004 +778721500.0,16.990409597853922,-34.33761140829923 +779221000.0,16.47842690926634,-34.351102460358454 +779720500.0,15.948372245313985,-34.36590665070085 +780220000.0,15.419784170279373,-34.37985372073014 +780719500.0,14.981192340480257,-34.39473628333273 +781219000.0,14.57523543868997,-34.4086381819202 +781718500.0,14.174081451436813,-34.4199459226139 +782218000.0,13.739344998120487,-34.434376836538235 +782717500.0,13.278842975559881,-34.446461519831345 +783217000.0,12.863011334529467,-34.459820606258006 +783716500.0,12.426238652694902,-34.47189672583226 +784216000.0,12.015957315412349,-34.484736231610434 +784715500.0,11.603688469699154,-34.49283149065959 +785215000.0,11.228781731948413,-34.50596009353614 +785714500.0,10.898607130512698,-34.51826930401569 +786214000.0,10.553279321986256,-34.53042805198092 +786713500.0,10.210910790892525,-34.53846547763432 +787213000.0,9.869896904017082,-34.547844370376886 +787712500.0,9.570945321485604,-34.55599523021309 +788212000.0,9.251773954215201,-34.565226270318654 +788711500.0,8.940265434959647,-34.57409422560305 +789211000.0,8.626191568046705,-34.583347538025016 +789710500.0,8.319779017526923,-34.58943469471292 +790210000.0,8.069954967948844,-34.59837204625622 +790709500.0,7.776181611845642,-34.6060255335651 +791209000.0,7.519859630027182,-34.61396373033136 +791708500.0,7.261446221741364,-34.61761952240591 +792208000.0,7.030588914651991,-34.62347633905217 +792707500.0,6.762423460269447,-34.626315880198824 +793207000.0,6.538414290319809,-34.63223483864436 +793706500.0,6.303442525551732,-34.63957920087909 +794206000.0,6.087428416232051,-34.6414420040905 +794705500.0,5.8756746011126815,-34.649062795669685 +795205000.0,5.659180604924178,-34.652835589971474 +795704500.0,5.465743052019735,-34.65585242563676 +796204000.0,5.250677180109672,-34.65669030867024 +796703500.0,5.0582823650247315,-34.66136651432904 +797203000.0,4.882672736331991,-34.66002771836068 +797702500.0,4.699970470706361,-34.66000977749592 +798202000.0,4.5410265058645605,-34.659293768215015 +798701500.0,4.374326888488022,-34.65773166847518 +799201000.0,4.2191817966060405,-34.65019086862943 +799700500.0,4.079755006382023,-34.64561165624468 +800200000.0,3.9356904822469603,-34.63993781753745 +800699500.0,3.8062712209251512,-34.635776169605215 +801199000.0,3.685091758572522,-34.628679791388045 +801698500.0,3.5742526038977527,-34.62056725303674 +802198000.0,3.470578917353764,-34.60768660033349 +802697500.0,3.35859447442979,-34.59726832818078 +803197000.0,3.2478184419361176,-34.587224808075916 +803696500.0,3.1387421357051686,-34.578136814268646 +804196000.0,3.039962463151686,-34.56555613699695 +804695500.0,2.9501041847386253,-34.55327367440194 +805195000.0,2.8601330209798688,-34.539085762090174 +805694500.0,2.7766343880688815,-34.52688910623302 +806194000.0,2.7013869736707177,-34.51285897778493 +806693500.0,2.617329351482171,-34.49977093097937 +807193000.0,2.546145560185839,-34.482183343943206 +807692500.0,2.4825809201939357,-34.46914598585732 +808192000.0,2.420361263436672,-34.45797216804519 +808691500.0,2.336842986502666,-34.44162126187187 +809191000.0,2.285559071433347,-34.427392721689 +809690500.0,2.236487315757505,-34.41123784166772 +810190000.0,2.1859248358077017,-34.39710704899434 +810689500.0,2.1466519477712334,-34.37923020043922 +811189000.0,2.1089605626796857,-34.363046259393776 +811688500.0,2.0697382831420073,-34.34476892467382 +812188000.0,2.032015829685001,-34.32658324788817 +812687500.0,2.0081234784595963,-34.31198435520686 +813187000.0,1.980007936976967,-34.29860610037418 +813686500.0,1.9465280807144112,-34.285473238500664 +814186000.0,1.9112469676214865,-34.27451653604977 +814685500.0,1.8864746003801105,-34.26191233963622 +815185000.0,1.8646630391400945,-34.253161033531974 +815684500.0,1.838999223404433,-34.24257189443562 +816184000.0,1.8121429198747092,-34.230665691707884 +816683500.0,1.7880233554309917,-34.219389278967725 +817183000.0,1.7714001805592792,-34.20920916609495 +817682500.0,1.7471294331352218,-34.19984232066912 +818182000.0,1.7162409714583104,-34.1897470380077 +818681500.0,1.7068640699544149,-34.18178179279202 +819181000.0,1.6831200679896414,-34.17399474174019 +819680500.0,1.6673169458156138,-34.170699958476405 +820180000.0,1.6491563235672313,-34.16227482935638 +820679500.0,1.6373272931467018,-34.15733925152851 +821179000.0,1.6202367075223816,-34.15195424762012 +821678500.0,1.6098342271001613,-34.15011698815326 +822178000.0,1.600049732892944,-34.14471433556682 +822677500.0,1.5932708681901588,-34.14337359443722 +823177000.0,1.5889160470269248,-34.13775844747172 +823676500.0,1.58759640308437,-34.13797431330013 +824176000.0,1.5856955354054854,-34.13323215638057 +824675500.0,1.5784413080079231,-34.13207343388136 +825175000.0,1.5635634414056894,-34.133509464051414 +825674500.0,1.5531579619704647,-34.13550914413455 +826174000.0,1.5464381885987213,-34.1309579021047 +826673500.0,1.5343718116200045,-34.135784941530964 +827173000.0,1.5240432251037301,-34.1369222256197 +827672500.0,1.5101578160379678,-34.14055126737333 +828172000.0,1.4997250979331938,-34.14392841858369 +828671500.0,1.5006357760495952,-34.14542170866667 +829171000.0,1.4877615193901603,-34.15551768773643 +829670500.0,1.4813044381176717,-34.1568280289044 +830170000.0,1.4717382119737088,-34.16247019800924 +830669500.0,1.4606827415042631,-34.16678487230157 +831169000.0,1.44774780292372,-34.17472443305676 +831668500.0,1.4325128217525143,-34.180776892754714 +832168000.0,1.4161823073283988,-34.1837715240069 +832667500.0,1.4064150410412692,-34.193574160716764 +833167000.0,1.3899645555363676,-34.20510799983209 +833666500.0,1.379497104939845,-34.21250485683416 +834166000.0,1.3686273582964135,-34.227470948092495 +834665500.0,1.3570243786898781,-34.2354966006372 +835165000.0,1.3454149571412175,-34.24264348568608 +835664500.0,1.3350998867709192,-34.243626047058385 +836164000.0,1.3250189128346592,-34.252704302218476 +836663500.0,1.3110239443661367,-34.25594956969541 +837163000.0,1.2963073210652625,-34.263467593315085 +837662500.0,1.2837245220901177,-34.27845485686366 +838162000.0,1.2661768697060243,-34.29317337368075 +838661500.0,1.2574589533815868,-34.29791915633564 +839161000.0,1.2446070312064033,-34.306620388188534 +839660500.0,1.2296299197878569,-34.31780250390059 +840160000.0,1.207143117599789,-34.33146415542211 +840659500.0,1.1874329939028534,-34.34119119525923 +841159000.0,1.1676063485335126,-34.350384419428586 +841658500.0,1.1554103052534723,-34.36292759194819 +842158000.0,1.1331138323802565,-34.37187785960063 +842657500.0,1.1193424321526173,-34.38032908113694 +843157000.0,1.0961417622197482,-34.383900743158634 +843656500.0,1.08789406203351,-34.40198376851972 +844156000.0,1.0668860032767498,-34.41567302089131 +844655500.0,1.053797113093299,-34.42994865649447 +845155000.0,1.0435743134317474,-34.437044316767334 +845654500.0,1.0293252949282226,-34.44716843148352 +846154000.0,1.0113117830260807,-34.45115340745749 +846653500.0,0.9943609350267436,-34.45310617897444 +847153000.0,0.9808944822829846,-34.472038481181436 +847652500.0,0.960593973724982,-34.49415854980212 +848152000.0,0.9432767809623794,-34.507788813122 +848651500.0,0.927868886960529,-34.52378124490744 +849151000.0,0.9085479629594686,-34.548747873294424 +849650500.0,0.8859214957058453,-34.5676158966914 +850150000.0,0.8660106165911126,-34.58173719286418 +850649500.0,0.8494053783608095,-34.60072740354668 +851149000.0,0.8335495389653045,-34.617437698374516 +851648500.0,0.8173869525262235,-34.63779039118277 +852148000.0,0.79946065319289,-34.652892004549294 +852647500.0,0.785956162102101,-34.670964032939274 +853147000.0,0.7724660247068516,-34.67947597105356 +853646500.0,0.7549411302714535,-34.685921309604694 +854146000.0,0.7441797154829825,-34.68789930609751 +854645500.0,0.7238508416982125,-34.68399005172588 +855145000.0,0.7077198594800911,-34.683615931795785 +855644500.0,0.6919570294298617,-34.687340475911284 +856144000.0,0.6753470308367884,-34.698670362127864 +856643500.0,0.6652069089953981,-34.68112351056783 +857143000.0,0.6535373084728718,-34.69607179319853 +857642500.0,0.6365630028792805,-34.697330627132644 +858142000.0,0.6211474064240015,-34.7097742908854 +858641500.0,0.6014978594058986,-34.72927428182165 +859141000.0,0.5775334679026218,-34.76508502738116 +859640500.0,0.5633333570314231,-34.76467579255636 +860140000.0,0.547133325025715,-34.76660905219664 +860639500.0,0.5323785192952143,-34.78444722200059 +861139000.0,0.5182194097685745,-34.80121872536933 +861638500.0,0.502014001089346,-34.81316201685515 +862138000.0,0.4857930837322963,-34.812173899638175 +862637500.0,0.47334049098971936,-34.83374693951918 +863137000.0,0.460405806824721,-34.82112411622584 +863636500.0,0.43920796553513347,-34.76339967235116 +864136000.0,0.4288195711037861,-34.78039069013006 +864635500.0,0.4151336858964905,-34.76042539142067 +865135000.0,0.40383528905551613,-34.78771685002707 +865634500.0,0.3907397813675216,-34.841779470707536 +866134000.0,0.37966853872969647,-34.887841441402195 +866633500.0,0.37223212885013407,-34.93848894707191 +867133000.0,0.3603047621598903,-35.03634203848588 +867632500.0,0.34941096255336607,-35.17154722728893 +868132000.0,0.33966466515688293,-35.32698556966081 +868631500.0,0.3243004391674549,-35.39852273676141 +869131000.0,0.31252406595012633,-35.49478248388567 +869630500.0,0.30124567252899287,-35.48932032299079 +870130000.0,0.2864871877228873,-35.39339366781835 +870629500.0,0.2793756418387928,-35.29016903210929 +871129000.0,0.2670078045244507,-35.134893128084336 +871628500.0,0.25721996818010046,-34.97399317777213 +872128000.0,0.24423883125696352,-34.937527829711144 +872627500.0,0.23023361680600282,-34.93757839346464 +873127000.0,0.2222668953285526,-34.941903155774845 +873626500.0,0.2140874541859355,-35.021785302229844 +874126000.0,0.19925257712120184,-35.12047742393938 +874625500.0,0.18497556382831767,-35.23545568002755 +875125000.0,0.17599311291625847,-35.28303627986467 +875624500.0,0.16732291397730492,-35.29127229457725 +876124000.0,0.16177386870694802,-35.27214060732615 +876623500.0,0.1517068654431935,-35.18911002298163 +877123000.0,0.14755711262153418,-35.175909901824475 +877622500.0,0.14067695317112364,-35.22141597718168 +878122000.0,0.1380599425881191,-35.22641059594058 +878621500.0,0.13245787619685068,-35.2168236492751 +879121000.0,0.13157194919429774,-35.30198777678642 +879620500.0,0.1274286458161058,-35.4372981319162 +880120000.0,0.12830796749611004,-35.53741290714412 +880619500.0,0.12576497670882036,-35.629402779842735 +881119000.0,0.12206343025786048,-35.72814165421601 +881618500.0,0.12126039228850384,-35.858473155347056 +882118000.0,0.12255125106473926,-35.97812226982738 +882617500.0,0.11832492673211753,-36.11489785667548 +883117000.0,0.11513416629960876,-36.19744535588607 +883616500.0,0.11258945354991168,-36.309892051206205 +884116000.0,0.11486700619308449,-36.392144813237906 +884615500.0,0.1111861231153416,-36.436467779602765 +885115000.0,0.10913911149464355,-36.511534235197026 +885614500.0,0.11186294816111088,-36.60789894666672 +886114000.0,0.11020461282296617,-36.70302628603372 +886613500.0,0.11032791733151194,-36.775928141424174 +887113000.0,0.110561889174646,-36.87984359980683 +887612500.0,0.1121315749425741,-36.998940897580674 +888112000.0,0.11706240024907837,-37.072702751032985 +888611500.0,0.11579839223538109,-37.21830689098647 +889111000.0,0.1109516721645281,-37.32570207861705 +889610500.0,0.11295053460964086,-37.43910898177968 +890110000.0,0.1139009046350406,-37.60467205768226 +890609500.0,0.11286132363020744,-37.67276472025634 +891109000.0,0.11334657591576869,-37.713285072037905 +891608500.0,0.1114319889767546,-37.755715823576665 +892108000.0,0.10817546419684375,-37.83382570279672 +892607500.0,0.10468716064330752,-37.898649068728126 +893107000.0,0.10359212023346788,-37.9068858721169 +893606500.0,0.10344269314035742,-37.90279622531929 +894106000.0,0.10285081463036713,-37.859616388552574 +894605500.0,0.10411833521129589,-37.89398660898732 +895105000.0,0.10271078593282228,-37.96467492472999 +895604500.0,0.10033551379173766,-38.013747894077156 +896104000.0,0.09296661027692313,-38.06160141584594 +896603500.0,0.08768390677700773,-38.10190582280124 +897103000.0,0.08518097605400687,-38.22379911569286 +897602500.0,0.085099182037356,-38.22694680011672 +898102000.0,0.08228196552272982,-38.259190664289015 +898601500.0,0.0872658858692823,-38.38336536039647 +899101000.0,0.08634667160145293,-38.46862283599064 +899600500.0,0.08820201318657464,-38.62128448507233 +900100000.0,0.08909595130604969,-38.73102469754455 +900599500.0,0.09243101906965713,-38.86561798988226 +901099000.0,0.09358886446736099,-39.02168802956543 +901598500.0,0.09556986644626461,-39.11647645002908 +902098000.0,0.10481065740490637,-39.20260390354852 +902597500.0,0.10587777433643335,-39.21037714524664 +903097000.0,0.1032938587415955,-39.0634983371564 +903596500.0,0.10658034562627451,-38.94770673003058 +904096000.0,0.10878399639590086,-38.69870722344131 +904595500.0,0.10587203967591101,-38.39051039697387 +905095000.0,0.10905807489422709,-38.07652309841387 +905594500.0,0.1056048080399964,-37.794352624859684 +906094000.0,0.10754971586056836,-37.58197254109156 +906593500.0,0.10830291562598116,-37.442761217402484 +907093000.0,0.11153208591813686,-37.24833680091174 +907592500.0,0.1110549795743034,-37.05065258778268 +908092000.0,0.11460428037977875,-36.83435084451078 +908591500.0,0.10848209380941802,-36.596913285308986 +909091000.0,0.11185861161098594,-36.284807696415584 +909590500.0,0.11276665912483252,-35.87399382533289 +910090000.0,0.11100737064239197,-35.49914320742302 +910589500.0,0.10917288401508589,-35.13524402694815 +911089000.0,0.10716191708927662,-34.69620295339383 +911588500.0,0.10848327805371463,-34.357225351928896 +912088000.0,0.11030238957169697,-34.03125833623449 +912587500.0,0.11523929220768057,-33.63898954666341 +913087000.0,0.11641605297650753,-33.35944338828098 +913586500.0,0.11835952010426987,-33.150703485710785 +914086000.0,0.11958832214180275,-32.929927857609016 +914585500.0,0.12323498901474653,-32.682275473251785 +915085000.0,0.11856279991731317,-32.474237764263016 +915584500.0,0.11976057210094516,-32.28769372304106 +916084000.0,0.12263561643022157,-32.13665945608423 +916583500.0,0.12343644257537059,-31.994661564105204 +917083000.0,0.12261441584497448,-31.84194873417189 +917582500.0,0.12766687543467897,-31.68419381507639 +918082000.0,0.12772871294106458,-31.567278455411685 +918581500.0,0.13093759147286146,-31.470551179765035 +919081000.0,0.13059899180989373,-31.356884287300268 +919580500.0,0.13405321637184167,-31.332825322062863 +920080000.0,0.13661634883659973,-31.331235676902367 +920579500.0,0.1357909074069105,-31.340291458502403 +921079000.0,0.14112542277737863,-31.399707924429574 +921578500.0,0.1413789626852051,-31.50067900334177 +922078000.0,0.13894397921176171,-31.60905020607316 +922577500.0,0.13918274113276924,-31.68554810407435 +923077000.0,0.1377111350363873,-31.867524316122655 +923576500.0,0.14058654452752994,-31.92116998719267 +924076000.0,0.15186369284374854,-32.007762124477495 +924575500.0,0.14975361938445142,-32.13851832079381 +925075000.0,0.15292067874224805,-32.08829277118594 +925574500.0,0.15121965991368705,-32.0663335473006 +926074000.0,0.1544289914190172,-32.059888920641065 +926573500.0,0.15814760575660086,-32.06931868442682 +927073000.0,0.15962232299632567,-31.986278285229506 +927572500.0,0.16172771373737518,-31.900895007711565 +928072000.0,0.1621073272036733,-31.843683172325395 +928571500.0,0.16021071633944617,-31.808921180289346 +929071000.0,0.1577911093449534,-31.791340126897094 +929570500.0,0.1590752033455538,-31.76939956932081 +930070000.0,0.15812808857824207,-31.725193942338965 +930569500.0,0.1597410685470795,-31.71019583220773 +931069000.0,0.1602085951238737,-31.715793908331957 +931568500.0,0.16173045321085297,-31.712469037033223 +932068000.0,0.16364062441916505,-31.661628267440108 +932567500.0,0.1660220640953909,-31.686350571422135 +933067000.0,0.1679297301405445,-31.72407671413434 +933566500.0,0.16578031052275718,-31.74668076284152 +934066000.0,0.1714304488006758,-31.74971853908945 +934565500.0,0.17092944779366953,-31.731645066961963 +935065000.0,0.17424960105271387,-31.739439439656547 +935564500.0,0.17888515937311808,-31.76905292166242 +936064000.0,0.18667529298791624,-31.73489281586706 +936563500.0,0.19114993618424225,-31.771978192231916 +937063000.0,0.1886515164349699,-31.774030858243563 +937562500.0,0.18793102394691547,-31.75080740262252 +938062000.0,0.18807712441449315,-31.760505023833122 +938561500.0,0.18715421735615873,-31.75636454340714 +939061000.0,0.18090475105518852,-31.710256720587594 +939560500.0,0.18069449518691058,-31.681135601082616 +940060000.0,0.18208317505970625,-31.724985866296706 +940559500.0,0.1817423282568239,-31.74707308888257 +941059000.0,0.18119445814497956,-31.75926162195576 +941558500.0,0.17976320317906044,-31.764614255192107 +942058000.0,0.18031995451927152,-31.795233149546835 +942557500.0,0.1828862919171639,-31.803415477211527 +943057000.0,0.1770303636159505,-31.88476627415675 +943556500.0,0.18042026122826255,-31.896887581760758 +944056000.0,0.17703927869290262,-31.95329656960348 +944555500.0,0.18060510635123775,-31.9625201966783 +945055000.0,0.18373968225505116,-31.94918372936998 +945554500.0,0.18894078511140067,-31.88941772268928 +946054000.0,0.19278370539696302,-31.88237472519608 +946553500.0,0.1911355233583142,-31.858603296346093 +947053000.0,0.18936639611696723,-31.821958647270307 +947552500.0,0.18838623097822063,-31.841334657842857 +948052000.0,0.18926466319715485,-31.867835766331197 +948551500.0,0.18798401696266762,-31.919919880467585 +949051000.0,0.18868316799430132,-31.918396881061934 +949550500.0,0.18960760390140535,-31.931282453943634 +950050000.0,0.19373696519121852,-31.93135562795569 +950549500.0,0.196304314970447,-31.925825903334516 +951049000.0,0.19824872434743704,-31.9282423748246 +951548500.0,0.19522233646448894,-31.932206739615992 +952048000.0,0.1987909410598862,-31.96029979489485 +952547500.0,0.19794985229270093,-31.96652956014285 +953047000.0,0.19822297436275554,-31.973932737102498 +953546500.0,0.1969275788503772,-31.93887461772647 +954046000.0,0.2021777539913935,-31.974615463668748 +954545500.0,0.20269142012494495,-31.994960420689623 +955045000.0,0.19885135313371727,-31.98745801672596 +955544500.0,0.20277829734176836,-32.043184385509555 +956044000.0,0.20257221504685913,-32.047507765669124 +956543500.0,0.19875178840262914,-32.06054256550749 +957043000.0,0.207502500536391,-32.092400998030165 +957542500.0,0.21264156768120093,-32.12915415448535 +958042000.0,0.21774105068882044,-32.1019387562435 +958541500.0,0.22561136907491167,-32.145416388593915 +959041000.0,0.22038063025551557,-32.1768246754251 +959540500.0,0.22510356284765828,-32.13984416593618 +960040000.0,0.22775851150527757,-32.13200371921947 +960539500.0,0.23291146973650673,-32.155613022922076 +961039000.0,0.2351309785639031,-32.1388954123976 +961538500.0,0.2353523321726568,-32.14351348527685 +962038000.0,0.23207850370587976,-32.15061831731173 +962537500.0,0.2294084346338281,-32.166342973695315 +963037000.0,0.2335229996244065,-32.15183387006502 +963536500.0,0.23015082453874847,-32.100253672953684 +964036000.0,0.23629496560558477,-32.08667773210694 +964535500.0,0.23436672213520512,-32.0673147937732 +965035000.0,0.23613902321169078,-32.055150405406856 +965534500.0,0.2331930649350129,-32.01956194821204 +966034000.0,0.23554544214699688,-31.97499879411387 +966533500.0,0.23661830105606985,-32.00096488526993 +967033000.0,0.2397145483399537,-31.985278071223565 +967532500.0,0.2370929112692583,-31.978919340319774 +968032000.0,0.23624515096158194,-31.957070831701593 +968531500.0,0.24071563286683612,-31.952694504541594 +969031000.0,0.23907033907059966,-31.91135774588175 +969530500.0,0.24689150530528522,-31.946918150488482 +970030000.0,0.24961011830923555,-32.00309030564149 +970529500.0,0.25219052471621695,-31.98627769174042 +971029000.0,0.2471158111064273,-31.99353671365313 +971528500.0,0.24453159190136872,-31.965618590096753 +972028000.0,0.23939748696745167,-31.949330734995854 +972527500.0,0.23716714075354497,-31.946910776365993 +973027000.0,0.23277609244526837,-31.966600580425283 +973526500.0,0.2271212843683368,-31.970326379986993 +974026000.0,0.2250056004696678,-31.997063811174648 +974525500.0,0.22306657662698348,-32.01775305425255 +975025000.0,0.21829798219317578,-32.05587973467681 +975524500.0,0.21877629151596684,-32.07145269110348 +976024000.0,0.21992673423812104,-32.109165516780735 +976523500.0,0.222529274788573,-32.160075414974855 +977023000.0,0.22197013423736386,-32.18177491356778 +977522500.0,0.21979465924613126,-32.213268322674764 +978022000.0,0.22124627510615621,-32.21508423992253 +978521500.0,0.21882157938801935,-32.22778210278828 +979021000.0,0.22366272047645414,-32.18822739709877 +979520500.0,0.2210711371040553,-32.1858474883805 +980020000.0,0.22362835109766585,-32.190381660136865 +980519500.0,0.2238856015234017,-32.15755728125485 +981019000.0,0.2201371673977312,-32.1320786543805 +981518500.0,0.22268381024904846,-32.140722315753116 +982018000.0,0.23025498161072128,-32.19318909868624 +982517500.0,0.23397127348210975,-32.22665524479399 +983017000.0,0.2337705608922006,-32.2290169368062 +983516500.0,0.23326098742379497,-32.23288387237499 +984016000.0,0.2326084329600846,-32.23564957166099 +984515500.0,0.2318160101615373,-32.23737916524302 +985015000.0,0.23088872035931224,-32.23815640739115 +985514500.0,0.2298334535552601,-32.238083676066736 +986014000.0,0.22865898842192323,-32.237281972922375 +986513500.0,0.22737599230253563,-32.23589092330192 +987013000.0,0.22599702121102214,-32.23406877624049 +987512500.0,0.22453651983200001,-32.231992404464464 +988012000.0,0.22301082152077759,-32.22985730439147 +988511500.0,0.22143814830335468,-32.22787759613042 +989011000.0,0.21983861087642279,-32.22628602348144 +989510500.0,0.21823420860736473,-32.225333953935966 +990010000.0,0.21664882953425524,-32.225291378676644 +990509500.0,0.21510825036586012,-32.22644691257742 +991009000.0,0.2136401364816372,-32.22910779420348 +991508500.0,0.21227404193173516,-32.23359988581126 +992008000.0,0.21104140943699484,-32.24026767334848 +992507500.0,0.20997557038894837,-32.24947426645409 +993007000.0,0.20911174484981931,-32.26160139845831 +993506500.0,0.2084870415525229,-32.27704942638263 +994006000.0,0.20814045790066565,-32.296237330939796 +994505500.0,0.20811287996854622,-32.319602716533794 +995005000.0,0.20844708250115407,-32.347601811259885 +995504500.0,0.20918772891417037,-32.38070946690459 +996004000.0,0.2103813712939681,-32.41941915894567 +996503500.0,0.2120764503976116,-32.46424298655218 +997003000.0,0.21432329565285693,-32.51571167258439 +997502500.0,0.21717412515815088,-32.574374563593864 +998002000.0,0.22068304568263275,-32.64079962982341 +998501500.0,0.22490605266613317,-32.71557346520709 +999001000.0,0.2299010302191742,-32.79930128737024 +999500500.0,0.2357277511229684,-32.892606937629445 +1000000000.0,0.2424478768294217,-32.99613288099255 diff --git a/NuRadioReco/detector/RNO_G/analog_components.py b/NuRadioReco/detector/RNO_G/analog_components.py index 7db23cd82..7be975e48 100644 --- a/NuRadioReco/detector/RNO_G/analog_components.py +++ b/NuRadioReco/detector/RNO_G/analog_components.py @@ -43,20 +43,18 @@ def iglu_correction_func(temp, freqs): amp_response = {} correction_function = None if amp_type == 'rno_surface': - ph = os.path.join(path, 'HardwareResponses/surface_chan0_LinA.csv') - ff = np.loadtxt(ph, delimiter=',', skiprows=7, usecols=0) + ph = os.path.join(path, 'HardwareResponses/surface_placeholder.csv') + ff = np.loadtxt(ph, delimiter=',', skiprows=1, usecols=0) ff *= units.Hz - amp_gain_discrete = np.loadtxt(ph, delimiter=',', skiprows=7, usecols=5) - amp_phase_discrete = np.loadtxt(ph, delimiter=',', skiprows=7, usecols=6) - amp_phase_discrete *= units.degree + amp_gain_discrete = np.loadtxt(ph, delimiter=',', skiprows=1, usecols=1) + amp_phase_discrete = np.loadtxt(ph, delimiter=',', skiprows=1, usecols=2) correction_function = surface_correction_func elif amp_type == 'iglu': - ph = os.path.join(path, 'HardwareResponses/iglu_drab_chan0_LinA.csv') - ff = np.loadtxt(ph, delimiter=',', skiprows=7, usecols=0) + ph = os.path.join(path, 'HardwareResponses/iglu_drab_placeholder.csv') + ff = np.loadtxt(ph, delimiter=',', skiprows=1, usecols=0) ff *= units.Hz - amp_gain_discrete = np.loadtxt(ph, delimiter=',', skiprows=7, usecols=5) - amp_phase_discrete = np.loadtxt(ph, delimiter=',', skiprows=7, usecols=6) - amp_phase_discrete *= units.degree + amp_gain_discrete = np.loadtxt(ph, delimiter=',', skiprows=1, usecols=1) + amp_phase_discrete = np.loadtxt(ph, delimiter=',', skiprows=1, usecols=2) correction_function = iglu_correction_func elif amp_type == 'phased_array': ph = os.path.join(path, 'HardwareResponses/ULP-216+_Plus25DegC.s2p') From 1993061ce778e5a48d442547f09090221c2aa711 Mon Sep 17 00:00:00 2001 From: Sjoerd Bouma Date: Wed, 22 Feb 2023 13:32:21 +0100 Subject: [PATCH 143/418] install_dev will now exit with error code if an error occurs during dependency installation --- install_dev.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/install_dev.py b/install_dev.py index d1d32789b..e08ca27fc 100644 --- a/install_dev.py +++ b/install_dev.py @@ -139,6 +139,7 @@ def convert_poetry_to_pip(reqs): top_dir = os.path.dirname(os.path.realpath(__file__)) os.chdir(top_dir) # change CWD to repository root + retcode = 0 if '.git' in os.listdir(top_dir): # check that we are in a git repository ### Install dependencies @@ -151,7 +152,7 @@ def convert_poetry_to_pip(reqs): # print("Installing poetry...") # subprocess.call([sys.executable, "-m", "pip", "install", "poetry"]) # subprocess.call(["poetry", "install", "--no-root"]) - subprocess.call([sys.executable, '-m', 'pip', 'install', 'toml']+ pip_install_as_user) # we need toml to read pyproject.toml + retcode |= subprocess.call([sys.executable, '-m', 'pip', 'install', 'toml']+ pip_install_as_user) # we need toml to read pyproject.toml import toml toml_dict = toml.load(os.path.join(top_dir, 'pyproject.toml')) reqs = toml_dict['tool']['poetry']['dependencies'] @@ -161,7 +162,7 @@ def convert_poetry_to_pip(reqs): with tempfile.NamedTemporaryFile(mode='w+t') as req_txt: # make a temporary requirements.txt req_txt.writelines('\n'.join(reqs_pip)) req_txt.seek(0) - subprocess.call([sys.executable, '-m', 'pip', 'install', '-r', req_txt.name] + pip_install_as_user) + retcode |= subprocess.call([sys.executable, '-m', 'pip', 'install', '-r', req_txt.name] + pip_install_as_user) ### Install optional / dev dependencies install_dev_dependencies = yesno_input( @@ -171,7 +172,7 @@ def convert_poetry_to_pip(reqs): try: import toml except ImportError: - subprocess.call([sys.executable, '-m', 'pip', 'install', 'toml'] + pip_install_as_user) # we need toml to read pyproject.toml + retcode |= subprocess.call([sys.executable, '-m', 'pip', 'install', 'toml'] + pip_install_as_user) # we need toml to read pyproject.toml import toml toml_dict = toml.load(os.path.join(top_dir, 'pyproject.toml')) reqs = toml_dict['tool']['poetry']['dev-dependencies'] @@ -230,7 +231,7 @@ def convert_poetry_to_pip(reqs): with tempfile.NamedTemporaryFile(mode='w+t') as req_txt: # make a temporary requirements.txt req_txt.writelines('\n'.join(reqs_pip)) req_txt.seek(0) - subprocess.call([sys.executable, '-m', 'pip', 'install', '-r', req_txt.name] + pip_install_as_user) + retcode |= subprocess.call([sys.executable, '-m', 'pip', 'install', '-r', req_txt.name] + pip_install_as_user) ### Add NuRadioMC to PYTHONPATH in .bashrc, if not already available try: @@ -270,7 +271,7 @@ def convert_poetry_to_pip(reqs): write_pre_commit_hook = yesno_input("Custom pre-commit file already present at {}. Overwrite?".format(new_file), skip=args['git_hook']) if write_pre_commit_hook: shutil.copy(old_file, new_file) - subprocess.call(['chmod', '+x', new_file]) + retcode |= subprocess.call(['chmod', '+x', new_file]) print('Successfully installed pre-commit hook at {}'.format(new_file)) else: msg = ( @@ -278,4 +279,6 @@ def convert_poetry_to_pip(reqs): 'the developer version please follow the manual installation ' 'instructions at https://nu-radio.github.io/NuRadioMC/Introduction/pages/installation.html#manual-installation' ) - print(msg) \ No newline at end of file + print(msg) + + sys.exit(retcode) \ No newline at end of file From cd1c95351173bc3eb967f7a29d4706626b1914f3 Mon Sep 17 00:00:00 2001 From: Sjoerd Bouma Date: Wed, 22 Feb 2023 13:35:11 +0100 Subject: [PATCH 144/418] added workflow_dispatch hook (can now manually start workflows) --- .github/workflows/build_and_publish.yaml | 2 +- .github/workflows/deploy_documentation.yaml | 2 +- .github/workflows/run_tests.yaml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build_and_publish.yaml b/.github/workflows/build_and_publish.yaml index e5068cfe3..e06ddfbb0 100644 --- a/.github/workflows/build_and_publish.yaml +++ b/.github/workflows/build_and_publish.yaml @@ -1,6 +1,6 @@ name: Build and publish -on: [push] +on: [push, workflow_dispatch] jobs: build: diff --git a/.github/workflows/deploy_documentation.yaml b/.github/workflows/deploy_documentation.yaml index 802f824f0..104f95fd5 100644 --- a/.github/workflows/deploy_documentation.yaml +++ b/.github/workflows/deploy_documentation.yaml @@ -1,6 +1,6 @@ name: Deploy Documentation -on: [push, pull_request] +on: [push, pull_request, workflow_dispatch] jobs: prepare: runs-on: ubuntu-latest diff --git a/.github/workflows/run_tests.yaml b/.github/workflows/run_tests.yaml index 2da0bd4e8..bfd2a08b6 100644 --- a/.github/workflows/run_tests.yaml +++ b/.github/workflows/run_tests.yaml @@ -1,6 +1,6 @@ name: Unit tests -on: [push, pull_request] +on: [push, pull_request, workflow_dispatch] jobs: prepare: From 5ed66dd83e9a8b4de12f5acc4fb6692dc832ea6e Mon Sep 17 00:00:00 2001 From: Sjoerd Bouma Date: Wed, 22 Feb 2023 13:35:38 +0100 Subject: [PATCH 145/418] update unit tests to run on ubuntu-latest --- .github/workflows/run_tests.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/run_tests.yaml b/.github/workflows/run_tests.yaml index bfd2a08b6..d666940fe 100644 --- a/.github/workflows/run_tests.yaml +++ b/.github/workflows/run_tests.yaml @@ -23,7 +23,7 @@ jobs: build: needs: [prepare] if: needs.prepare.outputs.runtests - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 From 94e66d24dd2df471881a5eb0ca5396a1f1707ed0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Thu, 23 Feb 2023 16:01:53 +0100 Subject: [PATCH 146/418] Fix issue with unkown numpy data type on my mac --- .../eventbrowser/apps/overview_plots/trigger_properties.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NuRadioReco/eventbrowser/apps/overview_plots/trigger_properties.py b/NuRadioReco/eventbrowser/apps/overview_plots/trigger_properties.py index 5c7bcf926..fbad603ad 100644 --- a/NuRadioReco/eventbrowser/apps/overview_plots/trigger_properties.py +++ b/NuRadioReco/eventbrowser/apps/overview_plots/trigger_properties.py @@ -35,7 +35,7 @@ def trigger_overview_properties(filename, evt_counter, station_id, juser_id): for setting_name in trigger.get_trigger_settings(): display_value = '{}' setting_value = trigger.get_trigger_settings()[setting_name] - if type(setting_value) in [float, np.float32, np.float64, np.float128]: + if isinstance(setting_value, float): display_value = '{:.5g}' props.append( html.Div([ From 7f51debc38788a211cc76dfa47208f01a51397d7 Mon Sep 17 00:00:00 2001 From: Alan Coleman Date: Thu, 23 Feb 2023 17:38:06 +0100 Subject: [PATCH 147/418] Added flag to keep full-band waveforms but trigger on narrow band --- NuRadioReco/test/test_noise_gen.py | 63 ++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 NuRadioReco/test/test_noise_gen.py diff --git a/NuRadioReco/test/test_noise_gen.py b/NuRadioReco/test/test_noise_gen.py new file mode 100644 index 000000000..421cfc8ea --- /dev/null +++ b/NuRadioReco/test/test_noise_gen.py @@ -0,0 +1,63 @@ +import numpy as np + +from NuRadioReco.modules.channelBandPassFilter import channelBandPassFilter +from NuRadioReco.utilities.noise import thermalNoiseGenerator +from NuRadioReco.utilities import units, fft + + +n_samples = 1000 +sampling_rate = 1 * units.GHz +Vrms = 1 +threshold = Vrms * 2 +time_coincidence = 5 * units.ns +n_majority = 2 +time_coincidence_majority = 40 * units.ns +n_channels = 10 +trigger_time = 0.2 * n_samples / sampling_rate + +filt = np.zeros + +cBPF = channelBandPassFilter() +frequencies = np.fft.rfftfreq(n_samples, 1.0 / sampling_rate) +filt = cBPF.get_filter( + frequencies, None, 0, None, passband=[sampling_rate * 0.1, sampling_rate * 0.3], filter_type="butter", order=10 +) + + +generator = thermalNoiseGenerator( + n_samples, + sampling_rate, + Vrms, + threshold, + time_coincidence, + n_majority, + time_coincidence_majority, + n_channels, + trigger_time, + filt, + noise_type="rayleigh", + keep_full_band=False, +) +traces_baseline = generator.generate_noise() +specs_baseline = np.median(np.abs(fft.time2freq(traces_baseline, sampling_rate)), axis=0) + + +generator = thermalNoiseGenerator( + n_samples, + sampling_rate, + Vrms, + threshold, + time_coincidence, + n_majority, + time_coincidence_majority, + n_channels, + trigger_time, + filt, + noise_type="rayleigh", + keep_full_band=True, +) +traces_fb = generator.generate_noise() +specs_fb = np.median(np.abs(fft.time2freq(traces_fb, sampling_rate)), axis=0) + +icheck = int(len(specs_fb) * 0.8) +assert np.sum(specs_baseline[icheck:] > specs_fb[icheck:]) == 0 From b8512e6ae872954b2a4cf4b9ef4548f2cb5541a8 Mon Sep 17 00:00:00 2001 From: Alan Coleman Date: Thu, 23 Feb 2023 17:45:26 +0100 Subject: [PATCH 148/418] Changelog --- changelog.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/changelog.txt b/changelog.txt index c4cffda76..16062ccae 100644 --- a/changelog.txt +++ b/changelog.txt @@ -9,6 +9,7 @@ new features: - adding default RadioPropa ice model object to medium with the feature to set a personlised object as alternative - add positions array functionality to simple ice model in average and gradient functions - analytic ray tracing solutions are now sorted consistently from lowest to highest ray +- added ability to generate high-low-triggered noise on a narrow band but return full-band waveforms bugfixes: From 00358cc37e3ad576e0926b3fc01a2e09e04e5e3f Mon Sep 17 00:00:00 2001 From: Alan Coleman Date: Thu, 23 Feb 2023 20:03:22 +0100 Subject: [PATCH 149/418] Added wrong file --- NuRadioReco/test/test_noise_gen.py | 63 ------------------------------ NuRadioReco/utilities/noise.py | 21 ++++++++-- 2 files changed, 17 insertions(+), 67 deletions(-) delete mode 100644 NuRadioReco/test/test_noise_gen.py diff --git a/NuRadioReco/test/test_noise_gen.py b/NuRadioReco/test/test_noise_gen.py deleted file mode 100644 index 421cfc8ea..000000000 --- a/NuRadioReco/test/test_noise_gen.py +++ /dev/null @@ -1,63 +0,0 @@ -import numpy as np - -from NuRadioReco.modules.channelBandPassFilter import channelBandPassFilter -from NuRadioReco.utilities.noise import thermalNoiseGenerator -from NuRadioReco.utilities import units, fft - - -n_samples = 1000 -sampling_rate = 1 * units.GHz -Vrms = 1 -threshold = Vrms * 2 -time_coincidence = 5 * units.ns -n_majority = 2 -time_coincidence_majority = 40 * units.ns -n_channels = 10 -trigger_time = 0.2 * n_samples / sampling_rate - -filt = np.zeros - -cBPF = channelBandPassFilter() -frequencies = np.fft.rfftfreq(n_samples, 1.0 / sampling_rate) -filt = cBPF.get_filter( - frequencies, None, 0, None, passband=[sampling_rate * 0.1, sampling_rate * 0.3], filter_type="butter", order=10 -) - - -generator = thermalNoiseGenerator( - n_samples, - sampling_rate, - Vrms, - threshold, - time_coincidence, - n_majority, - time_coincidence_majority, - n_channels, - trigger_time, - filt, - noise_type="rayleigh", - keep_full_band=False, -) -traces_baseline = generator.generate_noise() -specs_baseline = np.median(np.abs(fft.time2freq(traces_baseline, sampling_rate)), axis=0) - - -generator = thermalNoiseGenerator( - n_samples, - sampling_rate, - Vrms, - threshold, - time_coincidence, - n_majority, - time_coincidence_majority, - n_channels, - trigger_time, - filt, - noise_type="rayleigh", - keep_full_band=True, -) -traces_fb = generator.generate_noise() -specs_fb = np.median(np.abs(fft.time2freq(traces_fb, sampling_rate)), axis=0) - -icheck = int(len(specs_fb) * 0.8) -assert np.sum(specs_baseline[icheck:] > specs_fb[icheck:]) == 0 diff --git a/NuRadioReco/utilities/noise.py b/NuRadioReco/utilities/noise.py index 5dde02202..abcb13ea5 100644 --- a/NuRadioReco/utilities/noise.py +++ b/NuRadioReco/utilities/noise.py @@ -113,7 +113,7 @@ def rolled_sum_slicing(traces, rolling): class thermalNoiseGenerator(): def __init__(self, n_samples, sampling_rate, Vrms, threshold, time_coincidence, n_majority, time_coincidence_majority, - n_channels, trigger_time, filt, noise_type="rayleigh"): + n_channels, trigger_time, filt, noise_type="rayleigh", keep_full_band=False): """ Efficient algorithms to generate thermal noise fluctuations that fulfill a high/low trigger + a majority coincidence logic (as used by ARIANNA) @@ -144,6 +144,9 @@ def __init__(self, n_samples, sampling_rate, Vrms, threshold, time_coincidence, the type of the noise, can be * "rayleigh" (default) * "noise" + keep_full_band: bool + Flag to keep the full-band waveform instead of the one with the filter applied. Allows for + triggering on a different (i.e. `filt`) band than what is returned, (default is False) """ self.n_samples = n_samples self.sampling_rate = sampling_rate @@ -171,6 +174,8 @@ def __init__(self, n_samples, sampling_rate, Vrms, threshold, time_coincidence, self.noise = channelGenericNoiseAdder.channelGenericNoiseAdder() + self.keep_full_band = keep_full_band + def generate_noise(self): """ generates noise traces for all channels that will cause a high/low majority logic trigger @@ -183,14 +188,19 @@ def generate_noise(self): while n_traces[iCh] is None: spec = self.noise.bandlimited_noise(self.min_freq, self.max_freq, self.n_samples, self.sampling_rate, self.amplitude, self.noise_type, time_domain=False) + + if self.keep_full_band: + trace_copy = fft.freq2time(spec, self.sampling_rate) + spec *= self.filt trace = fft.freq2time(spec, self.sampling_rate) if(np.any(trace > self.threshold) and np.any(trace < -self.threshold)): triggered_bins = get_high_low_triggers(trace, self.threshold, -self.threshold, self.time_coincidence, self.dt) if(True in triggered_bins): t_bins[iCh] = triggered_bins + trace_to_keep = trace if not self.keep_full_band else trace_copy if(iCh == 0): - n_traces[iCh] = np.roll(trace, self.trigger_bin - np.argwhere(triggered_bins == True)[0]) + n_traces[iCh] = np.roll(trace_to_keep, self.trigger_bin - np.argwhere(triggered_bins == True)[0]) else: tmp = np.random.randint(self.trigger_bin_low, self.trigger_bin) n_traces[iCh] = np.roll(trace, tmp - np.argwhere(triggered_bins == True)[0]) @@ -203,8 +213,11 @@ def generate_noise(self): else: spec = self.noise.bandlimited_noise(self.min_freq, self.max_freq, self.n_samples, self.sampling_rate, self.amplitude, type=self.noise_type, time_domain=False) - spec *= self.filt - traces[iCh] = fft.freq2time(spec, self.sampling_rate) + + if self.keep_full_band: + traces[iCh] = fft.freq2time(spec, self.sampling_rate) + else: + traces[iCh] = fft.freq2time(spec * self.filt, self.sampling_rate) return traces From 5a89a4979a08e75876c853247f11f6d1d97b1b7d Mon Sep 17 00:00:00 2001 From: Alan Coleman Date: Fri, 24 Feb 2023 12:48:54 +0100 Subject: [PATCH 150/418] Fixed bug that leaves one filtered waveform --- NuRadioReco/utilities/noise.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NuRadioReco/utilities/noise.py b/NuRadioReco/utilities/noise.py index abcb13ea5..2dc66b775 100644 --- a/NuRadioReco/utilities/noise.py +++ b/NuRadioReco/utilities/noise.py @@ -203,7 +203,7 @@ def generate_noise(self): n_traces[iCh] = np.roll(trace_to_keep, self.trigger_bin - np.argwhere(triggered_bins == True)[0]) else: tmp = np.random.randint(self.trigger_bin_low, self.trigger_bin) - n_traces[iCh] = np.roll(trace, tmp - np.argwhere(triggered_bins == True)[0]) + n_traces[iCh] = np.roll(trace_to_keep, tmp - np.argwhere(triggered_bins == True)[0]) traces = np.zeros((self.n_channels, self.n_samples)) rnd_iterator = list(range(self.n_channels)) np.random.shuffle(rnd_iterator) From e92b929e1ff1ca9c780d5de6e3203d59a4efd049 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Mon, 27 Feb 2023 17:12:24 +0100 Subject: [PATCH 151/418] modify event.get_station() to return the first and only station of no station id is given --- NuRadioReco/framework/event.py | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/NuRadioReco/framework/event.py b/NuRadioReco/framework/event.py index c841ed8a0..f32c7075a 100644 --- a/NuRadioReco/framework/event.py +++ b/NuRadioReco/framework/event.py @@ -128,7 +128,30 @@ def set_id(self, evt_id): def get_run_number(self): return self.__run_number - def get_station(self, station_id): + def get_station(self, station_id=None): + """ + Returns the station for a given station id. + + Paramters + --------- + + station_id: int + Id of the station you want to get. If None and event has only one station + return it, otherwise raise error. (Default: None) + + Return + ------ + + station: NuRadioReco.framework.station + """ + if station_id is None: + if len(self.get_station_ids()) == 1: + return self.__stations[self.get_station_ids()[0]] + else: + err = "Event has more than one station, you have to specify \"station_id\"" + logger.error(err) + raise ValueError(err) + return self.__stations[station_id] def get_stations(self): From bcc9c7029635bae145b504026adbc80295387f1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= <30903175+fschlueter@users.noreply.github.com> Date: Mon, 27 Feb 2023 18:59:32 +0100 Subject: [PATCH 152/418] Update event.py Fix doc strings --- NuRadioReco/framework/event.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/NuRadioReco/framework/event.py b/NuRadioReco/framework/event.py index f32c7075a..80530be6c 100644 --- a/NuRadioReco/framework/event.py +++ b/NuRadioReco/framework/event.py @@ -132,15 +132,15 @@ def get_station(self, station_id=None): """ Returns the station for a given station id. - Paramters - --------- + Parameters + ---------- station_id: int Id of the station you want to get. If None and event has only one station return it, otherwise raise error. (Default: None) - Return - ------ + Returns + ------- station: NuRadioReco.framework.station """ From 84dfb77bf0e06785816a65f11fea953d7719a98b Mon Sep 17 00:00:00 2001 From: Sjoerd Bouma Date: Mon, 27 Feb 2023 19:27:34 +0100 Subject: [PATCH 153/418] temporarily use github version of proposal until pypi release is updated --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 26fe70497..adafc4562 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -46,7 +46,7 @@ numba = "*" Sphinx = "*" sphinx-rtd-theme = "*" numpydoc = "1.1.0" -proposal = "7.5.0" +proposal = {git = "https://github.com/tudo-astroparticlephysics/PROPOSAL.git", rev="b95628a"} pygdsm = {git = "https://github.com/telegraphic/pygdsm"} nifty5 = {git = "https://gitlab.mpcdf.mpg.de/ift/nifty.git", branch="NIFTy_5"} pypocketfft = {git = "https://gitlab.mpcdf.mpg.de/mtr/pypocketfft"} From c5aef92634cb4a05128dcb491f6bd1c40096ccb6 Mon Sep 17 00:00:00 2001 From: lpyras Date: Tue, 10 Jan 2023 17:09:27 +0100 Subject: [PATCH 154/418] catch file version 0.0 in event_parser_factory.py --- NuRadioReco/modules/io/NuRadioRecoio.py | 15 ++++++++++++--- NuRadioReco/modules/io/event_parser_factory.py | 7 ++++++- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/NuRadioReco/modules/io/NuRadioRecoio.py b/NuRadioReco/modules/io/NuRadioRecoio.py index bf57c652f..191eb4c40 100644 --- a/NuRadioReco/modules/io/NuRadioRecoio.py +++ b/NuRadioReco/modules/io/NuRadioRecoio.py @@ -6,6 +6,7 @@ import numpy as np import logging import time +import os VERSION = 2 VERSION_MINOR = 2 @@ -97,7 +98,15 @@ def _get_file(self, iF): def __check_file_version(self, iF): self.__file_version = int.from_bytes(self._get_file(iF).read(6), 'little') self.__file_version_minor = int.from_bytes(self._get_file(iF).read(6), 'little') - if(self.__file_version != VERSION): + + if (self.__file_version == 0): + self.logger.error( + f"File might be corrupt, file has version {self.__file_version}.{self.__file_version} " + f"but current version is {VERSION}.{VERSION_MINOR}. " + f"This might indicate the file is empty. The file size is {os.stat(self._filenames[iF]).st_size} B.") + + + elif(self.__file_version != VERSION): self.logger.error( "data file not readable. File has version {}.{} but current version is {}.{}".format( self.__file_version, @@ -108,9 +117,9 @@ def __check_file_version(self, iF): ) if(self.__fail_on_version_mismatch): raise IOError - if(self.__file_version_minor != VERSION_MINOR): + elif(self.__file_version_minor != VERSION_MINOR): self.logger.error( - "data file might not readable. File has version {}.{} but current version is {}.{}".format( + "Data file might not readable, File has version {}.{} but current version is {}.{}".format( self.__file_version, self.__file_version_minor, VERSION, diff --git a/NuRadioReco/modules/io/event_parser_factory.py b/NuRadioReco/modules/io/event_parser_factory.py index 3acdce9aa..1f0a02326 100644 --- a/NuRadioReco/modules/io/event_parser_factory.py +++ b/NuRadioReco/modules/io/event_parser_factory.py @@ -126,8 +126,11 @@ def scan_files_2_2(self, iF, current_byte): return scan_files_2_0 else: return scan_files_2_2 + elif version_major == 0: + raise ValueError(f'File version is {version_major}.{version_major} which might indicate the file is empty') else: - raise ValueError('File version {}.{} is not supported. Major version needs to be 2 but is {}'.format(version_major, version_minor, version_major)) + raise ValueError('File version {}.{} is not supported. Major version needs to be 2 but is {}.'.format(version_major, version_minor, version_major)) + def iter_events_function(version_major, version_minor): @@ -185,5 +188,7 @@ def iter_events_2_2(self): return iter_events_2_0 else: return iter_events_2_2 + elif version_major == 0: + raise ValueError(f'File version is {version_major}.{version_major} which might indicate the file is empty') else: raise ValueError('File version {}.{} is not supported. Major version needs to be 2 but is {}'.format(version_major, version_minor, version_major)) From 6ed398bed20d6daef68fa9e41d768ea6fb55913c Mon Sep 17 00:00:00 2001 From: lpyras Date: Tue, 24 Jan 2023 17:11:40 +0100 Subject: [PATCH 155/418] add a case for version == 1 and version > version_major. --- NuRadioReco/modules/io/NuRadioRecoio.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/NuRadioReco/modules/io/NuRadioRecoio.py b/NuRadioReco/modules/io/NuRadioRecoio.py index 191eb4c40..f7da59216 100644 --- a/NuRadioReco/modules/io/NuRadioRecoio.py +++ b/NuRadioReco/modules/io/NuRadioRecoio.py @@ -105,8 +105,14 @@ def __check_file_version(self, iF): f"but current version is {VERSION}.{VERSION_MINOR}. " f"This might indicate the file is empty. The file size is {os.stat(self._filenames[iF]).st_size} B.") + elif (self.__file_version > VERSION): + self.logger.error( + f"File might be corrupt, file has version {self.__file_version}.{self.__file_version} " + f"but current version is {VERSION}.{VERSION_MINOR}. " + f"This might indicate the file is empty. The file size is {os.stat(self._filenames[iF]).st_size} B.") + - elif(self.__file_version != VERSION): + elif(self.__file_version == 1): self.logger.error( "data file not readable. File has version {}.{} but current version is {}.{}".format( self.__file_version, From 6134773a3da779f6a6e42087caaa3d3eaf3a1dcf Mon Sep 17 00:00:00 2001 From: Janna Vischer Date: Tue, 28 Feb 2023 16:46:41 +0100 Subject: [PATCH 156/418] added else again --- NuRadioReco/modules/phasedarray/triggerSimulator.py | 1 + 1 file changed, 1 insertion(+) diff --git a/NuRadioReco/modules/phasedarray/triggerSimulator.py b/NuRadioReco/modules/phasedarray/triggerSimulator.py index d7faac39b..1527bd5df 100644 --- a/NuRadioReco/modules/phasedarray/triggerSimulator.py +++ b/NuRadioReco/modules/phasedarray/triggerSimulator.py @@ -569,6 +569,7 @@ def run(self, evt, station, det, #trigger_time(s)= time(s) from start of trace + start time of trace with respect to moment of first interaction = trigger time from moment of first interaction; time offset to interaction time (channel_trace_start_time) already recognized in self.phased_trigger trigger.set_trigger_time(trigger_time)# trigger.set_trigger_times(trigger_times) + else: trigger.set_trigger_time(None) station.set_trigger(trigger) From ffac17a964cf6af52648e1290d7c0a23c736f443 Mon Sep 17 00:00:00 2001 From: Sjoerd Bouma Date: Thu, 2 Mar 2023 11:54:27 +0100 Subject: [PATCH 157/418] enable custom css on deployed documentation --- documentation/source/conf.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/documentation/source/conf.py b/documentation/source/conf.py index a7c9b7fe4..41aa599f2 100644 --- a/documentation/source/conf.py +++ b/documentation/source/conf.py @@ -109,7 +109,8 @@ 'sticky_navigation': True, 'navigation_depth': 5 } -html_css_files = [os.path.abspath('custom_scripts/styling.css')] +html_static_path = ['custom_scripts'] +html_css_files = ['styling.css'] html_logo = 'logo_small.png' From 31dec237b50f335d48631912be972b2e6748bf71 Mon Sep 17 00:00:00 2001 From: Sjoerd Bouma Date: Thu, 2 Mar 2023 12:08:38 +0100 Subject: [PATCH 158/418] added HDF5 entries for trigger_times --- documentation/source/NuRadioMC/pages/HDF5_structure.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/documentation/source/NuRadioMC/pages/HDF5_structure.rst b/documentation/source/NuRadioMC/pages/HDF5_structure.rst index eb5dbc30e..66ad8022e 100644 --- a/documentation/source/NuRadioMC/pages/HDF5_structure.rst +++ b/documentation/source/NuRadioMC/pages/HDF5_structure.rst @@ -103,6 +103,7 @@ is the number of showers (which may be larger than the number of events), and `` ``interaction_type`` | (``n_showers``) | Interaction type producing the shower (for the first interaction that can be "nc" or "cc") ``multiple_triggers`` | (``n_showers``, ``n_triggers``) | Information which exact trigger fired each shower. The different triggers are specified in the attributes (``f.attrs["triggers"]``). The order of ``f.attrs["triggers"]`` matches that in ``multiple_triggers`` ``triggered`` | (``n_showers``) | A boolean; ``True`` if any trigger fired for this shower, ``False`` otherwise + ``trigger_times`` | (``n_showers``, ``n_triggers``) | The trigger times (relative to the first interaction) at which each shower triggered. If there are multiple stations, this will be the earliest trigger time. ``n_interaction`` | (``n_showers``) | Hierarchical counter for the number of showers per event (also accounts for showers which did not trigger and might not be saved) ``shower_ids`` | (``n_showers``) | Hierarchical counter for the number of triggered showers ``shower_realization_ARZ`` | (``n_showers``) | Which realization from the ARZ shower library was used for each shower (only if ARZ was used for signal generation). @@ -150,3 +151,4 @@ station triggered, with which amplitude, etc. The same approach works for ``show ``travel_times`` | (``m_showers``, ``n_channels``, ``n_ray_tracing_solutions``) | The time travelled by each ray tracing solution to a specific channel ``triggered`` | (``m_showers``) | Whether each shower contributed to an event that satisfied any trigger condition ``triggered_per_event`` | (``m_events``) | Whether each event fulfilled any trigger condition. + ``trigger_times`` | (``m_showers``, ``n_triggers``) | The trigger times for each shower and trigger. From 5df1b3619cc224ef59a9a0ea2b64971f96c3f4cd Mon Sep 17 00:00:00 2001 From: Sjoerd Bouma Date: Fri, 3 Mar 2023 13:20:30 +0100 Subject: [PATCH 159/418] simplify documentation error classification --- documentation/make_docs.py | 191 +++++++++++++------------------------ 1 file changed, 66 insertions(+), 125 deletions(-) diff --git a/documentation/make_docs.py b/documentation/make_docs.py index 15e09782b..f529dce94 100644 --- a/documentation/make_docs.py +++ b/documentation/make_docs.py @@ -3,62 +3,42 @@ import sys import argparse import logging +import re logging.basicConfig() logger = logging.getLogger(name="Make_docs") logger.setLevel(logging.INFO) -def filter_errs(errs, filter_string, multi_line=[], exclude=None, include_line_numbers=False): - """Selects only lines that contain filter_string - - Optionally can include multiple lines around each match, - and exclude matches containing 'exclude' - """ - line_numbers = [] - for filter_substr in filter_string.split('|'): - line_numbers += [ - i for i,err in enumerate(errs) - if filter_substr in err - ] - line_numbers = sorted(list(set(line_numbers))) # remove duplicates - matches = [(j, errs[j]) for j in line_numbers] - - if exclude != None: - matches = [k for k in matches if (not exclude in k[1])] - - if len(multi_line) == 2: - matches = [ - (k[0], errs[k[0]-multi_line[0]:k[0]+multi_line[1]]) - for k in matches - ] - - if not include_line_numbers: - return [k[1] for k in matches] - else: - return matches - -err_sections = [ - '[reference target not found]', - '[title underline too short]', - '[stub file not found]', - '[unexpected section title]', - '[numpydoc]', - '[indentation]', - '[toctree]', - '[other]' -] - -# we try to classify some of the errors to be helpful -# these are tuples (name, string_to_match) -error_classes = [ - ('reference target not found', 'reference target not found|undefined label'), - ('title underline too short', 'Title underline too short'), - ('stub file not found', 'stub file not found'), - ('unexpected section title', 'Unexpected section title'), - ('numpydoc', 'numpydoc'), - ('indentation', 'expected indent|expected unindent'), - ('toctree', 'toctree') -] +# we do some error classification, because we don't want to fail on all errors +# This is done with simple string matching using re.search +# The classification is exclusive, i.e. once a match has been found the error +# won't be included in a category lower down this list +error_dict = { + 'reference target not found': dict( + pattern='reference target not found|undefined label|unknown document', matches=[] + ), + 'title underline too short': dict( + pattern='Title underline too short', matches=[] + ), + 'Unexpected section title': dict( + pattern='Unexpected section title', matches=[] + ), + 'numpydoc': dict( + pattern='numpydoc', matches=[] + ), + 'stub file not found': dict( + pattern='stub file not found', matches=[] + ), + 'indentation': dict( + pattern='expected indent|expected unindent', matches=[] + ), + 'toctree': dict( + pattern='toctree', matches=[] + ), + 'other': dict( + pattern='', matches = [] + ) + } if __name__ == "__main__": argparser = argparse.ArgumentParser( @@ -86,6 +66,9 @@ def filter_errs(errs, filter_string, multi_line=[], exclude=None, include_line_n file_logger = logging.FileHandler(logfile) file_logger.setLevel(logger.getEffectiveLevel()) logger.addHandler(file_logger) + pipe_stdout = None + else: + pipe_stdout = subprocess.PIPE # hide the stdout doc_path = os.path.dirname(os.path.realpath(__file__)) os.chdir(doc_path) @@ -113,12 +96,12 @@ def filter_errs(errs, filter_string, multi_line=[], exclude=None, include_line_n logger.info("Creating automatic documentation files with apidoc:") logger.info("excluding modules: {}".format(exclude_modules)) - subprocess.call( + subprocess.run( [ 'sphinx-apidoc', '-efMT', '--ext-autodoc', '--ext-intersphinx', '--ext-coverage', '--ext-githubpages', '-o', output_folder, module_path, *exclude_modules - ] + ], stdout=pipe_stdout ) # We don't use the top level NuRadioReco.rst / NuRadioMC.rst toctrees, # so we remove them to eliminate a sphinx warning @@ -128,96 +111,54 @@ def filter_errs(errs, filter_string, multi_line=[], exclude=None, include_line_n if not parsed_args.no_clean: logger.info('Removing old \'build\' directory...') subprocess.check_output(['make', 'clean']) - sphinx_log = subprocess.run(['make', 'html'], stderr=subprocess.PIPE) # stdout=subprocess.PIPE, + sphinx_log = subprocess.run(['make', 'html'], stderr=subprocess.PIPE, stdout=pipe_stdout) - errs = sphinx_log.stderr.decode().split('\n') + # errs = sphinx_log.stderr.decode().split('\n') + errs = re.split('\\x1b\[[0-9;]+m', sphinx_log.stderr.decode()) # split the errors # output = sphinx_log.stdout.decode().split('\n') - # broken cross-references. We ignore warnings originating from docstrings - match_str = 'reference target not found|undefined label|unknown document' - xref_errs = filter_errs(errs, match_str) - xref_errs_in_docstrings = filter_errs(xref_errs, 'docstring') - xref_tofix = filter_errs(errs, match_str, exclude='docstring') - logger.info('{} broken xrefs, of which {} outside docstrings'.format(len(xref_errs), len(xref_tofix))) - - # broken sections - match_str = 'Title underline too short' - section_errs = filter_errs(errs, match_str, multi_line=(0,4)) - section_errs_tofix = filter_errs(errs, match_str, multi_line=(0,4), exclude='docstring') - logger.info('{} bad section titles, of which {} outside docstrings'.format( - len(section_errs), len(section_errs_tofix))) - - # bad docstrings - match_str = 'Unexpected section title' - unexpected_title_errs = filter_errs(errs, match_str, multi_line=(1,4)) - logger.info('{} bad docstring sections'.format(len(unexpected_title_errs))) - - match_str = 'numpydoc' - numpydoc_errs = filter_errs(errs, match_str, multi_line=(0,3)) - logger.info('{} numpydoc errors'.format(len(numpydoc_errs))) - - # missing stubs in .rst files - if these happen, may have to rerun apidoc! - match_str = 'stub file not found' - stub_errs = filter_errs(errs, match_str) - logger.info('{} stub errs'.format(len(stub_errs))) - - match_str = 'expected indent|expected unindent' - indentation_errs = filter_errs(errs, match_str) - indentation_errs_outside_docstrings = filter_errs(errs, match_str, exclude='docstring') - logger.info( - '{} indentation errors, of which {} outside docstrings'.format( - len(indentation_errs), len(indentation_errs_outside_docstrings)) - ) - - match_str = 'toctree' - toctree_errs = filter_errs(errs, match_str) - logger.info( - '{} toctree errors (missing document or missing entry)'.format(len(toctree_errs)) - ) - - all_errs = ( - ['[reference target not found]'] + xref_tofix # we exclude broken xrefs in docstrings - + ['[title underline too short]'] + [k for j in section_errs for k in j] - + ['[stub file not found]'] + stub_errs - + ['[unexpected section title]'] + [k for j in unexpected_title_errs for k in j] - + ['[numpydoc]'] + [k for j in numpydoc_errs for k in j] - + ['[indentation]'] + indentation_errs - + [err_sections[6]] + toctree_errs - ) - - other_errs = [ - err for err in errs - if (err not in all_errs) & (err not in xref_errs) - ] - - fixable_errors = (len(all_errs) > len(err_sections) - 1) + for err in errs: + if not err.split(): # whitespace only + continue + for key in error_dict.keys(): + if re.search(error_dict[key]['pattern'], err): + error_dict[key]['matches'].append(err) + break # we don't match errors to multiple categories + + fixable_errors = 0 + for key in error_dict.keys(): + if key == 'other': # we don't fail on these errors + continue + fixable_errors += len(error_dict[key]['matches']) + print(2*'\n'+78*'-') if fixable_errors: logger.warning("The documentation was not built without errors. Please fix the following errors!") - print('\n'.join(all_errs)) - elif len(other_errs): + for key, item in error_dict.items(): + if len(item['matches']): + print(f'[{key}]') + print('\n'.join(item['matches'])) + elif len(error_dict['other']['matches']): logger.warning(( "make_docs found some errors but doesn't know what to do with them.\n" "The documentation may not be rejected, but consider fixing the following anyway:" )) - print('\n'.join(other_errs)) + print('\n'.join(error_dict['other']['matches'])) + print(78*'-'+2*'\n') if sphinx_log.returncode: logger.error("The documentation failed to build, make_docs will raise an error.") - + # print(error_dict) if parsed_args.debug: logger.info('Logging output under {}'.format(logfile)) with open(logfile, 'w') as file: # file.write('[stdout]\n') # file.write('\n'.join(output)) # file.write('\n') - file.write('[broken references in docstrings] # these can be ignored\n') - file.write('\n'.join(xref_errs_in_docstrings)) - file.write('\n') - file.write('\n'.join(all_errs)) - file.write('\n') - file.write('[other]\n') - file.write('\n'.join(other_errs)) - + for key, item in error_dict.items(): + if len(item['matches']): + file.write(f'\n[{key}]\n') + file.write('\n'.join(item['matches'])) + if fixable_errors or sphinx_log.returncode: sys.exit(1) \ No newline at end of file From 22497c36343824613b5240dfd5a7efb51eb201de Mon Sep 17 00:00:00 2001 From: Sjoerd Bouma Date: Fri, 3 Mar 2023 13:22:36 +0100 Subject: [PATCH 160/418] fix some minor issues with cross-referencing errors --- documentation/source/conf.py | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/documentation/source/conf.py b/documentation/source/conf.py index 41aa599f2..d24163148 100644 --- a/documentation/source/conf.py +++ b/documentation/source/conf.py @@ -213,7 +213,12 @@ # Example configuration for intersphinx: refer to the Python standard library. -intersphinx_mapping = {'https://docs.python.org/': None} +intersphinx_mapping = { + 'python': ('https://docs.python.org/3', None), + 'scipy': ('https://docs.scipy.org/doc/scipy', None), + 'numpy': ("https://numpy.org/doc/stable", None) +} +default_role = 'autolink' #TODO: probably switch to py:obj? # Make sure the target is unique autosectionlabel_prefix_document = True @@ -222,6 +227,11 @@ numpydoc_class_members_toctree = False autoclass_content = 'both' # include __init__ docstrings in class description +autodoc_default_options = { + 'show-inheritance': True, # show 'Bases: Parent' for classes that inherit from parent classes + 'inherited-members': True, # also document inherited methods; mostly done to avoid missing cross-references +} +autodoc_member_order = 'bysource' # list methods/variables etc. by the order they are defined, rather than alphabetically # # coverage_ignore_modules @@ -237,14 +247,11 @@ # this ignores some cross-reference errors inside docstrings # that we don't care about nitpick_ignore_regex = [ - ("py:class", "NuRadioReco.*"), - ("py:class", "NuRadioMC.*"), ("py:class", "aenum.Enum"), ("py:class", "tinydb_serialization.Serializer"), ("py:class", "radiopropa.ScalarField"), - ("py:obj", "NuRadioReco.*"), - ("py:obj", "NuRadioMC.*"), - ("py:class", "nifty5.*") + ("py:class", "nifty5.*"), + ("py:obj",".*__call__") # not sure why this method is listed sometimes - it shouldn't be? ] # def skip_modules(app, what, name, obj, skip, options): From a61417eb8ebb36fbc60720e5035ff66364230707 Mon Sep 17 00:00:00 2001 From: Sjoerd Bouma Date: Fri, 3 Mar 2023 13:23:35 +0100 Subject: [PATCH 161/418] parameters info now shows up in the compiled documentation too --- NuRadioReco/framework/parameters.py | 279 ++++++++++++++-------------- 1 file changed, 142 insertions(+), 137 deletions(-) diff --git a/NuRadioReco/framework/parameters.py b/NuRadioReco/framework/parameters.py index 680d96bbf..575d7b402 100644 --- a/NuRadioReco/framework/parameters.py +++ b/NuRadioReco/framework/parameters.py @@ -1,164 +1,170 @@ +""" +Provides an interface to store simulated and reconstructed quantities + +The parameters module provides access to store and read simulated or +reconstructed quantities in the different custom classes used in NuRadioMC. + +""" + from aenum import Enum class stationParameters(Enum): - nu_zenith = 1 # the zenith angle of the incoming neutrino direction - nu_azimuth = 2 # the azimuth angle of the incoming neutrino direction - nu_energy = 3 # the energy of the neutrino - nu_flavor = 4 # the flavor of the neutrino - ccnc = 5 # neutral current of charged current interaction - nu_vertex = 6 # the neutrino vertex position - inelasticity = 7 # inelasticity ot neutrino interaction - triggered = 8 # flag if station was triggered or not - cr_energy = 9 # the cosmic-ray energy - cr_zenith = 10 # zenith angle of the cosmic-ray incoming direction - cr_azimuth = 11 # azimuth angle of the cosmic-ray incoming direction - channels_max_amplitude = 12 # the maximum amplitude of all channels (considered in the trigger module) - zenith = 13 # the zenith angle of the incoming signal direction (WARNING: this parameter is not well defined as the incoming signal direction might be different for different channels) - azimuth = 14 # the azimuth angle of the incoming signal direction (WARNING: this parameter is not well defined as the incoming signal direction might be different for different channels) + nu_zenith = 1 #: the zenith angle of the incoming neutrino direction + nu_azimuth = 2 #: the azimuth angle of the incoming neutrino direction + nu_energy = 3 #: the energy of the neutrino + nu_flavor = 4 #: the flavor of the neutrino + ccnc = 5 #: neutral current of charged current interaction + nu_vertex = 6 #: the neutrino vertex position + inelasticity = 7 #: inelasticity ot neutrino interaction + triggered = 8 #: flag if station was triggered or not + cr_energy = 9 #: the cosmic-ray energy + cr_zenith = 10 #: zenith angle of the cosmic-ray incoming direction + cr_azimuth = 11 #: azimuth angle of the cosmic-ray incoming direction + channels_max_amplitude = 12 #: the maximum amplitude of all channels (considered in the trigger module) + zenith = 13 #: the zenith angle of the incoming signal direction (WARNING: this parameter is not well defined as the incoming signal direction might be different for different channels) + azimuth = 14 #: the azimuth angle of the incoming signal direction (WARNING: this parameter is not well defined as the incoming signal direction might be different for different channels) zenith_cr_templatefit = 15 zenith_nu_templatefit = 16 - cr_xcorrelations = 19 # dict of result of crosscorrelations with cr templates - nu_xcorrelations = 20 # dict of result of crosscorrelations with nu templates + cr_xcorrelations = 19 #: dict of result of crosscorrelations with cr templates + nu_xcorrelations = 20 #: dict of result of crosscorrelations with nu templates station_time = 21 - cr_energy_em = 24 # the electromagnetic shower energy (the cosmic ray energy that ends up in electrons, positrons and gammas) - nu_inttype = 25 # interaction type, e.g., cc, nc, tau_em, tau_had - chi2_efield_time_direction_fit = 26 # the chi2 of the direction fitter that used the maximum pulse times of the efields - ndf_efield_time_direction_fit = 27 # the number of degrees of freedom of the direction fitter that used the maximum pulse times of the efields - cr_xmax = 28 # Depth of shower maximum of the air shower - vertex_2D_fit = 29 # horizontal distance and z coordinate of the reconstructed vertex of the neutrino + cr_energy_em = 24 #: the electromagnetic shower energy (the cosmic ray energy that ends up in electrons, positrons and gammas) + nu_inttype = 25 #: interaction type, e.g., cc, nc, tau_em, tau_had + chi2_efield_time_direction_fit = 26 #: the chi2 of the direction fitter that used the maximum pulse times of the efields + ndf_efield_time_direction_fit = 27 #: the number of degrees of freedom of the direction fitter that used the maximum pulse times of the efields + cr_xmax = 28 #: Depth of shower maximum of the air shower + vertex_2D_fit = 29 #: horizontal distance and z coordinate of the reconstructed vertex of the neutrino distance_correlations = 30 - shower_energy = 31 # the energy of the shower - viewing_angles = 32 # reconstructed viewing angles. A nested map structure. First key is channel id, second key is ray tracing solution id. Value is a float + shower_energy = 31 #: the energy of the shower + viewing_angles = 32 #: reconstructed viewing angles. A nested map structure. First key is channel id, second key is ray tracing solution id. Value is a float class channelParameters(Enum): - zenith = 1 # zenith angle of the incoming signal direction - azimuth = 2 # azimuth angle of the incoming signal direction - maximum_amplitude = 4 # the maximum ampliude of the magnitude of the trace - SNR = 5 # an dictionary of various signal-to-noise ratio definitions - maximum_amplitude_envelope = 6 # the maximum ampliude of the hilbert envelope of the trace - P2P_amplitude = 7 # the peak to peak amplitude - cr_xcorrelations = 8 # dict of result of crosscorrelations with cr templates - nu_xcorrelations = 9 # dict of result of crosscorrelations with nu templates - signal_time = 10 # the time of the maximum amplitude of the envelope - noise_rms = 11 # the root mean square of the noise - signal_regions = 12 # list of start and end times of regions that likely contain a signal - noise_regions = 13 # list of start and end times of regions that likel do not contain any signals - signal_time_offset = 14 # the relative timing differences of the signal arrival times between channels - signal_receiving_zenith = 15 # the zenith angle of direction at which the radio signal arrived at the antenna - signal_ray_type = 16 # type of the ray propagation path of the signal received by this channel. Options are direct, reflected and refracted - signal_receiving_azimuth = 17 # the azimuth angle of direction at which the radio signal arrived at the antenna + zenith = 1 #: zenith angle of the incoming signal direction + azimuth = 2 #: azimuth angle of the incoming signal direction + maximum_amplitude = 4 #: the maximum ampliude of the magnitude of the trace + SNR = 5 #: an dictionary of various signal-to-noise ratio definitions + maximum_amplitude_envelope = 6 #: the maximum ampliude of the hilbert envelope of the trace + P2P_amplitude = 7 #: the peak to peak amplitude + cr_xcorrelations = 8 #: dict of result of crosscorrelations with cr templates + nu_xcorrelations = 9 #: dict of result of crosscorrelations with nu templates + signal_time = 10 #: the time of the maximum amplitude of the envelope + noise_rms = 11 #: the root mean square of the noise + signal_regions = 12 #: list of start and end times of regions that likely contain a signal + noise_regions = 13 #: list of start and end times of regions that likel do not contain any signals + signal_time_offset = 14 #: the relative timing differences of the signal arrival times between channels + signal_receiving_zenith = 15 #: the zenith angle of direction at which the radio signal arrived at the antenna + signal_ray_type = 16 #: type of the ray propagation path of the signal received by this channel. Options are direct, reflected and refracted + signal_receiving_azimuth = 17 #: the azimuth angle of direction at which the radio signal arrived at the antenna class electricFieldParameters(Enum): - ray_path_type = 1 # the type of the ray tracing solution ('direct', 'refracted' or 'reflected') - polarization_angle = 2 # electric field polarization in onsky-coordinates. 0 corresponds to polarization in e_theta, 90deg is polarization in e_phi - polarization_angle_expectation = 3 # expected polarization based on shower geometry. Defined analogous to polarization_angle - signal_energy_fluence = 4 # Energy/area in the radio signal - cr_spectrum_slope = 5 # Slope of the radio signal's spectrum as reconstructed by the voltageToAnalyticEfieldConverter - zenith = 7 # zenith angle of the signal. Note that refraction at the air/ice boundary is not taken into account - azimuth = 8 # azimuth angle of the signal. Note that refraction at the air/ice boundary is not taken into account + ray_path_type = 1 #: the type of the ray tracing solution ('direct', 'refracted' or 'reflected') + polarization_angle = 2 #: electric field polarization in onsky-coordinates. 0 corresponds to polarization in e_theta, 90deg is polarization in e_phi + polarization_angle_expectation = 3 #: expected polarization based on shower geometry. Defined analogous to polarization_angle + signal_energy_fluence = 4 #: Energy/area in the radio signal + cr_spectrum_slope = 5 #: Slope of the radio signal's spectrum as reconstructed by the voltageToAnalyticEfieldConverter + zenith = 7 #: zenith angle of the signal. Note that refraction at the air/ice boundary is not taken into account + azimuth = 8 #: azimuth angle of the signal. Note that refraction at the air/ice boundary is not taken into account signal_time = 9 - nu_vertex_distance = 10 # the distance along the ray path from the vertex to the channel - nu_viewing_angle = 11 # the angle between shower axis and launch vector - max_amp_antenna = 12 # the maximum amplitude of the signal after convolution with the antenna response pattern, dict with channelid as key - max_amp_antenna_envelope = 13 # the maximum amplitude of the signal envelope after convolution with the antenna response pattern, dict with channelid as key - reflection_coefficient_theta = 14 # for reflected rays: the complex Fresnel reflection coefficient of the eTheta component - reflection_coefficient_phi = 15 # for reflected rays: the complex Fresnel reflection coefficient of the ePhi component - cr_spectrum_quadratic_term = 16 # result of the second order correction to the spectrum fitted by the voltageToAnalyticEfieldConverter - energy_fluence_ratios = 17 # Ratios of the energy fluences in different passbands - - -class ARIANNAParameters(Enum): # this class stores parameters specific to the ARIANNA data taking - seq_start_time = 1 # the start time of a sequence - seq_stop_time = 2 # the stop time of a sequence - seq_num = 3 # the sequence number of the current event - comm_period = 4 # length of data taking window - comm_duration = 5 # maximum diration of communication window - trigger_thresholds = 6 # trigger thresholds converted to voltage - l1_supression_value = 7 # This provieds the L1 supression value for given event - internal_clock_time = 8 # time since last trigger with ms precision + nu_vertex_distance = 10 #: the distance along the ray path from the vertex to the channel + nu_viewing_angle = 11 #: the angle between shower axis and launch vector + max_amp_antenna = 12 #: the maximum amplitude of the signal after convolution with the antenna response pattern, dict with channelid as key + max_amp_antenna_envelope = 13 #: the maximum amplitude of the signal envelope after convolution with the antenna response pattern, dict with channelid as key + reflection_coefficient_theta = 14 #: for reflected rays: the complex Fresnel reflection coefficient of the eTheta component + reflection_coefficient_phi = 15 #: for reflected rays: the complex Fresnel reflection coefficient of the ePhi component + cr_spectrum_quadratic_term = 16 #: result of the second order correction to the spectrum fitted by the voltageToAnalyticEfieldConverter + energy_fluence_ratios = 17 #: Ratios of the energy fluences in different passbands + + +class ARIANNAParameters(Enum): #: this class stores parameters specific to the ARIANNA data taking + seq_start_time = 1 #: the start time of a sequence + seq_stop_time = 2 #: the stop time of a sequence + seq_num = 3 #: the sequence number of the current event + comm_period = 4 #: length of data taking window + comm_duration = 5 #: maximum diration of communication window + trigger_thresholds = 6 #: trigger thresholds converted to voltage + l1_supression_value = 7 #: This provieds the L1 supression value for given event + internal_clock_time = 8 #: time since last trigger with ms precision class showerParameters(Enum): - zenith = 1 # zenith angle of the shower axis pointing towards xmax - azimuth = 2 # azimuth angle of the shower axis pointing towards xmax - core = 3 # position of the intersection between shower axis and an observer plane - energy = 4 # total energy of the primary particle, or shower energy for in-ice particle showers - electromagnetic_energy = 5 # energy of the electromagnetic shower component - radiation_energy = 6 # totally emitted radiation energy - electromagnetic_radiation_energy = 7 # radiation energy originated from the electromagnetic emission - primary_particle = 8 # particle id of the primary particle - shower_maximum = 9 # position of shower maximum in slant depth, e.g., Xmax - distance_shower_maximum_geometric = 10 # distance to xmax in meter - distance_shower_maximum_grammage = 11 # distance to xmax in g / cm^2 - parent_id = 12 # id of parent in sim particles - - # dedicated parameter for sim showers - refractive_index_at_ground = 100 # refractivity at sea level - atmospheric_model = 101 # atmospheric model used in simulation - # offset between magnetic field and north in reconstruction corrdinatesystem + zenith = 1 #: zenith angle of the shower axis pointing towards xmax + azimuth = 2 #: azimuth angle of the shower axis pointing towards xmax + core = 3 #: position of the intersection between shower axis and an observer plane + energy = 4 #: total energy of the primary particle, or shower energy for in-ice particle showers + electromagnetic_energy = 5 #: energy of the electromagnetic shower component + radiation_energy = 6 #: totally emitted radiation energy + electromagnetic_radiation_energy = 7 #: radiation energy originated from the electromagnetic emission + primary_particle = 8 #: particle id of the primary particle + shower_maximum = 9 #: position of shower maximum in slant depth, e.g., Xmax + distance_shower_maximum_geometric = 10 #: distance to xmax in meter + distance_shower_maximum_grammage = 11 #: distance to xmax in g / cm^2 + parent_id = 12 #: id of parent in sim particles + + #: dedicated parameter for sim showers + refractive_index_at_ground = 100 #: refractivity at sea level + atmospheric_model = 101 #: atmospheric model used in simulation + #: offset between magnetic field and north in reconstruction corrdinatesystem magnetic_field_rotation = 102 - magnetic_field_vector = 103 # magnetic field used in simulation in local coordinate system - observation_level = 104 # altitude a.s.l where the particles are stored + magnetic_field_vector = 103 #: magnetic field used in simulation in local coordinate system + observation_level = 104 #: altitude a.s.l where the particles are stored - charge_excess_profile_id = 105 # the id of the charge-excess profile used in the ARZ Askaryan calculation - type = 106 # for neutrino induces showers in ice: can be "HAD" or "EM" - vertex = 107 # the interaction vertex (for air showers this corresponds to the point of X0) - vertex_time = 108 # the propagation time relative to the first interactions - interaction_type = 109 # the interaction type, e.g. cc or nc - k_L = 110 # the k_L parameter of the Alvarez2009 parameter that controls the longitudional width of the charge excess profile - flavor = 111 # the flavor of the particle initiating the shower + charge_excess_profile_id = 105 #: the id of the charge-excess profile used in the ARZ Askaryan calculation + type = 106 #: for neutrino induces showers in ice: can be "HAD" or "EM" + vertex = 107 #: the interaction vertex (for air showers this corresponds to the point of X0) + vertex_time = 108 #: the propagation time relative to the first interactions + interaction_type = 109 #: the interaction type, e.g. cc or nc + k_L = 110 #: the k_L parameter of the Alvarez2009 parameter that controls the longitudional width of the charge excess profile + flavor = 111 #: the flavor of the particle initiating the shower - interferometric_shower_maximum = 120 # depth of the maximum of the longitudinal profile of the beam-formed signal - interferometric_shower_axis = 121 # shower axis (direction) derived from beam-formed signal - interferometric_core = 122 # core (intersection of shower axis with obs plane) derived from beam-formed signal + interferometric_shower_maximum = 120 #: depth of the maximum of the longitudinal profile of the beam-formed signal + interferometric_shower_axis = 121 #: shower axis (direction) derived from beam-formed signal + interferometric_core = 122 #: core (intersection of shower axis with obs plane) derived from beam-formed signal class particleParameters(Enum): - parent_id = 1 # the entry number of the parent particle, None if primary. - zenith = 2 # the zenith angle of the incoming neutrino direction - azimuth = 3 # the azimuth angle of the incoming neutrino direction - energy = 4 # the energy of the neutrino - flavor = 5 # the flavor of the neutrino, more generally the PDG code - vertex = 6 # the neutrino vertex position (x,y,z) + parent_id = 1 #: the entry number of the parent particle, None if primary. + zenith = 2 #: the zenith angle of the incoming neutrino direction + azimuth = 3 #: the azimuth angle of the incoming neutrino direction + energy = 4 #: the energy of the neutrino + flavor = 5 #: the flavor of the neutrino, more generally the PDG code + vertex = 6 #: the neutrino vertex position (x,y,z) vertex_time = 9 weight = 10 - inelasticity = 11 # inelasticity ot neutrino interaction - interaction_type = 12 # interaction type, e.g., cc, nc - n_interaction = 13 # number of interaction + inelasticity = 11 #: inelasticity ot neutrino interaction + interaction_type = 12 #: interaction type, e.g., cc, nc + n_interaction = 13 #: number of interaction - cr_energy = 101 # the cosmic-ray energy - cr_zenith = 102 # zenith angle of the cosmic-ray incoming direction - cr_azimuth = 103 # azimuth angle of the cosmic-ray incoming direction - cr_energy_em = 104 # the electromagnetic shower energy (the cosmic ray energy that ends up in electrons, positrons and gammas) + cr_energy = 101 #: the cosmic-ray energy + cr_zenith = 102 #: zenith angle of the cosmic-ray incoming direction + cr_azimuth = 103 #: azimuth angle of the cosmic-ray incoming direction + cr_energy_em = 104 #: the electromagnetic shower energy (the cosmic ray energy that ends up in electrons, positrons and gammas) class generatorAttributes(Enum): - Emax = 1 # maximum simulated energy - Emin = 2 # minimum simulated energy + Emax = 1 #: maximum simulated energy + Emin = 2 #: minimum simulated energy - deposited = 3 # deposited energies or neutrino energies? + deposited = 3 #: deposited energies or neutrino energies? - # fiducial volume parameters, rmin/max for circular footprint - fiducial_rmin = 4 - fiducial_rmax = 5 - # alternatively xy min/max for rectangular footprint will be set - fiducial_xmin = 6 - fiducial_xmax = 7 - fiducial_ymin = 8 - fiducial_ymax = 9 + fiducial_rmin = 4 #: fiducial volume parameter (if cylindrical footprint used) + fiducial_rmax = 5 #: fiducial volume parameter (if cylindrical footprint used) + + fiducial_xmin = 6 #: fiducial volume parameter (if rectangular footprint used) + fiducial_xmax = 7 #: fiducial volume parameter (if rectangular footprint used) + fiducial_ymin = 8 #: fiducial volume parameter (if rectangular footprint used) + fiducial_ymax = 9 #: fiducial volume parameter (if rectangular footprint used) fiducial_zmin = 10 fiducial_zmax = 11 - # volume parameters, rmin/max for circular footprint - rmin = 12 - rmax = 13 - # alternatively xy min/max for rectangular footprint will be set - xmin = 14 - xmax = 15 - ymin = 16 - ymax = 17 + rmin = 12 #: volume parameter (if cylindrical) + rmax = 13 #: volume parameter (if cylindrical) + + xmin = 14 #: volume parameter (if rectangular) + xmax = 15 #: volume parameter (if rectangular) + ymin = 16 #: volume parameter (if rectangular) + ymax = 17 #: volume parameter (if rectangular) zmin = 18 zmax = 19 @@ -167,14 +173,13 @@ class generatorAttributes(Enum): volume = 20 area = 21 - # simulated space angle range - phimax = 22 - phimin = 23 - thetamax = 24 - thetamin = 25 + phimax = 22 #: simulated space angle range + phimin = 23 #: simulated space angle range + thetamax = 24 #: simulated space angle range + thetamin = 25 #: simulated space angle range - flavors = 26 # list of simulated event flavours - dt = 27 # not sure the dt (time since primary vertex from proposal) is needed here. + flavors = 26 #: list of simulated event flavours + dt = 27 #: inverse of sampling rate used in the simulation # simulated statistics n_events = 100 @@ -189,6 +194,6 @@ class generatorAttributes(Enum): NuRadioMC_version_hash = 203 class eventParameters(Enum): - sim_config = 1 # contents of the config file that the NuRadioMC simulation was run with - hash_NuRadioReco = 2 # deprecated, since NuRadioReco is no longer its own repository - hash_NuRadioMC = 3 # git hash of the NuRadioMC commit that the file was created with + sim_config = 1 #: contents of the config file that the NuRadioMC simulation was run with + hash_NuRadioReco = 2 #: deprecated, since NuRadioReco is no longer its own repository + hash_NuRadioMC = 3 #: git hash of the NuRadioMC commit that the file was created with From 208c29ab708675331b2481f62a7371e3cbf28305 Mon Sep 17 00:00:00 2001 From: Sjoerd Bouma Date: Fri, 3 Mar 2023 13:27:28 +0100 Subject: [PATCH 162/418] minor update/fixes to documentation --- documentation/source/Introduction/pages/contributing.rst | 4 ++-- documentation/source/Introduction/pages/installation.rst | 4 ++-- documentation/source/NuRadioReco/pages/event_structure.rst | 1 + 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/documentation/source/Introduction/pages/contributing.rst b/documentation/source/Introduction/pages/contributing.rst index 38cc3152e..790f66cad 100644 --- a/documentation/source/Introduction/pages/contributing.rst +++ b/documentation/source/Introduction/pages/contributing.rst @@ -214,8 +214,8 @@ Compiling the documentation is then done by running python documentation/make_docs.py -This will build the documentation at `documentation/build/html` -(open `main.html` to view it in your browser). +This will build the documentation at ``documentation/build/html`` +(open ``main.html`` to view it in your browser). Headings and text ^^^^^^^^^^^^^^^^^ diff --git a/documentation/source/Introduction/pages/installation.rst b/documentation/source/Introduction/pages/installation.rst index 0b1d26517..58bdb7b3c 100644 --- a/documentation/source/Introduction/pages/installation.rst +++ b/documentation/source/Introduction/pages/installation.rst @@ -193,7 +193,7 @@ These packages are recommended to be able to use all of NuRadioMC/NuRadioReco's Note that the pip installation for this version of proposal may not work on all systems, in particular: - - conda cannot be used on all systems (eg. on Mac), in that case use a python venv, see details `here `_ + - conda cannot be used on all systems (eg. on Mac), in that case use a python venv, see details `here `__ - if the linux kernel is too old (eg. on some computing clusters), refer to `this step-by-step guide `_ @@ -218,6 +218,6 @@ ____________________________ With GSL installed, compile the CPP ray tracer by navigating to ``NuRadioMC/NuRadioMC/SignalProp`` and running the included ``install.sh`` script. - To use the :mod:`RadioPropa numerical ray tracing ` module, ``radiopropa`` needs to be installed. - The radiopropa github, with installation instructions, can be found `here `_. + The radiopropa github, with installation instructions, can be found `here `__. - To read ARIANNA files, `Snowshovel `_ needs to be installed. - To read ARA files, `ARA ROOT `_ needs to be installed. diff --git a/documentation/source/NuRadioReco/pages/event_structure.rst b/documentation/source/NuRadioReco/pages/event_structure.rst index 81cc5aae5..58e7daddd 100644 --- a/documentation/source/NuRadioReco/pages/event_structure.rst +++ b/documentation/source/NuRadioReco/pages/event_structure.rst @@ -122,6 +122,7 @@ it just needs to be added to the .. admonition:: For Developers New parameters should always be added to the bottom of the list. Do not re-use old Enums! + A description should be added to each new parameter with a comment docstring starting with ``#:``. Additionally, parameters can be written and accessed via indexing, like one would do to a dictionary: From 52c71a0db552b6baafdc5c03b39c6529628dad56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Tue, 7 Mar 2023 11:32:29 +0100 Subject: [PATCH 163/418] Only refactoring get_attenuation_along_path(): Renaming variables, coding style. --- NuRadioMC/SignalProp/analyticraytracing.py | 60 +++++++++++++--------- 1 file changed, 37 insertions(+), 23 deletions(-) diff --git a/NuRadioMC/SignalProp/analyticraytracing.py b/NuRadioMC/SignalProp/analyticraytracing.py index 988cc52a5..0c1fb5b13 100644 --- a/NuRadioMC/SignalProp/analyticraytracing.py +++ b/NuRadioMC/SignalProp/analyticraytracing.py @@ -556,11 +556,19 @@ def __get_frequencies_for_attenuation(self, frequency, max_detector_freq): self.__logger.debug(f"calculating attenuation for frequencies {freqs}") return freqs - def get_attenuation_along_path(self, x1, x2, C_0, frequency, max_detector_freq, reflection=0, reflection_case=1): - tmp_attenuation = None + + def get_attenuation_along_path(self, x1, x2, C_0, frequency, max_detector_freq, + reflection=0, reflection_case=1): + + attenuation = np.ones_like(frequency) + output = f"calculating attenuation for n_ref = {int(reflection):d}: " - for iS, segment in enumerate(self.get_path_segments(x1, x2, C_0, reflection, reflection_case)): - if(iS == 0 and reflection_case == 2): # we can only integrate upward going rays, so if the ray starts downwardgoing, we need to mirror + for iS, segment in enumerate(self.get_path_segments(x1, x2, C_0, reflection, + reflection_case)): + + # we can only integrate upward going rays, so if the ray starts downwardgoing, + # we need to mirror + if iS == 0 and reflection_case == 2: x11, x1, x22, x2, C_0, C_1 = segment x1t = copy.copy(x11) x2t = copy.copy(x2) @@ -570,17 +578,20 @@ def get_attenuation_along_path(self, x1, x2, C_0, frequency, max_detector_freq, x1 = x1t else: x11, x1, x22, x2, C_0, C_1 = segment - - if(cpp_available): + + if cpp_available: mask = frequency > 0 freqs = self.__get_frequencies_for_attenuation(frequency, max_detector_freq) tmp = np.zeros_like(freqs) for i, f in enumerate(freqs): tmp[i] = wrapper.get_attenuation_along_path( - x1, x2, C_0, f, self.medium.n_ice, self.medium.delta_n, self.medium.z_0, self.attenuation_model_int) + x1, x2, C_0, f, self.medium.n_ice, self.medium.delta_n, + self.medium.z_0, self.attenuation_model_int) + self.__logger.debug(tmp) - attenuation = np.ones_like(frequency) - attenuation[mask] = np.interp(frequency[mask], freqs, tmp) + tmp_attenuation = np.ones_like(frequency) + tmp_attenuation[mask] = np.interp(frequency[mask], freqs, tmp) + else: x2_mirrored = self.get_z_mirrored(x1, x2, C_0) @@ -588,31 +599,34 @@ def get_attenuation_along_path(self, x1, x2, C_0, frequency, max_detector_freq, def dt(t, C_0, frequency): z = self.get_z_unmirrored(t, C_0) return self.ds(t, C_0) / attenuation_util.get_attenuation_length(z, frequency, self.attenuation_model) - + # to speed up things we only calculate the attenuation for a few frequencies # and interpolate linearly between them mask = frequency > 0 freqs = self.__get_frequencies_for_attenuation(frequency, max_detector_freq) gamma_turn, z_turn = self.get_turning_point(self.medium.n_ice ** 2 - C_0 ** -2) points = None - if(x1[1] < z_turn and z_turn < x2_mirrored[1]): + if x1[1] < z_turn and z_turn < x2_mirrored[1]: points = [z_turn] - tmp = np.array([integrate.quad(dt, x1[1], x2_mirrored[1], args=( + + attenuation_exp = np.array([integrate.quad(dt, x1[1], x2_mirrored[1], args=( C_0, f), epsrel=1e-2, points=points)[0] for f in freqs]) - tmp = np.exp(-1 * tmp) - # tmp = np.array([integrate.quad(dt, x1[1], x2_mirrored[1], args=(C_0, f), epsrel=0.05)[0] for f in frequency[mask]]) - attenuation = np.ones_like(frequency) - attenuation[mask] = np.interp(frequency[mask], freqs, tmp) + tmp = np.exp(-1 * attenuation_exp) + # tmp = np.array([integrate.quad(dt, x1[1], x2_mirrored[1], args=(C_0, f), epsrel=0.05)[0] for f in frequency[mask]]) + + tmp_attenuation = np.ones_like(frequency) + tmp_attenuation[mask] = np.interp(frequency[mask], freqs, tmp) self.__logger.info("calculating attenuation from ({:.0f}, {:.0f}) to ({:.0f}, {:.0f}) = ({:.0f}, {:.0f}) = a factor {}".format( - x1[0], x1[1], x2[0], x2[1], x2_mirrored[0], x2_mirrored[1], 1 / attenuation)) + x1[0], x1[1], x2[0], x2[1], x2_mirrored[0], x2_mirrored[1], 1 / tmp_attenuation)) + iF = len(frequency) // 3 - output += f"adding attenuation for path segment {iS:d} -> {attenuation[iF]:.2g} at {frequency[iF]/units.MHz:.0f} MHz, " - if(tmp_attenuation is None): - tmp_attenuation = attenuation - else: - tmp_attenuation *= attenuation + output += f"adding attenuation for path segment {iS:d} -> {tmp_attenuation[iF]:.2g} at {frequency[iF]/units.MHz:.0f} MHz, " + + attenuation *= tmp_attenuation + self.__logger.info(output) - return tmp_attenuation + return attenuation + def get_path_segments(self, x1, x2, C_0, reflection=0, reflection_case=1): """ From 007a83f3629b4efddf54c264e3d69b5c663d9c24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Tue, 7 Mar 2023 13:53:31 +0100 Subject: [PATCH 164/418] Optimize get_attenuation_along_path for attenuation model GL3. Attenuation factor is now calculated along discrete (path)segments which are than summed. A fallback to a numerical integration at a turning point ensures high accuracy --- NuRadioMC/SignalProp/analyticraytracing.py | 98 ++++++++++++++++++++-- 1 file changed, 90 insertions(+), 8 deletions(-) diff --git a/NuRadioMC/SignalProp/analyticraytracing.py b/NuRadioMC/SignalProp/analyticraytracing.py index 0c1fb5b13..0fe9593d1 100644 --- a/NuRadioMC/SignalProp/analyticraytracing.py +++ b/NuRadioMC/SignalProp/analyticraytracing.py @@ -15,7 +15,6 @@ from NuRadioReco.framework.parameters import electricFieldParameters as efp from NuRadioMC.SignalProp.propagation_base_class import ray_tracing_base from NuRadioMC.SignalProp.propagation import solution_types, solution_types_revert - import logging logging.basicConfig() @@ -47,6 +46,20 @@ speed_of_light = scipy.constants.c * units.m / units.s +def get_n_steps(x1, x2, dx): + """ Returns number of segments necessary for width to be approx dx """ + return max(int(abs(x1 - x2) // dx), 3) + + +def get_segments(x1, x2, dx): + """ Returns equi.dist. segments (np.linspace). Choose number of segments such that + width of segments is approx. dx + """ + if x1 == x2: + return [x1] + return np.linspace(x1, x2, get_n_steps(x1, x2, dx)) + + @lru_cache(maxsize=32) def get_z_deep(ice_params): """ @@ -104,6 +117,7 @@ def __init__(self, medium, attenuation_model="SP1", self.__logger.setLevel(log_level) self.__n_frequencies_integration = n_frequencies_integration self.__use_optimized_start_values = use_optimized_start_values + def n(self, z): """ @@ -214,6 +228,7 @@ def get_y_diff(self, z_raw, C_0): """ derivative dy(z)/dz """ + z = self.get_z_unmirrored(z_raw, C_0) c = self.medium.n_ice ** 2 - C_0 ** -2 B = (0.2e1 * np.sqrt(c) * np.sqrt(-self.__b * self.medium.delta_n * np.exp(z / self.medium.z_0) + self.medium.delta_n ** @@ -605,14 +620,81 @@ def dt(t, C_0, frequency): mask = frequency > 0 freqs = self.__get_frequencies_for_attenuation(frequency, max_detector_freq) gamma_turn, z_turn = self.get_turning_point(self.medium.n_ice ** 2 - C_0 ** -2) - points = None - if x1[1] < z_turn and z_turn < x2_mirrored[1]: - points = [z_turn] - - attenuation_exp = np.array([integrate.quad(dt, x1[1], x2_mirrored[1], args=( - C_0, f), epsrel=1e-2, points=points)[0] for f in freqs]) + + if self.attenuation_model == "GL3": + # The integration of the attenuation factor along the path with scipy.quad is inefficient. The + # reason for this is that attenuation profile is varying a lot with depth. Hence, to improve + # performance we sum over discrete segments with loss of some accuracy. + # However, when a path becomes to horizontal (i.e., at the turning point of an refracted ray) + # the calculation via a discrete sum becomes to inaccurate. This is because we describe the + # path as a function of dz (vertical distance) and have the sum over discrete bins in dz. To avoid that + # we fall back to a numerical integration with scipy.quad only around the turning point. However, instead + # of integrating over dt (the exponent of the attenuation factor), we integrate only over ds (the path length) + # and evaluate the attenuation (as function of depth and frequency) for the central depth of this segment + # (because this is what takes time) + + # define the width of the vertical (!) segments over which we sum. + # Since we use linspace the actual width will differ slightly + dx = 10 + # define the vertical window around a turning point within we will fall back to a numerical integration + int_window_size = 20 + + # Check if a turning point "z_turn" is within our ray path or close to it (i.e., right behind the antenna) + # if so we need to fallback to numerical integration + fallback = False + if x1[1] - int_window_size / 2 < z_turn and z_turn < x2_mirrored[1] + int_window_size / 2: + fallback = True + + if fallback: + # If we need the fallback, make sure that the turning point is in the middle of a segment (unless it is at + # the edge of a path). Otherwise the segment next to the turning point will be inaccurate + int_window = [max(x1[1], z_turn - int_window_size / 2), + min(z_turn + int_window_size / 2, x2_mirrored[1])] + + # Merge two arrays which start and stop at int_window (and thus include it). The width might be slightly different + segments = np.append(get_segments(x1[1], int_window[0], dx), get_segments(int_window[1], x2_mirrored[1], dx)) + else: + segments = get_segments(x1[1], x2_mirrored[1], dx) + + # get the actual width of each segment and their center + dx_actuals = np.diff(segments) + mid_points = segments[:-1] + dx_actuals / 2 + + # calculate attenuation for the different segments using the middle depth of the segment + attenuation_exp_tmp = np.array( + [[dt(x, C_0, f) * dx_actual for x, dx_actual in zip(mid_points, dx_actuals)] + for f in freqs]) + + if fallback: + # for the segment around z_turn fall back to integration. We only integrate ds (and not dt) for performance reasons + + # find segment which contains z_turn + idx = np.digitize(z_turn, segments) - 1 + + # if z_turn is outside of segments + if idx == len(segments) - 1: + idx -= 1 + elif idx == -1: + idx = 0 + + att_int = np.array( + [integrate.quad(self.ds, segments[idx], segments[idx + 1], args=(C_0), epsrel=1e-2, points=[z_turn])[0] / + attenuation_util.get_attenuation_length(z_turn, f, self.attenuation_model) for f in freqs]) + + attenuation_exp_tmp[:, idx] = att_int + + # sum over all segments + attenuation_exp = np.sum(attenuation_exp_tmp, axis=1) + + else: + points = None + if x1[1] < z_turn and z_turn < x2_mirrored[1]: + points = [z_turn] + + attenuation_exp = np.array([integrate.quad(dt, x1[1], x2_mirrored[1], args=( + C_0, f), epsrel=1e-2, points=points)[0] for f in freqs]) + tmp = np.exp(-1 * attenuation_exp) - # tmp = np.array([integrate.quad(dt, x1[1], x2_mirrored[1], args=(C_0, f), epsrel=0.05)[0] for f in frequency[mask]]) tmp_attenuation = np.ones_like(frequency) tmp_attenuation[mask] = np.interp(frequency[mask], freqs, tmp) From 450ad55cecaa7f42774b42604d15e5c7fb67a42d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Tue, 7 Mar 2023 14:27:16 +0100 Subject: [PATCH 165/418] Add reference to PR --- NuRadioMC/SignalProp/analyticraytracing.py | 1 + 1 file changed, 1 insertion(+) diff --git a/NuRadioMC/SignalProp/analyticraytracing.py b/NuRadioMC/SignalProp/analyticraytracing.py index 0fe9593d1..3a98125ab 100644 --- a/NuRadioMC/SignalProp/analyticraytracing.py +++ b/NuRadioMC/SignalProp/analyticraytracing.py @@ -632,6 +632,7 @@ def dt(t, C_0, frequency): # of integrating over dt (the exponent of the attenuation factor), we integrate only over ds (the path length) # and evaluate the attenuation (as function of depth and frequency) for the central depth of this segment # (because this is what takes time) + # For more details and comparisons see PR #507 : https://github.com/nu-radio/NuRadioMC/pull/507 # define the width of the vertical (!) segments over which we sum. # Since we use linspace the actual width will differ slightly From b97abe795398d2a893fd01f5f5380bdcf38a857a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Tue, 7 Mar 2023 14:40:00 +0100 Subject: [PATCH 166/418] Rename and relocate modules which add/import measured noise --- NuRadioReco/modules/{io/noise => measured_noise}/__init__.py | 0 .../modules/{ => measured_noise}/channelMeasuredNoiseAdder.py | 0 .../noiseImporter.py => measured_noise/noiseImporterARIANNA.py} | 0 .../noiseImporterARIANNAROOT.py} | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename NuRadioReco/modules/{io/noise => measured_noise}/__init__.py (100%) rename NuRadioReco/modules/{ => measured_noise}/channelMeasuredNoiseAdder.py (100%) rename NuRadioReco/modules/{io/noise/noiseImporter.py => measured_noise/noiseImporterARIANNA.py} (100%) rename NuRadioReco/modules/{io/noise/noiseImporterROOT.py => measured_noise/noiseImporterARIANNAROOT.py} (100%) diff --git a/NuRadioReco/modules/io/noise/__init__.py b/NuRadioReco/modules/measured_noise/__init__.py similarity index 100% rename from NuRadioReco/modules/io/noise/__init__.py rename to NuRadioReco/modules/measured_noise/__init__.py diff --git a/NuRadioReco/modules/channelMeasuredNoiseAdder.py b/NuRadioReco/modules/measured_noise/channelMeasuredNoiseAdder.py similarity index 100% rename from NuRadioReco/modules/channelMeasuredNoiseAdder.py rename to NuRadioReco/modules/measured_noise/channelMeasuredNoiseAdder.py diff --git a/NuRadioReco/modules/io/noise/noiseImporter.py b/NuRadioReco/modules/measured_noise/noiseImporterARIANNA.py similarity index 100% rename from NuRadioReco/modules/io/noise/noiseImporter.py rename to NuRadioReco/modules/measured_noise/noiseImporterARIANNA.py diff --git a/NuRadioReco/modules/io/noise/noiseImporterROOT.py b/NuRadioReco/modules/measured_noise/noiseImporterARIANNAROOT.py similarity index 100% rename from NuRadioReco/modules/io/noise/noiseImporterROOT.py rename to NuRadioReco/modules/measured_noise/noiseImporterARIANNAROOT.py From b7bf707ca2c6b89aec16ac31f4612a1f88ba2f41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Tue, 7 Mar 2023 15:10:52 +0100 Subject: [PATCH 167/418] Extend interface of ray_tracing classes to allow to specify several attenuation models which use the optimized calculation and to overwrite these defaults. --- NuRadioMC/SignalProp/analyticraytracing.py | 36 ++++++++++++++++--- .../SignalProp/propagation_base_class.py | 4 ++- 2 files changed, 34 insertions(+), 6 deletions(-) diff --git a/NuRadioMC/SignalProp/analyticraytracing.py b/NuRadioMC/SignalProp/analyticraytracing.py index 3a98125ab..dc2826a07 100644 --- a/NuRadioMC/SignalProp/analyticraytracing.py +++ b/NuRadioMC/SignalProp/analyticraytracing.py @@ -45,6 +45,12 @@ """ speed_of_light = scipy.constants.c * units.m / units.s +""" +Models in the following list will use the speed-optimized algorithm to calculate the attenuation along the path. +Can be overwritten by init. +""" +speedup_attenuation_models = ["GL3"] + def get_n_steps(x1, x2, dx): """ Returns number of segments necessary for width to be approx dx """ @@ -85,7 +91,8 @@ class ray_tracing_2D(ray_tracing_base): def __init__(self, medium, attenuation_model="SP1", log_level=logging.WARNING, n_frequencies_integration=25, - use_optimized_start_values=False): + use_optimized_start_values=False, + overwrite_speedup=None): """ initialize 2D analytic ray tracing class @@ -102,7 +109,9 @@ def __init__(self, medium, attenuation_model="SP1", use_optimized_start_value: bool if True, the initial C_0 paramter (launch angle) is set to the ray that skims the surface (default: False) - + overwrite_speedup: bool + If not None, use value to overwrite _use_optimized_calculation. (Default: None) + """ self.medium = medium if(not hasattr(self.medium, "reflection")): @@ -118,6 +127,10 @@ def __init__(self, medium, attenuation_model="SP1", self.__n_frequencies_integration = n_frequencies_integration self.__use_optimized_start_values = use_optimized_start_values + self._use_optimized_calculation = self.attenuation_model in speedup_attenuation_models + if overwrite_speedup is not None: + self._use_optimized_calculation = overwrite_speedup + def n(self, z): """ @@ -620,8 +633,9 @@ def dt(t, C_0, frequency): mask = frequency > 0 freqs = self.__get_frequencies_for_attenuation(frequency, max_detector_freq) gamma_turn, z_turn = self.get_turning_point(self.medium.n_ice ** 2 - C_0 ** -2) + print("_use_optimized_calculation", self._use_optimized_calculation) - if self.attenuation_model == "GL3": + if self._use_optimized_calculation: # The integration of the attenuation factor along the path with scipy.quad is inefficient. The # reason for this is that attenuation profile is varying a lot with depth. Hence, to improve # performance we sum over discrete segments with loss of some accuracy. @@ -1625,7 +1639,7 @@ class ray_tracing(ray_tracing_base): def __init__(self, medium, attenuation_model="SP1", log_level=logging.WARNING, n_frequencies_integration=100, n_reflections=0, config=None, - detector=None): + detector=None, ray_tracing_2D_kwards={}): """ class initilization @@ -1633,10 +1647,13 @@ class initilization ---------- medium: medium class class describing the index-of-refraction profile + attenuation_model: string signal attenuation model + log_name: string name under which things should be logged + log_level: logging object specify the log level of the ray tracing class @@ -1646,12 +1663,15 @@ class describing the index-of-refraction profile * logging.DEBUG default is WARNING + n_frequencies_integration: int the number of frequencies for which the frequency dependent attenuation length is being calculated. The attenuation length for all other frequencies is obtained via linear interpolation. + n_reflections: int (default 0) in case of a medium with a reflective layer at the bottom, how many reflections should be considered + config: dict a dictionary with the optional config settings. If None, the config is intialized with default values, which is needed to avoid any "key not available" errors. The default settings are @@ -1662,6 +1682,10 @@ class describing the index-of-refraction profile * self._config['propagation']['focusing'] = False detector: detector object + + ray_tracing_2D_kwards: dict + Additional arguments which are passed to ray_tracing_2D + """ self.__logger = logging.getLogger('ray_tracing_analytic') self.__logger.setLevel(log_level) @@ -1679,8 +1703,10 @@ class describing the index-of-refraction profile config=config, detector=detector) self.set_config(config=config) + self._r2d = ray_tracing_2D(self._medium, self._attenuation_model, log_level=log_level, - n_frequencies_integration=self._n_frequencies_integration) + n_frequencies_integration=self._n_frequencies_integration, + **ray_tracing_2D_kwards) self._swap = None self._dPhi = None diff --git a/NuRadioMC/SignalProp/propagation_base_class.py b/NuRadioMC/SignalProp/propagation_base_class.py index bbcd1130d..376f5d19d 100644 --- a/NuRadioMC/SignalProp/propagation_base_class.py +++ b/NuRadioMC/SignalProp/propagation_base_class.py @@ -17,7 +17,7 @@ class ray_tracing_base: def __init__(self, medium, attenuation_model=None, log_level=logging.WARNING, n_frequencies_integration=None, n_reflections=None, config=None, - detector = None): + detector=None, ray_tracing_2D_kwards={}): """ class initilization @@ -45,6 +45,8 @@ class describing the index-of-refraction profile config: nested dictionary loaded yaml config file detector: detector object + ray_tracing_2D_kwards: dict + Additional arguments which are passed to ray_tracing_2D """ self.__logger = logging.getLogger('ray_tracing_base') self.__logger.setLevel(log_level) From c442383809116a5419b4e8283fa705c15cab32ef Mon Sep 17 00:00:00 2001 From: Janna Vischer Date: Wed, 8 Mar 2023 15:50:10 +0100 Subject: [PATCH 168/418] changed tab to spaces --- NuRadioReco/modules/phasedarray/triggerSimulator.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NuRadioReco/modules/phasedarray/triggerSimulator.py b/NuRadioReco/modules/phasedarray/triggerSimulator.py index 1527bd5df..9fba9b25d 100644 --- a/NuRadioReco/modules/phasedarray/triggerSimulator.py +++ b/NuRadioReco/modules/phasedarray/triggerSimulator.py @@ -569,7 +569,7 @@ def run(self, evt, station, det, #trigger_time(s)= time(s) from start of trace + start time of trace with respect to moment of first interaction = trigger time from moment of first interaction; time offset to interaction time (channel_trace_start_time) already recognized in self.phased_trigger trigger.set_trigger_time(trigger_time)# trigger.set_trigger_times(trigger_times) - else: + else: trigger.set_trigger_time(None) station.set_trigger(trigger) From a5aeb85594c3975fc7bcd681ffb7f51e8962f6ae Mon Sep 17 00:00:00 2001 From: Sjoerd Bouma Date: Wed, 8 Mar 2023 18:02:19 +0100 Subject: [PATCH 169/418] fix poetry to pip conversion for git dependencies with rev or tag specified --- install_dev.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/install_dev.py b/install_dev.py index e08ca27fc..820a5a73c 100644 --- a/install_dev.py +++ b/install_dev.py @@ -83,6 +83,10 @@ def convert_poetry_to_pip(reqs): req = 'git+{}'.format(version['git']) if 'branch' in version: req+='@{}'.format(version['branch']) + elif 'rev' in version: + req+='@{}'.format(version['rev']) + elif 'tag' in version: + req+='@{}'.format(version['tag']) if 'version' in version: version = version['version'] else: From ee20726a6a3d47ed4bd40626062113fc3b73e2a5 Mon Sep 17 00:00:00 2001 From: Jean-Marco Alameddine Date: Thu, 9 Mar 2023 09:21:51 +0100 Subject: [PATCH 170/418] update proposal to version 7.5.1, so we don't need to checkout the fixed commit anymore --- documentation/source/Introduction/pages/installation.rst | 2 +- pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/documentation/source/Introduction/pages/installation.rst b/documentation/source/Introduction/pages/installation.rst index 58bdb7b3c..402faee2e 100644 --- a/documentation/source/Introduction/pages/installation.rst +++ b/documentation/source/Introduction/pages/installation.rst @@ -189,7 +189,7 @@ These packages are recommended to be able to use all of NuRadioMC/NuRadioReco's .. code-block:: bash - pip install proposal==7.5.0 + pip install proposal==7.5.1 Note that the pip installation for this version of proposal may not work on all systems, in particular: diff --git a/pyproject.toml b/pyproject.toml index adafc4562..b3b89eac1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -46,7 +46,7 @@ numba = "*" Sphinx = "*" sphinx-rtd-theme = "*" numpydoc = "1.1.0" -proposal = {git = "https://github.com/tudo-astroparticlephysics/PROPOSAL.git", rev="b95628a"} +proposal = "7.5.1" pygdsm = {git = "https://github.com/telegraphic/pygdsm"} nifty5 = {git = "https://gitlab.mpcdf.mpg.de/ift/nifty.git", branch="NIFTy_5"} pypocketfft = {git = "https://gitlab.mpcdf.mpg.de/mtr/pypocketfft"} From 801ae1b7e824d5d18687f025de080b84d24f527d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Sun, 12 Mar 2023 11:32:26 +0100 Subject: [PATCH 171/418] Introduce subdirectory measured_noise/ARIANNA. Move modules and remove experiment name from module name --- NuRadioReco/modules/measured_noise/ARIANNA/__init__.py | 0 .../{noiseImporterARIANNA.py => ARIANNA/noiseImporter.py} | 0 .../{noiseImporterARIANNAROOT.py => ARIANNA/noiseImporterROOT.py} | 0 3 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 NuRadioReco/modules/measured_noise/ARIANNA/__init__.py rename NuRadioReco/modules/measured_noise/{noiseImporterARIANNA.py => ARIANNA/noiseImporter.py} (100%) rename NuRadioReco/modules/measured_noise/{noiseImporterARIANNAROOT.py => ARIANNA/noiseImporterROOT.py} (100%) diff --git a/NuRadioReco/modules/measured_noise/ARIANNA/__init__.py b/NuRadioReco/modules/measured_noise/ARIANNA/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/NuRadioReco/modules/measured_noise/noiseImporterARIANNA.py b/NuRadioReco/modules/measured_noise/ARIANNA/noiseImporter.py similarity index 100% rename from NuRadioReco/modules/measured_noise/noiseImporterARIANNA.py rename to NuRadioReco/modules/measured_noise/ARIANNA/noiseImporter.py diff --git a/NuRadioReco/modules/measured_noise/noiseImporterARIANNAROOT.py b/NuRadioReco/modules/measured_noise/ARIANNA/noiseImporterROOT.py similarity index 100% rename from NuRadioReco/modules/measured_noise/noiseImporterARIANNAROOT.py rename to NuRadioReco/modules/measured_noise/ARIANNA/noiseImporterROOT.py From acbb7f896d2f39f74047282e8cbbc9bae5632813 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Sun, 12 Mar 2023 11:34:15 +0100 Subject: [PATCH 172/418] Add ARIANNA into logger names --- NuRadioReco/modules/measured_noise/ARIANNA/noiseImporter.py | 2 +- NuRadioReco/modules/measured_noise/ARIANNA/noiseImporterROOT.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/NuRadioReco/modules/measured_noise/ARIANNA/noiseImporter.py b/NuRadioReco/modules/measured_noise/ARIANNA/noiseImporter.py index 85f483526..883ff6d6a 100644 --- a/NuRadioReco/modules/measured_noise/ARIANNA/noiseImporter.py +++ b/NuRadioReco/modules/measured_noise/ARIANNA/noiseImporter.py @@ -6,7 +6,7 @@ import os import sys from NuRadioReco.modules.io import NuRadioRecoio -logger = logging.getLogger('noiseImporter') +logger = logging.getLogger('noiseImporterARIANNA') class noiseImporter: diff --git a/NuRadioReco/modules/measured_noise/ARIANNA/noiseImporterROOT.py b/NuRadioReco/modules/measured_noise/ARIANNA/noiseImporterROOT.py index 23645700d..ab4e32f6a 100644 --- a/NuRadioReco/modules/measured_noise/ARIANNA/noiseImporterROOT.py +++ b/NuRadioReco/modules/measured_noise/ARIANNA/noiseImporterROOT.py @@ -4,7 +4,7 @@ from NuRadioReco.utilities import units import numpy as np import logging -logger = logging.getLogger('noiseImporter') +logger = logging.getLogger('noiseImporterARIANNAROOT') class noiseImporter: From 52dfe799189d69043729af2368ab77d02eb16a11 Mon Sep 17 00:00:00 2001 From: Pawan Giri Date: Tue, 14 Mar 2023 15:20:38 -0500 Subject: [PATCH 173/418] pass event time to the sim station to simulate time dependent detector / a single line in simulation.py is added to make private ARA package compatible with NuRadioMC --- NuRadioMC/simulation/simulation.py | 3 ++- changelog.txt | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/NuRadioMC/simulation/simulation.py b/NuRadioMC/simulation/simulation.py index 9212cecb9..35b6be0ac 100644 --- a/NuRadioMC/simulation/simulation.py +++ b/NuRadioMC/simulation/simulation.py @@ -850,7 +850,8 @@ def run(self): t1 = time.time() self._station = NuRadioReco.framework.station.Station(self._station_id) self._station.set_sim_station(self._sim_station) - + self._station.get_sim_station().set_station_time(self._evt_time) + # convert efields to voltages at digitizer if hasattr(self, '_detector_simulation_part1'): # we give the user the opportunity to define a custom detector simulation diff --git a/changelog.txt b/changelog.txt index 93a263be3..206a3b7ce 100644 --- a/changelog.txt +++ b/changelog.txt @@ -21,11 +21,11 @@ new features: - adding minimize mode to the radiopropa propagation module & more configurable settings in config file - add uniform ice model with 1.78 refractive index - update ARA detector description and add a file to Print ARA detector json file +- pass evt_time to sim station bugfixes: - fix bug in NuRadioProposal which pervented muons from tau decays to be propagated - update proposal version to 6.1.8 to avoid problems with pypi - version 2.1.6 bugfixes: - the n_interaction parameter was accidentally overridden. n_interaction counts the number of interactions of taus and From 584ccc173b0d24132d001e9d23938c14620c164f Mon Sep 17 00:00:00 2001 From: Steffen Hallmann Date: Wed, 15 Mar 2023 11:04:51 +0100 Subject: [PATCH 174/418] apply fix --- NuRadioMC/utilities/Veff.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/NuRadioMC/utilities/Veff.py b/NuRadioMC/utilities/Veff.py index a7be6893d..bbf09194e 100644 --- a/NuRadioMC/utilities/Veff.py +++ b/NuRadioMC/utilities/Veff.py @@ -60,6 +60,7 @@ def FC_limits(counts): """ Returns the 68% confidence belt for a number of counts, using the Feldman-Cousins method. + Published in Phys. Rev. D 57, 3873, DOI 10.1103/PhysRevD.57.3873 Parameters ---------- @@ -99,7 +100,7 @@ def FC_limits(counts): 4.25, 5.30, 6.78, - 7, 81, + 7.81, 9.28, 10.30, 11.32, From 938d148b7d525d1be0be5dcec15a3243fa0f90ee Mon Sep 17 00:00:00 2001 From: Steffen Hallmann Date: Wed, 15 Mar 2023 11:05:54 +0100 Subject: [PATCH 175/418] edit changelog: --- changelog.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelog.txt b/changelog.txt index 93a263be3..cb3c18730 100644 --- a/changelog.txt +++ b/changelog.txt @@ -12,7 +12,7 @@ new features: - added ability to generate high-low-triggered noise on a narrow band but return full-band waveforms bugfixes: - fixed/improved C++ raytracer not finding solutions for some near-horizontal or near-shadowzone vertices - +- fixed wrong number in Feldman-Cousins upper limit version 2.1.7 new features: From 80616d1e72c6f12691d9a335f44c2f04010f715e Mon Sep 17 00:00:00 2001 From: Steffen Hallmann Date: Wed, 15 Mar 2023 11:37:07 +0100 Subject: [PATCH 176/418] there was also one value missing --- NuRadioMC/utilities/Veff.py | 1 + 1 file changed, 1 insertion(+) diff --git a/NuRadioMC/utilities/Veff.py b/NuRadioMC/utilities/Veff.py index bbf09194e..9ee5eaa14 100644 --- a/NuRadioMC/utilities/Veff.py +++ b/NuRadioMC/utilities/Veff.py @@ -114,6 +114,7 @@ def FC_limits(counts): 20.80, 21.81, 22.82, + 23.82, 25.30] if counts > count_list[-1]: From d7a6a4f918d3667c5a61f9ee6f864d1643e6bf33 Mon Sep 17 00:00:00 2001 From: Christoph Date: Mon, 20 Mar 2023 15:53:38 -0500 Subject: [PATCH 177/418] Fix LPDA positions and include surface cable measurements --- .../detector/RNO_G/RNO_season_2022.json | 198 +++++++++--------- 1 file changed, 99 insertions(+), 99 deletions(-) diff --git a/NuRadioReco/detector/RNO_G/RNO_season_2022.json b/NuRadioReco/detector/RNO_G/RNO_season_2022.json index 0c66c43ce..c5c2f664f 100644 --- a/NuRadioReco/detector/RNO_G/RNO_season_2022.json +++ b/NuRadioReco/detector/RNO_G/RNO_season_2022.json @@ -281,7 +281,7 @@ "ant_position_y": -1.3494044168342043, "ant_position_z": -0.5, "amp_type": "rno_surface", - "cab_time_delay": 52.7, + "cab_time_delay": 52.57621291824783, "adc_n_samples": 2048, "adc_sampling_frequency": 3.2, "commission_time": "{TinyDate}:2021-07-11T00:00:00", @@ -299,7 +299,7 @@ "ant_position_y": -3.680467011662472, "ant_position_z": -0.5, "amp_type": "rno_surface", - "cab_time_delay": 45.5, + "cab_time_delay": 45.398781691972694, "adc_n_samples": 2048, "adc_sampling_frequency": 3.2, "commission_time": "{TinyDate}:2021-07-11T00:00:00", @@ -317,7 +317,7 @@ "ant_position_y": -8.874503105185909, "ant_position_z": -0.5, "amp_type": "rno_surface", - "cab_time_delay": 52.7, + "cab_time_delay": 52.51394131174265, "adc_n_samples": 2048, "adc_sampling_frequency": 3.2, "commission_time": "{TinyDate}:2021-07-11T00:00:00", @@ -335,7 +335,7 @@ "ant_position_y": -17.09129526105096, "ant_position_z": -0.5, "amp_type": "rno_surface", - "cab_time_delay": 52.7, + "cab_time_delay": 52.51563909722448, "adc_n_samples": 2048, "adc_sampling_frequency": 3.2, "commission_time": "{TinyDate}:2021-07-11T00:00:00", @@ -353,7 +353,7 @@ "ant_position_y": -16.26019998902143, "ant_position_z": -0.5, "amp_type": "rno_surface", - "cab_time_delay": 45.5, + "cab_time_delay": 45.43439538521371, "adc_n_samples": 2048, "adc_sampling_frequency": 3.2, "commission_time": "{TinyDate}:2021-07-11T00:00:00", @@ -371,7 +371,7 @@ "ant_position_y": -17.227018480620586, "ant_position_z": -0.5, "amp_type": "rno_surface", - "cab_time_delay": 49.1, + "cab_time_delay": 49.32699419041931, "adc_n_samples": 2048, "adc_sampling_frequency": 3.2, "commission_time": "{TinyDate}:2021-07-11T00:00:00", @@ -389,7 +389,7 @@ "ant_position_y": -9.147827107359035, "ant_position_z": -0.5, "amp_type": "rno_surface", - "cab_time_delay": 49.1, + "cab_time_delay": 49.556691492869795, "adc_n_samples": 2048, "adc_sampling_frequency": 3.2, "commission_time": "{TinyDate}:2021-07-11T00:00:00", @@ -407,7 +407,7 @@ "ant_position_y": -6.738870967144862, "ant_position_z": -0.5, "amp_type": "rno_surface", - "cab_time_delay": 45.5, + "cab_time_delay": 45.883012205651234, "adc_n_samples": 2048, "adc_sampling_frequency": 3.2, "commission_time": "{TinyDate}:2021-07-11T00:00:00", @@ -425,7 +425,7 @@ "ant_position_y": -4.185859006174496, "ant_position_z": -0.5, "amp_type": "rno_surface", - "cab_time_delay": 49.1, + "cab_time_delay": 49.20101294697667, "adc_n_samples": 2048, "adc_sampling_frequency": 3.2, "commission_time": "{TinyDate}:2021-07-11T00:00:00", @@ -596,7 +596,7 @@ }, "33": { "station_id": 12, - "channel_id": 14, + "channel_id": 20, "ant_rotation_phi": 90.0, "ant_rotation_theta": 90.0, "ant_orientation_phi": 0.0, @@ -605,7 +605,7 @@ "ant_position_y": 13.036622167753876, "ant_position_z": -0.5, "amp_type": "rno_surface", - "cab_time_delay": 45.5, + "cab_time_delay": 45.89728312662527, "adc_n_samples": 2048, "adc_sampling_frequency": 3.2, "commission_time": "{TinyDate}:2022-06-16T00:00:00", @@ -614,7 +614,7 @@ }, "34": { "station_id": 12, - "channel_id": 13, + "channel_id": 19, "ant_rotation_phi": 90.0, "ant_rotation_theta": 90.0, "ant_orientation_phi": 0.0, @@ -623,7 +623,7 @@ "ant_position_y": 13.217878076629859, "ant_position_z": -0.5, "amp_type": "rno_surface", - "cab_time_delay": 45.5, + "cab_time_delay": 45.846178367177174, "adc_n_samples": 2048, "adc_sampling_frequency": 3.2, "commission_time": "{TinyDate}:2022-06-16T00:00:00", @@ -632,7 +632,7 @@ }, "35": { "station_id": 12, - "channel_id": 12, + "channel_id": 18, "ant_rotation_phi": 90.0, "ant_rotation_theta": 90.0, "ant_orientation_phi": 180.0, @@ -641,7 +641,7 @@ "ant_position_y": 13.389808333216479, "ant_position_z": -0.5, "amp_type": "rno_surface", - "cab_time_delay": 45.5, + "cab_time_delay": 45.59430891887436, "adc_n_samples": 2048, "adc_sampling_frequency": 3.2, "commission_time": "{TinyDate}:2022-06-16T00:00:00", @@ -650,7 +650,7 @@ }, "36": { "station_id": 12, - "channel_id": 20, + "channel_id": 17, "ant_rotation_phi": 330.0, "ant_rotation_theta": 90.0, "ant_orientation_phi": 240.0, @@ -659,7 +659,7 @@ "ant_position_y": 21.576903538867327, "ant_position_z": -0.5, "amp_type": "rno_surface", - "cab_time_delay": 45.5, + "cab_time_delay": 45.91827499385921, "adc_n_samples": 2048, "adc_sampling_frequency": 3.2, "commission_time": "{TinyDate}:2022-06-17T00:00:00", @@ -668,7 +668,7 @@ }, "37": { "station_id": 12, - "channel_id": 19, + "channel_id": 16, "ant_rotation_phi": 330.0, "ant_rotation_theta": 90.0, "ant_orientation_phi": 0.0, @@ -677,7 +677,7 @@ "ant_position_y": 23.948815527683337, "ant_position_z": -0.5, "amp_type": "rno_surface", - "cab_time_delay": 45.5, + "cab_time_delay": 45.83638105867064, "adc_n_samples": 2048, "adc_sampling_frequency": 3.2, "commission_time": "{TinyDate}:2022-06-17T00:00:00", @@ -686,7 +686,7 @@ }, "38": { "station_id": 12, - "channel_id": 18, + "channel_id": 15, "ant_rotation_phi": 330.0, "ant_rotation_theta": 90.0, "ant_orientation_phi": 60.0, @@ -695,7 +695,7 @@ "ant_position_y": 26.735356136899554, "ant_position_z": -0.5, "amp_type": "rno_surface", - "cab_time_delay": 45.5, + "cab_time_delay": 45.730803410479524, "adc_n_samples": 2048, "adc_sampling_frequency": 3.2, "commission_time": "{TinyDate}:2022-06-17T00:00:00", @@ -704,7 +704,7 @@ }, "39": { "station_id": 12, - "channel_id": 17, + "channel_id": 14, "ant_rotation_phi": 210.0, "ant_rotation_theta": 90.0, "ant_orientation_phi": 120.0, @@ -713,7 +713,7 @@ "ant_position_y": 26.003802943914252, "ant_position_z": -0.5, "amp_type": "rno_surface", - "cab_time_delay": 45.5, + "cab_time_delay": 46.01978301616729, "adc_n_samples": 2048, "adc_sampling_frequency": 3.2, "commission_time": "{TinyDate}:2022-06-21T00:00:00", @@ -722,7 +722,7 @@ }, "40": { "station_id": 12, - "channel_id": 16, + "channel_id": 13, "ant_rotation_phi": 210.0, "ant_rotation_theta": 90.0, "ant_orientation_phi": 0.0, @@ -731,7 +731,7 @@ "ant_position_y": 23.906866861842673, "ant_position_z": -0.5, "amp_type": "rno_surface", - "cab_time_delay": 45.5, + "cab_time_delay": 45.742412236972015, "adc_n_samples": 2048, "adc_sampling_frequency": 3.2, "commission_time": "{TinyDate}:2022-06-21T00:00:00", @@ -740,7 +740,7 @@ }, "41": { "station_id": 12, - "channel_id": 15, + "channel_id": 12, "ant_rotation_phi": 210.0, "ant_rotation_theta": 90.0, "ant_orientation_phi": 300.0, @@ -749,7 +749,7 @@ "ant_position_y": 21.587278338471833, "ant_position_z": -0.5, "amp_type": "rno_surface", - "cab_time_delay": 45.5, + "cab_time_delay": 45.839198595315175, "adc_n_samples": 2048, "adc_sampling_frequency": 3.2, "commission_time": "{TinyDate}:2022-06-21T00:00:00", @@ -1028,7 +1028,7 @@ }, "57": { "station_id": 13, - "channel_id": 14, + "channel_id": 20, "ant_rotation_phi": 90.0, "ant_rotation_theta": 90.0, "ant_orientation_phi": 0.0, @@ -1037,7 +1037,7 @@ "ant_position_y": 14.166779940559536, "ant_position_z": -0.5, "amp_type": "rno_surface", - "cab_time_delay": 45.5, + "cab_time_delay": 45.764002862920535, "adc_n_samples": 2048, "adc_sampling_frequency": 3.2, "commission_time": "{TinyDate}:2022-06-30T00:00:00", @@ -1046,7 +1046,7 @@ }, "58": { "station_id": 13, - "channel_id": 13, + "channel_id": 19, "ant_rotation_phi": 90.0, "ant_rotation_theta": 90.0, "ant_orientation_phi": 0.0, @@ -1055,7 +1055,7 @@ "ant_position_y": 13.354700187115668, "ant_position_z": -0.5, "amp_type": "rno_surface", - "cab_time_delay": 45.5, + "cab_time_delay": 45.97540552376522, "adc_n_samples": 2048, "adc_sampling_frequency": 3.2, "commission_time": "{TinyDate}:2022-06-30T00:00:00", @@ -1064,7 +1064,7 @@ }, "59": { "station_id": 13, - "channel_id": 12, + "channel_id": 18, "ant_rotation_phi": 90.0, "ant_rotation_theta": 90.0, "ant_orientation_phi": 180.0, @@ -1073,7 +1073,7 @@ "ant_position_y": 13.38742235362679, "ant_position_z": -0.5, "amp_type": "rno_surface", - "cab_time_delay": 45.5, + "cab_time_delay": 45.75640441890302, "adc_n_samples": 2048, "adc_sampling_frequency": 3.2, "commission_time": "{TinyDate}:2022-06-30T00:00:00", @@ -1082,7 +1082,7 @@ }, "60": { "station_id": 13, - "channel_id": 20, + "channel_id": 17, "ant_rotation_phi": 330.0, "ant_rotation_theta": 90.0, "ant_orientation_phi": 240.0, @@ -1091,7 +1091,7 @@ "ant_position_y": 21.608732090688136, "ant_position_z": -0.5, "amp_type": "rno_surface", - "cab_time_delay": 45.5, + "cab_time_delay": 45.4816564960653, "adc_n_samples": 2048, "adc_sampling_frequency": 3.2, "commission_time": "{TinyDate}:2022-07-04T00:00:00", @@ -1100,7 +1100,7 @@ }, "61": { "station_id": 13, - "channel_id": 19, + "channel_id": 16, "ant_rotation_phi": 330.0, "ant_rotation_theta": 90.0, "ant_orientation_phi": 0.0, @@ -1109,7 +1109,7 @@ "ant_position_y": 24.792913281642996, "ant_position_z": -0.5, "amp_type": "rno_surface", - "cab_time_delay": 45.5, + "cab_time_delay": 45.917833705247084, "adc_n_samples": 2048, "adc_sampling_frequency": 3.2, "commission_time": "{TinyDate}:2022-07-04T00:00:00", @@ -1118,7 +1118,7 @@ }, "62": { "station_id": 13, - "channel_id": 18, + "channel_id": 15, "ant_rotation_phi": 330.0, "ant_rotation_theta": 90.0, "ant_orientation_phi": 60.0, @@ -1127,7 +1127,7 @@ "ant_position_y": 26.426624719792926, "ant_position_z": -0.5, "amp_type": "rno_surface", - "cab_time_delay": 45.5, + "cab_time_delay": 45.38950686394398, "adc_n_samples": 2048, "adc_sampling_frequency": 3.2, "commission_time": "{TinyDate}:2022-07-04T00:00:00", @@ -1136,7 +1136,7 @@ }, "63": { "station_id": 13, - "channel_id": 17, + "channel_id": 14, "ant_rotation_phi": 210.0, "ant_rotation_theta": 90.0, "ant_orientation_phi": 120.0, @@ -1145,7 +1145,7 @@ "ant_position_y": 26.55067316693976, "ant_position_z": -0.5, "amp_type": "rno_surface", - "cab_time_delay": 45.5, + "cab_time_delay": 45.977255276242445, "adc_n_samples": 2048, "adc_sampling_frequency": 3.2, "commission_time": "{TinyDate}:2022-07-01T00:00:00", @@ -1154,7 +1154,7 @@ }, "64": { "station_id": 13, - "channel_id": 16, + "channel_id": 13, "ant_rotation_phi": 210.0, "ant_rotation_theta": 90.0, "ant_orientation_phi": 0.0, @@ -1163,7 +1163,7 @@ "ant_position_y": 23.596333245058304, "ant_position_z": -0.5, "amp_type": "rno_surface", - "cab_time_delay": 45.5, + "cab_time_delay": 45.85528602130243, "adc_n_samples": 2048, "adc_sampling_frequency": 3.2, "commission_time": "{TinyDate}:2022-07-01T00:00:00", @@ -1172,7 +1172,7 @@ }, "65": { "station_id": 13, - "channel_id": 15, + "channel_id": 12, "ant_rotation_phi": 210.0, "ant_rotation_theta": 90.0, "ant_orientation_phi": 300.0, @@ -1181,7 +1181,7 @@ "ant_position_y": 21.375716286736406, "ant_position_z": -0.5, "amp_type": "rno_surface", - "cab_time_delay": 45.5, + "cab_time_delay": 46.01961725310455, "adc_n_samples": 2048, "adc_sampling_frequency": 3.2, "commission_time": "{TinyDate}:2022-07-01T00:00:00", @@ -1577,7 +1577,7 @@ "ant_position_y": 3.2254831301034983, "ant_position_z": -0.5, "amp_type": "rno_surface", - "cab_time_delay": 49.1, + "cab_time_delay": 48.99288182695537, "adc_n_samples": 2048, "adc_sampling_frequency": 3.2, "commission_time": "{TinyDate}:2021-07-04T00:00:00", @@ -1595,7 +1595,7 @@ "ant_position_y": 5.594519497753538, "ant_position_z": -0.5, "amp_type": "rno_surface", - "cab_time_delay": 45.5, + "cab_time_delay": 45.75937993162733, "adc_n_samples": 2048, "adc_sampling_frequency": 3.2, "commission_time": "{TinyDate}:2021-07-04T00:00:00", @@ -1613,7 +1613,7 @@ "ant_position_y": 8.05359447730956, "ant_position_z": -0.5, "amp_type": "rno_surface", - "cab_time_delay": 49.1, + "cab_time_delay": 49.48968661430838, "adc_n_samples": 2048, "adc_sampling_frequency": 3.2, "commission_time": "{TinyDate}:2021-07-04T00:00:00", @@ -1631,7 +1631,7 @@ "ant_position_y": 17.5452668631047, "ant_position_z": -0.5, "amp_type": "rno_surface", - "cab_time_delay": 49.1, + "cab_time_delay": 48.96724049428868, "adc_n_samples": 2048, "adc_sampling_frequency": 3.2, "commission_time": "{TinyDate}:2021-07-04T00:00:00", @@ -1649,7 +1649,7 @@ "ant_position_y": 17.169127453384192, "ant_position_z": -0.5, "amp_type": "rno_surface", - "cab_time_delay": 45.5, + "cab_time_delay": 45.82958226071196, "adc_n_samples": 2048, "adc_sampling_frequency": 3.2, "commission_time": "{TinyDate}:2021-07-04T00:00:00", @@ -1667,7 +1667,7 @@ "ant_position_y": 16.93301208843849, "ant_position_z": -0.5, "amp_type": "rno_surface", - "cab_time_delay": 49.1, + "cab_time_delay": 49.254956245215354, "adc_n_samples": 2048, "adc_sampling_frequency": 3.2, "commission_time": "{TinyDate}:2021-07-04T00:00:00", @@ -1685,7 +1685,7 @@ "ant_position_y": 7.489814438818087, "ant_position_z": -0.5, "amp_type": "rno_surface", - "cab_time_delay": 49.1, + "cab_time_delay": 49.42704773531392, "adc_n_samples": 2048, "adc_sampling_frequency": 3.2, "commission_time": "{TinyDate}:2021-07-04T00:00:00", @@ -1703,7 +1703,7 @@ "ant_position_y": 5.257865215171478, "ant_position_z": -0.5, "amp_type": "rno_surface", - "cab_time_delay": 45.5, + "cab_time_delay": 45.43375896297529, "adc_n_samples": 2048, "adc_sampling_frequency": 3.2, "commission_time": "{TinyDate}:2021-07-04T00:00:00", @@ -1721,7 +1721,7 @@ "ant_position_y": 3.2079300892245897, "ant_position_z": -0.5, "amp_type": "rno_surface", - "cab_time_delay": 49.1, + "cab_time_delay": 49.36961127763919, "adc_n_samples": 2048, "adc_sampling_frequency": 3.2, "commission_time": "{TinyDate}:2021-07-04T00:00:00", @@ -2009,7 +2009,7 @@ "ant_position_y": 11.075112525619716, "ant_position_z": -0.5, "amp_type": "rno_surface", - "cab_time_delay": 49.1, + "cab_time_delay": 49.510627155343215, "adc_n_samples": 2048, "adc_sampling_frequency": 3.2, "commission_time": "{TinyDate}:2021-07-01T00:00:00", @@ -2027,7 +2027,7 @@ "ant_position_y": 11.485023263238872, "ant_position_z": -0.5, "amp_type": "rno_surface", - "cab_time_delay": 45.5, + "cab_time_delay": 45.777650776480506, "adc_n_samples": 2048, "adc_sampling_frequency": 3.2, "commission_time": "{TinyDate}:2021-07-01T00:00:00", @@ -2045,7 +2045,7 @@ "ant_position_y": 11.198884671868882, "ant_position_z": -0.5, "amp_type": "rno_surface", - "cab_time_delay": 52.7, + "cab_time_delay": 52.95363112541108, "adc_n_samples": 2048, "adc_sampling_frequency": 3.2, "commission_time": "{TinyDate}:2021-07-01T00:00:00", @@ -2063,7 +2063,7 @@ "ant_position_y": 21.441595538089814, "ant_position_z": -0.5, "amp_type": "rno_surface", - "cab_time_delay": 52.7, + "cab_time_delay": 52.71319900390884, "adc_n_samples": 2048, "adc_sampling_frequency": 3.2, "commission_time": "{TinyDate}:2021-07-01T00:00:00", @@ -2081,7 +2081,7 @@ "ant_position_y": 23.84064026792589, "ant_position_z": -0.5, "amp_type": "rno_surface", - "cab_time_delay": 45.5, + "cab_time_delay": 45.602214424020616, "adc_n_samples": 2048, "adc_sampling_frequency": 3.2, "commission_time": "{TinyDate}:2021-07-01T00:00:00", @@ -2099,7 +2099,7 @@ "ant_position_y": 25.951689672003567, "ant_position_z": -0.5, "amp_type": "rno_surface", - "cab_time_delay": 52.7, + "cab_time_delay": 52.983380707350655, "adc_n_samples": 2048, "adc_sampling_frequency": 3.2, "commission_time": "{TinyDate}:2021-07-01T00:00:00", @@ -2117,7 +2117,7 @@ "ant_position_y": 25.52425338015405, "ant_position_z": -0.5, "amp_type": "rno_surface", - "cab_time_delay": 49.1, + "cab_time_delay": 49.527426912487186, "adc_n_samples": 2048, "adc_sampling_frequency": 3.2, "commission_time": "{TinyDate}:2021-07-01T00:00:00", @@ -2135,7 +2135,7 @@ "ant_position_y": 23.126331129435584, "ant_position_z": -0.5, "amp_type": "rno_surface", - "cab_time_delay": 45.5, + "cab_time_delay": 45.989096119098235, "adc_n_samples": 2048, "adc_sampling_frequency": 3.2, "commission_time": "{TinyDate}:2021-07-01T00:00:00", @@ -2153,7 +2153,7 @@ "ant_position_y": 17.60411927594305, "ant_position_z": -0.5, "amp_type": "rno_surface", - "cab_time_delay": 49.1, + "cab_time_delay": 49.07793698494233, "adc_n_samples": 2048, "adc_sampling_frequency": 3.2, "commission_time": "{TinyDate}:2021-07-01T00:00:00", @@ -2324,7 +2324,7 @@ }, "129": { "station_id": 23, - "channel_id": 14, + "channel_id": 20, "ant_rotation_phi": 150.0, "ant_rotation_theta": 90.0, "ant_orientation_phi": 60.0, @@ -2333,7 +2333,7 @@ "ant_position_y": 8.913768817867094, "ant_position_z": -0.5, "amp_type": "rno_surface", - "cab_time_delay": 45.5, + "cab_time_delay": 45.9267504993418, "adc_n_samples": 2048, "adc_sampling_frequency": 3.2, "commission_time": "{TinyDate}:2022-06-23T00:00:00", @@ -2342,7 +2342,7 @@ }, "130": { "station_id": 23, - "channel_id": 13, + "channel_id": 19, "ant_rotation_phi": 150.0, "ant_rotation_theta": 90.0, "ant_orientation_phi": 0.0, @@ -2351,7 +2351,7 @@ "ant_position_y": 6.6245011479177265, "ant_position_z": -0.5, "amp_type": "rno_surface", - "cab_time_delay": 45.5, + "cab_time_delay": 45.3209139461091, "adc_n_samples": 2048, "adc_sampling_frequency": 3.2, "commission_time": "{TinyDate}:2022-06-23T00:00:00", @@ -2360,7 +2360,7 @@ }, "131": { "station_id": 23, - "channel_id": 12, + "channel_id": 18, "ant_rotation_phi": 150.0, "ant_rotation_theta": 90.0, "ant_orientation_phi": 240.0, @@ -2369,7 +2369,7 @@ "ant_position_y": 3.9565460690787404, "ant_position_z": -0.5, "amp_type": "rno_surface", - "cab_time_delay": 45.5, + "cab_time_delay": 45.77034957757189, "adc_n_samples": 2048, "adc_sampling_frequency": 3.2, "commission_time": "{TinyDate}:2022-06-23T00:00:00", @@ -2432,7 +2432,7 @@ }, "135": { "station_id": 23, - "channel_id": 20, + "channel_id": 17, "ant_rotation_phi": 30.0, "ant_rotation_theta": 90.0, "ant_orientation_phi": 300.0, @@ -2441,7 +2441,7 @@ "ant_position_y": 4.513950933839169, "ant_position_z": -0.5, "amp_type": "rno_surface", - "cab_time_delay": 45.5, + "cab_time_delay": 45.39048669843476, "adc_n_samples": 2048, "adc_sampling_frequency": 3.2, "commission_time": "{TinyDate}:2022-06-26T00:00:00", @@ -2450,7 +2450,7 @@ }, "136": { "station_id": 23, - "channel_id": 19, + "channel_id": 16, "ant_rotation_phi": 30.0, "ant_rotation_theta": 90.0, "ant_orientation_phi": 0.0, @@ -2459,7 +2459,7 @@ "ant_position_y": 6.905528423480973, "ant_position_z": -0.5, "amp_type": "rno_surface", - "cab_time_delay": 45.5, + "cab_time_delay": 45.40997699209948, "adc_n_samples": 2048, "adc_sampling_frequency": 3.2, "commission_time": "{TinyDate}:2022-06-26T00:00:00", @@ -2468,7 +2468,7 @@ }, "137": { "station_id": 23, - "channel_id": 18, + "channel_id": 15, "ant_rotation_phi": 30.0, "ant_rotation_theta": 90.0, "ant_orientation_phi": 120.0, @@ -2477,7 +2477,7 @@ "ant_position_y": 9.398254723507762, "ant_position_z": -0.5, "amp_type": "rno_surface", - "cab_time_delay": 45.5, + "cab_time_delay": 45.83094862959857, "adc_n_samples": 2048, "adc_sampling_frequency": 3.2, "commission_time": "{TinyDate}:2022-06-26T00:00:00", @@ -2540,7 +2540,7 @@ }, "141": { "station_id": 23, - "channel_id": 17, + "channel_id": 14, "ant_rotation_phi": 270.0, "ant_rotation_theta": 90.0, "ant_orientation_phi": 180.0, @@ -2549,7 +2549,7 @@ "ant_position_y": 17.039319755117504, "ant_position_z": -0.5, "amp_type": "rno_surface", - "cab_time_delay": 45.5, + "cab_time_delay": 45.54795118967973, "adc_n_samples": 2048, "adc_sampling_frequency": 3.2, "commission_time": "{TinyDate}:2022-06-24T00:00:00", @@ -2558,7 +2558,7 @@ }, "142": { "station_id": 23, - "channel_id": 16, + "channel_id": 13, "ant_rotation_phi": 270.0, "ant_rotation_theta": 90.0, "ant_orientation_phi": 0.0, @@ -2567,7 +2567,7 @@ "ant_position_y": 17.047938425702796, "ant_position_z": -0.5, "amp_type": "rno_surface", - "cab_time_delay": 45.5, + "cab_time_delay": 45.7577340623503, "adc_n_samples": 2048, "adc_sampling_frequency": 3.2, "commission_time": "{TinyDate}:2022-06-24T00:00:00", @@ -2576,7 +2576,7 @@ }, "143": { "station_id": 23, - "channel_id": 15, + "channel_id": 12, "ant_rotation_phi": 270.0, "ant_rotation_theta": 90.0, "ant_orientation_phi": 0.0, @@ -2585,7 +2585,7 @@ "ant_position_y": 17.110824238700843, "ant_position_z": -0.5, "amp_type": "rno_surface", - "cab_time_delay": 45.5, + "cab_time_delay": 45.78713480723031, "adc_n_samples": 2048, "adc_sampling_frequency": 3.2, "commission_time": "{TinyDate}:2022-06-24T00:00:00", @@ -2756,7 +2756,7 @@ }, "153": { "station_id": 24, - "channel_id": 14, + "channel_id": 20, "ant_rotation_phi": 90.0, "ant_rotation_theta": 90.0, "ant_orientation_phi": 0.0, @@ -2765,7 +2765,7 @@ "ant_position_y": 9.783970419230172, "ant_position_z": -0.5, "amp_type": "rno_surface", - "cab_time_delay": 45.5, + "cab_time_delay": 45.8043779968151, "adc_n_samples": 2048, "adc_sampling_frequency": 3.2, "commission_time": "{TinyDate}:2022-07-05T00:00:00", @@ -2774,7 +2774,7 @@ }, "154": { "station_id": 24, - "channel_id": 13, + "channel_id": 19, "ant_rotation_phi": 90.0, "ant_rotation_theta": 90.0, "ant_orientation_phi": 0.0, @@ -2783,7 +2783,7 @@ "ant_position_y": 9.69794171581998, "ant_position_z": -0.5, "amp_type": "rno_surface", - "cab_time_delay": 45.5, + "cab_time_delay": 46.20942421716986, "adc_n_samples": 2048, "adc_sampling_frequency": 3.2, "commission_time": "{TinyDate}:2022-07-05T00:00:00", @@ -2792,7 +2792,7 @@ }, "155": { "station_id": 24, - "channel_id": 12, + "channel_id": 18, "ant_rotation_phi": 90.0, "ant_rotation_theta": 90.0, "ant_orientation_phi": 180.0, @@ -2801,7 +2801,7 @@ "ant_position_y": 8.763806538503559, "ant_position_z": -0.5, "amp_type": "rno_surface", - "cab_time_delay": 45.5, + "cab_time_delay": 45.72635561302779, "adc_n_samples": 2048, "adc_sampling_frequency": 3.2, "commission_time": "{TinyDate}:2022-07-05T00:00:00", @@ -2864,7 +2864,7 @@ }, "159": { "station_id": 24, - "channel_id": 20, + "channel_id": 17, "ant_rotation_phi": 330.0, "ant_rotation_theta": 90.0, "ant_orientation_phi": 240.0, @@ -2873,7 +2873,7 @@ "ant_position_y": 13.728847626744027, "ant_position_z": -0.5, "amp_type": "rno_surface", - "cab_time_delay": 45.5, + "cab_time_delay": 45.767816340568835, "adc_n_samples": 2048, "adc_sampling_frequency": 3.2, "commission_time": "{TinyDate}:2022-07-12T00:00:00", @@ -2882,7 +2882,7 @@ }, "160": { "station_id": 24, - "channel_id": 19, + "channel_id": 16, "ant_rotation_phi": 330.0, "ant_rotation_theta": 90.0, "ant_orientation_phi": 0.0, @@ -2891,7 +2891,7 @@ "ant_position_y": 15.972603155508295, "ant_position_z": -0.5, "amp_type": "rno_surface", - "cab_time_delay": 45.5, + "cab_time_delay": 45.458824371215705, "adc_n_samples": 2048, "adc_sampling_frequency": 3.2, "commission_time": "{TinyDate}:2022-07-12T00:00:00", @@ -2900,7 +2900,7 @@ }, "161": { "station_id": 24, - "channel_id": 18, + "channel_id": 15, "ant_rotation_phi": 330.0, "ant_rotation_theta": 90.0, "ant_orientation_phi": 60.0, @@ -2909,7 +2909,7 @@ "ant_position_y": 18.089740914087088, "ant_position_z": -0.5, "amp_type": "rno_surface", - "cab_time_delay": 45.5, + "cab_time_delay": 45.75439206401613, "adc_n_samples": 2048, "adc_sampling_frequency": 3.2, "commission_time": "{TinyDate}:2022-07-12T00:00:00", @@ -2972,7 +2972,7 @@ }, "165": { "station_id": 24, - "channel_id": 17, + "channel_id": 14, "ant_rotation_phi": 210.0, "ant_rotation_theta": 90.0, "ant_orientation_phi": 120.0, @@ -2981,7 +2981,7 @@ "ant_position_y": 21.12356453178745, "ant_position_z": -0.5, "amp_type": "rno_surface", - "cab_time_delay": 45.5, + "cab_time_delay": 45.61878753278558, "adc_n_samples": 2048, "adc_sampling_frequency": 3.2, "commission_time": "{TinyDate}:2022-07-06T00:00:00", @@ -2990,7 +2990,7 @@ }, "166": { "station_id": 24, - "channel_id": 16, + "channel_id": 13, "ant_rotation_phi": 210.0, "ant_rotation_theta": 90.0, "ant_orientation_phi": 0.0, @@ -2999,7 +2999,7 @@ "ant_position_y": 18.788879136683136, "ant_position_z": -0.5, "amp_type": "rno_surface", - "cab_time_delay": 45.5, + "cab_time_delay": 45.824131294404665, "adc_n_samples": 2048, "adc_sampling_frequency": 3.2, "commission_time": "{TinyDate}:2022-07-06T00:00:00", @@ -3008,7 +3008,7 @@ }, "167": { "station_id": 24, - "channel_id": 15, + "channel_id": 12, "ant_rotation_phi": 210.0, "ant_rotation_theta": 90.0, "ant_orientation_phi": 300.0, @@ -3017,7 +3017,7 @@ "ant_position_y": 16.187269998868032, "ant_position_z": -0.5, "amp_type": "rno_surface", - "cab_time_delay": 45.5, + "cab_time_delay": 45.364441874451146, "adc_n_samples": 2048, "adc_sampling_frequency": 3.2, "commission_time": "{TinyDate}:2022-07-06T00:00:00", From 393a08305843abb1214ec0b68e464d24f319a976 Mon Sep 17 00:00:00 2001 From: alisanozdrina Date: Tue, 21 Mar 2023 12:22:22 -0500 Subject: [PATCH 178/418] Update ara_detector_db.json Removed extra curly brace from line 2. Doesn't match proper json file formatting.. --- NuRadioReco/detector/ARA/ara_detector_db.json | 1 - 1 file changed, 1 deletion(-) diff --git a/NuRadioReco/detector/ARA/ara_detector_db.json b/NuRadioReco/detector/ARA/ara_detector_db.json index ec5fa08bb..b0f194bb9 100644 --- a/NuRadioReco/detector/ARA/ara_detector_db.json +++ b/NuRadioReco/detector/ARA/ara_detector_db.json @@ -1,4 +1,3 @@ -{ { "_default": {}, "channels": { From 360ca22f461038752899ca21e97ba9f213c8e991 Mon Sep 17 00:00:00 2001 From: Christian Glaser Date: Fri, 24 Mar 2023 13:20:44 +0100 Subject: [PATCH 179/418] fix bug that nur files are not closed properly --- NuRadioReco/modules/io/eventWriter.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/NuRadioReco/modules/io/eventWriter.py b/NuRadioReco/modules/io/eventWriter.py index fac065eae..35a3b0d9c 100644 --- a/NuRadioReco/modules/io/eventWriter.py +++ b/NuRadioReco/modules/io/eventWriter.py @@ -38,6 +38,7 @@ def __init__(self): self.__event_ids_and_runs = None self.__events_per_file = None self.__events_in_current_file = 0 + self.__fout = None def __write_fout_header(self): if self.__number_of_files > 1: @@ -301,7 +302,9 @@ def __check_for_duplicate_ids(self, run_number, event_id): return def end(self): - if(hasattr(self, "__fout")): + if self.__fout is not None: self.__fout.close() - self.debug(f"closing file.") + self.info(f"closing file {self.__filename}.") + else: + self.warning(f"file {self.__filename} does not exist and won't be closed.") return self.__number_of_events From f64c7bef838257facd22008b23f2b2ee67242cae Mon Sep 17 00:00:00 2001 From: Christian Glaser Date: Fri, 24 Mar 2023 13:32:40 +0100 Subject: [PATCH 180/418] fix logger --- NuRadioReco/modules/io/eventWriter.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/NuRadioReco/modules/io/eventWriter.py b/NuRadioReco/modules/io/eventWriter.py index 35a3b0d9c..3bd450d0a 100644 --- a/NuRadioReco/modules/io/eventWriter.py +++ b/NuRadioReco/modules/io/eventWriter.py @@ -304,7 +304,7 @@ def __check_for_duplicate_ids(self, run_number, event_id): def end(self): if self.__fout is not None: self.__fout.close() - self.info(f"closing file {self.__filename}.") + logger.info(f"closing file {self.__filename}.") else: - self.warning(f"file {self.__filename} does not exist and won't be closed.") + logger.warning(f"file {self.__filename} does not exist and won't be closed.") return self.__number_of_events From 6f8130d8343d70424034991150ec4ce5b056a7cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= <30903175+fschlueter@users.noreply.github.com> Date: Fri, 24 Mar 2023 15:01:51 +0100 Subject: [PATCH 181/418] Update analyticraytracing.py Improve doc-string --- NuRadioMC/SignalProp/analyticraytracing.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/NuRadioMC/SignalProp/analyticraytracing.py b/NuRadioMC/SignalProp/analyticraytracing.py index dc2826a07..d9e3c670a 100644 --- a/NuRadioMC/SignalProp/analyticraytracing.py +++ b/NuRadioMC/SignalProp/analyticraytracing.py @@ -110,7 +110,13 @@ def __init__(self, medium, attenuation_model="SP1", if True, the initial C_0 paramter (launch angle) is set to the ray that skims the surface (default: False) overwrite_speedup: bool - If not None, use value to overwrite _use_optimized_calculation. (Default: None) + The signal attenuation is calculated using a numerical integration + along the ray path. This calculation can be computational inefficient depending on the details of + the ice model. An optimization is implemented approximating the integral with a discrete sum with the loss + of some accuracy, See PR #507. This optimization is used for all ice models listed in + speedup_attenuation_models (i.e., "GL3"). With this argument you can explicitly activate or deactivate + (True or False) if you want to use the optimization. (Default: None, i.e., use optimization if ice model is + listed in speedup_attenuation_models) """ self.medium = medium From 4fa7ce67e82ccf8a200b6c379585d805603af49e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Sat, 25 Mar 2023 16:23:33 +0100 Subject: [PATCH 182/418] Start implementing features from ARIANNA/noiseImporter.py into channelMeasuredNoiseAdder.py to make the former redundant --- .../channelMeasuredNoiseAdder.py | 109 +++++++++++++++--- 1 file changed, 92 insertions(+), 17 deletions(-) diff --git a/NuRadioReco/modules/measured_noise/channelMeasuredNoiseAdder.py b/NuRadioReco/modules/measured_noise/channelMeasuredNoiseAdder.py index 581a316a3..fc06d2098 100644 --- a/NuRadioReco/modules/measured_noise/channelMeasuredNoiseAdder.py +++ b/NuRadioReco/modules/measured_noise/channelMeasuredNoiseAdder.py @@ -1,11 +1,11 @@ -from NuRadioReco.modules.base.module import register_run -import NuRadioReco.modules.io.NuRadioRecoio import numpy as np -from NuRadioReco.utilities import units -import numpy.random import logging import matplotlib.pyplot as plt +from NuRadioReco.modules.base.module import register_run +import NuRadioReco.modules.io.NuRadioRecoio +from NuRadioReco.utilities import units + class channelMeasuredNoiseAdder: """ @@ -21,11 +21,12 @@ def __init__(self): self.__io = None self.__random_state = None self.__max_iterations = None - self.__debug = None self.logger = logging.getLogger('NuRadioReco.channelMeasuredNoiseAdder') self.__noise_data = None - def begin(self, filenames, random_seed=None, max_iterations=100, debug=False, draw_noise_statistics=False): + + def begin(self, filenames, random_seed=None, max_iterations=100, debug=False, + draw_noise_statistics=False, channel_mapping=None, log_level=logging.WARNING, mean_opt=True): """ Set up module parameters @@ -33,26 +34,59 @@ def begin(self, filenames, random_seed=None, max_iterations=100, debug=False, dr ---------- filenames: list of strings List of .nur files containing the measured noise + random_seed: int, default: None Seed for the random number generator. By default, no seed is set. + max_iterations: int, default: 100 The module will pick a random event from the noise files, until a suitable event is found or until the number of iterations exceeds max_iterations. In that case, an error is thrown. + debug: bool, default: False Set True to get debug output + draw_noise_statistics: boolean, default: False If true, the values of all samples is stored and a histogram with noise statistics is drawn be the end() method + + channel_mapping: dict or None + option relevant for MC studies of new station designs where we do not + have forced triggers for. The channel_mapping dictionary maps the channel + ids of the MC station to the channel ids of the noise data + Default is None which is 1-to-1 mapping + + log_level: loggging log level + the log level, default logging.WARNING + + mean_opt: boolean + option to subtract mean from trace. Set mean_opt=False to remove mean subtraction from trace. """ self.__filenames = filenames self.__io = NuRadioReco.modules.io.NuRadioRecoio.NuRadioRecoio(self.__filenames) - self.__random_state = numpy.random.Generator(numpy.random.Philox(random_seed)) + self.__random_state = np.random.Generator(np.random.Philox(random_seed)) self.__max_iterations = max_iterations + + self.__channel_mapping = channel_mapping + self.__mean_opt = mean_opt + + self.__use_same_station = True + self.__allow_noise_resampling = False + self.logger.setLevel(log_level) + if debug: self.logger.setLevel(logging.DEBUG) self.logger.debug('Reading noise from {} files containing {} events'.format(len(filenames), self.__io.get_n_events())) + if draw_noise_statistics: self.__noise_data = [] + + + def __get_noise_channel(self, channel_id): + if self.__channel_mapping is None: + return channel_id + else: + return self.__channel_mapping[channel_id] + @register_run() def run(self, event, station, det): @@ -66,25 +100,45 @@ def run(self, event, station, det): det: detector description """ noise_station = None - for i in range(self.__max_iterations): + + for _ in range(self.__max_iterations): noise_station = self.get_noise_station(station) # Get random station from noise file. If we got a suitable station, we continue, # otherwise we try again if noise_station is not None: break + # To avoid infinite loops, if no suitable noise station was found after a number of iterations we raise an error if noise_station is None: raise ValueError('Could not find suitable noise event in noise files after {} iterations'.format(self.__max_iterations)) + for channel in station.iter_channels(): - noise_channel = noise_station.get_channel(channel.get_id()) + noise_channel = noise_station.get_channel(self.__get_noise_channel(channel.get_id())) channel_trace = channel.get_trace() + + # if resampling is not desired no channel with wrong sampling rate is selected in get_noise_station() if noise_channel.get_sampling_rate() != channel.get_sampling_rate(): noise_channel.resample(channel.get_sampling_rate()) + noise_trace = noise_channel.get_trace() + + if self.__mean_opt: + mean = noise_trace.mean() + std = noise_trace.std() + if mean > 0.05 * std: + self.logger.warning(( + "the noise trace has an offset of {:.2}mV which is more than 5% of the STD of {:.2f}mV. " + "The module corrects for the offset but it might points to an error in the FPN subtraction.").format(mean, std)) + + noise_trace -= mean + channel_trace += noise_trace[:channel.get_number_of_samples()] + + # if draw_noise_statistics == True if self.__noise_data is not None: self.__noise_data.append(noise_trace) + def get_noise_station(self, station): """ Returns a random station from the noise files that can be used as a noise sample. @@ -103,25 +157,46 @@ def get_noise_station(self, station): """ event_i = self.__random_state.randint(self.__io.get_n_events()) noise_event = self.__io.get_event_i(event_i) - if station.get_id() not in noise_event.get_station_ids(): - self.logger.debug('No station with ID {} found in event'.format(station.get_id())) + + if self.__use_same_station and station.get_id() not in noise_event.get_station_ids(): + self.logger.debug('Event {}: No station with ID {} found.'.format(event_i, station.get_id())) return None - noise_station = noise_event.get_station(station.get_id()) + + if self.__use_same_station: + noise_station = noise_event.get_station(station.get_id()) + else: + noise_station = noise_event.get_station() # get first station stored in event + for trigger_name in noise_station.get_triggers(): trigger = noise_station.get_trigger(trigger_name) if trigger.has_triggered(): - self.logger.debug('Noise station has triggered') + self.logger.debug('Noise station has triggered, reject noise event.') return None + for channel_id in station.get_channel_ids(): - if channel_id not in noise_station.get_channel_ids(): - self.logger.debug('Channel {} found in station but not in noise file'.format(channel_id)) + noise_channel_id = self.__get_noise_channel(channel_id) + if noise_channel_id not in noise_station.get_channel_ids(): + if channel_id == noise_channel_id: + self.logger.debug('Event {}: Requested channel {} not found'.format(event_i, noise_channel_id)) return None - noise_channel = noise_station.get_channel(channel_id) + + noise_channel = noise_station.get_channel(noise_channel_id) channel = station.get_channel(channel_id) - if noise_channel.get_number_of_samples() / noise_channel.get_sampling_rate() < channel.get_number_of_samples() / channel.get_sampling_rate(): + + if noise_channel.get_number_of_samples() != noise_channel.get_sampling_rate() and not self.__allow_noise_resampling: + self.logger.debug('Event {}, Channel {}: Different sampling rates, reject noise event.' + .format(event_i, noise_channel_id)) + return None + + if (noise_channel.get_number_of_samples() / noise_channel.get_sampling_rate() < + channel.get_number_of_samples() / channel.get_sampling_rate()): + self.logger.debug('Event {}, Channel {}: Different sampling rate / trace lenght ratios' + .format(event_i, noise_channel_id)) return None + return noise_station + def end(self): """ End method. Draws a histogram of the noise statistics and fits a From 2561ecb291e71b1eca84fd93f266596383a7f175 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Mon, 27 Mar 2023 11:50:30 +0200 Subject: [PATCH 183/418] Implement more features: Allow to specift the station id used for the noise file. Some renaming and fixing of the begin method --- .../channelMeasuredNoiseAdder.py | 67 +++++++++++++------ 1 file changed, 46 insertions(+), 21 deletions(-) diff --git a/NuRadioReco/modules/measured_noise/channelMeasuredNoiseAdder.py b/NuRadioReco/modules/measured_noise/channelMeasuredNoiseAdder.py index fc06d2098..314dc9c11 100644 --- a/NuRadioReco/modules/measured_noise/channelMeasuredNoiseAdder.py +++ b/NuRadioReco/modules/measured_noise/channelMeasuredNoiseAdder.py @@ -1,6 +1,5 @@ import numpy as np import logging -import matplotlib.pyplot as plt from NuRadioReco.modules.base.module import register_run import NuRadioReco.modules.io.NuRadioRecoio @@ -26,7 +25,8 @@ def __init__(self): def begin(self, filenames, random_seed=None, max_iterations=100, debug=False, - draw_noise_statistics=False, channel_mapping=None, log_level=logging.WARNING, mean_opt=True): + draw_noise_statistics=False, channel_mapping=None, log_level=logging.WARNING, + restrict_station_id=True, station_id=None, allow_noise_resampling=False, baseline_substraction=True): """ Set up module parameters @@ -58,8 +58,18 @@ def begin(self, filenames, random_seed=None, max_iterations=100, debug=False, log_level: loggging log level the log level, default logging.WARNING - mean_opt: boolean - option to subtract mean from trace. Set mean_opt=False to remove mean subtraction from trace. + baseline_substraction: boolean + Option to subtract mean from trace. Set mean_opt=False to remove mean subtraction from trace. + + restrict_station_id: bool + Require the station in the noise event to be the same as in the simulated event. (Default: True) + + station_id: int + If restrict_station_id is False specify the station id to be used for the noise. If None take first station + in the noise event. (Default: None) + + allow_noise_resampling: bool + Allow resampling the noise trace to match the simulated trace. (Default: False) """ self.__filenames = filenames self.__io = NuRadioReco.modules.io.NuRadioRecoio.NuRadioRecoio(self.__filenames) @@ -67,10 +77,11 @@ def begin(self, filenames, random_seed=None, max_iterations=100, debug=False, self.__max_iterations = max_iterations self.__channel_mapping = channel_mapping - self.__mean_opt = mean_opt + self.__baseline_substraction = baseline_substraction - self.__use_same_station = True - self.__allow_noise_resampling = False + self.__restrict_station_id = restrict_station_id + self.__noise_station_id = station_id + self.__allow_noise_resampling = allow_noise_resampling self.logger.setLevel(log_level) if debug: @@ -117,22 +128,33 @@ def run(self, event, station, det): channel_trace = channel.get_trace() # if resampling is not desired no channel with wrong sampling rate is selected in get_noise_station() + resampled = False if noise_channel.get_sampling_rate() != channel.get_sampling_rate(): noise_channel.resample(channel.get_sampling_rate()) + resampled = True noise_trace = noise_channel.get_trace() - if self.__mean_opt: + if self.__baseline_substraction: mean = noise_trace.mean() std = noise_trace.std() if mean > 0.05 * std: self.logger.warning(( - "the noise trace has an offset of {:.2}mV which is more than 5% of the STD of {:.2f}mV. " + "The noise trace has an offset/baseline of {:.2f}mV which is more than 5% of the STD of {:.2f}mV. " "The module corrects for the offset but it might points to an error in the FPN subtraction.").format(mean, std)) noise_trace -= mean - - channel_trace += noise_trace[:channel.get_number_of_samples()] + + if len(channel_trace) > len(noise_trace): + err = "{} is shorter than simulated trace. Stop".format("Resampled noise trace" if resampled else "Noise trace") + self.logger.error(err) + raise ValueError(err) + elif len(channel_trace) < len(noise_trace): + noise_trace = noise_trace[:channel.get_number_of_samples()] # if to long, clip the end + else: + pass + + channel_trace += noise_trace # if draw_noise_statistics == True if self.__noise_data is not None: @@ -158,14 +180,15 @@ def get_noise_station(self, station): event_i = self.__random_state.randint(self.__io.get_n_events()) noise_event = self.__io.get_event_i(event_i) - if self.__use_same_station and station.get_id() not in noise_event.get_station_ids(): + if self.__restrict_station_id and station.get_id() not in noise_event.get_station_ids(): self.logger.debug('Event {}: No station with ID {} found.'.format(event_i, station.get_id())) return None - if self.__use_same_station: + if self.__restrict_station_id: noise_station = noise_event.get_station(station.get_id()) else: - noise_station = noise_event.get_station() # get first station stored in event + # If __noise_station_id == None get first station stored in event + noise_station = noise_event.get_station(self.__noise_station_id) for trigger_name in noise_station.get_triggers(): trigger = noise_station.get_trigger(trigger_name) @@ -190,9 +213,9 @@ def get_noise_station(self, station): if (noise_channel.get_number_of_samples() / noise_channel.get_sampling_rate() < channel.get_number_of_samples() / channel.get_sampling_rate()): + # Just add debug message... self.logger.debug('Event {}, Channel {}: Different sampling rate / trace lenght ratios' - .format(event_i, noise_channel_id)) - return None + .format(event_i, noise_channel_id)) return noise_station @@ -203,16 +226,18 @@ def end(self): Gaussian distribution to it. """ if self.__noise_data is not None: + import matplotlib.pyplot as plt + plt.close('all') + noise_entries = np.array(self.__noise_data) noise_bins = np.arange(-150, 150, 5.) * units.mV noise_entries = noise_entries.flatten() mean = noise_entries.mean() - sigma = np.sqrt(np.mean((noise_entries - mean)**2)) - plt.close('all') - fig1 = plt.figure() - ax1_1 = fig1.add_subplot(111) + sigma = noise_entries.std() + + fig1, ax1_1 = plt.subplots() n, bins, pathes = ax1_1.hist(noise_entries / units.mV, bins=noise_bins / units.mV) - ax1_1.plot(noise_bins / units.mV, np.max(n) * np.exp(-.5 * (noise_bins - mean)**2 / sigma**2)) + ax1_1.plot(noise_bins / units.mV, np.max(n) * np.exp(-0.5 * (noise_bins - mean) ** 2 / sigma ** 2)) ax1_1.grid() ax1_1.set_xlabel('sample value [mV]') ax1_1.set_ylabel('entries') From 027aa09299fc5d7fec2c1d018783921e4ee92814 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Thu, 30 Mar 2023 18:14:59 +0200 Subject: [PATCH 184/418] Modify getter and setter for station._station_time. Now the time format is not controlled/converted during setting but only during getting. This makes the code more readable but the state interally is undefined (but its only the format) --- NuRadioReco/framework/base_station.py | 43 ++++++++++++++++++++------- 1 file changed, 32 insertions(+), 11 deletions(-) diff --git a/NuRadioReco/framework/base_station.py b/NuRadioReco/framework/base_station.py index 8ef4ef97a..66a22bf9c 100644 --- a/NuRadioReco/framework/base_station.py +++ b/NuRadioReco/framework/base_station.py @@ -76,20 +76,41 @@ def remove_parameter(self, key): self._parameters.pop(key, None) def set_station_time(self, time): - if time is None: - self._station_time = None - return + """ + Set the (absolute) time for the station (stored as astropy.time.Time). + Not related to the event._event_time. + + Parameters + ---------- + + time: astropy.time.Time or datetime.datetime or float + If time is a float it is interpreted as UTC unix timestamp. + """ + if isinstance(time, datetime.datetime): - time_strings = str(time).split(' ') - self._station_time = astropy.time.Time('{}T{}'.format(time_strings[0], time_strings[1]), format='isot') + self._station_time = astropy.time.Time(time) + elif isinstance(time, astropy.time): + self._station_time = time else: - if time.format == 'datetime': - time_strings = str(time).split(' ') - self._station_time = astropy.time.Time('{}T{}'.format(time_strings[0], time_strings[1]), format='isot') - else: - self._station_time = time + # time is interpreted as unix utc timestamp + self._station_time = astropy.time.Time(time, format='unix') - def get_station_time(self): + def get_station_time(self, format='isot'): + """ + Returns a astropy.time.Time object + + Parameters + ---------- + + format: str + Format in which the time object is displayed. (Default: isot) + + Returns + ------- + + _station_time: astropy.time.Time + """ + self._station_time.format = format return self._station_time def get_id(self): From 8d0358f87d9218e3f42ea97e27cc2aceff662247 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= <30903175+fschlueter@users.noreply.github.com> Date: Thu, 30 Mar 2023 18:23:58 +0200 Subject: [PATCH 185/418] Update base_station.py Allow to set station._station_time = None --- NuRadioReco/framework/base_station.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/NuRadioReco/framework/base_station.py b/NuRadioReco/framework/base_station.py index 66a22bf9c..a362e8969 100644 --- a/NuRadioReco/framework/base_station.py +++ b/NuRadioReco/framework/base_station.py @@ -91,6 +91,8 @@ def set_station_time(self, time): self._station_time = astropy.time.Time(time) elif isinstance(time, astropy.time): self._station_time = time + elif time == None: + self._station_time = None else: # time is interpreted as unix utc timestamp self._station_time = astropy.time.Time(time, format='unix') From 6d17305a6774c8a96d0284d5015063f49a874da8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= <30903175+fschlueter@users.noreply.github.com> Date: Thu, 30 Mar 2023 19:17:49 +0200 Subject: [PATCH 186/418] Update base_station.py Fix Sjoerds comments --- NuRadioReco/framework/base_station.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/NuRadioReco/framework/base_station.py b/NuRadioReco/framework/base_station.py index a362e8969..43bf94807 100644 --- a/NuRadioReco/framework/base_station.py +++ b/NuRadioReco/framework/base_station.py @@ -89,9 +89,9 @@ def set_station_time(self, time): if isinstance(time, datetime.datetime): self._station_time = astropy.time.Time(time) - elif isinstance(time, astropy.time): + elif isinstance(time, astropy.time.Time): self._station_time = time - elif time == None: + elif time is None: self._station_time = None else: # time is interpreted as unix utc timestamp From faa65c0c6002f86a81e4aebb9785c1a4df0e2f75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= <30903175+fschlueter@users.noreply.github.com> Date: Thu, 30 Mar 2023 19:22:25 +0200 Subject: [PATCH 187/418] Update base_station.py Add format to interface --- NuRadioReco/framework/base_station.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/NuRadioReco/framework/base_station.py b/NuRadioReco/framework/base_station.py index 43bf94807..fac7c4c0c 100644 --- a/NuRadioReco/framework/base_station.py +++ b/NuRadioReco/framework/base_station.py @@ -75,7 +75,7 @@ def remove_parameter(self, key): raise ValueError("parameter key needs to be of type NuRadioReco.framework.parameters.stationParameters") self._parameters.pop(key, None) - def set_station_time(self, time): + def set_station_time(self, time, format=None): """ Set the (absolute) time for the station (stored as astropy.time.Time). Not related to the event._event_time. @@ -84,7 +84,10 @@ def set_station_time(self, time): ---------- time: astropy.time.Time or datetime.datetime or float - If time is a float it is interpreted as UTC unix timestamp. + If "time" is a float, you have to specify its format. + + format: str + Only used when "time" is a float. Format to interpret "time". (Default: None) """ if isinstance(time, datetime.datetime): @@ -94,8 +97,7 @@ def set_station_time(self, time): elif time is None: self._station_time = None else: - # time is interpreted as unix utc timestamp - self._station_time = astropy.time.Time(time, format='unix') + self._station_time = astropy.time.Time(time, format=format) def get_station_time(self, format='isot'): """ From 33407de5fb9985f2b9228abad37def1bc5bc658b Mon Sep 17 00:00:00 2001 From: Sjoerd Bouma Date: Fri, 31 Mar 2023 12:04:36 +0200 Subject: [PATCH 188/418] pin awkward<2 --- documentation/source/Introduction/pages/installation.rst | 2 +- pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/documentation/source/Introduction/pages/installation.rst b/documentation/source/Introduction/pages/installation.rst index 402faee2e..6d5f298b9 100644 --- a/documentation/source/Introduction/pages/installation.rst +++ b/documentation/source/Introduction/pages/installation.rst @@ -145,7 +145,7 @@ These packages are recommended to be able to use all of NuRadioMC/NuRadioReco's .. code-block:: bash - pip install uproot==4.1.1 + pip install uproot==4.1.1 'awkward<2' - To access some detector databases: diff --git a/pyproject.toml b/pyproject.toml index b3b89eac1..d936b0ee8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -33,7 +33,7 @@ h5py = "*" peakutils = "*" pymongo = "*" pyyaml = "*" -awkward = "*" +awkward = "<2" python = "^3.6" matplotlib = "*" requests = "*" From ec4e0955daf786b5330d39ee40f3c81ed5e784e9 Mon Sep 17 00:00:00 2001 From: lpyras Date: Fri, 31 Mar 2023 15:19:57 +0200 Subject: [PATCH 189/418] class to access muon flux from MCEq --- NuRadioMC/utilities/muon_flux.py | 175 +++++++++++++++++++++++++++++++ 1 file changed, 175 insertions(+) create mode 100644 NuRadioMC/utilities/muon_flux.py diff --git a/NuRadioMC/utilities/muon_flux.py b/NuRadioMC/utilities/muon_flux.py new file mode 100644 index 000000000..5d65dfe8c --- /dev/null +++ b/NuRadioMC/utilities/muon_flux.py @@ -0,0 +1,175 @@ +from NuRadioReco.utilities import units +import numpy as np +import os +import pickle +from scipy.interpolate import interp1d +from MCEq.core import MCEqRun +import crflux.models as crf +from functools import lru_cache + +class MuonFlux: + def __init__(self): + self.mc_cm = 1. + self.mc_m = 1e2 + self.mc_km = 1e3 * self.mc_m + + self.mc_deg = 1. + self.mc_rad = 180. / np.pi + + self.mc_eV = 1.e-9 + self.mc_GeV = 1 + self.mc_TeV = 1.e3 + self.mc_PeV = 1.e6 + self.mc_EeV = 1.e9 + + self.mc_s = 1 + self.mc_ns = 1e-9 + + self.__buffer = {} + self.file_buffer = "data/surface_muon_buffer.pkl" + if(os.path.exists(self.file_buffer)): + fin = open(self.file_buffer, "rb") + self.__buffer = pickle.load(fin) + fin.close() + + @lru_cache(maxsize=5000) + def get_mu_flux(self, theta, altitude=3200, interaction_model='SIBYLL23C', primary_model=(crf.GlobalSplineFitBeta, None), particle_names=("total_mu+", "total_mu-")): + + """ + The function get_mu_flux returns the muon flux at theta, for a given altitude, CR model, and hadronic interaction model. + + Parameters + + ---------- + energy: float + energy in eV + theta_min: float + minimum zenith angle in rad + theta_max: float + maximum zenith angle in rad + n_steps: int + number of steps to use for the numerical integration + + Returns + ------- + e_grid: array of floats + energy grid in eV + flux: array of floats + flux in NuRadioReco units 1/(area * time * energy * steradian) + + """ + + altitude *= self.mc_m + mceq = MCEqRun(interaction_model=interaction_model, + primary_model=primary_model, + theta_deg=theta * self.mc_rad) + + h_grid = np.linspace(50 * 1e3 * 1e2, 0, 500) + X_grid = mceq.density_model.h2X(h_grid) + + alt_idx = np.abs(h_grid - altitude).argmin() + + mceq.solve(int_grid=X_grid) + flux = None + for particle_name in particle_names: + if flux is None: + flux = mceq.get_solution(particle_name, grid_idx=alt_idx, integrate=False) + else: + flux += mceq.get_solution(particle_name, grid_idx=alt_idx, integrate=False) + + flux *= self.mc_m ** 2 * self.mc_eV * self.mc_ns # convert to NuRadioReco units + e_grid = mceq.e_grid / self.mc_eV + + return e_grid, flux + + def get_interp_angle_mu_flux(self, theta_min, theta_max, altitude=3200, n_steps=3, primary_model=(crf.GlobalSplineFitBeta, None), + interaction_model='SIBYLL23C', particle_names=("total_mu+", "total_mu-")): + """ + The function get_int_angle_mu_flux returns the interpolation function of the integrated muon flux from theta_min to theta_max, + The integration is just a simple Riemannian sum that should be enough, provided the band is small. + + Returns zenith angle integrated flux in NuRadioReco units 1/(area * time * energy) + + Parameters + + ---------- + energy: float + energy in eV + theta_min: float + minimum zenith angle in rad + theta_max: float + maximum zenith angle in rad + n_steps: int + number of steps to use for the numerical integration + + Returns + ------- + interpolator: function + function that returns the flux for a given energy + """ + angle_edges = np.arccos(np.linspace(np.cos(theta_max), np.cos(theta_min), n_steps + 1)) + angle_centers = 0.5 *(angle_edges[1:] + angle_edges[:-1]) + d_cos_theta = np.abs(np.cos(theta_min) - np.cos(theta_max)) + + #print(f"integrating the flux from {theta_min/units.deg:.1f} deg to {theta_max/units.deg:.1f} deg by adding the flux from {angle_centers/units.deg}") + + flux = None + for angle in angle_centers: + e_grid, flux_tmp = self.get_mu_flux(angle, altitude, primary_model=primary_model, + interaction_model=interaction_model, particle_names=particle_names) + + # solid angle element is sin(theta) dtheta dphi in spherical coordinates. + flux_tmp *= np.sin(angle) * (d_cos_theta * 2 * np.pi ) / n_steps + if(flux is None): + flux = flux_tmp + else: + flux += flux_tmp + + return interp1d(np.log10(e_grid), flux, kind='cubic') + + + def get_int_angle_mu_flux_buffered(self, energy, theta_min, theta_max, altitude=3200, n_steps=3, primary_model=(crf.GlobalSplineFitBeta, None),interaction_model='SIBYLL23C', particle_names=("total_mu+", "total_mu-")): + + """ + The function get_int_angle_mu_flux evalueates the integrated muon flux from theta_min to theta_max and caches the result. + + Parameters + + ---------- + energy: float + energy in eV + theta_min: float + minimum zenith angle in rad + theta_max: float + maximum zenith angle in rad + altitude: float + altitude in meters + n_steps: int + number of steps to use for the numerical integration + + Returns + ------- + flux: float + zenith angle integrated flux in NuRadioReco units 1/(area * time * energy) + + """ + + params = (np.round(energy), np.round(theta_min, 6), np.round(theta_max, 6), np.round(altitude), + n_steps, primary_model, interaction_model, particle_names) + + if(params not in self.__buffer): + print(f"calculating muon flux for {params}") + finterp = self.get_interp_angle_mu_flux(theta_min, theta_max, altitude, n_steps=n_steps, primary_model=primary_model, + interaction_model=interaction_model, particle_names=particle_names) + + flux = finterp(np.log10(energy)) + self.__buffer[params] = flux + with open(self.file_buffer, "wb") as fout: + pickle.dump(self.__buffer, fout, protocol=4) + + return self.__buffer[params] + + def get_e_grid(self, theta_deg=50, interaction_model='SIBYLL23C', primary_model=(crf.GlobalSplineFitBeta, None)): + mceq = MCEqRun(interaction_model=interaction_model, primary_model=primary_model, theta_deg=theta_deg) + e_grid = mceq.e_grid / self.mc_eV + return e_grid \ No newline at end of file From 34670bb391a597e67546a16840225c8801865817 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Sat, 1 Apr 2023 12:46:34 +0200 Subject: [PATCH 190/418] Update interface of channelMeasuredNoiseAdder: Allow to specify location of noise files --- .../channelMeasuredNoiseAdder.py | 28 +++++++++++++++++-- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/NuRadioReco/modules/measured_noise/channelMeasuredNoiseAdder.py b/NuRadioReco/modules/measured_noise/channelMeasuredNoiseAdder.py index 314dc9c11..49dd4b90a 100644 --- a/NuRadioReco/modules/measured_noise/channelMeasuredNoiseAdder.py +++ b/NuRadioReco/modules/measured_noise/channelMeasuredNoiseAdder.py @@ -1,5 +1,6 @@ import numpy as np import logging +import glob from NuRadioReco.modules.base.module import register_run import NuRadioReco.modules.io.NuRadioRecoio @@ -24,7 +25,8 @@ def __init__(self): self.__noise_data = None - def begin(self, filenames, random_seed=None, max_iterations=100, debug=False, + def begin(self, filenames=None, folder=None, file_pattern="*", + random_seed=None, max_iterations=100, debug=False, draw_noise_statistics=False, channel_mapping=None, log_level=logging.WARNING, restrict_station_id=True, station_id=None, allow_noise_resampling=False, baseline_substraction=True): """ @@ -33,7 +35,15 @@ def begin(self, filenames, random_seed=None, max_iterations=100, debug=False, Parameters ---------- filenames: list of strings - List of .nur files containing the measured noise + List of .nur files containing the measured noise. If None, look for .nur files in "folder". + (Default: None) + + folder: str + Only used when "filenames" is None. Directory to search for .nur files matching the "file_pattern" + including subdirectories. (Default: None) + + file_pattern: str + Use glob.glob(f"{folder}/**/{file_pattern}.nur", recursive=True) to search for files. (Default: "*") random_seed: int, default: None Seed for the random number generator. By default, no seed is set. @@ -71,7 +81,20 @@ def begin(self, filenames, random_seed=None, max_iterations=100, debug=False, allow_noise_resampling: bool Allow resampling the noise trace to match the simulated trace. (Default: False) """ + + self.logger.setLevel(log_level) + self.__filenames = filenames + if self.__filenames is None: + if folder is None: + err = "Both, \"filenames\" and \"folder\" are None, you have to specify at least one ..." + self.logger.error(err) + raise ValueError(err) + + self.__filenames = glob.glob(f"{folder}/**/{file_pattern}.nur", recursive=True) + + self.logger.info(f"Found {len(self.__filenames)} noise file(s) ...") + self.__io = NuRadioReco.modules.io.NuRadioRecoio.NuRadioRecoio(self.__filenames) self.__random_state = np.random.Generator(np.random.Philox(random_seed)) self.__max_iterations = max_iterations @@ -82,7 +105,6 @@ def begin(self, filenames, random_seed=None, max_iterations=100, debug=False, self.__restrict_station_id = restrict_station_id self.__noise_station_id = station_id self.__allow_noise_resampling = allow_noise_resampling - self.logger.setLevel(log_level) if debug: self.logger.setLevel(logging.DEBUG) From 2d39956b4700b901ab47a5397a59381a74c2975c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Sat, 1 Apr 2023 12:49:00 +0200 Subject: [PATCH 191/418] Add logger.warn --- NuRadioReco/modules/measured_noise/channelMeasuredNoiseAdder.py | 1 + 1 file changed, 1 insertion(+) diff --git a/NuRadioReco/modules/measured_noise/channelMeasuredNoiseAdder.py b/NuRadioReco/modules/measured_noise/channelMeasuredNoiseAdder.py index 49dd4b90a..18f770c4a 100644 --- a/NuRadioReco/modules/measured_noise/channelMeasuredNoiseAdder.py +++ b/NuRadioReco/modules/measured_noise/channelMeasuredNoiseAdder.py @@ -172,6 +172,7 @@ def run(self, event, station, det): self.logger.error(err) raise ValueError(err) elif len(channel_trace) < len(noise_trace): + self.logger.warn("Noise trace has more samples than the simulated one, clip noise trace at the end ...") noise_trace = noise_trace[:channel.get_number_of_samples()] # if to long, clip the end else: pass From e96a99b356fca8086ed62bb7f032224242a0e6ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Sat, 1 Apr 2023 12:53:52 +0200 Subject: [PATCH 192/418] Remove redundant noiseImporter.py module --- .../measured_noise/ARIANNA/noiseImporter.py | 140 ------------------ 1 file changed, 140 deletions(-) delete mode 100644 NuRadioReco/modules/measured_noise/ARIANNA/noiseImporter.py diff --git a/NuRadioReco/modules/measured_noise/ARIANNA/noiseImporter.py b/NuRadioReco/modules/measured_noise/ARIANNA/noiseImporter.py deleted file mode 100644 index 883ff6d6a..000000000 --- a/NuRadioReco/modules/measured_noise/ARIANNA/noiseImporter.py +++ /dev/null @@ -1,140 +0,0 @@ -from NuRadioReco.modules.base.module import register_run -from NuRadioReco.utilities import units -import numpy as np -import logging -import glob -import os -import sys -from NuRadioReco.modules.io import NuRadioRecoio -logger = logging.getLogger('noiseImporterARIANNA') - - -class noiseImporter: - """ - Imports recorded noise from ARIANNA station. The recorded noise needs to match the station geometry and sampling - as chosen with channelResampler and channelLengthAdjuster - - For different stations, new noise files need to be used. - Collect forced triggers from any type of station to use for analysis. - A seizable fraction of data is recommended for accuracy. - - The noise will be random. This module therefore might produce non-reproducible results on a single event basis, - if run several times. - """ - - def __init__(self): - self.__channel_mapping = None - self.__station_id = None - self.__mean_opt = None - self.__noise_files = None - self.__open_files = None - self.__n_tot = None - - def begin(self, noise_folder, station_id=None, noise_files=None, - channel_mapping=None, log_level=logging.WARNING, mean_opt=True): - """ - Parameters - ---------- - noise_folder: string - the folder containing the noise files - station_id: int - the station id, specifies from which station the forced triggers are used - as a noise sample. The data must have the naming convention 'forced_station_.nur' - where is replaced with the station id. If station_id is None, the noiseImporter - will try to find the station with the same iD as the one passed to the run - function in the noise file - noise_files: list of strings (default: None) - List of noisefiles. If None is passed, all files in the noise_folder are used - channel_mapping: dict or None - option relevant for MC studies of new station designs where we do not - have forced triggers for. The channel_mapping dictionary maps the channel - ids of the MC station to the channel ids of the noise data - Default is None which is 1-to-1 mapping - log_level: loggging log level - the log level, default logging.WARNING - mean_opt: boolean - option to subtract mean from trace. Set mean_opt=False to remove mean subtraction from trace. - """ - logger.setLevel(log_level) - self.__channel_mapping = channel_mapping - self.__mean_opt = mean_opt - if(noise_files is not None): - self.__noise_files = noise_files - else: - if(station_id is None): - logger.error("noise_files and station_id can't be both None") - sys.exit(-1) - else: - self.__noise_files = glob.glob(os.path.join(noise_folder, "forced_station_{}.nur".format(station_id))) - if(len(self.__noise_files) == 0): - logger.error("no noise files found for station {} in folder {}".format(station_id, noise_folder)) - sys.exit(-1) - - # open files and scan for number of events - self.__open_files = [] - self.__n_tot = 0 - for file_name in self.__noise_files: - f = NuRadioRecoio.NuRadioRecoio(file_name, parse_header=False) - n = f.get_n_events() - self.__open_files.append({'f': f, 'n_low': self.__n_tot, - 'n_high': self.__n_tot + n - 1}) - self.__n_tot += n - - def __get_noise_event(self, i): - for f in self.__open_files: - if(f['n_low'] <= i <= f['n_high']): - return f['f'].get_event_i(i - f['n_low']) - - def __get_noise_channel(self, channel_id): - if(self.__channel_mapping is None): - return channel_id - else: - return self.__channel_mapping[channel_id] - - @register_run() - def run(self, evt, station, det): - # loop over stations in simulation - i_noise = np.random.randint(0, self.__n_tot) - noise_event = self.__get_noise_event(i_noise) - if self.__station_id is None: - station_id = station.get_id() - else: - station_id = self.__station_id - noise_station = noise_event.get_station(station_id) - if noise_station is None: - raise KeyError('Station whith ID {} not found in noise file'.format(station_id)) - logger.info("choosing noise event {} ({}, run {}, event {}) randomly".format(i_noise, noise_station.get_station_time(), - noise_event.get_run_number(), - noise_event.get_id())) - - for channel in station.iter_channels(): - channel_id = channel.get_id() - - trace = channel.get_trace() - noise_channel = noise_station.get_channel(self.__get_noise_channel(channel_id)) - noise_trace = noise_channel.get_trace() - # check if trace has the same size - if (len(trace) != len(noise_trace)): - logger.error("Mismatch: Noise has {0} and simulation {1} samples".format(len(noise_trace), len(trace))) - sys.exit(-1) - # check sampling rate - if (channel.get_sampling_rate() != noise_channel.get_sampling_rate()): - logger.error("Mismatch in sampling rate: Noise has {0} and simulation {1} GHz".format( - noise_channel.get_sampling_rate() / units.GHz, channel.get_sampling_rate() / units.GHz)) - sys.exit(-1) - - trace = trace + noise_trace - - if self.__mean_opt: - mean = noise_trace.mean() - std = noise_trace.std() - if(mean > 0.05 * std): - logger.warning( - "the noise trace has an offset of {:.2}mV which is more than 5% of the STD of {:.2f}mV. The module corrects for the offset but it might points to an error in the FPN subtraction.".format(mean, std)) - trace = trace - mean - - channel.set_trace(trace, channel.get_sampling_rate()) - - def end(self): - for f in self.__open_files: - f['f'].close_file() From 14dccb0df7d1e25e92cc45f7768b9c17992f9043 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Mon, 3 Apr 2023 15:35:52 +0200 Subject: [PATCH 193/418] some fixes, allow certain triggers to be used --- .../channelMeasuredNoiseAdder.py | 23 +++++++++++++------ 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/NuRadioReco/modules/measured_noise/channelMeasuredNoiseAdder.py b/NuRadioReco/modules/measured_noise/channelMeasuredNoiseAdder.py index 18f770c4a..1cf89e2c2 100644 --- a/NuRadioReco/modules/measured_noise/channelMeasuredNoiseAdder.py +++ b/NuRadioReco/modules/measured_noise/channelMeasuredNoiseAdder.py @@ -28,7 +28,8 @@ def __init__(self): def begin(self, filenames=None, folder=None, file_pattern="*", random_seed=None, max_iterations=100, debug=False, draw_noise_statistics=False, channel_mapping=None, log_level=logging.WARNING, - restrict_station_id=True, station_id=None, allow_noise_resampling=False, baseline_substraction=True): + restrict_station_id=True, station_id=None, allow_noise_resampling=False, + baseline_substraction=True, allowed_triggers=["FORCE"]): """ Set up module parameters @@ -80,6 +81,9 @@ def begin(self, filenames=None, folder=None, file_pattern="*", allow_noise_resampling: bool Allow resampling the noise trace to match the simulated trace. (Default: False) + + allowed_triggers: list(str) + List of trigger names which should be used, events with other triggers are not used. (Default: ["FORCE"]) """ self.logger.setLevel(log_level) @@ -105,6 +109,8 @@ def begin(self, filenames=None, folder=None, file_pattern="*", self.__restrict_station_id = restrict_station_id self.__noise_station_id = station_id self.__allow_noise_resampling = allow_noise_resampling + + self._allowed_triggers = allowed_triggers if debug: self.logger.setLevel(logging.DEBUG) @@ -162,9 +168,9 @@ def run(self, event, station, det): std = noise_trace.std() if mean > 0.05 * std: self.logger.warning(( - "The noise trace has an offset/baseline of {:.2f}mV which is more than 5% of the STD of {:.2f}mV. " - "The module corrects for the offset but it might points to an error in the FPN subtraction.").format(mean, std)) - + "The noise trace has an offset/baseline of {:.3f}mV which is more than 5% of the STD of {:.3f}mV. " + "The module corrects for the offset but it might points to an error in the FPN subtraction.").format(mean / units.mV, std / units.mV)) + noise_trace -= mean if len(channel_trace) > len(noise_trace): @@ -200,7 +206,7 @@ def get_noise_station(self, station): station: Station class The station to which the noise shall be added """ - event_i = self.__random_state.randint(self.__io.get_n_events()) + event_i = self.__random_state.integers(0, self.__io.get_n_events()) noise_event = self.__io.get_event_i(event_i) if self.__restrict_station_id and station.get_id() not in noise_event.get_station_ids(): @@ -214,9 +220,12 @@ def get_noise_station(self, station): noise_station = noise_event.get_station(self.__noise_station_id) for trigger_name in noise_station.get_triggers(): + if trigger_name in self._allowed_triggers: + continue + trigger = noise_station.get_trigger(trigger_name) if trigger.has_triggered(): - self.logger.debug('Noise station has triggered, reject noise event.') + self.logger.debug(f'Noise station has triggered ({trigger_name}), reject noise event.') return None for channel_id in station.get_channel_ids(): @@ -229,7 +238,7 @@ def get_noise_station(self, station): noise_channel = noise_station.get_channel(noise_channel_id) channel = station.get_channel(channel_id) - if noise_channel.get_number_of_samples() != noise_channel.get_sampling_rate() and not self.__allow_noise_resampling: + if channel.get_sampling_rate() != noise_channel.get_sampling_rate() and not self.__allow_noise_resampling: self.logger.debug('Event {}, Channel {}: Different sampling rates, reject noise event.' .format(event_i, noise_channel_id)) return None From e4a65231cd1aa07541b492f1302897e6c1f1fe65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Mon, 3 Apr 2023 16:04:18 +0200 Subject: [PATCH 194/418] Store station time in event header also dict and not astropy (causes problems and is probably inefficient). --- NuRadioReco/framework/base_station.py | 30 +++++++++++++++--------- NuRadioReco/modules/io/NuRadioRecoio.py | 31 +++++++++++++++---------- NuRadioReco/modules/io/eventWriter.py | 6 +++-- 3 files changed, 42 insertions(+), 25 deletions(-) diff --git a/NuRadioReco/framework/base_station.py b/NuRadioReco/framework/base_station.py index fac7c4c0c..432ca746a 100644 --- a/NuRadioReco/framework/base_station.py +++ b/NuRadioReco/framework/base_station.py @@ -116,6 +116,13 @@ def get_station_time(self, format='isot'): """ self._station_time.format = format return self._station_time + + def get_station_time_dict(self): + """ Return the station time as dict {value, format}. Used for reading and writing """ + if self._station_time is None: + return None + else: + return {'value': self._station_time.value, 'format': self._station_time.format} def get_id(self): return self._station_id @@ -260,16 +267,13 @@ def serialize(self, save_efield_traces): trigger_pkls = [] for trigger in self._triggers.values(): trigger_pkls.append(trigger.serialize()) + efield_pkls = [] for efield in self.get_electric_fields(): efield_pkls.append(efield.serialize(save_trace=save_efield_traces)) - if self._station_time is None: - station_time_dict = None - else: - station_time_dict = { - 'value': self._station_time.value, - 'format': self._station_time.format - } + + station_time_dict = self.get_station_time_dict() + data = {'_parameters': NuRadioReco.framework.parameter_serialization.serialize(self._parameters), '_parameter_covariances': NuRadioReco.framework.parameter_serialization.serialize_covariances(self._parameter_covariances), '_ARIANNA_parameters': self._ARIANNA_parameters, @@ -279,15 +283,16 @@ def serialize(self, save_efield_traces): 'triggers': trigger_pkls, '_triggered': self._triggered, 'electric_fields': efield_pkls} + return pickle.dumps(data, protocol=4) def deserialize(self, data_pkl): data = pickle.loads(data_pkl) - if ('triggers' in data): + if 'triggers' in data: self._triggers = NuRadioReco.framework.trigger.deserialize(data['triggers']) - if ('triggers' in data): + if 'triggers' in data: self._triggered = data['_triggered'] for electric_field in data['electric_fields']: @@ -298,8 +303,10 @@ def deserialize(self, data_pkl): self._parameters = NuRadioReco.framework.parameter_serialization.deserialize(data['_parameters'], parameters.stationParameters) - self._parameter_covariances = NuRadioReco.framework.parameter_serialization.deserialize_covariances(data['_parameter_covariances'], parameters.stationParameters) - if ('_ARIANNA_parameters') in data: + self._parameter_covariances = NuRadioReco.framework.parameter_serialization.deserialize_covariances( + data['_parameter_covariances'], parameters.stationParameters) + + if '_ARIANNA_parameters' in data: self._ARIANNA_parameters = data['_ARIANNA_parameters'] self._station_id = data['_station_id'] @@ -310,4 +317,5 @@ def deserialize(self, data_pkl): # For backward compatibility, we also keep supporting station times stored as astropy.time objects else: self.set_station_time(data['_station_time']) + self._particle_type = data['_particle_type'] diff --git a/NuRadioReco/modules/io/NuRadioRecoio.py b/NuRadioReco/modules/io/NuRadioRecoio.py index f7da59216..8aa4c1728 100644 --- a/NuRadioReco/modules/io/NuRadioRecoio.py +++ b/NuRadioReco/modules/io/NuRadioRecoio.py @@ -164,28 +164,35 @@ def get_filenames(self): def _parse_event_header(self, evt_header): from NuRadioReco.framework.parameters import stationParameters as stnp self.__event_ids.append(evt_header['event_id']) + for station_id, station in evt_header['stations'].items(): + if station_id not in self.__event_headers: self.__event_headers[station_id] = {} + for key, value in station.items(): # treat sim_station differently - if(key == 'sim_station'): - pass - else: + if key != 'sim_station': + if key not in self.__event_headers[station_id]: self.__event_headers[station_id][key] = [] - if(key == stnp.station_time): + + if key == stnp.station_time: import astropy.time + station_time = None if value is not None: - if value.format == 'datetime': - time_strings = str(value).split(' ') - station_time = astropy.time.Time('{}T{}'.format(time_strings[0], time_strings[1]), format='isot') + if isinstance(value, dict): + station_time = astropy.time.Time(value["value"], format=value["format"]) + # For backward compatibility, we also keep supporting station times stored as astropy.time objects + elif isinstance(value, astropy.time.Time): + station_time = value else: - value.in_subfmt = 'date_hms' - value.out_subfmt = 'date_hms' - station_time=value - else: - station_time = None + err = f"Station time not stored as dict or astropy.time.Time: ({type(value)})" + self.logger.error(err) + raise ValueError(err) + + station_time.format = 'isot' + self.__event_headers[station_id][key].append(station_time) else: self.__event_headers[station_id][key].append(value) diff --git a/NuRadioReco/modules/io/eventWriter.py b/NuRadioReco/modules/io/eventWriter.py index 3bd450d0a..b7094a477 100644 --- a/NuRadioReco/modules/io/eventWriter.py +++ b/NuRadioReco/modules/io/eventWriter.py @@ -12,10 +12,12 @@ def get_header(evt): header = {'stations': {}} for iS, station in enumerate(evt.get_stations()): header['stations'][station.get_id()] = station.get_parameters().copy() - if(station.has_sim_station()): + header['stations'][station.get_id()][stnp.station_time] = station.get_station_time_dict() + + if station.has_sim_station(): header['stations'][station.get_id()]['sim_station'] = {} header['stations'][station.get_id()]['sim_station'] = station.get_sim_station().get_parameters() - header['stations'][station.get_id()][stnp.station_time] = station.get_station_time() + header['event_id'] = (evt.get_run_number(), evt.get_id()) return header From 75d4bfa0e95387ced8a14369a00d701736cb3c96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Mon, 3 Apr 2023 16:14:23 +0200 Subject: [PATCH 195/418] Also copy the sim station parameter --- NuRadioReco/modules/io/eventWriter.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NuRadioReco/modules/io/eventWriter.py b/NuRadioReco/modules/io/eventWriter.py index b7094a477..a924b646d 100644 --- a/NuRadioReco/modules/io/eventWriter.py +++ b/NuRadioReco/modules/io/eventWriter.py @@ -16,7 +16,7 @@ def get_header(evt): if station.has_sim_station(): header['stations'][station.get_id()]['sim_station'] = {} - header['stations'][station.get_id()]['sim_station'] = station.get_sim_station().get_parameters() + header['stations'][station.get_id()]['sim_station'] = station.get_sim_station().get_parameters().copy() header['event_id'] = (evt.get_run_number(), evt.get_id()) return header From a18e2599d51ec8d5a9dc36d951964cbff1608d69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Mon, 3 Apr 2023 17:05:19 +0200 Subject: [PATCH 196/418] Fix getter --- NuRadioReco/framework/base_station.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/NuRadioReco/framework/base_station.py b/NuRadioReco/framework/base_station.py index 432ca746a..d1d671e9b 100644 --- a/NuRadioReco/framework/base_station.py +++ b/NuRadioReco/framework/base_station.py @@ -114,6 +114,9 @@ def get_station_time(self, format='isot'): _station_time: astropy.time.Time """ + if self._station_time is None: + return None + self._station_time.format = format return self._station_time From 2b5b9ee9fa2a8b4f96655021053b591d12809d6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Tue, 7 Mar 2023 14:46:29 +0100 Subject: [PATCH 197/418] Add RNO-G data reader (based on mattak) and, based on this reader, a noiseImporter module for RNO-G --- .../modules/io/rno_g/readRNOGDataMattak.py | 205 ++++++++++++++++++ .../measured_noise/noiseImporterRNOG.py | 142 ++++++++++++ 2 files changed, 347 insertions(+) create mode 100644 NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py create mode 100644 NuRadioReco/modules/measured_noise/noiseImporterRNOG.py diff --git a/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py b/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py new file mode 100644 index 000000000..7dfc60644 --- /dev/null +++ b/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py @@ -0,0 +1,205 @@ +import numpy as np + +import logging +import os +import time +import datetime + +from NuRadioReco.modules.base.module import register_run + +import NuRadioReco.framework.event +import NuRadioReco.framework.station +import NuRadioReco.framework.channel +import NuRadioReco.framework.trigger + +from NuRadioReco.utilities import units + +import mattak.Dataset + + +def baseline_correction_128(wfs): + + # Get baseline in chunks of 128 bins + # np.split -> (16, n_events, n_channels, 128) + # np.mean -> (16, n_events, n_channels) + means = np.mean(np.split(wfs, 2048 // 128, axis=-1), axis=-1) + + # Get baseline traces + # np.repeat -> (2048, n_events, n_channels) + baseline_traces = np.repeat(means, 128 % 2048, axis=0) + + # np.moveaxis -> (n_events, n_channels, 2048) + baseline_traces = np.moveaxis(baseline_traces, 0, -1) + + return wfs - baseline_traces + + +class readRNOGData: + + def begin(self, + data_dirs, log_level=logging.INFO, selectors=None, + read_calibrated_data=False, + apply_baseline_correction=True, + convert_to_voltage=True, + select_triggers=None): + + """ + + Parameters + ---------- + + data_dirs: list of strings / string + Path to run directories (i.e. ".../stationXX/runXXX/") + + log_level: enum + Set verbosity level of logger + + selectors: list of lambdas + List of lambda(eventInfo) -> bool to pass to mattak.Dataset.iterate to select events. + Example: + + trigger_selector = lambda eventInfo: eventInfo.triggerType == "FORCE" + + read_calibrated_data: bool + If True, read calibrated waveforms from Mattak.Dataset. If False, read "raw" ADC traces. + (temp. Default: False) + + apply_baseline_correction: bool + Only applies when non-calibrated data are read. If true, correct for DC offset. + (Default: True) + + convert_to_voltage: bool + Only applies when non-calibrated data are read. If true, convert ADC to voltage. + (Default: True) + """ + + t0 = time.time() + + self.logger = logging.getLogger('NuRadioReco.readRNOGData') + self.logger.setLevel(log_level) + + self._read_calibrated_data = read_calibrated_data + self._apply_baseline_correction = apply_baseline_correction + self._convert_to_voltage = convert_to_voltage + + # Temporary solution hard-coded values from Cosmin. Only used when uncalibrated data + # is read and convert_to_voltage is True. + self._adc_ref_voltage_range = 2.5 * units.volt + self._adc_n_bits = 12 + + if not isinstance(data_dirs, (list, np.ndarray)): + data_dirs = [data_dirs] + + if selectors is not None: + if not isinstance(selectors, (list, np.ndarray)): + selectors = [selectors] + + if select_triggers is not None: + if isinstance(select_triggers, str): + selectors.append(lambda eventInfo: eventInfo.triggerType == select_triggers) + else: + for select_trigger in select_triggers: + selectors.append(lambda eventInfo: eventInfo.triggerType == select_trigger) + + self._selectors = selectors + self.logger.info(f"Found {len(self._selectors)} selectors") + + self._time_begin = 0 + self._time_run = 0 + self.__counter = 0 + self.__skipped = 0 + + self._datasets = [] + self.__n_events_per_dataset = [] + + self.logger.info(f"Parse through {len(data_dirs)} directories.") + + for data_dir in data_dirs: + + if not os.path.exists(data_dir): + self.logger.error(f"The directory {data_dir} does not exist") + + dataset = mattak.Dataset.Dataset(station=0, run=0, data_dir=data_dir) + self._datasets.append(dataset) + self.__n_events_per_dataset.append(dataset.N()) + + # keeps track which event index is in which dataset + self._event_idxs_datasets = np.cumsum(self.__n_events_per_dataset) + self._n_events_total = np.sum(self.__n_events_per_dataset) + + self._time_begin = time.time() - t0 + + + def get_n_events_of_prev_datasets(self, dataset_idx): + dataset_idx_prev = dataset_idx - 1 + return int(self._event_idxs_datasets[dataset_idx_prev]) if dataset_idx_prev >= 0 else 0 + + + @register_run() + def run(self): + + for event_idx in range(self._n_events_total): + self.logger.debug(f"Processing event number {event_idx} out of total {self._n_events_total}") + t0 = time.time() + + # find correct dataset + dataset_idx = np.digitize(event_idx, self._event_idxs_datasets) + dataset = self._datasets[dataset_idx] + + event_idx_in_dataset = event_idx - self.get_n_events_of_prev_datasets(dataset_idx) + dataset.setEntries(event_idx_in_dataset) # increment iterator -> point to new event + + event_info = dataset.eventInfo() + + skip = False + if self._selectors is not None: + for selector in self._selectors: + if not selector(event_info): + skip = True + + if skip: + self.__skipped += 1 + continue + + evt = NuRadioReco.framework.event.Event(event_info.run, event_info.eventNumber) + station = NuRadioReco.framework.station.Station(event_info.station) + station.set_station_time(datetime.datetime.fromtimestamp(event_info.readoutTime)) + + trigger = NuRadioReco.framework.trigger.Trigger(event_info.triggerType) + trigger.set_triggered() + trigger.set_trigger_time(event_info.triggerTime) + station.set_trigger(trigger) + + waveforms = dataset.wfs() + + for channel_id, wf in enumerate(waveforms): + channel = NuRadioReco.framework.channel.Channel(channel_id) + if self._read_calibrated_data: + channel.set_trace(wf * units.mV, event_info.sampleRate * units.GHz) + else: + # wf stores ADC counts + + if self._apply_baseline_correction: + # correct baseline + wf = baseline_correction_128(wf) + + if self._convert_to_voltage: + # convert adc to voltage + wf *= (self._adc_ref_voltage_range / (2 ** (self._adc_n_bits) - 1)) + + channel.set_trace(wf, event_info.sampleRate * units.GHz) + + station.add_channel(channel) + + evt.set_station(station) + + self._time_run += time.time() - t0 + self.__counter += 1 + yield evt + + + def end(self): + self.logger.info(f"Read {self.__counter} events (skipped {self.__skipped} events)" + f"\n\tTime to initialize data sets : {self._time_begin:.2f}" + f"\n\tTime to initialize all events : {self._time_run:.2f}" + f"\n\tTime to per event : {self._time_run / self.__counter:.2f}") \ No newline at end of file diff --git a/NuRadioReco/modules/measured_noise/noiseImporterRNOG.py b/NuRadioReco/modules/measured_noise/noiseImporterRNOG.py new file mode 100644 index 000000000..ff55705e2 --- /dev/null +++ b/NuRadioReco/modules/measured_noise/noiseImporterRNOG.py @@ -0,0 +1,142 @@ +import numpy as np +import glob +import os +import sys + +from NuRadioReco.modules.io.rno_g.readRNOGDataMattak import readRNOGData +from NuRadioReco.modules.base.module import register_run +from NuRadioReco.utilities import units + +from NuRadioReco.modules import channelResampler + +import logging + + +class noiseImporterRNOG: + """ + Imports recorded traces from RNOG stations. + + """ + + + def begin(self, noise_folder, station_ids=None, + channel_mapping=None, log_level=logging.INFO, + convert_noise_to_voltage=True, + match_station_ids=False): + """ + + Parameters + ---------- + noise_folder: string + the folder containing the noise file or subfolders containing noise files + + station_ids: list(int) + the station ids from which to add noise () + + channel_mapping: dict or None + option relevant for MC studies of new station designs where we do not + have forced triggers for. The channel_mapping dictionary maps the channel + ids of the MC station to the channel ids of the noise data + Default is None which is 1-to-1 mapping + + log_level: loggging log level + the log level, default logging.INFO + + """ + + self.__channel_mapping = channel_mapping + self.__station_ids = station_ids + self._convert_noise_to_voltage = convert_noise_to_voltage + self._match_station_ids = match_station_ids + + self._channel_respampler = channelResampler.channelResampler() + + self.logger = logging.getLogger('noiseImporter') + + self.logger.setLevel(log_level) + self.__channel_mapping = channel_mapping + + noise_files = glob.glob(f"{noise_folder}/**/*root", recursive=True) + self.__noise_folders = np.unique([os.path.dirname(e) for e in noise_files]) + + self.logger.info(f"Found {len(self.__noise_folders)} folders in {noise_folder}") + if not len(self.__noise_folders): + raise ValueError + + noise_reader = readRNOGData() + selectors = [lambda einfo: einfo.triggerType == "FORCE"] + noise_reader.begin(self.__noise_folders, selectors=selectors) + self._noise_events = [evt for evt in noise_reader.run()] + noise_reader.end() + + + def _buffer_station_id_list(self): + if self.__station_id_list is None: + self.__station_id_list = np.squeeze([evt.get_station_ids() for evt in self._noise_events]) + + return self.__station_id_list + + + def __get_noise_channel(self, channel_id): + if self.__channel_mapping is None: + return channel_id + else: + return self.__channel_mapping[channel_id] + + + @register_run() + def run(self, evt, station, det): + + if self._match_station_ids: + + station_ids = self._buffer_station_id_list() + mask = station_ids == station.get_id() + if not np.any(mask): + raise ValueError(f"No station with id {station.get_id()} in noise data.") + + i_noise = np.random.choice(np.arange(len(mask))[mask]) + + else: + i_noise = np.random.randint(0, len(self._noise_events)) + + noise_event = self._noise_events[i_noise] + + station_id = noise_event.get_station_ids()[0] + noise_station = noise_event.get_station(station_id) + + if self.__station_ids is not None and not station_id in self.__station_ids: + raise KeyError() + + self.logger.debug("Selected noise event {} ({}, run {}, event {})".format( + i_noise, noise_station.get_station_time(), noise_event.get_run_number(), + noise_event.get_id())) + + for channel in station.iter_channels(): + channel_id = channel.get_id() + + trace = channel.get_trace() + noise_channel = noise_station.get_channel(self.__get_noise_channel(channel_id)) + noise_trace = noise_channel.get_trace() + + if len(trace) > 2048: + self.logger.warn("Simulated trace is longer than 2048 bins... trim with :2048") + trace = trace[:2048] + + # sanity checks + if len(trace) != len(noise_trace): + erg_msg = f"Mismatch in trace lenght: Noise has {len(noise_trace)} " + \ + "and simulation has {len(trace)} samples" + self.logger.error(erg_msg) + raise ValueError(erg_msg) + + if channel.get_sampling_rate() != noise_channel.get_sampling_rate(): + erg_msg = "Mismatch in sampling rate: Noise has {} and simulation has {} GHz".format( + noise_channel.get_sampling_rate() / units.GHz, channel.get_sampling_rate() / units.GHz) + self.logger.error(erg_msg) + raise ValueError(erg_msg) + + trace = trace + noise_trace + channel.set_trace(trace, channel.get_sampling_rate()) + + def end(self): + pass From 38a5eec5ebc0224d53f707d4064afd25d4794613 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Mon, 27 Mar 2023 12:11:43 +0200 Subject: [PATCH 198/418] Add substructur for RNO-G noise importer --- NuRadioReco/modules/measured_noise/RNO-G/__init__.py | 0 .../{noiseImporterRNOG.py => RNO-G/noiseImporter.py} | 0 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 NuRadioReco/modules/measured_noise/RNO-G/__init__.py rename NuRadioReco/modules/measured_noise/{noiseImporterRNOG.py => RNO-G/noiseImporter.py} (100%) diff --git a/NuRadioReco/modules/measured_noise/RNO-G/__init__.py b/NuRadioReco/modules/measured_noise/RNO-G/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/NuRadioReco/modules/measured_noise/noiseImporterRNOG.py b/NuRadioReco/modules/measured_noise/RNO-G/noiseImporter.py similarity index 100% rename from NuRadioReco/modules/measured_noise/noiseImporterRNOG.py rename to NuRadioReco/modules/measured_noise/RNO-G/noiseImporter.py From 1451221ae3e05e336d8a8967a5590a89ba9bb375 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Tue, 28 Mar 2023 12:09:16 +0200 Subject: [PATCH 199/418] Add interface to RunTable to select runs --- .../modules/io/rno_g/readRNOGDataMattak.py | 95 +++++++++++++++---- 1 file changed, 79 insertions(+), 16 deletions(-) diff --git a/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py b/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py index 7dfc60644..0a6aade6a 100644 --- a/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py +++ b/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py @@ -14,24 +14,42 @@ from NuRadioReco.utilities import units +try: + from rnog_data.runtable import RunTable + import pandas + imported_runtable = True +except ImportError: + print("Import of run table failed. You will not be able to select runs! \n" + "You can get the interface from GitHub: git@github.com:RNO-G/rnog-data-analysis-and-issues.git") + imported_runtable = False + + + import mattak.Dataset -def baseline_correction_128(wfs): +def baseline_correction(wfs, n_bins=128): - # Get baseline in chunks of 128 bins - # np.split -> (16, n_events, n_channels, 128) - # np.mean -> (16, n_events, n_channels) - means = np.mean(np.split(wfs, 2048 // 128, axis=-1), axis=-1) + # Get baseline in chunks of 128 bins + # np.split -> (16, n_events, n_channels, 128) + # np.mean -> (16, n_events, n_channels) + if n_bins is not None: + medians = np.media(np.split(wfs, 2048 // n_bins, axis=-1), axis=-1) - # Get baseline traces - # np.repeat -> (2048, n_events, n_channels) - baseline_traces = np.repeat(means, 128 % 2048, axis=0) + # Get baseline traces + # np.repeat -> (2048, n_events, n_channels) + baseline_traces = np.repeat(medians, n_bins % 2048, axis=0) + else: + medians = np.media(wfs, axis=-1) - # np.moveaxis -> (n_events, n_channels, 2048) - baseline_traces = np.moveaxis(baseline_traces, 0, -1) + # Get baseline traces + # np.repeat -> (2048, n_events, n_channels) + baseline_traces = np.repeat(medians, 2048, axis=0) + + # np.moveaxis -> (n_events, n_channels, 2048) + baseline_traces = np.moveaxis(baseline_traces, 0, -1) - return wfs - baseline_traces + return wfs - baseline_traces class readRNOGData: @@ -41,7 +59,9 @@ def begin(self, read_calibrated_data=False, apply_baseline_correction=True, convert_to_voltage=True, - select_triggers=None): + select_triggers=None, + run_types=["physics"], + max_trigger_rate=1 * units.Hz): """ @@ -70,7 +90,14 @@ def begin(self, convert_to_voltage: bool Only applies when non-calibrated data are read. If true, convert ADC to voltage. - (Default: True) + (Default: True) + + run_types: list + Used to select/reject runs from information in the RNO-G RunTable. List of run_types to be used. (Default: ['physics']) + + max_trigger_rate: float + Used to select/reject runs from information in the RNO-G RunTable. Maximum allowed trigger rate (per run) in Hz. + If 0, no cut is applied. (Default: 1 Hz) """ t0 = time.time() @@ -86,6 +113,13 @@ def begin(self, # is read and convert_to_voltage is True. self._adc_ref_voltage_range = 2.5 * units.volt self._adc_n_bits = 12 + + self.__max_trigger_rate = max_trigger_rate + self.__run_types = run_types + + if imported_runtable: + self.logger.debug("Access RunTable database ...") + self.__run_table = RunTable().get_table() if not isinstance(data_dirs, (list, np.ndarray)): data_dirs = [data_dirs] @@ -120,6 +154,11 @@ def begin(self, self.logger.error(f"The directory {data_dir} does not exist") dataset = mattak.Dataset.Dataset(station=0, run=0, data_dir=data_dir) + + # filter runs/datasets based on + if not self.__select_run(dataset): + continue + self._datasets.append(dataset) self.__n_events_per_dataset.append(dataset.N()) @@ -128,9 +167,33 @@ def begin(self, self._n_events_total = np.sum(self.__n_events_per_dataset) self._time_begin = time.time() - t0 + + + def __select_run(self, dataset): + """ Filter/select runs/datasets. Return True to select an dataset, return False to skip it """ + if not imported_runtable: + return True + + # get first eventInfo + dataset.setEntries(0) + event_info = dataset.eventInfo() + + run_id = event_info.run + station_id = event_info.station + + run_info = self.__run_table.query(f"station == {station_id:d} & run == {run_id:d}") + + if not run_info["run_type"].values[0] in self.__run_types: + return False + + if self.__max_trigger_rate and run_info["trigger_rate"].values[0] * units.Hz > self.__max_trigger_rate: + return False + + return True - def get_n_events_of_prev_datasets(self, dataset_idx): + def __get_n_events_of_prev_datasets(self, dataset_idx): + """ Get number of events from previous dataset to correctly set pointer """ dataset_idx_prev = dataset_idx - 1 return int(self._event_idxs_datasets[dataset_idx_prev]) if dataset_idx_prev >= 0 else 0 @@ -146,7 +209,7 @@ def run(self): dataset_idx = np.digitize(event_idx, self._event_idxs_datasets) dataset = self._datasets[dataset_idx] - event_idx_in_dataset = event_idx - self.get_n_events_of_prev_datasets(dataset_idx) + event_idx_in_dataset = event_idx - self.__get_n_events_of_prev_datasets(dataset_idx) dataset.setEntries(event_idx_in_dataset) # increment iterator -> point to new event event_info = dataset.eventInfo() @@ -181,7 +244,7 @@ def run(self): if self._apply_baseline_correction: # correct baseline - wf = baseline_correction_128(wf) + wf = baseline_correction(wf) if self._convert_to_voltage: # convert adc to voltage From 88f97f98b13dae4ede79f1e5adfa00dff194d08c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Tue, 28 Mar 2023 12:10:36 +0200 Subject: [PATCH 200/418] Add counter for skipped runs --- NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py b/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py index 0a6aade6a..65a03b81c 100644 --- a/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py +++ b/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py @@ -148,6 +148,8 @@ def begin(self, self.logger.info(f"Parse through {len(data_dirs)} directories.") + self.__skipped_runs = 0 + for data_dir in data_dirs: if not os.path.exists(data_dir): @@ -157,6 +159,7 @@ def begin(self, # filter runs/datasets based on if not self.__select_run(dataset): + self.__skipped_runs += 1 continue self._datasets.append(dataset) @@ -265,4 +268,5 @@ def end(self): self.logger.info(f"Read {self.__counter} events (skipped {self.__skipped} events)" f"\n\tTime to initialize data sets : {self._time_begin:.2f}" f"\n\tTime to initialize all events : {self._time_run:.2f}" - f"\n\tTime to per event : {self._time_run / self.__counter:.2f}") \ No newline at end of file + f"\n\tTime to per event : {self._time_run / self.__counter:.2f}" + f"\n\tSkipped {self.__skipped_runs} runs.") \ No newline at end of file From 1ba190860578ee76a0035084196adfa9425ee94d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Tue, 28 Mar 2023 12:32:55 +0200 Subject: [PATCH 201/418] Small fix, more infos --- .../modules/io/rno_g/readRNOGDataMattak.py | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py b/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py index 65a03b81c..682b1ae19 100644 --- a/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py +++ b/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py @@ -34,13 +34,13 @@ def baseline_correction(wfs, n_bins=128): # np.split -> (16, n_events, n_channels, 128) # np.mean -> (16, n_events, n_channels) if n_bins is not None: - medians = np.media(np.split(wfs, 2048 // n_bins, axis=-1), axis=-1) + medians = np.median(np.split(wfs, 2048 // n_bins, axis=-1), axis=-1) # Get baseline traces # np.repeat -> (2048, n_events, n_channels) baseline_traces = np.repeat(medians, n_bins % 2048, axis=0) else: - medians = np.media(wfs, axis=-1) + medians = np.median(wfs, axis=-1) # Get baseline traces # np.repeat -> (2048, n_events, n_channels) @@ -149,6 +149,7 @@ def begin(self, self.logger.info(f"Parse through {len(data_dirs)} directories.") self.__skipped_runs = 0 + self.__n_runs = 0 for data_dir in data_dirs: @@ -162,6 +163,7 @@ def begin(self, self.__skipped_runs += 1 continue + self.__n_runs += 1 self._datasets.append(dataset) self.__n_events_per_dataset.append(dataset.N()) @@ -265,8 +267,9 @@ def run(self): def end(self): - self.logger.info(f"Read {self.__counter} events (skipped {self.__skipped} events)" - f"\n\tTime to initialize data sets : {self._time_begin:.2f}" - f"\n\tTime to initialize all events : {self._time_run:.2f}" - f"\n\tTime to per event : {self._time_run / self.__counter:.2f}" - f"\n\tSkipped {self.__skipped_runs} runs.") \ No newline at end of file + self.logger.info( + f"\n\tRead {self.__counter} events (skipped {self.__skipped} events)" + f"\n\tTime to initialize data sets : {self._time_begin:.2f}s" + f"\n\tTime to initialize all events : {self._time_run:.2f}s" + f"\n\tTime to per event : {self._time_run / self.__counter:.2f}s" + f"\n\tRead {self.__n_runs} runs, skipped {self.__skipped_runs} runs.") \ No newline at end of file From 0f2b4297ac80d1517341c4285eaf89f7c43e1294 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Tue, 28 Mar 2023 12:33:24 +0200 Subject: [PATCH 202/418] Renamed RNO-G noise directory --- NuRadioReco/modules/measured_noise/{RNO-G => RNO_G}/__init__.py | 0 .../modules/measured_noise/{RNO-G => RNO_G}/noiseImporter.py | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename NuRadioReco/modules/measured_noise/{RNO-G => RNO_G}/__init__.py (100%) rename NuRadioReco/modules/measured_noise/{RNO-G => RNO_G}/noiseImporter.py (99%) diff --git a/NuRadioReco/modules/measured_noise/RNO-G/__init__.py b/NuRadioReco/modules/measured_noise/RNO_G/__init__.py similarity index 100% rename from NuRadioReco/modules/measured_noise/RNO-G/__init__.py rename to NuRadioReco/modules/measured_noise/RNO_G/__init__.py diff --git a/NuRadioReco/modules/measured_noise/RNO-G/noiseImporter.py b/NuRadioReco/modules/measured_noise/RNO_G/noiseImporter.py similarity index 99% rename from NuRadioReco/modules/measured_noise/RNO-G/noiseImporter.py rename to NuRadioReco/modules/measured_noise/RNO_G/noiseImporter.py index ff55705e2..ff8589d76 100644 --- a/NuRadioReco/modules/measured_noise/RNO-G/noiseImporter.py +++ b/NuRadioReco/modules/measured_noise/RNO_G/noiseImporter.py @@ -12,7 +12,7 @@ import logging -class noiseImporterRNOG: +class noiseImporter: """ Imports recorded traces from RNOG stations. From ef19896577216253d8a09e203207d536c9e788cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Thu, 30 Mar 2023 11:52:59 +0200 Subject: [PATCH 203/418] Add more logger.info --- NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py b/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py index 682b1ae19..536ebf8d4 100644 --- a/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py +++ b/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py @@ -13,6 +13,7 @@ import NuRadioReco.framework.trigger from NuRadioReco.utilities import units +import mattak.Dataset try: from rnog_data.runtable import RunTable @@ -24,10 +25,6 @@ imported_runtable = False - -import mattak.Dataset - - def baseline_correction(wfs, n_bins=128): # Get baseline in chunks of 128 bins @@ -114,6 +111,9 @@ def begin(self, self._adc_ref_voltage_range = 2.5 * units.volt self._adc_n_bits = 12 + self.logger.info("\n\tSelect runs with type: {}".format(", ".join(run_types)) + + f"\n\tSelect runs with max. trigger rate of {max_trigger_rate / units.Hz} Hz") + self.__max_trigger_rate = max_trigger_rate self.__run_types = run_types From dd0893ad215885c022e74cc60d62b5f4b436a4d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Thu, 30 Mar 2023 12:14:21 +0200 Subject: [PATCH 204/418] Some cleanup, adding more logger info --- .../measured_noise/RNO_G/noiseImporter.py | 50 +++++++++++-------- 1 file changed, 29 insertions(+), 21 deletions(-) diff --git a/NuRadioReco/modules/measured_noise/RNO_G/noiseImporter.py b/NuRadioReco/modules/measured_noise/RNO_G/noiseImporter.py index ff8589d76..0e48c69d3 100644 --- a/NuRadioReco/modules/measured_noise/RNO_G/noiseImporter.py +++ b/NuRadioReco/modules/measured_noise/RNO_G/noiseImporter.py @@ -1,14 +1,12 @@ import numpy as np import glob import os -import sys +import random from NuRadioReco.modules.io.rno_g.readRNOGDataMattak import readRNOGData from NuRadioReco.modules.base.module import register_run from NuRadioReco.utilities import units -from NuRadioReco.modules import channelResampler - import logging @@ -19,49 +17,59 @@ class noiseImporter: """ - def begin(self, noise_folder, station_ids=None, - channel_mapping=None, log_level=logging.INFO, - convert_noise_to_voltage=True, - match_station_ids=False): + def begin(self, noise_folder, + match_station_id=False, station_ids=None, + channel_mapping=None, scramble_noise_file_order=True, + log_level=logging.INFO): """ Parameters ---------- noise_folder: string - the folder containing the noise file or subfolders containing noise files + Folder containing noise file(s). Search in any subfolder as well. + + match_station_id: bool + If True, add only noise from stations with the same id. (Default: False) station_ids: list(int) - the station ids from which to add noise () + Only add noise from those station ids. If None, use any station. (Default: None) channel_mapping: dict or None option relevant for MC studies of new station designs where we do not have forced triggers for. The channel_mapping dictionary maps the channel ids of the MC station to the channel ids of the noise data Default is None which is 1-to-1 mapping + + scramble_noise_file_order: bool + If True, randomize the order of noise files before reading them. (Default: True) log_level: loggging log level the log level, default logging.INFO """ - self.__channel_mapping = channel_mapping - self.__station_ids = station_ids - self._convert_noise_to_voltage = convert_noise_to_voltage - self._match_station_ids = match_station_ids - - self._channel_respampler = channelResampler.channelResampler() - self.logger = logging.getLogger('noiseImporter') - self.logger.setLevel(log_level) + + self._match_station_id = match_station_id + self.__station_ids = station_ids + self.__channel_mapping = channel_mapping + self.logger.info(f"\n\tMatch station id: {match_station_id}" + f"\n\tUse noise from only those stations: {station_ids}" + f"\n\tUse the following channel mapping: {channel_mapping}" + f"\n\tRandomize sequence of noise files: {scramble_noise_file_order}") + noise_files = glob.glob(f"{noise_folder}/**/*root", recursive=True) - self.__noise_folders = np.unique([os.path.dirname(e) for e in noise_files]) + self.__noise_folders = np.unique([os.path.dirname(e) for e in noise_files]) self.logger.info(f"Found {len(self.__noise_folders)} folders in {noise_folder}") if not len(self.__noise_folders): raise ValueError + + if scramble_noise_file_order: + random.shuffle(self.__noise_folders) noise_reader = readRNOGData() selectors = [lambda einfo: einfo.triggerType == "FORCE"] @@ -87,7 +95,7 @@ def __get_noise_channel(self, channel_id): @register_run() def run(self, evt, station, det): - if self._match_station_ids: + if self._match_station_id: station_ids = self._buffer_station_id_list() mask = station_ids == station.get_id() @@ -105,7 +113,7 @@ def run(self, evt, station, det): noise_station = noise_event.get_station(station_id) if self.__station_ids is not None and not station_id in self.__station_ids: - raise KeyError() + raise ValueError(f"Station id {station_id} not in list of allowed ids: {self.__station_ids}") self.logger.debug("Selected noise event {} ({}, run {}, event {})".format( i_noise, noise_station.get_station_time(), noise_event.get_run_number(), @@ -117,7 +125,7 @@ def run(self, evt, station, det): trace = channel.get_trace() noise_channel = noise_station.get_channel(self.__get_noise_channel(channel_id)) noise_trace = noise_channel.get_trace() - + if len(trace) > 2048: self.logger.warn("Simulated trace is longer than 2048 bins... trim with :2048") trace = trace[:2048] From d9ada9a523083787e6cbd588305156ace936c35e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Thu, 30 Mar 2023 16:29:36 +0200 Subject: [PATCH 205/418] Make run selection optional, add time_offset between trigger/event time and trace_start_time --- .../modules/io/rno_g/readRNOGDataMattak.py | 47 ++++++++++++++++++- 1 file changed, 45 insertions(+), 2 deletions(-) diff --git a/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py b/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py index 536ebf8d4..f14b68162 100644 --- a/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py +++ b/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py @@ -49,6 +49,42 @@ def baseline_correction(wfs, n_bins=128): return wfs - baseline_traces +def get_time_offset(trigger_type): + """ + Mapping the offset between trace start time and trigger time (~ signal time). + Temporary use hard-coded values for each trigger type. In the future this + information might be time, station, and channel dependent and should come + from a database (or is already calibrated in mattak) + + Parameters + ---------- + + trigger_type: str + Trigger type encoded as string from Mattak + + Returns + ------- + + time_offset: float + trace_start_time = trigger_time - time_offset + + """ + + time_offsets = { + "FORCE": 0, + "LT": 213 * units.ns, # ~ 1 / 3 of trace @ 2048 sample with 3.2 GSa/s + "RADIANT": 320 * units.ns # ~ 1 / 2 of trace @ 2048 sample with 3.2 GSa/s + } + + if trigger_type.startswith("RADIANT"): + trigger_type = "RADIANT" + + if trigger_type in time_offsets: + return time_offsets[trigger_type] + else: + raise KeyError(f"Unknown trigger type: {trigger_type}. Known are: FORCE, LT, RADIANT. Abort ....") + + class readRNOGData: def begin(self, @@ -57,6 +93,7 @@ def begin(self, apply_baseline_correction=True, convert_to_voltage=True, select_triggers=None, + select_runs=True, run_types=["physics"], max_trigger_rate=1 * units.Hz): @@ -89,6 +126,9 @@ def begin(self, Only applies when non-calibrated data are read. If true, convert ADC to voltage. (Default: True) + select_runs: bool + Select runs + run_types: list Used to select/reject runs from information in the RNO-G RunTable. List of run_types to be used. (Default: ['physics']) @@ -159,7 +199,7 @@ def begin(self, dataset = mattak.Dataset.Dataset(station=0, run=0, data_dir=data_dir) # filter runs/datasets based on - if not self.__select_run(dataset): + if select_runs and not self.__select_run(dataset): self.__skipped_runs += 1 continue @@ -231,11 +271,11 @@ def run(self): evt = NuRadioReco.framework.event.Event(event_info.run, event_info.eventNumber) station = NuRadioReco.framework.station.Station(event_info.station) - station.set_station_time(datetime.datetime.fromtimestamp(event_info.readoutTime)) trigger = NuRadioReco.framework.trigger.Trigger(event_info.triggerType) trigger.set_triggered() trigger.set_trigger_time(event_info.triggerTime) + station.set_station_time(datetime.datetime.fromtimestamp(event_info.triggerTime)) station.set_trigger(trigger) waveforms = dataset.wfs() @@ -256,6 +296,9 @@ def run(self): wf *= (self._adc_ref_voltage_range / (2 ** (self._adc_n_bits) - 1)) channel.set_trace(wf, event_info.sampleRate * units.GHz) + + time_offset = get_time_offset(event_info.triggerType) + channel.set_trace_start_time(-time_offset) # relative to event/trigger time station.add_channel(channel) From b1b435fd212e10bb1c85392b3a5c149d509d151c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Thu, 30 Mar 2023 18:26:58 +0200 Subject: [PATCH 206/418] Use astropy.time instead of datetime to convert and set the station time --- NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py b/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py index f14b68162..446eef930 100644 --- a/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py +++ b/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py @@ -3,7 +3,7 @@ import logging import os import time -import datetime +import astropy.time from NuRadioReco.modules.base.module import register_run @@ -271,11 +271,11 @@ def run(self): evt = NuRadioReco.framework.event.Event(event_info.run, event_info.eventNumber) station = NuRadioReco.framework.station.Station(event_info.station) + station.set_station_time(astropy.time.Time(event_info.triggerTime, format='unix')) trigger = NuRadioReco.framework.trigger.Trigger(event_info.triggerType) trigger.set_triggered() trigger.set_trigger_time(event_info.triggerTime) - station.set_station_time(datetime.datetime.fromtimestamp(event_info.triggerTime)) station.set_trigger(trigger) waveforms = dataset.wfs() From b1e10f75ecaf6427083294610262a8a910f147a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Fri, 31 Mar 2023 13:05:27 +0200 Subject: [PATCH 207/418] Add logger info and sanity check --- .../modules/io/rno_g/readRNOGDataMattak.py | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py b/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py index 446eef930..44875f0bc 100644 --- a/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py +++ b/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py @@ -151,8 +151,9 @@ def begin(self, self._adc_ref_voltage_range = 2.5 * units.volt self._adc_n_bits = 12 - self.logger.info("\n\tSelect runs with type: {}".format(", ".join(run_types)) + - f"\n\tSelect runs with max. trigger rate of {max_trigger_rate / units.Hz} Hz") + if select_runs: + self.logger.info("\n\tSelect runs with type: {}".format(", ".join(run_types)) + + f"\n\tSelect runs with max. trigger rate of {max_trigger_rate / units.Hz} Hz") self.__max_trigger_rate = max_trigger_rate self.__run_types = run_types @@ -210,9 +211,13 @@ def begin(self, # keeps track which event index is in which dataset self._event_idxs_datasets = np.cumsum(self.__n_events_per_dataset) self._n_events_total = np.sum(self.__n_events_per_dataset) - self._time_begin = time.time() - t0 + if not self._n_events_total: + err = "No runs have been selected. Abort ..." + self.logger.error(err) + raise ValueError(err) + def __select_run(self, dataset): """ Filter/select runs/datasets. Return True to select an dataset, return False to skip it """ @@ -227,11 +232,15 @@ def __select_run(self, dataset): station_id = event_info.station run_info = self.__run_table.query(f"station == {station_id:d} & run == {run_id:d}") + run_type = run_info["run_type"].values[0] - if not run_info["run_type"].values[0] in self.__run_types: + if not run_type in self.__run_types: + self.logger.info(f"Reject station {station_id} run {run_id} because of run type {run_type}") return False - if self.__max_trigger_rate and run_info["trigger_rate"].values[0] * units.Hz > self.__max_trigger_rate: + trigger_rate = run_info["trigger_rate"].values[0] * units.Hz + if self.__max_trigger_rate and trigger_rate > self.__max_trigger_rate: + self.logger.info(f"Reject station {station_id} run {run_id} because trigger rate is to high ({trigger_rate / units.Hz} Hz)") return False return True From 6f6134c92f82850f8337b9b5880f6156cddfcaa0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Fri, 31 Mar 2023 13:05:45 +0200 Subject: [PATCH 208/418] small fix --- NuRadioReco/modules/measured_noise/RNO_G/noiseImporter.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/NuRadioReco/modules/measured_noise/RNO_G/noiseImporter.py b/NuRadioReco/modules/measured_noise/RNO_G/noiseImporter.py index 0e48c69d3..2a9e6ed1a 100644 --- a/NuRadioReco/modules/measured_noise/RNO_G/noiseImporter.py +++ b/NuRadioReco/modules/measured_noise/RNO_G/noiseImporter.py @@ -73,10 +73,12 @@ def begin(self, noise_folder, noise_reader = readRNOGData() selectors = [lambda einfo: einfo.triggerType == "FORCE"] - noise_reader.begin(self.__noise_folders, selectors=selectors) + noise_reader.begin(self.__noise_folders, selectors=selectors, log_level=log_level) self._noise_events = [evt for evt in noise_reader.run()] noise_reader.end() + self.__station_id_list = None + def _buffer_station_id_list(self): if self.__station_id_list is None: From 28f4ae7746cc27ee718ef8ec3dac247e71f8d828 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Mon, 3 Apr 2023 14:39:11 +0200 Subject: [PATCH 209/418] Add example script to read rno-g data with the new Mattak based reader. --- .../RNO_data/read_data_example/read_rnog.py | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 NuRadioReco/examples/RNO_data/read_data_example/read_rnog.py diff --git a/NuRadioReco/examples/RNO_data/read_data_example/read_rnog.py b/NuRadioReco/examples/RNO_data/read_data_example/read_rnog.py new file mode 100644 index 000000000..a88ac77b9 --- /dev/null +++ b/NuRadioReco/examples/RNO_data/read_data_example/read_rnog.py @@ -0,0 +1,65 @@ +from NuRadioReco.modules.io.rno_g import readRNOGDataMattak +from NuRadioReco.modules.io import eventWriter +from NuRadioReco.utilities import units + +import sys +import logging + +""" read in data """ +list_of_root_files = sys.argv[1:-1] +output_filename = sys.argv[-1] + +rnog_reader = readRNOGDataMattak.readRNOGData() +writer = eventWriter.eventWriter() + +""" +With a selector you can select or reject events based on information in the +Mattak class EventInfo. See https://github.com/RNO-G/mattak/blob/main/py/mattak/Dataset.py + +class EventInfo: + eventNumber: int + station : int + run: int + readoutTime : float + triggerTime : float + triggerType: str + sysclk: int + sysclkLastPPS: Tuple[int, int] # the last 2 PPS sysclks, most recent first + pps: int + radiantStartWindows: numpy.ndarray + sampleRate: float # Sample rate, in GSa/s +""" + +# The following selector selects only events with a forced trigger. +selectors = [lambda einfo: einfo.triggerType == "FORCE"] + +rnog_reader.begin( + list_of_root_files, + selectors=selectors, + log_level=logging.INFO, + # Currently false because Mattak does not contain calibrated data yet + read_calibrated_data=False, + # Only used when read_calibrated_data==False, performs a simple baseline subtraction each 128 bins + apply_baseline_correction=True, + # Only used when read_calibrated_data==False, performs a linear voltage calibration with hardcoded values + convert_to_voltage=True, + # Can be used instead of defining a selector (only for triggers) + select_triggers=None, + # If true, and if the RunTable database is available select runs based on the following criteria + select_runs=True, + # Only use runs of a certain run type + run_types=["physics"], + # Only use runs with a maximum trigger rate of 1 Hz + max_trigger_rate=1 * units.Hz) + +writer.begin(filename=output_filename) + +for i_event, event in enumerate(rnog_reader.run()): + + writer.run(event) + +print(i_event) +rnog_reader.end() +writer.end() + + From db82af0645b9af93c0892070f3e92a7e2831dd62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Mon, 3 Apr 2023 14:40:24 +0200 Subject: [PATCH 210/418] Access to DB can fail (for example without internet connection). Catch that --- .../modules/io/rno_g/readRNOGDataMattak.py | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py b/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py index 44875f0bc..d115b2d86 100644 --- a/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py +++ b/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py @@ -158,9 +158,15 @@ def begin(self, self.__max_trigger_rate = max_trigger_rate self.__run_types = run_types + global imported_runtable if imported_runtable: self.logger.debug("Access RunTable database ...") - self.__run_table = RunTable().get_table() + try: + self.__run_table = RunTable().get_table() + except: + self.logger.error("No connect to RunTable database could be established. " + "Runs will not be filtered.") + imported_runtable = False if not isinstance(data_dirs, (list, np.ndarray)): data_dirs = [data_dirs] @@ -200,7 +206,7 @@ def begin(self, dataset = mattak.Dataset.Dataset(station=0, run=0, data_dir=data_dir) # filter runs/datasets based on - if select_runs and not self.__select_run(dataset): + if select_runs and imported_runtable and not self.__select_run(dataset): self.__skipped_runs += 1 continue @@ -221,9 +227,7 @@ def begin(self, def __select_run(self, dataset): """ Filter/select runs/datasets. Return True to select an dataset, return False to skip it """ - if not imported_runtable: - return True - + # get first eventInfo dataset.setEntries(0) event_info = dataset.eventInfo() @@ -287,6 +291,7 @@ def run(self): trigger.set_trigger_time(event_info.triggerTime) station.set_trigger(trigger) + # access data waveforms = dataset.wfs() for channel_id, wf in enumerate(waveforms): From 85cc1daffadffff10af306165e300f5e6a5d381f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Mon, 3 Apr 2023 14:41:58 +0200 Subject: [PATCH 211/418] Small refactoring of eventWriter.py --- NuRadioReco/modules/io/eventWriter.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/NuRadioReco/modules/io/eventWriter.py b/NuRadioReco/modules/io/eventWriter.py index a924b646d..0204943bd 100644 --- a/NuRadioReco/modules/io/eventWriter.py +++ b/NuRadioReco/modules/io/eventWriter.py @@ -72,12 +72,14 @@ def begin(self, filename, max_file_size=1024, check_for_duplicates=False, events both set, the file will be split whenever any of the two conditions is fullfilled. """ logger.setLevel(log_level) - if filename[-4:] == '.nur': + if filename.endswith(".nur"): self.__filename = filename[:-4] else: self.__filename = filename - if filename[-4:] == '.ari': + + if filename.endswith('.ari'): logger.warning('The file ending .ari for NuRadioReco files is deprecated. Please use .nur instead.') + self.__check_for_duplicates = check_for_duplicates self.__number_of_events = 0 self.__current_file_size = 0 From a74fbc963704fd375cea2ef7d2b3597675cc788d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Tue, 4 Apr 2023 18:14:00 +0200 Subject: [PATCH 212/418] Implement run() as wrapper around __run(). This allows to specify the event index to get a specific event rather than only looping over all. Started to implement some function to get event header information --- .../modules/io/rno_g/readRNOGDataMattak.py | 159 +++++++++++------- 1 file changed, 102 insertions(+), 57 deletions(-) diff --git a/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py b/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py index d115b2d86..10ded678a 100644 --- a/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py +++ b/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py @@ -254,73 +254,118 @@ def __get_n_events_of_prev_datasets(self, dataset_idx): """ Get number of events from previous dataset to correctly set pointer """ dataset_idx_prev = dataset_idx - 1 return int(self._event_idxs_datasets[dataset_idx_prev]) if dataset_idx_prev >= 0 else 0 + + + def __get_dataset_and_event_info(self, event_idx): + """ Set pointer to correct """ + # find correct dataset + dataset_idx = np.digitize(event_idx, self._event_idxs_datasets) + dataset = self._datasets[dataset_idx] + event_idx_in_dataset = event_idx - self.__get_n_events_of_prev_datasets(dataset_idx) + dataset.setEntries(event_idx_in_dataset) # increment iterator -> point to new event + + event_info = dataset.eventInfo() - @register_run() - def run(self): - + if self._selectors is not None: + for selector in self._selectors: + if not selector(event_info): + return None, None + + return dataset, event_info + + + def get_event_information_dict(self, keys=["station", "run"]): + + data = {} + for event_idx in range(self._n_events_total): - self.logger.debug(f"Processing event number {event_idx} out of total {self._n_events_total}") - t0 = time.time() - - # find correct dataset - dataset_idx = np.digitize(event_idx, self._event_idxs_datasets) - dataset = self._datasets[dataset_idx] - - event_idx_in_dataset = event_idx - self.__get_n_events_of_prev_datasets(dataset_idx) - dataset.setEntries(event_idx_in_dataset) # increment iterator -> point to new event - event_info = dataset.eventInfo() - - skip = False - if self._selectors is not None: - for selector in self._selectors: - if not selector(event_info): - skip = True + _, event_info = self.__get_dataset_and_event_info(event_idx) - if skip: - self.__skipped += 1 + if event_info is None: continue - - evt = NuRadioReco.framework.event.Event(event_info.run, event_info.eventNumber) - station = NuRadioReco.framework.station.Station(event_info.station) - station.set_station_time(astropy.time.Time(event_info.triggerTime, format='unix')) + + data[event_idx] = {getattr(event_info, key) for key in keys} + + return data - trigger = NuRadioReco.framework.trigger.Trigger(event_info.triggerType) - trigger.set_triggered() - trigger.set_trigger_time(event_info.triggerTime) - station.set_trigger(trigger) + + def __run(self, event_idx): + """ Returns a single event with certain index """ + + self.logger.debug(f"Processing event number {event_idx} out of total {self._n_events_total}") + t0 = time.time() - # access data - waveforms = dataset.wfs() - - for channel_id, wf in enumerate(waveforms): - channel = NuRadioReco.framework.channel.Channel(channel_id) - if self._read_calibrated_data: - channel.set_trace(wf * units.mV, event_info.sampleRate * units.GHz) - else: - # wf stores ADC counts - - if self._apply_baseline_correction: - # correct baseline - wf = baseline_correction(wf) - - if self._convert_to_voltage: - # convert adc to voltage - wf *= (self._adc_ref_voltage_range / (2 ** (self._adc_n_bits) - 1)) - - channel.set_trace(wf, event_info.sampleRate * units.GHz) + dataset, event_info = self.__get_dataset_and_event_info(event_idx) + + if event_info is None: + self.__skipped += 1 + return None + + evt = NuRadioReco.framework.event.Event(event_info.run, event_info.eventNumber) + station = NuRadioReco.framework.station.Station(event_info.station) + station.set_station_time(astropy.time.Time(event_info.triggerTime, format='unix')) + + trigger = NuRadioReco.framework.trigger.Trigger(event_info.triggerType) + trigger.set_triggered() + trigger.set_trigger_time(event_info.triggerTime) + station.set_trigger(trigger) + + # access data + waveforms = dataset.wfs() + + for channel_id, wf in enumerate(waveforms): + channel = NuRadioReco.framework.channel.Channel(channel_id) + if self._read_calibrated_data: + channel.set_trace(wf * units.mV, event_info.sampleRate * units.GHz) + else: + # wf stores ADC counts - time_offset = get_time_offset(event_info.triggerType) - channel.set_trace_start_time(-time_offset) # relative to event/trigger time - - station.add_channel(channel) - - evt.set_station(station) + if self._apply_baseline_correction: + # correct baseline + wf = baseline_correction(wf) + + if self._convert_to_voltage: + # convert adc to voltage + wf *= (self._adc_ref_voltage_range / (2 ** (self._adc_n_bits) - 1)) + + channel.set_trace(wf, event_info.sampleRate * units.GHz) - self._time_run += time.time() - t0 - self.__counter += 1 - yield evt + time_offset = get_time_offset(event_info.triggerType) + channel.set_trace_start_time(-time_offset) # relative to event/trigger time + + station.add_channel(channel) + + evt.set_station(station) + + self._time_run += time.time() - t0 + self.__counter += 1 + yield evt + + + @register_run() + def run(self, event_index=None): + """ + Loop over all events or one specific event with event_index. + + Parameters + ---------- + + event_index: int + Incremental index. If None, loop over all events. (Default: None) + + Returns + ------- + + evt: NuRadioReco.framework.event + """ + + if event_index is None: + for event_idx in range(self._n_events_total): + yield from self.__run(event_idx) + else: + yield from self.__run(event_index) def end(self): From 2015fdbb2b5bb39a7f6f21e7451a6ddaacf75f7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Wed, 5 Apr 2023 14:43:00 +0200 Subject: [PATCH 213/418] Make interface of rnog noiseImporter more flexiable: Allow to provide list of noise folders --- .../measured_noise/RNO_G/noiseImporter.py | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/NuRadioReco/modules/measured_noise/RNO_G/noiseImporter.py b/NuRadioReco/modules/measured_noise/RNO_G/noiseImporter.py index 2a9e6ed1a..dd86d0914 100644 --- a/NuRadioReco/modules/measured_noise/RNO_G/noiseImporter.py +++ b/NuRadioReco/modules/measured_noise/RNO_G/noiseImporter.py @@ -17,7 +17,7 @@ class noiseImporter: """ - def begin(self, noise_folder, + def begin(self, noise_folders, file_pattern="*", match_station_id=False, station_ids=None, channel_mapping=None, scramble_noise_file_order=True, log_level=logging.INFO): @@ -25,8 +25,11 @@ def begin(self, noise_folder, Parameters ---------- - noise_folder: string - Folder containing noise file(s). Search in any subfolder as well. + noise_folders: str or list(str) + Folder(s) containing noise file(s). Search in any subfolder as well. + + file_patters: str + File patters used to search for directories, (Default: "*", other examples might be "combined") match_station_id: bool If True, add only noise from stations with the same id. (Default: False) @@ -61,10 +64,16 @@ def begin(self, noise_folder, f"\n\tUse the following channel mapping: {channel_mapping}" f"\n\tRandomize sequence of noise files: {scramble_noise_file_order}") - noise_files = glob.glob(f"{noise_folder}/**/*root", recursive=True) + if not isinstance(noise_folders, list): + noise_folders = [noise_folders] + + # find all subfolders + noise_files = [] + for noise_folder in noise_folders: + noise_files += glob.glob(f"{noise_folder}/**/{file_pattern}root", recursive=True) self.__noise_folders = np.unique([os.path.dirname(e) for e in noise_files]) - self.logger.info(f"Found {len(self.__noise_folders)} folders in {noise_folder}") + self.logger.info(f"Found {len(self.__noise_folders)}") if not len(self.__noise_folders): raise ValueError From 2714ada31d529742360c9765f39d3d339ebf7563 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Wed, 5 Apr 2023 15:37:10 +0200 Subject: [PATCH 214/418] Optimize reader --- .../modules/io/rno_g/readRNOGDataMattak.py | 23 ++++++++++++------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py b/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py index 10ded678a..68f10aacd 100644 --- a/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py +++ b/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py @@ -183,7 +183,7 @@ def begin(self, selectors.append(lambda eventInfo: eventInfo.triggerType == select_trigger) self._selectors = selectors - self.logger.info(f"Found {len(self._selectors)} selectors") + self.logger.info(f"Found {len(self._selectors)} selector(s)") self._time_begin = 0 self._time_run = 0 @@ -193,7 +193,7 @@ def begin(self, self._datasets = [] self.__n_events_per_dataset = [] - self.logger.info(f"Parse through {len(data_dirs)} directories.") + self.logger.info(f"Parse through {len(data_dirs)} directory/ies.") self.__skipped_runs = 0 self.__n_runs = 0 @@ -265,7 +265,7 @@ def __get_dataset_and_event_info(self, event_idx): event_idx_in_dataset = event_idx - self.__get_n_events_of_prev_datasets(dataset_idx) dataset.setEntries(event_idx_in_dataset) # increment iterator -> point to new event - event_info = dataset.eventInfo() + event_info = dataset.eventInfo() # returns a single eventInfo if self._selectors is not None: for selector in self._selectors: @@ -278,15 +278,22 @@ def __get_dataset_and_event_info(self, event_idx): def get_event_information_dict(self, keys=["station", "run"]): data = {} + n_prev = 0 + for dataset in self._datasets: + dataset.setEntries(0, dataset.N()) + + for idx, eventinfo in enumerate(dataset.eventInfo()): # returns a list - for event_idx in range(self._n_events_total): + event_idx = idx + n_prev # event index accross all datasets combined - _, event_info = self.__get_dataset_and_event_info(event_idx) + if self._selectors is not None: + for selector in self._selectors: + if not selector(eventinfo): + continue - if event_info is None: - continue + data[event_idx] = {getattr(eventinfo, key) for key in keys} - data[event_idx] = {getattr(event_info, key) for key in keys} + n_prev += dataset.N() return data From 2ab1b5fa5391331df6c5b39330627238ab77d29c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Wed, 5 Apr 2023 16:05:09 +0200 Subject: [PATCH 215/418] Allow to specift the mattak backend for both modules. Small fix in reader --- .../modules/io/rno_g/readRNOGDataMattak.py | 11 +++++--- .../measured_noise/RNO_G/noiseImporter.py | 27 +++++++++---------- 2 files changed, 20 insertions(+), 18 deletions(-) diff --git a/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py b/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py index 68f10aacd..d0c7c878c 100644 --- a/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py +++ b/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py @@ -95,7 +95,8 @@ def begin(self, select_triggers=None, select_runs=True, run_types=["physics"], - max_trigger_rate=1 * units.Hz): + max_trigger_rate=1 * units.Hz, + mattak_backend="auto"): """ @@ -135,6 +136,10 @@ def begin(self, max_trigger_rate: float Used to select/reject runs from information in the RNO-G RunTable. Maximum allowed trigger rate (per run) in Hz. If 0, no cut is applied. (Default: 1 Hz) + + mattak_backend: str + Select a mattak backend. Options are "auto", "pyroot", "uproot". If "auto" is selected, pyroot is used if available otherwise + a "fallback" to uproot is used. (Default: "auto") """ t0 = time.time() @@ -203,7 +208,7 @@ def begin(self, if not os.path.exists(data_dir): self.logger.error(f"The directory {data_dir} does not exist") - dataset = mattak.Dataset.Dataset(station=0, run=0, data_dir=data_dir) + dataset = mattak.Dataset.Dataset(station=0, run=0, data_dir=data_dir, backend=mattak_backend) # filter runs/datasets based on if select_runs and imported_runtable and not self.__select_run(dataset): @@ -280,7 +285,7 @@ def get_event_information_dict(self, keys=["station", "run"]): data = {} n_prev = 0 for dataset in self._datasets: - dataset.setEntries(0, dataset.N()) + dataset.setEntries((0, dataset.N())) for idx, eventinfo in enumerate(dataset.eventInfo()): # returns a list diff --git a/NuRadioReco/modules/measured_noise/RNO_G/noiseImporter.py b/NuRadioReco/modules/measured_noise/RNO_G/noiseImporter.py index dd86d0914..a52de7f9b 100644 --- a/NuRadioReco/modules/measured_noise/RNO_G/noiseImporter.py +++ b/NuRadioReco/modules/measured_noise/RNO_G/noiseImporter.py @@ -20,7 +20,7 @@ class noiseImporter: def begin(self, noise_folders, file_pattern="*", match_station_id=False, station_ids=None, channel_mapping=None, scramble_noise_file_order=True, - log_level=logging.INFO): + log_level=logging.INFO, mattak_backend="auto"): """ Parameters @@ -48,7 +48,10 @@ def begin(self, noise_folders, file_pattern="*", log_level: loggging log level the log level, default logging.INFO - + + mattak_backend: str + Select a mattak backend. Options are "auto", "pyroot", "uproot". If "auto" is selected, pyroot is used if available otherwise + a "fallback" to uproot is used. (Default: "auto") """ self.logger = logging.getLogger('noiseImporter') @@ -80,20 +83,14 @@ def begin(self, noise_folders, file_pattern="*", if scramble_noise_file_order: random.shuffle(self.__noise_folders) - noise_reader = readRNOGData() + self._noise_reader = readRNOGData() selectors = [lambda einfo: einfo.triggerType == "FORCE"] - noise_reader.begin(self.__noise_folders, selectors=selectors, log_level=log_level) - self._noise_events = [evt for evt in noise_reader.run()] - noise_reader.end() - - self.__station_id_list = None - - - def _buffer_station_id_list(self): - if self.__station_id_list is None: - self.__station_id_list = np.squeeze([evt.get_station_ids() for evt in self._noise_events]) - - return self.__station_id_list + self._noise_reader.begin(self.__noise_folders, selectors=selectors, log_level=log_level, mattak_backend=mattak_backend) + import time + + t0 = time.time() + self._noise_events = [evt for evt in self._noise_reader.run()] + print(time.time() - t0) def __get_noise_channel(self, channel_id): From 07dc3b217bff0ea74848963f186d431137dfd767 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Wed, 5 Apr 2023 17:04:19 +0200 Subject: [PATCH 216/418] Finish implementing optimization for noiseImporter. Decoupled generator function (i.e., run()) and function to return a specific event (read_event). Some fixes --- .../modules/io/rno_g/readRNOGDataMattak.py | 78 ++++++++++--------- .../measured_noise/RNO_G/noiseImporter.py | 33 ++++---- 2 files changed, 59 insertions(+), 52 deletions(-) diff --git a/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py b/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py index d0c7c878c..01ef01346 100644 --- a/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py +++ b/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py @@ -224,6 +224,9 @@ def begin(self, self._n_events_total = np.sum(self.__n_events_per_dataset) self._time_begin = time.time() - t0 + # Variable not yet implemented in mattak + # self.logger.info(f"Using the {self._datasets[0].backend} Mattak backend.") + if not self._n_events_total: err = "No runs have been selected. Abort ..." self.logger.error(err) @@ -261,7 +264,7 @@ def __get_n_events_of_prev_datasets(self, dataset_idx): return int(self._event_idxs_datasets[dataset_idx_prev]) if dataset_idx_prev >= 0 else 0 - def __get_dataset_and_event_info(self, event_idx): + def __get_dataset_for_event(self, event_idx): """ Set pointer to correct """ # find correct dataset dataset_idx = np.digitize(event_idx, self._event_idxs_datasets) @@ -269,15 +272,8 @@ def __get_dataset_and_event_info(self, event_idx): event_idx_in_dataset = event_idx - self.__get_n_events_of_prev_datasets(dataset_idx) dataset.setEntries(event_idx_in_dataset) # increment iterator -> point to new event - - event_info = dataset.eventInfo() # returns a single eventInfo - - if self._selectors is not None: - for selector in self._selectors: - if not selector(event_info): - return None, None - - return dataset, event_info + + return dataset def get_event_information_dict(self, keys=["station", "run"]): @@ -287,19 +283,27 @@ def get_event_information_dict(self, keys=["station", "run"]): for dataset in self._datasets: dataset.setEntries((0, dataset.N())) - for idx, eventinfo in enumerate(dataset.eventInfo()): # returns a list + for idx, evtinfo in enumerate(dataset.eventInfo()): # returns a list event_idx = idx + n_prev # event index accross all datasets combined + skip = False if self._selectors is not None: - for selector in self._selectors: - if not selector(eventinfo): - continue + for selector in self._selectors: + if not selector(evtinfo): + self.logger.debug(f"Event {event_idx} (station {evtinfo.station}, run {evtinfo.run}, " + f"event number {evtinfo.eventNumber}) is skipped.") + skip = True + break + + if skip: + self.__skipped += 1 + continue - data[event_idx] = {getattr(eventinfo, key) for key in keys} + data[event_idx] = {key: getattr(evtinfo, key) for key in keys} n_prev += dataset.N() - + return data @@ -309,12 +313,17 @@ def __run(self, event_idx): self.logger.debug(f"Processing event number {event_idx} out of total {self._n_events_total}") t0 = time.time() - dataset, event_info = self.__get_dataset_and_event_info(event_idx) - - if event_info is None: - self.__skipped += 1 - return None - + dataset = self.__get_dataset_for_event(event_idx) + event_info = dataset.eventInfo() # returns a single eventInfo + + if self._selectors is not None: + for selector in self._selectors: + if not selector(event_info): + self.logger.debug(f"Event {event_idx} (station {event_info.station}, run {event_info.run}, " + f"event number {event_info.eventNumber}) is skipped.") + self.__skipped += 1 + return None + evt = NuRadioReco.framework.event.Event(event_info.run, event_info.eventNumber) station = NuRadioReco.framework.station.Station(event_info.station) station.set_station_time(astropy.time.Time(event_info.triggerTime, format='unix')) @@ -353,31 +362,26 @@ def __run(self, event_idx): self._time_run += time.time() - t0 self.__counter += 1 - yield evt + return evt @register_run() - def run(self, event_index=None): + def run(self): """ - Loop over all events or one specific event with event_index. - - Parameters - ---------- - - event_index: int - Incremental index. If None, loop over all events. (Default: None) + Loop over all events. Returns ------- evt: NuRadioReco.framework.event """ - - if event_index is None: - for event_idx in range(self._n_events_total): - yield from self.__run(event_idx) - else: - yield from self.__run(event_index) + + for event_idx in range(self._n_events_total): + yield self.__run(event_idx) + + + def read_event(self, event_index): + return self.__run(event_index) def end(self): diff --git a/NuRadioReco/modules/measured_noise/RNO_G/noiseImporter.py b/NuRadioReco/modules/measured_noise/RNO_G/noiseImporter.py index a52de7f9b..31051de69 100644 --- a/NuRadioReco/modules/measured_noise/RNO_G/noiseImporter.py +++ b/NuRadioReco/modules/measured_noise/RNO_G/noiseImporter.py @@ -2,6 +2,7 @@ import glob import os import random +import sys from NuRadioReco.modules.io.rno_g.readRNOGDataMattak import readRNOGData from NuRadioReco.modules.base.module import register_run @@ -86,12 +87,14 @@ def begin(self, noise_folders, file_pattern="*", self._noise_reader = readRNOGData() selectors = [lambda einfo: einfo.triggerType == "FORCE"] self._noise_reader.begin(self.__noise_folders, selectors=selectors, log_level=log_level, mattak_backend=mattak_backend) - import time - t0 = time.time() - self._noise_events = [evt for evt in self._noise_reader.run()] - print(time.time() - t0) - + + self.logger.info("Get event informations ...") + # instead of reading all noise events into memory we only get certain information here and read all data in run() + noise_information = self._noise_reader.get_event_information_dict(keys=["station"]) + self.__event_index_list = np.array(list(noise_information.keys())) + self.__station_id_list = np.array([ele["station"] for ele in noise_information.values()]) + def __get_noise_channel(self, channel_id): if self.__channel_mapping is None: @@ -104,18 +107,17 @@ def __get_noise_channel(self, channel_id): def run(self, evt, station, det): if self._match_station_id: - - station_ids = self._buffer_station_id_list() - mask = station_ids == station.get_id() - if not np.any(mask): + # select only noise events from simulated station id + station_mask = self.__station_id_list == station.get_id() + if not np.any(station_mask): raise ValueError(f"No station with id {station.get_id()} in noise data.") - - i_noise = np.random.choice(np.arange(len(mask))[mask]) - + else: - i_noise = np.random.randint(0, len(self._noise_events)) - - noise_event = self._noise_events[i_noise] + # select all noise events + station_mask = np.full_like(self.__event_index_list, True) + + i_noise = np.random.choice(self.__event_index_list[station_mask]) + noise_event = self._noise_reader.read_event(i_noise) station_id = noise_event.get_station_ids()[0] noise_station = noise_event.get_station(station_id) @@ -155,4 +157,5 @@ def run(self, evt, station, det): channel.set_trace(trace, channel.get_sampling_rate()) def end(self): + self._noise_reader.end() pass From 2d217d9702db05dd8ada60a44dfc8d9d353ee63e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Wed, 5 Apr 2023 19:02:09 +0200 Subject: [PATCH 217/418] Further optimizing the mattak reader. This commit should improve the performance when using the generator (i.e., the run() method) and in particular the uproot backend. Add some logger info to the noiseImporter --- .../modules/io/rno_g/readRNOGDataMattak.py | 101 +++++++++++------- .../measured_noise/RNO_G/noiseImporter.py | 13 ++- 2 files changed, 74 insertions(+), 40 deletions(-) diff --git a/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py b/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py index 01ef01346..08b5f1587 100644 --- a/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py +++ b/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py @@ -276,6 +276,18 @@ def __get_dataset_for_event(self, event_idx): return dataset + def filter_event(self, evtinfo, event_idx=None): + if self._selectors is not None: + for selector in self._selectors: + if not selector(evtinfo): + self.logger.debug(f"Event {event_idx} (station {evtinfo.station}, run {evtinfo.run}, " + f"event number {evtinfo.eventNumber}) is skipped.") + self.__skipped += 1 + return True + + return False + + def get_event_information_dict(self, keys=["station", "run"]): data = {} @@ -287,17 +299,7 @@ def get_event_information_dict(self, keys=["station", "run"]): event_idx = idx + n_prev # event index accross all datasets combined - skip = False - if self._selectors is not None: - for selector in self._selectors: - if not selector(evtinfo): - self.logger.debug(f"Event {event_idx} (station {evtinfo.station}, run {evtinfo.run}, " - f"event number {evtinfo.eventNumber}) is skipped.") - skip = True - break - - if skip: - self.__skipped += 1 + if self.filter_event(evtinfo, event_idx): continue data[event_idx] = {key: getattr(evtinfo, key) for key in keys} @@ -305,25 +307,10 @@ def get_event_information_dict(self, keys=["station", "run"]): n_prev += dataset.N() return data - - def __run(self, event_idx): - """ Returns a single event with certain index """ - self.logger.debug(f"Processing event number {event_idx} out of total {self._n_events_total}") - t0 = time.time() - - dataset = self.__get_dataset_for_event(event_idx) - event_info = dataset.eventInfo() # returns a single eventInfo - - if self._selectors is not None: - for selector in self._selectors: - if not selector(event_info): - self.logger.debug(f"Event {event_idx} (station {event_info.station}, run {event_info.run}, " - f"event number {event_info.eventNumber}) is skipped.") - self.__skipped += 1 - return None - + def get_event(self, event_info, waveforms): + evt = NuRadioReco.framework.event.Event(event_info.run, event_info.eventNumber) station = NuRadioReco.framework.station.Station(event_info.station) station.set_station_time(astropy.time.Time(event_info.triggerTime, format='unix')) @@ -332,9 +319,6 @@ def __run(self, event_idx): trigger.set_triggered() trigger.set_trigger_time(event_info.triggerTime) station.set_trigger(trigger) - - # access data - waveforms = dataset.wfs() for channel_id, wf in enumerate(waveforms): channel = NuRadioReco.framework.channel.Channel(channel_id) @@ -360,9 +344,7 @@ def __run(self, event_idx): evt.set_station(station) - self._time_run += time.time() - t0 - self.__counter += 1 - return evt + return evt @register_run() @@ -375,13 +357,58 @@ def run(self): evt: NuRadioReco.framework.event """ + event_idx = -1 + for dataset in self._datasets: + dataset.setEntries((0, dataset.N())) + + # read all event infos of the entier dataset (= run) + event_infos = dataset.eventInfo() + wfs = None + + for idx, evtinfo in enumerate(event_infos): # returns a list + event_idx += 1 + + self.logger.debug(f"Processing event number {event_idx} out of total {self._n_events_total}") + t0 = time.time() + + if self.filter_event(evtinfo, event_idx): + continue + + # Just read wfs if necessary + if wfs is None: + wfs = dataset.wfs() + + waveforms_of_event = wfs[idx] + + evt = self.get_event(evtinfo, waveforms_of_event) + + self._time_run += time.time() - t0 + self.__counter += 1 + + yield evt - for event_idx in range(self._n_events_total): - yield self.__run(event_idx) def read_event(self, event_index): - return self.__run(event_index) + + self.logger.debug(f"Processing event number {event_index} out of total {self._n_events_total}") + t0 = time.time() + + dataset = self.__get_dataset_for_event(event_index) + event_info = dataset.eventInfo() # returns a single eventInfo + + if self.filter_event(event_info, event_index): + return None + + # access data + waveforms = dataset.wfs() + + evt = self.get_event(event_info, waveforms) + + self._time_run += time.time() - t0 + self.__counter += 1 + + return evt def end(self): diff --git a/NuRadioReco/modules/measured_noise/RNO_G/noiseImporter.py b/NuRadioReco/modules/measured_noise/RNO_G/noiseImporter.py index 31051de69..e018a9715 100644 --- a/NuRadioReco/modules/measured_noise/RNO_G/noiseImporter.py +++ b/NuRadioReco/modules/measured_noise/RNO_G/noiseImporter.py @@ -2,7 +2,7 @@ import glob import os import random -import sys +import collections from NuRadioReco.modules.io.rno_g.readRNOGDataMattak import readRNOGData from NuRadioReco.modules.base.module import register_run @@ -55,7 +55,7 @@ def begin(self, noise_folders, file_pattern="*", a "fallback" to uproot is used. (Default: "auto") """ - self.logger = logging.getLogger('noiseImporter') + self.logger = logging.getLogger('NuRadioReco.RNOG.noiseImporter') self.logger.setLevel(log_level) self._match_station_id = match_station_id @@ -94,6 +94,8 @@ def begin(self, noise_folders, file_pattern="*", noise_information = self._noise_reader.get_event_information_dict(keys=["station"]) self.__event_index_list = np.array(list(noise_information.keys())) self.__station_id_list = np.array([ele["station"] for ele in noise_information.values()]) + + self._n_use_event = collections.defaultdict(int) def __get_noise_channel(self, channel_id): @@ -116,7 +118,8 @@ def run(self, evt, station, det): # select all noise events station_mask = np.full_like(self.__event_index_list, True) - i_noise = np.random.choice(self.__event_index_list[station_mask]) + i_noise = np.random.choice(self.__event_index_list[station_mask]) + self._n_use_event[i_noise] += 1 noise_event = self._noise_reader.read_event(i_noise) station_id = noise_event.get_station_ids()[0] @@ -158,4 +161,8 @@ def run(self, evt, station, det): def end(self): self._noise_reader.end() + n_use = np.array(list(self._n_use_event.values())) + sort = np.flip(np.argsort(n_use)) + self.logger.info("\n\tThe five most used noise events have been used: {}" + .format(", ".join([str(ele) for ele in n_use[sort][:5]]))) pass From b098e28df7fc13e0a23688c7beb58a562e0c8ab9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Wed, 5 Apr 2023 19:26:40 +0200 Subject: [PATCH 218/418] Add doc strings to please the coding god --- .../modules/io/rno_g/readRNOGDataMattak.py | 96 ++++++++++++++++++- 1 file changed, 92 insertions(+), 4 deletions(-) diff --git a/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py b/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py index 08b5f1587..9ce6512e7 100644 --- a/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py +++ b/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py @@ -234,7 +234,16 @@ def begin(self, def __select_run(self, dataset): - """ Filter/select runs/datasets. Return True to select an dataset, return False to skip it """ + """ Filter/select runs/datasets. + + Parameters + ---------- + + dataset: mattak.Dataset.Dataset + + select: bool + Return True to select an dataset, return False to reject/skip it. + """ # get first eventInfo dataset.setEntries(0) @@ -259,13 +268,25 @@ def __select_run(self, dataset): def __get_n_events_of_prev_datasets(self, dataset_idx): - """ Get number of events from previous dataset to correctly set pointer """ + """ Get accumulated number of events from previous datasets """ dataset_idx_prev = dataset_idx - 1 return int(self._event_idxs_datasets[dataset_idx_prev]) if dataset_idx_prev >= 0 else 0 def __get_dataset_for_event(self, event_idx): - """ Set pointer to correct """ + """ Get correct dataset and set entry accordingly to event index + + Parameters + ---------- + + event_index: int + Same as in read_event(). + + Retruns + ------- + + dataset: mattak.Dataset.Dataset + """ # find correct dataset dataset_idx = np.digitize(event_idx, self._event_idxs_datasets) dataset = self._datasets[dataset_idx] @@ -277,6 +298,23 @@ def __get_dataset_for_event(self, event_idx): def filter_event(self, evtinfo, event_idx=None): + """ Filter an event base on its EventInfo and the configured selectors. + + Parameters + ---------- + + event_info: mattak.Dataset.EventInfo + The event info object for one event. + + event_index: int + Same as in read_event(). Only use for logger.info(). (Default: None) + + Returns + ------- + + skip: bool + Returns True to skip/reject event, return False to keep/read event + """ if self._selectors is not None: for selector in self._selectors: if not selector(evtinfo): @@ -289,6 +327,26 @@ def filter_event(self, evtinfo, event_idx=None): def get_event_information_dict(self, keys=["station", "run"]): + """ Return information of all events from the EventInfo + + This function is useful to make a pre-selection of events before actually reading them in combination with + self.read_event(). + + Parameters + ---------- + + keys: list(str) + List of the information to receive from each event. Have to match the attributes (member variables) + of the mattak.Dataset.EventInfo class (examples are "station", "run", "triggerTime", "triggerType", "eventNumber", ...). + (Default: ["station", "run"]) + + Returns + ------- + + data: dict + Keys of the dict are the event indecies (as used in self.read_event(event_index)). The values are dictinaries + them self containing the information specified with "keys" parameter. + """ data = {} n_prev = 0 @@ -310,6 +368,22 @@ def get_event_information_dict(self, keys=["station", "run"]): def get_event(self, event_info, waveforms): + """ Return a NuRadioReco event + + Parameters + ---------- + + event_info: mattak.Dataset.EventInfo + The event info object for one event. + + waveforms: np.array(n_channel, n_samples) + Typically what dataset.wfs() returns (for one event!) + + Returns + ------- + + evt: NuRadioReco.framework.event + """ evt = NuRadioReco.framework.event.Event(event_info.run, event_info.eventNumber) station = NuRadioReco.framework.station.Station(event_info.station) @@ -355,7 +429,7 @@ def run(self): Returns ------- - evt: NuRadioReco.framework.event + evt: generator(NuRadioReco.framework.event) """ event_idx = -1 for dataset in self._datasets: @@ -390,6 +464,20 @@ def run(self): def read_event(self, event_index): + """ Allows to read a specific event identifed by its index + + Parameters + ---------- + + event_index: int + The index of a particluar event. The index is the chronological number from 0 to + number of total events (across all datasets). + + Returns + ------- + + evt: NuRadioReco.framework.event + """ self.logger.debug(f"Processing event number {event_index} out of total {self._n_events_total}") t0 = time.time() From 758c7eff539149dad60b83002cdc63933218b033 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Thu, 6 Apr 2023 17:44:56 +0200 Subject: [PATCH 219/418] Details: Allow to import run summary table from a cvs file. Add run selection based on time. Change interface of noiseImporter to accept dict for reader arguments --- .../modules/io/rno_g/readRNOGDataMattak.py | 77 ++++++++++++++----- .../measured_noise/RNO_G/noiseImporter.py | 18 +++-- 2 files changed, 71 insertions(+), 24 deletions(-) diff --git a/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py b/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py index 9ce6512e7..f8bbba1f2 100644 --- a/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py +++ b/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py @@ -94,7 +94,9 @@ def begin(self, convert_to_voltage=True, select_triggers=None, select_runs=True, + run_table_path=None, run_types=["physics"], + run_time_range=None, max_trigger_rate=1 * units.Hz, mattak_backend="auto"): @@ -112,8 +114,7 @@ def begin(self, selectors: list of lambdas List of lambda(eventInfo) -> bool to pass to mattak.Dataset.iterate to select events. Example: - - trigger_selector = lambda eventInfo: eventInfo.triggerType == "FORCE" + trigger_selector = lambda eventInfo: eventInfo.triggerType == "FORCE" read_calibrated_data: bool If True, read calibrated waveforms from Mattak.Dataset. If False, read "raw" ADC traces. @@ -130,9 +131,18 @@ def begin(self, select_runs: bool Select runs + run_table_path: str + Path to a run_table.cvs file. If None, the run table is queried from the DB. (Default: None) + run_types: list Used to select/reject runs from information in the RNO-G RunTable. List of run_types to be used. (Default: ['physics']) + run_time_range: tuple + Specify a time range to select runs (it is sufficient that runs cover the time range partially). + Each value of the tuple has to be in a format which astropy.time.Time understands. A value can be None + which means that the lower or upper bound is unconstrained. If run_time_range is None no time selection is + applied. (Default: None) + max_trigger_rate: float Used to select/reject runs from information in the RNO-G RunTable. Maximum allowed trigger rate (per run) in Hz. If 0, no cut is applied. (Default: 1 Hz) @@ -156,23 +166,37 @@ def begin(self, self._adc_ref_voltage_range = 2.5 * units.volt self._adc_n_bits = 12 - if select_runs: - self.logger.info("\n\tSelect runs with type: {}".format(", ".join(run_types)) + - f"\n\tSelect runs with max. trigger rate of {max_trigger_rate / units.Hz} Hz") - self.__max_trigger_rate = max_trigger_rate self.__run_types = run_types - global imported_runtable - if imported_runtable: - self.logger.debug("Access RunTable database ...") - try: - self.__run_table = RunTable().get_table() - except: - self.logger.error("No connect to RunTable database could be established. " - "Runs will not be filtered.") - imported_runtable = False - + if run_time_range is not None: + convert_time = lambda t: None if t is None else astropy.time.Time(t) + self._time_low = convert_time(run_time_range[0]) + self._time_high = convert_time(run_time_range[1]) + else: + self._time_low = None + self._time_high = None + + if select_runs: + if run_table_path is None: + global imported_runtable + if imported_runtable: + self.logger.debug("Access RunTable database ...") + try: + self.__run_table = RunTable().get_table() + except: + self.logger.error("No connect to RunTable database could be established. " + "Runs will not be filtered.") + imported_runtable = False + else: + self.__run_table = pandas.read_csv(run_table_path) + imported_runtable = True + + if select_runs: + self.logger.info("\n\tSelect runs with type: {}".format(", ".join(run_types)) + + f"\n\tSelect runs with max. trigger rate of {max_trigger_rate / units.Hz} Hz" + f"\n\tSelect runs which are between {self._time_low} - {self._time_high}") + if not isinstance(data_dirs, (list, np.ndarray)): data_dirs = [data_dirs] @@ -209,7 +233,7 @@ def begin(self, self.logger.error(f"The directory {data_dir} does not exist") dataset = mattak.Dataset.Dataset(station=0, run=0, data_dir=data_dir, backend=mattak_backend) - + # filter runs/datasets based on if select_runs and imported_runtable and not self.__select_run(dataset): self.__skipped_runs += 1 @@ -224,6 +248,8 @@ def begin(self, self._n_events_total = np.sum(self.__n_events_per_dataset) self._time_begin = time.time() - t0 + self.logger.info(f"{self._n_events_total} events in {len(self._datasets)} runs/datasets have been found.") + # Variable not yet implemented in mattak # self.logger.info(f"Using the {self._datasets[0].backend} Mattak backend.") @@ -253,8 +279,23 @@ def __select_run(self, dataset): station_id = event_info.station run_info = self.__run_table.query(f"station == {station_id:d} & run == {run_id:d}") - run_type = run_info["run_type"].values[0] + # "time_start/end" is stored in the isot format. datetime is much faster than astropy (~85ns vs 55 mus). + # But using datetime would mean to stip decimals because datetime can only handle mu sec precision and can not cope + # with the additional decimals for ns. + if self._time_low is not None: + time_end = astropy.time.Time(run_info["time_end"].values[0]) + if time_end < self._time_low: + self.logger.info(f"Reject station {station_id} run {run_id} because run ended before {self._time_low}") + return False + + if self._time_high is not None: + time_start = astropy.time.Time(run_info["time_start"].values[0]) + if time_start > self._time_high: + self.logger.info(f"Reject station {station_id} run {run_id} because run started time after {self._time_high}") + return False + + run_type = run_info["run_type"].values[0] if not run_type in self.__run_types: self.logger.info(f"Reject station {station_id} run {run_id} because of run type {run_type}") return False diff --git a/NuRadioReco/modules/measured_noise/RNO_G/noiseImporter.py b/NuRadioReco/modules/measured_noise/RNO_G/noiseImporter.py index e018a9715..d046a37fd 100644 --- a/NuRadioReco/modules/measured_noise/RNO_G/noiseImporter.py +++ b/NuRadioReco/modules/measured_noise/RNO_G/noiseImporter.py @@ -21,7 +21,7 @@ class noiseImporter: def begin(self, noise_folders, file_pattern="*", match_station_id=False, station_ids=None, channel_mapping=None, scramble_noise_file_order=True, - log_level=logging.INFO, mattak_backend="auto"): + log_level=logging.INFO, reader_kwargs={}): """ Parameters @@ -50,9 +50,8 @@ def begin(self, noise_folders, file_pattern="*", log_level: loggging log level the log level, default logging.INFO - mattak_backend: str - Select a mattak backend. Options are "auto", "pyroot", "uproot". If "auto" is selected, pyroot is used if available otherwise - a "fallback" to uproot is used. (Default: "auto") + reader_kwargs: dict + Optional arguements passed to readRNOGDataMattak """ self.logger = logging.getLogger('NuRadioReco.RNOG.noiseImporter') @@ -84,9 +83,16 @@ def begin(self, noise_folders, file_pattern="*", if scramble_noise_file_order: random.shuffle(self.__noise_folders) - self._noise_reader = readRNOGData() + if "log_level" in reader_kwargs: + log_level_reader = reader_kwargs.pop("log_level") + else: + log_level_reader = log_level + + self._noise_reader = readRNOGData() selectors = [lambda einfo: einfo.triggerType == "FORCE"] - self._noise_reader.begin(self.__noise_folders, selectors=selectors, log_level=log_level, mattak_backend=mattak_backend) + self._noise_reader.begin(self.__noise_folders, selectors=selectors, + log_level=log_level_reader, + **reader_kwargs) self.logger.info("Get event informations ...") From 300ffceefcc4702e8116d81cbb29f7ac98f16118 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Thu, 6 Apr 2023 17:49:30 +0200 Subject: [PATCH 220/418] Add explicit dtpe conversion --- NuRadioReco/modules/measured_noise/RNO_G/noiseImporter.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/NuRadioReco/modules/measured_noise/RNO_G/noiseImporter.py b/NuRadioReco/modules/measured_noise/RNO_G/noiseImporter.py index d046a37fd..6f9460716 100644 --- a/NuRadioReco/modules/measured_noise/RNO_G/noiseImporter.py +++ b/NuRadioReco/modules/measured_noise/RNO_G/noiseImporter.py @@ -97,13 +97,14 @@ def begin(self, noise_folders, file_pattern="*", self.logger.info("Get event informations ...") # instead of reading all noise events into memory we only get certain information here and read all data in run() + noise_information = self._noise_reader.get_event_information_dict(keys=["station"]) self.__event_index_list = np.array(list(noise_information.keys())) self.__station_id_list = np.array([ele["station"] for ele in noise_information.values()]) self._n_use_event = collections.defaultdict(int) - - + + def __get_noise_channel(self, channel_id): if self.__channel_mapping is None: return channel_id @@ -124,7 +125,8 @@ def run(self, evt, station, det): # select all noise events station_mask = np.full_like(self.__event_index_list, True) - i_noise = np.random.choice(self.__event_index_list[station_mask]) + # int(..) necessary because pyroot can not handle np.int64 + i_noise = int(np.random.choice(self.__event_index_list[station_mask])) self._n_use_event[i_noise] += 1 noise_event = self._noise_reader.read_event(i_noise) From 3c5f26994fa1045771887c1377c72b8541cc82ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Thu, 6 Apr 2023 18:02:17 +0200 Subject: [PATCH 221/418] small import fix --- NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py b/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py index f8bbba1f2..dd75ba78c 100644 --- a/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py +++ b/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py @@ -1,5 +1,5 @@ import numpy as np - +import pandas import logging import os import time @@ -17,7 +17,6 @@ try: from rnog_data.runtable import RunTable - import pandas imported_runtable = True except ImportError: print("Import of run table failed. You will not be able to select runs! \n" From f0b50a01df3259c564dd51216019fff23fc1fc56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Wed, 12 Apr 2023 11:12:23 +0200 Subject: [PATCH 222/418] Add docstrings for one last function --- .../modules/io/rno_g/readRNOGDataMattak.py | 48 +++++++++++++------ 1 file changed, 34 insertions(+), 14 deletions(-) diff --git a/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py b/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py index dd75ba78c..06cd576a9 100644 --- a/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py +++ b/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py @@ -24,23 +24,43 @@ imported_runtable = False -def baseline_correction(wfs, n_bins=128): +def baseline_correction(wfs, n_bins=128, func=np.median): + """ + Simple baseline correction function. Determines baseline in discrete chuncks of "n_bins" with + the function specified (i.e., mean or median). + + Parameters + ---------- + + wfs: np.array(n_events, n_channels, n_samples) + Waveforms of several events/channels. + + n_bins: int + Number of samples/bins in one "chunck". If None, calculate median/mean over entire trace. (Default: 128) + + func: np.mean or np.median + Function to calculate pedestal + + Returns + ------- + + wfs_corrected: np.array(n_events, n_channels, n_samples) + Baseline/pedestal corrected waveforms + """ - # Get baseline in chunks of 128 bins - # np.split -> (16, n_events, n_channels, 128) - # np.mean -> (16, n_events, n_channels) + # Example: Get baselines in chunks of 128 bins + # wfs in (n_events, n_channels, 2048) + # np.split -> (16, n_events, n_channels, 128) each waveform split in 16 chuncks + # func -> (16, n_events, n_channels) pedestal for each chunck if n_bins is not None: - medians = np.median(np.split(wfs, 2048 // n_bins, axis=-1), axis=-1) - - # Get baseline traces - # np.repeat -> (2048, n_events, n_channels) - baseline_traces = np.repeat(medians, n_bins % 2048, axis=0) + baseline_values = func(np.split(wfs, 2048 // n_bins, axis=-1), axis=-1) + + # np.repeat -> (2048, n_events, n_channels) concatenate the 16 chuncks to one baseline + baseline_traces = np.repeat(baseline_values, n_bins % 2048, axis=0) else: - medians = np.median(wfs, axis=-1) - - # Get baseline traces - # np.repeat -> (2048, n_events, n_channels) - baseline_traces = np.repeat(medians, 2048, axis=0) + baseline_values = func(wfs, axis=-1) + # np.repeat -> (2048, n_events, n_channels) concatenate the 16 chuncks to one baseline + baseline_traces = np.repeat(baseline_values, 2048, axis=0) # np.moveaxis -> (n_events, n_channels, 2048) baseline_traces = np.moveaxis(baseline_traces, 0, -1) From 4308690b4c78f2debf03ae9d085d6ca4f26ce9fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Wed, 12 Apr 2023 11:57:56 +0200 Subject: [PATCH 223/418] Add pandas to dependencies --- pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pyproject.toml b/pyproject.toml index d936b0ee8..577a24204 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -41,6 +41,7 @@ toml = ">=0.10.2" uproot = "4.1.1" importlib-metadata = {version = ">=4.8.1", python = "<3.8"} numba = "*" +pandas = "*" [tool.poetry.dev-dependencies] Sphinx = "*" From b1dda670b76dec90bbe0733be3578326b8f07e9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Wed, 12 Apr 2023 12:03:41 +0200 Subject: [PATCH 224/418] Fix docstring --- NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py b/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py index 06cd576a9..2624c47e8 100644 --- a/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py +++ b/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py @@ -118,12 +118,11 @@ def begin(self, run_time_range=None, max_trigger_rate=1 * units.Hz, mattak_backend="auto"): - """ - + Parameters ---------- - + data_dirs: list of strings / string Path to run directories (i.e. ".../stationXX/runXXX/") @@ -132,13 +131,12 @@ def begin(self, selectors: list of lambdas List of lambda(eventInfo) -> bool to pass to mattak.Dataset.iterate to select events. - Example: - trigger_selector = lambda eventInfo: eventInfo.triggerType == "FORCE" + Example: trigger_selector = lambda eventInfo: eventInfo.triggerType == "FORCE" read_calibrated_data: bool If True, read calibrated waveforms from Mattak.Dataset. If False, read "raw" ADC traces. (temp. Default: False) - + apply_baseline_correction: bool Only applies when non-calibrated data are read. If true, correct for DC offset. (Default: True) From eb351d4a39f8b5cafba91a9ed984362db45cfe65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= <30903175+fschlueter@users.noreply.github.com> Date: Wed, 12 Apr 2023 14:11:46 +0200 Subject: [PATCH 225/418] Update readRNOGDataMattak.py Update doctoring --- NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py b/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py index 2624c47e8..e072fa578 100644 --- a/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py +++ b/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py @@ -146,7 +146,8 @@ def begin(self, (Default: True) select_runs: bool - Select runs + If True, use information in run_table to select runs (based on run_type, run_time, trigger_rate, ...). If the run_table is + not available no selection is performed (and the programm is not interrupted, only an error message is raised). (Default: True) run_table_path: str Path to a run_table.cvs file. If None, the run table is queried from the DB. (Default: None) @@ -563,4 +564,4 @@ def end(self): f"\n\tTime to initialize data sets : {self._time_begin:.2f}s" f"\n\tTime to initialize all events : {self._time_run:.2f}s" f"\n\tTime to per event : {self._time_run / self.__counter:.2f}s" - f"\n\tRead {self.__n_runs} runs, skipped {self.__skipped_runs} runs.") \ No newline at end of file + f"\n\tRead {self.__n_runs} runs, skipped {self.__skipped_runs} runs.") From 657cf6c12590bd3c6e88f1e944bc1eccda79412c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= <30903175+fschlueter@users.noreply.github.com> Date: Wed, 12 Apr 2023 14:54:14 +0200 Subject: [PATCH 226/418] Update readRNOGDataMattak.py Update trigger specific time offset base on plots by Steffen --- NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py b/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py index e072fa578..19d391d14 100644 --- a/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py +++ b/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py @@ -75,6 +75,8 @@ def get_time_offset(trigger_type): information might be time, station, and channel dependent and should come from a database (or is already calibrated in mattak) + Current values motivated by figures posted in PR https://github.com/nu-radio/NuRadioMC/pull/519 + Parameters ---------- @@ -91,8 +93,8 @@ def get_time_offset(trigger_type): time_offsets = { "FORCE": 0, - "LT": 213 * units.ns, # ~ 1 / 3 of trace @ 2048 sample with 3.2 GSa/s - "RADIANT": 320 * units.ns # ~ 1 / 2 of trace @ 2048 sample with 3.2 GSa/s + "LT": 250 * units.ns, + "RADIANT": 475 * units.ns } if trigger_type.startswith("RADIANT"): From c0057268906e6dff69009327a06dfa8ab4ca7cb2 Mon Sep 17 00:00:00 2001 From: Sjoerd Bouma Date: Wed, 19 Apr 2023 13:18:50 +0200 Subject: [PATCH 227/418] change to smarter minimization --- .../modules/RNO_G/channelBlockOffsetFitter.py | 104 +++++++++--------- 1 file changed, 54 insertions(+), 50 deletions(-) diff --git a/NuRadioReco/modules/RNO_G/channelBlockOffsetFitter.py b/NuRadioReco/modules/RNO_G/channelBlockOffsetFitter.py index eeb34e87d..4467fd0d8 100644 --- a/NuRadioReco/modules/RNO_G/channelBlockOffsetFitter.py +++ b/NuRadioReco/modules/RNO_G/channelBlockOffsetFitter.py @@ -184,8 +184,8 @@ def _pedestal_fit(self, a): def fit_block_offsets( trace, block_size=128, sampling_rate=3.2*units.GHz, - max_frequency=50*units.MHz, return_trace = False, - xtol=1e-6, maxiter=100000): + max_frequency=50*units.MHz, mode='fit', return_trace = False, + tol=1e-6,): """ Fit 'block' offsets for a voltage trace @@ -204,6 +204,10 @@ def fit_block_offsets( the fit to the block offsets is performed in the frequency domain, in the band up to max_frequency + mode: 'fit' | 'approximate' + Whether to fit the block offsets (default) + or just use the first guess from the out-of-band + component (faster) return_trace: bool (default: False) if True, return the tuple (offsets, output_trace) where the output_trace is the input trace with @@ -219,11 +223,8 @@ def fit_block_offsets( Other Parameters ---------------- - xtol: float (default: 1e-6) - tolerance parameter passed on to scipy.optimize.fmin - maxiter: int (default: 100000) - maximum number of iterations for scipy.optimize.fmin - + tol: float (default: 1e-6) + tolerance parameter passed on to scipy.optimize.minimize """ dt = 1. / sampling_rate spectrum = fft.time2freq(trace, sampling_rate) @@ -245,49 +246,52 @@ def fit_block_offsets( np.mean(filtered_trace[i*block_size:(i+1)*block_size]) for i in range(n_blocks) ]) - # self._offset_guess[channel_id] = a_guess - # we can get rid of one parameter through a global shift - a_guess = a_guess[:-1] - a_guess[-1] - - # we perform the fit out-of-band, in order to avoid - # distorting any actual signal - - # most of the terms in the fit depend only on the frequencies, - # sampling rate and number of blocks. We therefore calculate these - # only once, outside the fit function. - pre_factor_exponent = np.array([ - -2.j * np.pi * frequencies_oob * dt * ((j+.5) * block_size - .5) - for j in range(len(a_guess)) - ]) - const_fft_term = ( - 1 / sampling_rate * np.sqrt(2) # NuRadio FFT normalization - * np.exp(pre_factor_exponent) - * np.sin(np.pi*frequencies_oob*block_size*dt)[None] - / np.sin(np.pi*frequencies_oob*dt)[None] - ) - - def pedestal_fit(a): - fit = np.sum(a[:, None] * const_fft_term, axis=0) - chi2 = np.sum(np.abs(fit-spectrum_oob)**2) - return chi2 - - # self._spectrum = spectrum_oob - res = scipy.optimize.fmin( - pedestal_fit, a_guess, disp=0, - xtol=xtol, maxiter=maxiter) - ### maybe TODO - include option to use Minuit, which seems a lot quicker? - # m = Minuit(self._pedestal_fit_minuit, a_guess * nufft_conversion_factor) - # m.errordef = 1 - # m.errors = 0.01 * np.ones_like(a_guess) - # m.migrad(ncall=20000) - # res = m.values - - block_offsets = np.zeros(len(res) + 1) - block_offsets[:-1] = res - - # the fit is not sensitive to an overall shift, - # so we include the zero-meaning here - block_offsets += np.mean(trace) - np.mean(block_offsets) + if mode == 'approximate': + block_offsets = a_guess + elif mode == 'fit': + # self._offset_guess[channel_id] = a_guess + # we can get rid of one parameter through a global shift + a_guess = a_guess[:-1] - a_guess[-1] + + # we perform the fit out-of-band, in order to avoid + # distorting any actual signal + + # most of the terms in the fit depend only on the frequencies, + # sampling rate and number of blocks. We therefore calculate these + # only once, outside the fit function. + pre_factor_exponent = np.array([ + -2.j * np.pi * frequencies_oob * dt * ((j+.5) * block_size - .5) + for j in range(len(a_guess)) + ]) + const_fft_term = ( + 1 / sampling_rate * np.sqrt(2) # NuRadio FFT normalization + * np.exp(pre_factor_exponent) + * np.sin(np.pi*frequencies_oob*block_size*dt)[None] + / np.sin(np.pi*frequencies_oob*dt)[None] + ) + + def pedestal_fit(a): + fit = np.sum(a[:, None] * const_fft_term, axis=0) + chi2 = np.sum(np.abs(fit-spectrum_oob)**2) + return chi2 + + # self._spectrum = spectrum_oob + res = scipy.optimize.minimize(pedestal_fit, a_guess, tol=tol).x + ### maybe TODO - include option to use Minuit, which seems a lot quicker? + # m = Minuit(self._pedestal_fit_minuit, a_guess * nufft_conversion_factor) + # m.errordef = 1 + # m.errors = 0.01 * np.ones_like(a_guess) + # m.migrad(ncall=20000) + # res = m.values + + block_offsets = np.zeros(len(res) + 1) + block_offsets[:-1] = res + + # the fit is not sensitive to an overall shift, + # so we include the zero-meaning here + block_offsets += np.mean(trace) - np.mean(block_offsets) + else: + raise ValueError(f'Invalid value for mode={mode}. Accepted values are {{"fit", "approximate"}}') if return_trace: output_trace = trace - np.repeat(block_offsets, block_size) From 76a2a37369a41b2cfcf64e509ef9baf0bc4cd2be Mon Sep 17 00:00:00 2001 From: Sjoerd Bouma Date: Thu, 6 Apr 2023 16:26:42 +0200 Subject: [PATCH 228/418] enable channel/trigger-specific readout windows --- NuRadioReco/modules/triggerTimeAdjuster.py | 30 +++++++++++++++++++--- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/NuRadioReco/modules/triggerTimeAdjuster.py b/NuRadioReco/modules/triggerTimeAdjuster.py index 01f893e5d..9c8567ce2 100644 --- a/NuRadioReco/modules/triggerTimeAdjuster.py +++ b/NuRadioReco/modules/triggerTimeAdjuster.py @@ -29,9 +29,16 @@ def begin(self, trigger_name=None, pre_trigger_time=55. * units.ns): If trigger_name is None, the trigger with the smalles trigger_time will be used. If a name is give, corresponding trigger module must be run beforehand. If the trigger does not exist or did not trigger, this module will do nothing - pre_trigger_time: float - Amount of time that should be stored in the channel trace before the trigger. If the channel trace is long - enough, it will be cut accordingly. Otherwise, it will be rolled. + pre_trigger_time: float or dict + Amount of time that should be stored in the channel trace before the trigger. + If the channel trace is long enough, it will be cut accordingly. + Otherwise, it will be rolled. + + If given as a float, the same ``pre_trigger_time`` will be used for all channels. + If a dict, the keys should be ``channel_id``, and the values the ``pre_trigger_time`` + to use for each channel. Alternatively, the keys should be the ``trigger_name``, + and the values either a float or a dictionary with (``channel_id``, ``pre_trigger_time``) + pairs. """ self.__trigger_name = trigger_name self.__pre_trigger_time = pre_trigger_time @@ -69,7 +76,22 @@ def run(self, event, station, detector): sampling_rate = channel.get_sampling_rate() trigger_time_sample = int(np.round(trigger_time_channel * sampling_rate)) # logger.debug(f"channel {channel.get_id()}: trace_start_time = {channel.get_trace_start_time():.1f}ns, trigger time channel {trigger_time_channel/units.ns:.1f}ns, trigger time sample = {trigger_time_sample}") - samples_before_trigger = int(self.__pre_trigger_time * sampling_rate) + pre_trigger_time = self.__pre_trigger_time + channel_id = channel.get_id() + trigger_name = trigger.get_name() + while isinstance(pre_trigger_time, dict): + if trigger_name in pre_trigger_time.keys(): # keys are different triggers + pre_trigger_time = pre_trigger_time[trigger_name] + elif channel_id in pre_trigger_time: # keys are channel_ids + pre_trigger_time = pre_trigger_time[channel_id] + else: + logger.error( + 'pre_trigger_time was specified as a dictionary, ' + f'but the neither the trigger_name {trigger_name} ' + f'nor the channel id {channel_id} are present as keys' + ) + raise KeyError + samples_before_trigger = int(pre_trigger_time * sampling_rate) rel_station_time_samples = 0 cut_samples_beginning = 0 if(samples_before_trigger < trigger_time_sample): From fdd3dc8f5fe1f207fa17f431a9d51804d0ede416 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Fri, 21 Apr 2023 13:18:25 +0200 Subject: [PATCH 229/418] Small fix in begin() --- NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py b/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py index 19d391d14..d837fdc7b 100644 --- a/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py +++ b/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py @@ -223,6 +223,10 @@ def begin(self, if selectors is not None: if not isinstance(selectors, (list, np.ndarray)): selectors = [selectors] + + self.logger.info(f"Found {len(selectors)} selector(s)") + + self._selectors = selectors if select_triggers is not None: if isinstance(select_triggers, str): @@ -230,9 +234,6 @@ def begin(self, else: for select_trigger in select_triggers: selectors.append(lambda eventInfo: eventInfo.triggerType == select_trigger) - - self._selectors = selectors - self.logger.info(f"Found {len(self._selectors)} selector(s)") self._time_begin = 0 self._time_run = 0 From fe2d69f860fef9ed280c46321c5d095b08aa98c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Fri, 21 Apr 2023 13:48:31 +0200 Subject: [PATCH 230/418] Rename functions, implement get_event(event_id) method --- .../modules/io/rno_g/readRNOGDataMattak.py | 104 ++++++++++++++---- .../measured_noise/RNO_G/noiseImporter.py | 2 +- 2 files changed, 85 insertions(+), 21 deletions(-) diff --git a/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py b/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py index d837fdc7b..2c0ac3098 100644 --- a/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py +++ b/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py @@ -240,6 +240,7 @@ def begin(self, self.__counter = 0 self.__skipped = 0 + self._event_informations = None self._datasets = [] self.__n_events_per_dataset = [] @@ -344,7 +345,7 @@ def __get_dataset_for_event(self, event_idx): event_index: int Same as in read_event(). - Retruns + Returns ------- dataset: mattak.Dataset.Dataset @@ -388,7 +389,7 @@ def filter_event(self, evtinfo, event_idx=None): return False - def get_event_information_dict(self, keys=["station", "run"]): + def get_event_informations(self, keys=["station", "run", "eventNumber"]): """ Return information of all events from the EventInfo This function is useful to make a pre-selection of events before actually reading them in combination with @@ -400,7 +401,7 @@ def get_event_information_dict(self, keys=["station", "run"]): keys: list(str) List of the information to receive from each event. Have to match the attributes (member variables) of the mattak.Dataset.EventInfo class (examples are "station", "run", "triggerTime", "triggerType", "eventNumber", ...). - (Default: ["station", "run"]) + (Default: ["station", "run", "eventNumber"]) Returns ------- @@ -410,26 +411,39 @@ def get_event_information_dict(self, keys=["station", "run"]): them self containing the information specified with "keys" parameter. """ - data = {} - n_prev = 0 - for dataset in self._datasets: - dataset.setEntries((0, dataset.N())) - - for idx, evtinfo in enumerate(dataset.eventInfo()): # returns a list + # Read if dict is None ... + do_read = self._event_informations is None - event_idx = idx + n_prev # event index accross all datasets combined - - if self.filter_event(evtinfo, event_idx): - continue - - data[event_idx] = {key: getattr(evtinfo, key) for key in keys} + if not do_read: + # ... or when it does not have the desired information + first_event_info = next(iter(self._event_informations)) + print(first_event_info) + for key in keys: + if key not in list(first_event_info.keys()): + do_read = True + + if do_read: + + self._event_informations = {} + n_prev = 0 + for dataset in self._datasets: + dataset.setEntries((0, dataset.N())) + + for idx, evtinfo in enumerate(dataset.eventInfo()): # returns a list - n_prev += dataset.N() + event_idx = idx + n_prev # event index accross all datasets combined + + if self.filter_event(evtinfo, event_idx): + continue + + self._event_informations[event_idx] = {key: getattr(evtinfo, key) for key in keys} + + n_prev += dataset.N() - return data + return self._event_informations - def get_event(self, event_info, waveforms): + def _get_event(self, event_info, waveforms): """ Return a NuRadioReco event Parameters @@ -516,7 +530,7 @@ def run(self): waveforms_of_event = wfs[idx] - evt = self.get_event(evtinfo, waveforms_of_event) + evt = self._get_event(evtinfo, waveforms_of_event) self._time_run += time.time() - t0 self.__counter += 1 @@ -553,12 +567,62 @@ def read_event(self, event_index): # access data waveforms = dataset.wfs() - evt = self.get_event(event_info, waveforms) + evt = self._get_event(event_info, waveforms) self._time_run += time.time() - t0 self.__counter += 1 return evt + + + def get_event(self, event_id): + """ Allows to read a specific event identifed by its id + + Parameters + ---------- + + event_id: int + Event Id + + Returns + ------- + + evt: NuRadioReco.framework.event + """ + + self.logger.debug(f"Processing event {event_id}") + t0 = time.time() + + event_infos = self.get_event_informations(keys=["eventNumber"]) + event_idx_ids = np.array([[index, ele["eventNumber"]] for index, ele in event_infos.items()]) + mask = event_idx_ids[:, 1] == event_id + + if not np.any(mask): + self.logger.info(f"Could not find event with id: {event_id}.") + return None + elif np.sum(mask) > 1: + self.logger.error(f"Found several events with the same id: {event_id}.") + raise ValueError(f"Found several events with the same id: {event_id}.") + else: + pass + + event_index = event_idx_ids[mask, 0][0] + + dataset = self.__get_dataset_for_event(event_index) + event_info = dataset.eventInfo() # returns a single eventInfo + + if self.filter_event(event_info, event_index): + return None + + # access data + waveforms = dataset.wfs() + + evt = self._get_event(event_info, waveforms) + + self._time_run += time.time() - t0 + self.__counter += 1 + + return evt def end(self): diff --git a/NuRadioReco/modules/measured_noise/RNO_G/noiseImporter.py b/NuRadioReco/modules/measured_noise/RNO_G/noiseImporter.py index 6f9460716..a65617887 100644 --- a/NuRadioReco/modules/measured_noise/RNO_G/noiseImporter.py +++ b/NuRadioReco/modules/measured_noise/RNO_G/noiseImporter.py @@ -98,7 +98,7 @@ def begin(self, noise_folders, file_pattern="*", self.logger.info("Get event informations ...") # instead of reading all noise events into memory we only get certain information here and read all data in run() - noise_information = self._noise_reader.get_event_information_dict(keys=["station"]) + noise_information = self._noise_reader.get_event_informations(keys=["station"]) self.__event_index_list = np.array(list(noise_information.keys())) self.__station_id_list = np.array([ele["station"] for ele in noise_information.values()]) From 22ba95814a3c155881bdbc63c3dd8da48b91d825 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Fri, 21 Apr 2023 14:08:02 +0200 Subject: [PATCH 231/418] Improve doc string --- .../modules/io/rno_g/readRNOGDataMattak.py | 42 ++++++++++++------- 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py b/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py index 2c0ac3098..a2523d29e 100644 --- a/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py +++ b/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py @@ -109,17 +109,19 @@ def get_time_offset(trigger_type): class readRNOGData: def begin(self, - data_dirs, log_level=logging.INFO, selectors=None, + data_dirs, read_calibrated_data=False, - apply_baseline_correction=True, - convert_to_voltage=True, select_triggers=None, select_runs=True, + apply_baseline_correction=True, + convert_to_voltage=True, + selectors=None, run_table_path=None, run_types=["physics"], run_time_range=None, max_trigger_rate=1 * units.Hz, - mattak_backend="auto"): + mattak_backend="auto", + log_level=logging.INFO): """ Parameters @@ -128,17 +130,22 @@ def begin(self, data_dirs: list of strings / string Path to run directories (i.e. ".../stationXX/runXXX/") - log_level: enum - Set verbosity level of logger - - selectors: list of lambdas - List of lambda(eventInfo) -> bool to pass to mattak.Dataset.iterate to select events. - Example: trigger_selector = lambda eventInfo: eventInfo.triggerType == "FORCE" - read_calibrated_data: bool If True, read calibrated waveforms from Mattak.Dataset. If False, read "raw" ADC traces. (temp. Default: False) - + + select_triggers: str or list(str) + Names of triggers which should be selected. Convinence interface instead of passing a selector + (see "selectors" below. (Default: None) + + select_runs: bool + If True, use information in run_table to select runs (based on run_type, run_time, trigger_rate, ...). + If the run_table is not available no selection is performed (and the programm is not interrupted, + only an error message is raised). See parameters to configure run selection. (Default: True) + + Other Parameters + ---------------- + apply_baseline_correction: bool Only applies when non-calibrated data are read. If true, correct for DC offset. (Default: True) @@ -146,10 +153,10 @@ def begin(self, convert_to_voltage: bool Only applies when non-calibrated data are read. If true, convert ADC to voltage. (Default: True) - - select_runs: bool - If True, use information in run_table to select runs (based on run_type, run_time, trigger_rate, ...). If the run_table is - not available no selection is performed (and the programm is not interrupted, only an error message is raised). (Default: True) + + selectors: list of lambdas + List of lambda(eventInfo) -> bool to pass to mattak.Dataset.iterate to select events. + Example: trigger_selector = lambda eventInfo: eventInfo.triggerType == "FORCE" run_table_path: str Path to a run_table.cvs file. If None, the run table is queried from the DB. (Default: None) @@ -170,6 +177,9 @@ def begin(self, mattak_backend: str Select a mattak backend. Options are "auto", "pyroot", "uproot". If "auto" is selected, pyroot is used if available otherwise a "fallback" to uproot is used. (Default: "auto") + + log_level: enum + Set verbosity level of logger """ t0 = time.time() From 9b8528dbeeff8b48e7b5f3b112353e7086640b2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Sun, 23 Apr 2023 17:38:30 +0200 Subject: [PATCH 232/418] Change default max. trigger rate --- NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py b/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py index a2523d29e..3103f1f3a 100644 --- a/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py +++ b/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py @@ -119,7 +119,7 @@ def begin(self, run_table_path=None, run_types=["physics"], run_time_range=None, - max_trigger_rate=1 * units.Hz, + max_trigger_rate=0 * units.Hz, mattak_backend="auto", log_level=logging.INFO): """ From 2740c072985e7bb8af93f2632fba8aef1d9ea221 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Sun, 23 Apr 2023 17:39:03 +0200 Subject: [PATCH 233/418] Rename function and variable --- .../modules/io/rno_g/readRNOGDataMattak.py | 16 ++++++++-------- .../measured_noise/RNO_G/noiseImporter.py | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py b/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py index 3103f1f3a..807ae6801 100644 --- a/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py +++ b/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py @@ -250,7 +250,7 @@ def begin(self, self.__counter = 0 self.__skipped = 0 - self._event_informations = None + self._events_information = None self._datasets = [] self.__n_events_per_dataset = [] @@ -399,7 +399,7 @@ def filter_event(self, evtinfo, event_idx=None): return False - def get_event_informations(self, keys=["station", "run", "eventNumber"]): + def get_events_information(self, keys=["station", "run", "eventNumber"]): """ Return information of all events from the EventInfo This function is useful to make a pre-selection of events before actually reading them in combination with @@ -422,11 +422,11 @@ def get_event_informations(self, keys=["station", "run", "eventNumber"]): """ # Read if dict is None ... - do_read = self._event_informations is None + do_read = self._events_information is None if not do_read: # ... or when it does not have the desired information - first_event_info = next(iter(self._event_informations)) + first_event_info = next(iter(self._events_information)) print(first_event_info) for key in keys: if key not in list(first_event_info.keys()): @@ -434,7 +434,7 @@ def get_event_informations(self, keys=["station", "run", "eventNumber"]): if do_read: - self._event_informations = {} + self._events_information = {} n_prev = 0 for dataset in self._datasets: dataset.setEntries((0, dataset.N())) @@ -446,11 +446,11 @@ def get_event_informations(self, keys=["station", "run", "eventNumber"]): if self.filter_event(evtinfo, event_idx): continue - self._event_informations[event_idx] = {key: getattr(evtinfo, key) for key in keys} + self._events_information[event_idx] = {key: getattr(evtinfo, key) for key in keys} n_prev += dataset.N() - return self._event_informations + return self._events_information def _get_event(self, event_info, waveforms): @@ -603,7 +603,7 @@ def get_event(self, event_id): self.logger.debug(f"Processing event {event_id}") t0 = time.time() - event_infos = self.get_event_informations(keys=["eventNumber"]) + event_infos = self.get_events_information(keys=["eventNumber"]) event_idx_ids = np.array([[index, ele["eventNumber"]] for index, ele in event_infos.items()]) mask = event_idx_ids[:, 1] == event_id diff --git a/NuRadioReco/modules/measured_noise/RNO_G/noiseImporter.py b/NuRadioReco/modules/measured_noise/RNO_G/noiseImporter.py index a65617887..9ae0955de 100644 --- a/NuRadioReco/modules/measured_noise/RNO_G/noiseImporter.py +++ b/NuRadioReco/modules/measured_noise/RNO_G/noiseImporter.py @@ -98,7 +98,7 @@ def begin(self, noise_folders, file_pattern="*", self.logger.info("Get event informations ...") # instead of reading all noise events into memory we only get certain information here and read all data in run() - noise_information = self._noise_reader.get_event_informations(keys=["station"]) + noise_information = self._noise_reader.get_events_information(keys=["station"]) self.__event_index_list = np.array(list(noise_information.keys())) self.__station_id_list = np.array([ele["station"] for ele in noise_information.values()]) From d4ba05deb6a3ed91ffed44c5ba03d970f966cdc3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Sun, 23 Apr 2023 17:40:22 +0200 Subject: [PATCH 234/418] Make function privat --- NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py b/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py index 807ae6801..15f03eee7 100644 --- a/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py +++ b/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py @@ -370,7 +370,7 @@ def __get_dataset_for_event(self, event_idx): return dataset - def filter_event(self, evtinfo, event_idx=None): + def _filter_event(self, evtinfo, event_idx=None): """ Filter an event base on its EventInfo and the configured selectors. Parameters @@ -443,7 +443,7 @@ def get_events_information(self, keys=["station", "run", "eventNumber"]): event_idx = idx + n_prev # event index accross all datasets combined - if self.filter_event(evtinfo, event_idx): + if self._filter_event(evtinfo, event_idx): continue self._events_information[event_idx] = {key: getattr(evtinfo, key) for key in keys} @@ -531,7 +531,7 @@ def run(self): self.logger.debug(f"Processing event number {event_idx} out of total {self._n_events_total}") t0 = time.time() - if self.filter_event(evtinfo, event_idx): + if self._filter_event(evtinfo, event_idx): continue # Just read wfs if necessary @@ -571,7 +571,7 @@ def read_event(self, event_index): dataset = self.__get_dataset_for_event(event_index) event_info = dataset.eventInfo() # returns a single eventInfo - if self.filter_event(event_info, event_index): + if self._filter_event(event_info, event_index): return None # access data @@ -621,7 +621,7 @@ def get_event(self, event_id): dataset = self.__get_dataset_for_event(event_index) event_info = dataset.eventInfo() # returns a single eventInfo - if self.filter_event(event_info, event_index): + if self._filter_event(event_info, event_index): return None # access data From 9ad3bb74b2a82148647e084cbfb5cd57b17ffa17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Sun, 23 Apr 2023 17:44:23 +0200 Subject: [PATCH 235/418] Rename function --- NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py | 2 +- NuRadioReco/modules/measured_noise/RNO_G/noiseImporter.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py b/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py index 15f03eee7..043051ba2 100644 --- a/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py +++ b/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py @@ -549,7 +549,7 @@ def run(self): - def read_event(self, event_index): + def get_event_by_index(self, event_index): """ Allows to read a specific event identifed by its index Parameters diff --git a/NuRadioReco/modules/measured_noise/RNO_G/noiseImporter.py b/NuRadioReco/modules/measured_noise/RNO_G/noiseImporter.py index 9ae0955de..eae85ea2d 100644 --- a/NuRadioReco/modules/measured_noise/RNO_G/noiseImporter.py +++ b/NuRadioReco/modules/measured_noise/RNO_G/noiseImporter.py @@ -128,7 +128,7 @@ def run(self, evt, station, det): # int(..) necessary because pyroot can not handle np.int64 i_noise = int(np.random.choice(self.__event_index_list[station_mask])) self._n_use_event[i_noise] += 1 - noise_event = self._noise_reader.read_event(i_noise) + noise_event = self._noise_reader.get_event_by_index(i_noise) station_id = noise_event.get_station_ids()[0] noise_station = noise_event.get_station(station_id) From cfaea77b3496f7441cb27a03a7cc9aa564cf20ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Sun, 23 Apr 2023 17:50:18 +0200 Subject: [PATCH 236/418] Correct import after renaming --- NuRadioReco/modules/measured_noise/RNO_G/noiseImporter.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NuRadioReco/modules/measured_noise/RNO_G/noiseImporter.py b/NuRadioReco/modules/measured_noise/RNO_G/noiseImporter.py index eae85ea2d..16fa0cfe5 100644 --- a/NuRadioReco/modules/measured_noise/RNO_G/noiseImporter.py +++ b/NuRadioReco/modules/measured_noise/RNO_G/noiseImporter.py @@ -4,7 +4,7 @@ import random import collections -from NuRadioReco.modules.io.rno_g.readRNOGDataMattak import readRNOGData +from NuRadioReco.modules.io.RNO_G.readRNOGDataMattak import readRNOGData from NuRadioReco.modules.base.module import register_run from NuRadioReco.utilities import units From 8bef940016eca205e11ada6c324543ae61e6b5fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Sun, 23 Apr 2023 17:55:11 +0200 Subject: [PATCH 237/418] Renamed directory, removed old reader classes/files --- .../modules/io/{rno_g => RNO_G}/__init__.py | 0 .../io/{rno_g => RNO_G}/readRNOGDataMattak.py | 0 NuRadioReco/modules/io/rno_g/readRNOGData.py | 224 ------------------ .../modules/io/rno_g/rnogDataReader.py | 126 ---------- 4 files changed, 350 deletions(-) rename NuRadioReco/modules/io/{rno_g => RNO_G}/__init__.py (100%) rename NuRadioReco/modules/io/{rno_g => RNO_G}/readRNOGDataMattak.py (100%) delete mode 100755 NuRadioReco/modules/io/rno_g/readRNOGData.py delete mode 100644 NuRadioReco/modules/io/rno_g/rnogDataReader.py diff --git a/NuRadioReco/modules/io/rno_g/__init__.py b/NuRadioReco/modules/io/RNO_G/__init__.py similarity index 100% rename from NuRadioReco/modules/io/rno_g/__init__.py rename to NuRadioReco/modules/io/RNO_G/__init__.py diff --git a/NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py b/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py similarity index 100% rename from NuRadioReco/modules/io/rno_g/readRNOGDataMattak.py rename to NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py diff --git a/NuRadioReco/modules/io/rno_g/readRNOGData.py b/NuRadioReco/modules/io/rno_g/readRNOGData.py deleted file mode 100755 index e1fc23d08..000000000 --- a/NuRadioReco/modules/io/rno_g/readRNOGData.py +++ /dev/null @@ -1,224 +0,0 @@ -import NuRadioReco.framework.event -from NuRadioReco.modules.base.module import register_run -import NuRadioReco.framework.station -import NuRadioReco.framework.channel -import NuRadioReco.framework.trigger -import NuRadioReco.modules.channelSignalReconstructor -signal_reconstructor = NuRadioReco.modules.channelSignalReconstructor.channelSignalReconstructor() - -import uproot -# default uproot readout is awkward arrays, but requires awkward package installed. RNOG data format does not require this. Use numpy instead. -uproot.default_library = "np" - -import numpy as np -from NuRadioReco.utilities import units -import sys -import os -import logging -import time -from scipy import interpolate -import six -from collections import OrderedDict -import astropy.time - - -class readRNOGData: - """ - This is the data reader for RNO-G. Reads RNO-G data from ROOT format using uproot - """ - def __init__(self): - self.logger = logging.getLogger("NuRadioReco.readRNOGdata") - self.__id_current_event = None - self.__t = None - self.__sampling_rate = 3.2 * units.GHz #TODO: 3.2 at the beginning of deployment. Will change to 2.4 GHz after firmware update eventually, but info not yet contained in the .root files. Read out once available. - self._iterator_data = None - self._iterator_header = None - self._data_treename = "waveforms" - self._header_treename = "header" - self.n_events = None - self.input_files = [] - - def begin(self, input_files, input_files_header=None): - - """ - Begin function of the RNO-G reader - - Parameters - ---------- - input_files: list of paths to files containing waveforms - input_files_header: list of paths to files containing header, - if None, headers are expected to be stored in the input_files also - """ - - self.__id_current_event = -1 - self.__t = time.time() - - if isinstance(input_files, six.string_types): - input_files = [input_files] - if isinstance(input_files_header, six.string_types): - input_files_header = [input_files_header] - if input_files_header is None: - input_files_header = input_files - - self.input_files = input_files - self.input_files_header = input_files_header - - self.n_events = 0 - # get the total number of events of all input files - for filename in input_files: - file = uproot.open(filename) - if 'combined' in file: - file = file['combined'] - self.n_events += file[self._data_treename].num_entries - self._set_iterators() - - return self.n_events - - def _set_iterators(self, cut=None): - """ - Set uproot iterators to loop over event trees - - Parameters - ---------- - cut: str - cut string to apply (e.g. for initial event selection based on event_number, ... - e.g. "(event_number==1)" or "(run_number==1)&(event_number<10)" - """ - self.__id_current_event = -1 - - datadict = OrderedDict() - for filename in self.input_files: - if 'combined' in uproot.open(filename): - datadict[filename] = 'combined/' + self._data_treename - else: - datadict[filename] = self._data_treename - - headerdict = OrderedDict() - for filename in self.input_files_header: - if 'combined' in uproot.open(filename): - headerdict[filename] = 'combined/' + self._header_treename - else: - headerdict[filename] = self._header_treename - - # iterator over single events (step 1), for event looping in NuRadioReco dataformat - # may restrict which data to read in the iterator by adding second argument - # read_branches = ['run_number', 'event_number', 'station_number', 'radiant_data[24][2048]'] - self._iterator_data = uproot.iterate(datadict, cut=cut,step_size=1, how=dict, library="np") - self._iterator_header = uproot.iterate(headerdict, cut=cut, step_size=1, how=dict, library="np") - - self.uproot_iterator_data = uproot.iterate(datadict, cut=cut, step_size=1000) - self.uproot_iterator_header = uproot.iterate(headerdict, cut=cut, step_size=1000) - - @register_run() - def run(self, channels=np.arange(24), event_numbers=None, run_numbers=None, cut_string=None): - """ - Run function of the RNOG reader - - Parameters - ---------- - n_channels: int - number of RNOG channels to loop over, default 24 - - event_numbers: None or dict - if dict, use a dict with run number as key and list of event numbers as items - - run_numbers: None or list - list of run numbers to select - Caveat: use only if event_numbers are not set - - cut_string: string - selection string for event pre-selection - Cavieat: use only if event_numbers and run_numbers are not set - """ - - # generate cut string based on passed event_numbers or run_numbers parameters - if not run_numbers is None: - event_cuts = "|".join(["(run_number==%i)" for run_number in run_numbers]) - cut_string = "|".join(event_cuts) - if not event_numbers is None: - event_cuts = [] - for run in event_numbers: - events = event_numbers[run] - for event in events: - event_cuts.append("(run_number==%i)&(event_number==%i)" %(run, event)) - cut_string = "|".join(event_cuts) - self.cut_string = cut_string - - self._set_iterators(cut=self.cut_string) - root_trigger_keys = [ - 'trigger_info.rf_trigger', 'trigger_info.force_trigger', - 'trigger_info.pps_trigger', 'trigger_info.ext_trigger', - 'trigger_info.radiant_trigger', 'trigger_info.lt_trigger', - 'trigger_info.surface_trigger' - ] - self.__t = time.time() - # Note: reading single events is inefficient... - # for event_header, event in zip(self._iterator_header, self._iterator_data): - for event_headers, events in zip(self.uproot_iterator_header, self.uproot_iterator_data): - for event_header, event in zip(event_headers, events): - self.__id_current_event += 1 - #if self.__id_current_event >= self.n_events: - # # all events processed, but iterator should stop before anyways. - # break - if self.__id_current_event % 1000 == 0: - progress = 1. * self.__id_current_event / self.n_events - eta = 0 - if self.__id_current_event > 0: - eta = (time.time() - self.__t) / self.__id_current_event * (self.n_events - self.__id_current_event) / 60. - self.logger.warning("reading in event {}/{} ({:.0f}%) ETA: {:.1f} minutes".format(self.__id_current_event, self.n_events, 100 * progress, eta)) - - run_number = event["run_number"] - evt_number = event["event_number"] - station_id = event_header["station_number"] - self.logger.info("Reading Run: {run_number}, Event {evt_number}, Station {station_id}") - - evt = NuRadioReco.framework.event.Event(run_number, evt_number) - station = NuRadioReco.framework.station.Station(station_id) - #TODO in future: do need to apply calibrations? - - unix_time = event_header["trigger_time"] - event_time = astropy.time.Time(unix_time, format='unix') - - station.set_station_time(event_time) - for trigger_key in root_trigger_keys: - try: - has_triggered = bool(event_header[trigger_key]) - trigger = NuRadioReco.framework.trigger.Trigger(trigger_key.split('.')[-1]) - trigger.set_triggered(has_triggered) - station.set_trigger(trigger) - except ValueError: - pass - - radiant_data = event["radiant_data[24][2048]"] # returns array of n_channels, n_points - # Loop over all requested channels in data - for chan in channels: - channel = NuRadioReco.framework.channel.Channel(chan) - - # Get data from array via graph method - voltage = np.array(radiant_data[chan]) * units.mV - #times = np.arange(len(voltage)) * sampling - - if voltage.shape[0] % 2 != 0: - voltage = voltage[:-1] - - #TODO: need to subtract mean... probably not if running signal reconstructor? - #channel.set_trace(voltage-np.mean(voltage), sampling_rate) - channel.set_trace(voltage, self.__sampling_rate) - station.add_channel(channel) - evt.set_station(station) - # we want to have access to basic signal quantities with implementation from NuRadioReco - #TODO: maybe this should be run in external module? - signal_reconstructor.run(evt, station, None) - yield evt - - def get_events(self): - return self.run() - - def get_n_events(self): - return self.n_events - - def get_filenames(self): - return self.input_files - - def end(self): - pass diff --git a/NuRadioReco/modules/io/rno_g/rnogDataReader.py b/NuRadioReco/modules/io/rno_g/rnogDataReader.py deleted file mode 100644 index cea0be080..000000000 --- a/NuRadioReco/modules/io/rno_g/rnogDataReader.py +++ /dev/null @@ -1,126 +0,0 @@ -import numpy as np -import uproot -import NuRadioReco.framework.event -import NuRadioReco.framework.station -import NuRadioReco.framework.channel -from NuRadioReco.utilities import units -import astropy.time -import glob -import logging -import time -from functools import lru_cache -import six -import NuRadioReco.utilities.metaclasses - -logger = logging.getLogger("RNO-G_IO") -# logger.setLevel(logging.DEBUG) - -# @six.add_metaclass(NuRadioReco.utilities.metaclasses.Singleton) # maybe? -class RNOGDataReader: - - def __init__(self, filenames, *args, **kwargs): - logger.debug("Initializing RNOGDataReader") - self.__filenames = filenames - self.__event_ids = None - self.__sampling_rate = 3.2 * units.GHz #TODO: 3.2 at the beginning of deployment. Will change to 2.4 GHz after firmware update eventually, but info not yet contained in the .root files. Read out once available. - self.__parse_event_ids() - self.__i_events_per_file = np.zeros((len(self.__filenames), 2), dtype=int) - i_event = 0 - for i_file, filename in enumerate(filenames): - file = self.__open_file(filename) - events_in_file = file['waveforms'].num_entries - self.__i_events_per_file[i_file] = [i_event, i_event + events_in_file] - i_event += events_in_file - - self._root_trigger_keys = [ - 'trigger_info.rf_trigger', 'trigger_info.force_trigger', - 'trigger_info.pps_trigger', 'trigger_info.ext_trigger', - 'trigger_info.radiant_trigger', 'trigger_info.lt_trigger', - 'trigger_info.surface_trigger' - ] - - def get_filenames(self): - return self.__filenames - - def get_event_ids(self): - if self.__event_ids is None: - return self.__parse_event_ids() - return self.__event_ids - - def __parse_event_ids(self): - logger.debug('Parsing event ids') - event_ids = np.array([], dtype=int) - run_numbers = np.array([], dtype=int) - for filename in self.__filenames: - file = self.__open_file(filename) - event_ids = np.append(event_ids, file['waveforms']['event_number'].array(library='np').astype(int)) - run_numbers = np.append(run_numbers, file['header']['run_number'].array(library='np').astype(int)) - self.__event_ids = np.array([run_numbers, event_ids]).T - - def __open_file(self, filename): - logger.debug("Opening file {}".format(filename)) - file = uproot.open(filename) - if 'combined' in file: - file = file['combined'] - return file - - def get_n_events(self): - return self.get_event_ids().shape[0] - - # @lru_cache(maxsize=1) # probably not actually relevant outside the data viewer? - def get_event_i(self, i_event): - read_time = time.time() - event = NuRadioReco.framework.event.Event(*self.get_event_ids()[i_event]) - for i_file, filename in enumerate(self.__filenames): - if self.__i_events_per_file[i_file, 0] <= i_event < self.__i_events_per_file[i_file, 1]: - i_event_in_file = i_event - self.__i_events_per_file[i_file, 0] - file = self.__open_file(self.__filenames[i_file]) - station = NuRadioReco.framework.station.Station((file['waveforms']['station_number'].array(library='np', entry_start=i_event_in_file, entry_stop=(i_event_in_file+1))[0])) - # station not set properly in first runs, try from header - if station.get_id() == 0 and 'header' in file: - station = NuRadioReco.framework.station.Station((file['header']['station_number'].array(library='np', entry_start=i_event_in_file, entry_stop=(i_event_in_file+1))[0])) - station.set_is_neutrino() - - if 'header' in file: - unix_time = file['header']['readout_time'].array(library='np', entry_start=i_event_in_file, entry_stop=(i_event_in_file+1))[0] - event_time = astropy.time.Time(unix_time, format='unix') - station.set_station_time(event_time) - ### read in basic trigger data - for trigger_key in self._root_trigger_keys: - try: - has_triggered = bool(file['header'][trigger_key].array(library='np', entry_start=i_event_in_file, entry_stop=(i_event_in_file+1))[0]) - trigger = NuRadioReco.framework.trigger.Trigger(trigger_key.split('.')[-1]) - trigger.set_triggered(has_triggered) - # trigger.set_trigger_time(file['header']['trigger_time']) - station.set_trigger(trigger) - except uproot.exceptions.KeyInFileError: - pass - - waveforms = file['waveforms']['radiant_data[24][2048]'].array(library='np', entry_start=i_event_in_file, entry_stop=(i_event_in_file+1)) - for i_channel in range(waveforms.shape[1]): - channel = NuRadioReco.framework.channel.Channel(i_channel) - channel.set_trace(waveforms[0, i_channel]*units.mV, self.__sampling_rate) - station.add_channel(channel) - event.set_station(station) - logger.debug("Spent {:.0f} ms reading event {}".format((time.time()-read_time) * 1e3, i_event)) - return event - return None - - def get_event(self, event_id): - find_event = np.where((self.get_event_ids()[:,0] == event_id[0]) & (self.get_event_ids()[:,1] == event_id[1]))[0] - if len(find_event) == 0: - return None - elif len(find_event) == 1: - return self.get_event_i(find_event[0]) - else: - raise RuntimeError('There are multiple events with the ID [{}, {}] in the file'.format(event_id[0], event_id[1])) - - def get_events(self): - for ev_i in range(self.get_n_events()): - yield self.get_event_i(ev_i) - - def get_detector(self): - return None - - def get_header(self): - return None From b097ff14c0b13ea42417d4d2d67aa2a1a53e038a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Mon, 24 Apr 2023 13:53:09 +0200 Subject: [PATCH 238/418] Refactor/cosmetics base_trace.py --- NuRadioReco/framework/base_trace.py | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/NuRadioReco/framework/base_trace.py b/NuRadioReco/framework/base_trace.py index 0b735967f..c79c86c29 100644 --- a/NuRadioReco/framework/base_trace.py +++ b/NuRadioReco/framework/base_trace.py @@ -36,7 +36,7 @@ def get_trace(self): trace: np.array of floats the time trace """ - if(not self.__time_domain_up_to_date): + if not self.__time_domain_up_to_date: self._time_trace = fft.freq2time(self._frequency_spectrum, self._sampling_rate) self.__time_domain_up_to_date = True self._frequency_spectrum = None @@ -62,10 +62,10 @@ def get_filtered_trace(self, passband, filter_type='butter', order=10, rp=None): return fft.freq2time(spec, self.get_sampling_rate()) def get_frequency_spectrum(self): - if(self.__time_domain_up_to_date): + if self.__time_domain_up_to_date: self._frequency_spectrum = fft.time2freq(self._time_trace, self._sampling_rate) self._time_trace = None -# logger.debug("frequency spectrum has shape {}".format(self._frequency_spectrum.shape)) + # logger.debug("frequency spectrum has shape {}".format(self._frequency_spectrum.shape)) self.__time_domain_up_to_date = False return np.copy(self._frequency_spectrum) @@ -82,7 +82,8 @@ def set_trace(self, trace, sampling_rate): """ if trace is not None: if trace.shape[trace.ndim - 1] % 2 != 0: - raise ValueError('Attempted to set trace with an uneven number ({}) of samples. Only traces with an even number of samples are allowed.'.format(trace.shape[trace.ndim - 1])) + raise ValueError(('Attempted to set trace with an uneven number ({}) of samples. ' + 'Only traces with an even number of samples are allowed.').format(trace.shape[trace.ndim - 1])) self.__time_domain_up_to_date = True self._time_trace = np.copy(trace) self._sampling_rate = sampling_rate @@ -109,9 +110,10 @@ def get_times(self): try: length = self.get_number_of_samples() times = np.arange(0, length / self._sampling_rate - 0.1 / self._sampling_rate, 1. / self._sampling_rate) + self._trace_start_time - if(len(times) != length): - logger.error("time array does not have the same length as the trace. n_samples = {:d}, sampling rate = {:.5g}".format(length, self._sampling_rate)) - raise ValueError("time array does not have the same length as the trace") + if len(times) != length: + err = f"time array does not have the same length as the trace. n_samples = {length:d}, sampling rate = {self._sampling_rate:.5g}" + logger.error(err) + raise ValueError(err) except: times = np.array([]) return times @@ -148,7 +150,7 @@ def get_number_of_samples(self): n_samples: int number of samples in time domain """ - if(self.__time_domain_up_to_date): + if self.__time_domain_up_to_date: length = self._time_trace.shape[-1] # returns the correct length independent of the dimension of the array (channels are 1dim, efields are 3dim) else: length = (self._frequency_spectrum.shape[-1] - 1) * 2 @@ -184,12 +186,14 @@ def resample(self, sampling_rate): if resampling_factor.numerator != 1: # resample and use axis -1 since trace might be either shape (N) for analytic trace or shape (3,N) for E-field resampled_trace = scipy.signal.resample(resampled_trace, resampling_factor.numerator * self.get_number_of_samples(), axis=-1) + if resampling_factor.denominator != 1: # resample and use axis -1 since trace might be either shape (N) for analytic trace or shape (3,N) for E-field resampled_trace = scipy.signal.resample(resampled_trace, np.shape(resampled_trace)[-1] // resampling_factor.denominator, axis=-1) if resampled_trace.shape[-1] % 2 != 0: resampled_trace = resampled_trace.T[:-1].T + self.set_trace(resampled_trace, sampling_rate) def serialize(self): @@ -201,7 +205,7 @@ def serialize(self): def deserialize(self, data_pkl): data = pickle.loads(data_pkl) self.set_trace(data['time_trace'], data['sampling_rate']) - if('trace_start_time' in data.keys()): + if 'trace_start_time' in data.keys(): self.set_trace_start_time(data['trace_start_time']) def __add__(self, x): @@ -214,10 +218,13 @@ def __add__(self, x): # Some sanity checks if not isinstance(x, BaseTrace): raise TypeError('+ operator is only defined for 2 BaseTrace objects') + if self.get_trace() is None or x.get_trace() is None: raise ValueError('One of the trace objects has no trace set') + if self.get_trace().ndim != x.get_trace().ndim: raise ValueError('Traces have different dimensions') + if self.get_sampling_rate() != x.get_sampling_rate(): # Upsample trace with lower sampling rate # Create new baseTrace object for the resampling so we don't change the originals @@ -249,10 +256,12 @@ def __add__(self, x): first_trace = trace_2 second_trace = trace_1 trace_start = x.get_trace_start_time() + # Calculate the difference in the trace start time between the traces and the number of # samples that time difference corresponds to time_offset = np.abs(x.get_trace_start_time() - self.get_trace_start_time()) i_start = int(round(time_offset * sampling_rate)) + # We have to distinguish 2 cases: Trace is 1D (channel) or 2D(E-field) # and treat them differently if trace_1.ndim == 1: @@ -273,11 +282,13 @@ def __add__(self, x): early_trace[:, :first_trace.shape[1]] = first_trace late_trace = np.zeros((second_trace.shape[0], trace_length)) late_trace[:, :second_trace.shape[1]] = second_trace + # Correct for different trace start times by using fourier shift theorem to # shift the later trace backwards. late_trace_object = BaseTrace() late_trace_object.set_trace(late_trace, sampling_rate) late_trace_object.apply_time_shift(time_offset, True) + # Create new BaseTrace object holding the summed traces new_trace = BaseTrace() new_trace.set_trace(early_trace + late_trace_object.get_trace(), sampling_rate) From 7fbdefbf28f4205a7936faeb2eceec0429196211 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Mon, 24 Apr 2023 14:28:29 +0200 Subject: [PATCH 239/418] Change default for select_runs, improve doc string --- NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py b/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py index 043051ba2..97963de61 100644 --- a/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py +++ b/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py @@ -112,7 +112,7 @@ def begin(self, data_dirs, read_calibrated_data=False, select_triggers=None, - select_runs=True, + select_runs=False, apply_baseline_correction=True, convert_to_voltage=True, selectors=None, @@ -132,7 +132,7 @@ def begin(self, read_calibrated_data: bool If True, read calibrated waveforms from Mattak.Dataset. If False, read "raw" ADC traces. - (temp. Default: False) + (temp. Default: False, this can/should be switched once the calibration in incorp. into Mattak) select_triggers: str or list(str) Names of triggers which should be selected. Convinence interface instead of passing a selector @@ -141,7 +141,7 @@ def begin(self, select_runs: bool If True, use information in run_table to select runs (based on run_type, run_time, trigger_rate, ...). If the run_table is not available no selection is performed (and the programm is not interrupted, - only an error message is raised). See parameters to configure run selection. (Default: True) + only an error message is raised). See parameters to configure run selection. (Default: False) Other Parameters ---------------- From 9d41271ca9e38f8f25431e664ce6eeaab80e7317 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Mon, 24 Apr 2023 14:38:46 +0200 Subject: [PATCH 240/418] Fix doc-string, implement random generator --- .../RNO_data/read_data_example/read_rnog.py | 2 +- .../measured_noise/RNO_G/noiseImporter.py | 17 ++++++++++------- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/NuRadioReco/examples/RNO_data/read_data_example/read_rnog.py b/NuRadioReco/examples/RNO_data/read_data_example/read_rnog.py index a88ac77b9..950e8c3cb 100644 --- a/NuRadioReco/examples/RNO_data/read_data_example/read_rnog.py +++ b/NuRadioReco/examples/RNO_data/read_data_example/read_rnog.py @@ -1,4 +1,4 @@ -from NuRadioReco.modules.io.rno_g import readRNOGDataMattak +from NuRadioReco.modules.io.RNO_G import readRNOGDataMattak from NuRadioReco.modules.io import eventWriter from NuRadioReco.utilities import units diff --git a/NuRadioReco/modules/measured_noise/RNO_G/noiseImporter.py b/NuRadioReco/modules/measured_noise/RNO_G/noiseImporter.py index 16fa0cfe5..738fd4b59 100644 --- a/NuRadioReco/modules/measured_noise/RNO_G/noiseImporter.py +++ b/NuRadioReco/modules/measured_noise/RNO_G/noiseImporter.py @@ -1,7 +1,6 @@ import numpy as np import glob import os -import random import collections from NuRadioReco.modules.io.RNO_G.readRNOGDataMattak import readRNOGData @@ -21,7 +20,7 @@ class noiseImporter: def begin(self, noise_folders, file_pattern="*", match_station_id=False, station_ids=None, channel_mapping=None, scramble_noise_file_order=True, - log_level=logging.INFO, reader_kwargs={}): + log_level=logging.INFO, random_seed=None, reader_kwargs={}): """ Parameters @@ -29,8 +28,8 @@ def begin(self, noise_folders, file_pattern="*", noise_folders: str or list(str) Folder(s) containing noise file(s). Search in any subfolder as well. - file_patters: str - File patters used to search for directories, (Default: "*", other examples might be "combined") + file_pattern: str + File pattern used to search for directories, (Default: "*", other examples might be "combined") match_station_id: bool If True, add only noise from stations with the same id. (Default: False) @@ -48,7 +47,10 @@ def begin(self, noise_folders, file_pattern="*", If True, randomize the order of noise files before reading them. (Default: True) log_level: loggging log level - the log level, default logging.INFO + The log level to controll verbosity. (Default: logging.INFO) + + random_seed: int + Seed for the random number generator. (Default: None, no fixed seed). reader_kwargs: dict Optional arguements passed to readRNOGDataMattak @@ -56,6 +58,7 @@ def begin(self, noise_folders, file_pattern="*", self.logger = logging.getLogger('NuRadioReco.RNOG.noiseImporter') self.logger.setLevel(log_level) + self.__random_gen = np.random.Generator(np.random.Philox(random_seed)) self._match_station_id = match_station_id self.__station_ids = station_ids @@ -81,7 +84,7 @@ def begin(self, noise_folders, file_pattern="*", raise ValueError if scramble_noise_file_order: - random.shuffle(self.__noise_folders) + self.__random_gen.shuffle(self.__noise_folders) if "log_level" in reader_kwargs: log_level_reader = reader_kwargs.pop("log_level") @@ -126,7 +129,7 @@ def run(self, evt, station, det): station_mask = np.full_like(self.__event_index_list, True) # int(..) necessary because pyroot can not handle np.int64 - i_noise = int(np.random.choice(self.__event_index_list[station_mask])) + i_noise = int(self.__random_gen.choice(self.__event_index_list[station_mask])) self._n_use_event[i_noise] += 1 noise_event = self._noise_reader.get_event_by_index(i_noise) From ebdcab3535a2e92b92dcfce5d0ed4034247a58b7 Mon Sep 17 00:00:00 2001 From: Sjoerd Bouma Date: Tue, 25 Apr 2023 16:30:06 +0200 Subject: [PATCH 241/418] added mattak, run table and pandas as optional RNO-G dependencies --- pyproject.toml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 577a24204..7fb653fb4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -41,7 +41,6 @@ toml = ">=0.10.2" uproot = "4.1.1" importlib-metadata = {version = ">=4.8.1", python = "<3.8"} numba = "*" -pandas = "*" [tool.poetry.dev-dependencies] Sphinx = "*" @@ -51,9 +50,13 @@ proposal = "7.5.1" pygdsm = {git = "https://github.com/telegraphic/pygdsm"} nifty5 = {git = "https://gitlab.mpcdf.mpg.de/ift/nifty.git", branch="NIFTy_5"} pypocketfft = {git = "https://gitlab.mpcdf.mpg.de/mtr/pypocketfft"} +pandas = "*" +mattak = {git = "https://github.com/RNO-G/mattak"} +runtable = {git = "ssh://git@github.com/RNO-G/rnog-runtable.git"} [tool.poetry.extras] documentation = ["Sphinx", "sphinx-rtd-theme", "numpydoc"] proposal = ["proposal"] galacticnoise = ['pygdsm'] ift_reco = ['nifty5', 'pypocketfft'] +RNO_G_DATA = ["mattak", "runtable", "pandas"] From 22755e68368006ece06584d173c20352e1fd6cab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Tue, 25 Apr 2023 18:49:54 +0200 Subject: [PATCH 242/418] Set meaningful default arguments for MattakReader in NoiseImporter after the default arugments for the MattakReader changed --- .../modules/io/RNO_G/readRNOGDataMattak.py | 6 ++--- .../measured_noise/RNO_G/noiseImporter.py | 24 +++++++++---------- 2 files changed, 13 insertions(+), 17 deletions(-) diff --git a/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py b/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py index 97963de61..ac5da9bdb 100644 --- a/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py +++ b/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py @@ -280,11 +280,9 @@ def begin(self, self._n_events_total = np.sum(self.__n_events_per_dataset) self._time_begin = time.time() - t0 + self.logger.info(f"Using the {self._datasets[0].backend} Mattak backend.") self.logger.info(f"{self._n_events_total} events in {len(self._datasets)} runs/datasets have been found.") - - # Variable not yet implemented in mattak - # self.logger.info(f"Using the {self._datasets[0].backend} Mattak backend.") - + if not self._n_events_total: err = "No runs have been selected. Abort ..." self.logger.error(err) diff --git a/NuRadioReco/modules/measured_noise/RNO_G/noiseImporter.py b/NuRadioReco/modules/measured_noise/RNO_G/noiseImporter.py index 738fd4b59..305bd7fee 100644 --- a/NuRadioReco/modules/measured_noise/RNO_G/noiseImporter.py +++ b/NuRadioReco/modules/measured_noise/RNO_G/noiseImporter.py @@ -85,22 +85,20 @@ def begin(self, noise_folders, file_pattern="*", if scramble_noise_file_order: self.__random_gen.shuffle(self.__noise_folders) - - if "log_level" in reader_kwargs: - log_level_reader = reader_kwargs.pop("log_level") - else: - log_level_reader = log_level - - self._noise_reader = readRNOGData() - selectors = [lambda einfo: einfo.triggerType == "FORCE"] - self._noise_reader.begin(self.__noise_folders, selectors=selectors, - log_level=log_level_reader, - **reader_kwargs) + self._noise_reader = readRNOGData() + + default_reader_kwargs = { + "selectors": [lambda einfo: einfo.triggerType == "FORCE"], + "log_level": log_level, "select_runs": True, "max_trigger_rate": 2 * units.Hz, + "run_types": ["physics"] + } + default_reader_kwargs.update(reader_kwargs) + + self._noise_reader.begin(self.__noise_folders, **default_reader_kwargs) - self.logger.info("Get event informations ...") # instead of reading all noise events into memory we only get certain information here and read all data in run() - + self.logger.info("Get event informations ...") noise_information = self._noise_reader.get_events_information(keys=["station"]) self.__event_index_list = np.array(list(noise_information.keys())) self.__station_id_list = np.array([ele["station"] for ele in noise_information.values()]) From 14c897abeb55fee47e6e83decc3c8e6b7f1078a4 Mon Sep 17 00:00:00 2001 From: Sjoerd Bouma Date: Wed, 26 Apr 2023 10:23:15 +0200 Subject: [PATCH 243/418] update eventbrowser dataprovider --- NuRadioReco/eventbrowser/dataprovider_root.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/NuRadioReco/eventbrowser/dataprovider_root.py b/NuRadioReco/eventbrowser/dataprovider_root.py index fedb8a57f..0782ccb29 100644 --- a/NuRadioReco/eventbrowser/dataprovider_root.py +++ b/NuRadioReco/eventbrowser/dataprovider_root.py @@ -1,4 +1,4 @@ -import NuRadioReco.modules.io.rno_g.rnogDataReader +from NuRadioReco.modules.io.RNO_G.readRNOGDataMattak import readRNOGData class DataProviderRoot(object): @@ -16,11 +16,11 @@ def get_file_handler(self, user_id, filename): if filename is None: return if user_id not in self.__user_instances: - self.__user_instances[user_id] = NuRadioReco.modules.io.rno_g.rnogDataReader.RNOGDataReader([filename]) + self.__user_instances[user_id] = readRNOGData.begin([filename]) if filename != self.__user_instances[user_id].get_filenames()[0]: # user is requesting new file -> close current file and open new one - self.__user_instances[user_id] = NuRadioReco.modules.io.rno_g.rnogDataReader.RNOGDataReader([filename]) + self.__user_instances[user_id] = readRNOGData.begin([filename]) #TODO begin method does not exist in RNOGDataReader #self.__user_instances[user_id].begin(filename) return self.__user_instances[user_id] From c5fdc1da723ae2e21fc3d63e2942707ce420f6d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Wed, 26 Apr 2023 18:56:30 +0200 Subject: [PATCH 244/418] Extend interface of get_event to take the run number as well --- NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py b/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py index ac5da9bdb..6f4dbfdf2 100644 --- a/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py +++ b/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py @@ -583,11 +583,14 @@ def get_event_by_index(self, event_index): return evt - def get_event(self, event_id): + def get_event(self, run_nr, event_id): """ Allows to read a specific event identifed by its id Parameters ---------- + + run_nr: int + Run number event_id: int Event Id @@ -601,9 +604,9 @@ def get_event(self, event_id): self.logger.debug(f"Processing event {event_id}") t0 = time.time() - event_infos = self.get_events_information(keys=["eventNumber"]) - event_idx_ids = np.array([[index, ele["eventNumber"]] for index, ele in event_infos.items()]) - mask = event_idx_ids[:, 1] == event_id + event_infos = self.get_events_information(keys=["eventNumber", "run"]) + event_idx_ids = np.array([[index, ele["eventNumber"], ele["run"]] for index, ele in event_infos.items()]) + mask = np.all([event_idx_ids[:, 1] == event_id, event_idx_ids[:, 2] == run_nr], axis=0) if not np.any(mask): self.logger.info(f"Could not find event with id: {event_id}.") From bde35fa7a774709b520f096b6e5f290b85ae16a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Wed, 26 Apr 2023 18:57:02 +0200 Subject: [PATCH 245/418] Fix small bug in begin() --- NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py b/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py index 6f4dbfdf2..2035f790b 100644 --- a/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py +++ b/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py @@ -235,8 +235,6 @@ def begin(self, selectors = [selectors] self.logger.info(f"Found {len(selectors)} selector(s)") - - self._selectors = selectors if select_triggers is not None: if isinstance(select_triggers, str): @@ -244,6 +242,8 @@ def begin(self, else: for select_trigger in select_triggers: selectors.append(lambda eventInfo: eventInfo.triggerType == select_trigger) + + self._selectors = selectors self._time_begin = 0 self._time_run = 0 From 9d19a81be7330f586131c3325db4b8ba0cd65b5a Mon Sep 17 00:00:00 2001 From: Christian Glaser Date: Tue, 2 May 2023 11:38:49 +0200 Subject: [PATCH 246/418] Update README.md --- README.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 799965a22..98bd87634 100644 --- a/README.md +++ b/README.md @@ -32,14 +32,16 @@ NuRadioMC is continuously improved and new features are being added. The followi If you would like to contribute, please contact @cg-laser or @anelles for permissions to work on NuRadioMC. We work with pull requests only that can be merged after review. Also please visit https://nu-radio.github.io/NuRadioMC/Introduction/pages/contributing.html for details on our workflow and coding conventions. + +## Publications builing up on NuRadioMC/Reco NuRadioMC is used in an increasing number of studies. To get an overview for what NuRadioMC can be used for, please have a look at the following publications or see [here](https://inspirehep.net/literature?sort=mostrecent&size=25&page=1&q=refersto%3Arecid%3A1738571%20or%20refersto%3Arecid%3A1725583): -* V. B. Valera, M. Bustamante and C. Glaser, “Near-future discovery of the diffuse flux of ultra-high-energy cosmic neutrinos”, [arXiv:2210.03756](https://arxiv.org/abs/2210.03756) -* Alfonso Garcia Soto, Diksha Garg, Mary Hall Reno, Carlos A. Argüelles, "Probing Quantum Gravity with Elastic Interactions of Ultra-High-Energy Neutrinos", [arXiv:2209.06282](https://arxiv.org/abs/2209.06282) -* Damiano F. G. Fiorillo, Mauricio Bustamante, Victor B. Valera, "Near-future discovery of point sources of ultra-high-energy neutrinos", [arXiv:2205.15985](https://arxiv.org/abs/2205.15985) +* V. B. Valera, M. Bustamante and C. Glaser, “Near-future discovery of the diffuse flux of ultra-high-energy cosmic neutrinos”, Phys. Rev. D 107, 043019 [arXiv:2210.03756](https://arxiv.org/abs/2210.03756) +* Alfonso Garcia Soto, Diksha Garg, Mary Hall Reno, Carlos A. Argüelles, "Probing Quantum Gravity with Elastic Interactions of Ultra-High-Energy Neutrinos", Phys. Rev. D 107, 033009 (2023) [arXiv:2209.06282](https://arxiv.org/abs/2209.06282) +* Damiano F. G. Fiorillo, Mauricio Bustamante, Victor B. Valera, "Near-future discovery of point sources of ultra-high-energy neutrinos", JCAP 03 (2023) 026 [arXiv:2205.15985](https://arxiv.org/abs/2205.15985) * C. Glaser, S. McAleer, S. Stjärnholm, P. Baldi, S. W. Barwick, “Deep learning reconstruction of the neutrino direction and energy from in-ice radio detector data”, Astroparticle Physics 145, (2023) 102781, [doi:10.1016/j.astropartphys.2022.102781](https://doi.org/10.1016/j.astropartphys.2022.102781), [arXiv:2205.15872](https://arxiv.org/abs/2205.15872) -* J. Beise and C. Glaser, “In-situ calibration system for the measurement of the snow accumulation and the index-of-refraction profile for radio neutrino detectors”, [arXiv:2205.00726](https://arxiv.org/abs/2205.00726) +* J. Beise and C. Glaser, “In-situ calibration system for the measurement of the snow accumulation and the index-of-refraction profile for radio neutrino detectors”, Journal of Instrumentation 18 P01036 (2023), [arXiv:2205.00726](https://arxiv.org/abs/2205.00726) * V. B. Valera, M. Bustamante and C. Glaser, “The ultra-high-energy neutrino-nucleon cross section: measurement forecasts for an era of cosmic EeV-neutrino discovery”, Journal of High Energy Physics 06 (2022) 105, [doi:10.1007/JHEP06(2022)105](https://doi.org/10.1007/JHEP06(2022%29105), [arXiv:2204.04237](https://arxiv.org/abs/2204.04237) * ARIANNA collaboration (A. Anker et al.), “Measuring the Polarization Reconstruction Resolution of the ARIANNA Neutrino Detector with Cosmic Rays”, Journal of Cosmology and Astroparticle Physics 04(2022)022, [doi:10.1088/1475-7516/2022/04/022](https://doi.org/10.1088/1475-7516/2022/04/022), [arXiv:2112.01501](https://arxiv.org/abs/2112.01501) * ARIANNA collaboration (A. Anker et al.), “Improving sensitivity of the ARIANNA detector by rejecting thermal noise with deep learning”, Journal of Instrumentation 17 P03007 (2022), [doi:10.1088/1748-0221/17/03/P03007](https://doi.org/10.1088/1748-0221/17/03/P03007), [arXiv:2112.01031](https://arxiv.org/abs/2112.01031) From 7c82ea65717281101580d26f2f1d1cfc556b15cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Wed, 26 Apr 2023 11:25:43 +0200 Subject: [PATCH 247/418] Add several sanity checks which otherwise would lead to terminations. Check if run is present in run table, check if all mattak files are in directory (improves confidence that mattak files are not corrupt), check that event trigger time is not inf. Simplify/restructure import of runtable --- .../modules/io/RNO_G/readRNOGDataMattak.py | 86 +++++++++++++++---- 1 file changed, 67 insertions(+), 19 deletions(-) diff --git a/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py b/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py index 2035f790b..759630bde 100644 --- a/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py +++ b/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py @@ -1,9 +1,9 @@ import numpy as np -import pandas import logging import os import time import astropy.time +import math from NuRadioReco.modules.base.module import register_run @@ -15,14 +15,6 @@ from NuRadioReco.utilities import units import mattak.Dataset -try: - from rnog_data.runtable import RunTable - imported_runtable = True -except ImportError: - print("Import of run table failed. You will not be able to select runs! \n" - "You can get the interface from GitHub: git@github.com:RNO-G/rnog-data-analysis-and-issues.git") - imported_runtable = False - def baseline_correction(wfs, n_bins=128, func=np.median): """ @@ -104,6 +96,38 @@ def get_time_offset(trigger_type): return time_offsets[trigger_type] else: raise KeyError(f"Unknown trigger type: {trigger_type}. Known are: FORCE, LT, RADIANT. Abort ....") + + +def all_files_in_directory(mattak_dir): + """ + Checks if all Mattak root files are in a directory. + Ignoring runinfo.root because (asaik) not all runs have those and information is currently not read by Mattak. + There are mattak directories which produce a ReferenceError when reading. They have a "combined.root" which is + apparently empty but are missing the daqstatus, pedestal, and header file. + + Parameters + ---------- + + mattak_dir: str + Path to a mattak directory + + Returns + ------- + + all_there: bool + True, if all "req_files" are there and waveforms.root or combined.root. Otherwise returns False. + """ + # one or the other has to be present + if not os.path.exists(os.path.join(mattak_dir, "waveforms.root")) and \ + not os.path.exists(os.path.join(mattak_dir, "combined.root")): + return False + + req_files = ["daqstatus.root", "headers.root", "pedestal.root"] + for file in req_files: + if not os.path.exists(os.path.join(mattak_dir, file)): + return False + + return True class readRNOGData: @@ -207,22 +231,25 @@ def begin(self, self._time_low = None self._time_high = None + self.__run_table = None if select_runs: if run_table_path is None: - global imported_runtable - if imported_runtable: + try: + from rnog_data.runtable import RunTable self.logger.debug("Access RunTable database ...") try: self.__run_table = RunTable().get_table() except: self.logger.error("No connect to RunTable database could be established. " "Runs will not be filtered.") - imported_runtable = False + except ImportError: + self.logger.error("Import of run table failed. You will not be able to select runs! \n" + "You can get the interface from GitHub: git@github.com:RNO-G/rnog-data-analysis-and-issues.git") else: + import pandas self.__run_table = pandas.read_csv(run_table_path) - imported_runtable = True - if select_runs: + if select_runs and self.__run_table is not None: self.logger.info("\n\tSelect runs with type: {}".format(", ".join(run_types)) + f"\n\tSelect runs with max. trigger rate of {max_trigger_rate / units.Hz} Hz" f"\n\tSelect runs which are between {self._time_low} - {self._time_high}") @@ -263,17 +290,27 @@ def begin(self, if not os.path.exists(data_dir): self.logger.error(f"The directory {data_dir} does not exist") + continue + + if not all_files_in_directory(data_dir): + self.logger.error(f"Incomplete directory: {data_dir}. Skip ...") + continue dataset = mattak.Dataset.Dataset(station=0, run=0, data_dir=data_dir, backend=mattak_backend) # filter runs/datasets based on - if select_runs and imported_runtable and not self.__select_run(dataset): + if select_runs and self.__run_table is not None and not self.__select_run(dataset): self.__skipped_runs += 1 continue self.__n_runs += 1 self._datasets.append(dataset) self.__n_events_per_dataset.append(dataset.N()) + + if not len(self._datasets): + err = "Found no valid datasets. Stop!" + self.logger.error(err) + raise FileNotFoundError(err) # keeps track which event index is in which dataset self._event_idxs_datasets = np.cumsum(self.__n_events_per_dataset) @@ -310,6 +347,10 @@ def __select_run(self, dataset): run_info = self.__run_table.query(f"station == {station_id:d} & run == {run_id:d}") + if not len(run_info): + self.logger.error(f"Run {run_id:d} (station {station_id:d}) not in run table. Reject...") + return False + # "time_start/end" is stored in the isot format. datetime is much faster than astropy (~85ns vs 55 mus). # But using datetime would mean to stip decimals because datetime can only handle mu sec precision and can not cope # with the additional decimals for ns. @@ -425,7 +466,6 @@ def get_events_information(self, keys=["station", "run", "eventNumber"]): if not do_read: # ... or when it does not have the desired information first_event_info = next(iter(self._events_information)) - print(first_event_info) for key in keys: if key not in list(first_event_info.keys()): do_read = True @@ -468,14 +508,20 @@ def _get_event(self, event_info, waveforms): evt: NuRadioReco.framework.event """ - + + trigger_time = event_info.triggerTime + if math.isinf(trigger_time): + self.logger.error(f"Event {event_info.eventNumber} (st {event_info.station}, run {event_info.run}) " + "has inf trigger time. Skip event...") + return None + evt = NuRadioReco.framework.event.Event(event_info.run, event_info.eventNumber) station = NuRadioReco.framework.station.Station(event_info.station) - station.set_station_time(astropy.time.Time(event_info.triggerTime, format='unix')) + station.set_station_time(astropy.time.Time(trigger_time, format='unix')) trigger = NuRadioReco.framework.trigger.Trigger(event_info.triggerType) trigger.set_triggered() - trigger.set_trigger_time(event_info.triggerTime) + trigger.set_trigger_time(trigger_time) station.set_trigger(trigger) for channel_id, wf in enumerate(waveforms): @@ -539,6 +585,8 @@ def run(self): waveforms_of_event = wfs[idx] evt = self._get_event(evtinfo, waveforms_of_event) + if evt is None: + continue self._time_run += time.time() - t0 self.__counter += 1 From cab2c559321f26ab5070945a63df2fc9c2bdd97f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Wed, 26 Apr 2023 11:35:12 +0200 Subject: [PATCH 248/418] Add more logger info to noiseImporter --- NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py | 2 +- NuRadioReco/modules/measured_noise/RNO_G/noiseImporter.py | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py b/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py index 759630bde..beabba213 100644 --- a/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py +++ b/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py @@ -512,7 +512,7 @@ def _get_event(self, event_info, waveforms): trigger_time = event_info.triggerTime if math.isinf(trigger_time): self.logger.error(f"Event {event_info.eventNumber} (st {event_info.station}, run {event_info.run}) " - "has inf trigger time. Skip event...") + "has inf trigger time. Skip event...") return None evt = NuRadioReco.framework.event.Event(event_info.run, event_info.eventNumber) diff --git a/NuRadioReco/modules/measured_noise/RNO_G/noiseImporter.py b/NuRadioReco/modules/measured_noise/RNO_G/noiseImporter.py index 305bd7fee..85b011e01 100644 --- a/NuRadioReco/modules/measured_noise/RNO_G/noiseImporter.py +++ b/NuRadioReco/modules/measured_noise/RNO_G/noiseImporter.py @@ -2,6 +2,7 @@ import glob import os import collections +import time from NuRadioReco.modules.io.RNO_G.readRNOGDataMattak import readRNOGData from NuRadioReco.modules.base.module import register_run @@ -98,8 +99,11 @@ def begin(self, noise_folders, file_pattern="*", self._noise_reader.begin(self.__noise_folders, **default_reader_kwargs) # instead of reading all noise events into memory we only get certain information here and read all data in run() - self.logger.info("Get event informations ...") + self.logger.info("Get event informations ...") + t0 = time.time() noise_information = self._noise_reader.get_events_information(keys=["station"]) + self.logger.info(f"... in {t0 - time.time():.2f}s") + self.__event_index_list = np.array(list(noise_information.keys())) self.__station_id_list = np.array([ele["station"] for ele in noise_information.values()]) From 413776cb713dbc67b0b3eaae6249c1c7395f569b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Wed, 26 Apr 2023 12:08:40 +0200 Subject: [PATCH 249/418] With changes to the mattak reader, get_event_by_index can return none. Catch that in the noiseImporter --- .../measured_noise/RNO_G/noiseImporter.py | 45 ++++++++++++++++--- 1 file changed, 40 insertions(+), 5 deletions(-) diff --git a/NuRadioReco/modules/measured_noise/RNO_G/noiseImporter.py b/NuRadioReco/modules/measured_noise/RNO_G/noiseImporter.py index 85b011e01..287ca1ae8 100644 --- a/NuRadioReco/modules/measured_noise/RNO_G/noiseImporter.py +++ b/NuRadioReco/modules/measured_noise/RNO_G/noiseImporter.py @@ -102,7 +102,7 @@ def begin(self, noise_folders, file_pattern="*", self.logger.info("Get event informations ...") t0 = time.time() noise_information = self._noise_reader.get_events_information(keys=["station"]) - self.logger.info(f"... in {t0 - time.time():.2f}s") + self.logger.info(f"... in {time.time() - t0:.2f}s") self.__event_index_list = np.array(list(noise_information.keys())) self.__station_id_list = np.array([ele["station"] for ele in noise_information.values()]) @@ -116,6 +116,44 @@ def __get_noise_channel(self, channel_id): else: return self.__channel_mapping[channel_id] + + def __draw_noise_event(self, mask): + """ + reader.get_event_by_index can return None when, e.g., the trigger time is inf or the sampling rate 0. + Hence, try again if that happens (should only occur rearly). + + Parameters + ---------- + + mask: np.array(bool) + Mask of which noise events are allowed (e.g. because of matching station ids, ...) + + Returns + ------- + + noise_event: NuRadioReco.framework.event + A event containing noise traces + + i_noise: int + The index of the drawn event + """ + tries = 0 + while tries < 100: + # int(..) necessary because pyroot can not handle np.int64 + i_noise = int(self.__random_gen.choice(self.__event_index_list[mask])) + noise_event = self._noise_reader.get_event_by_index(i_noise) + tries += 1 + if noise_event is not None: + break + + if noise_event is None: + err = "Could not draw a random station which is not None after 100 tries. Stop." + self.logger.error(err) + raise ValueError(err) + + self._n_use_event[i_noise] += 1 + return noise_event, i_noise + @register_run() def run(self, evt, station, det): @@ -130,10 +168,7 @@ def run(self, evt, station, det): # select all noise events station_mask = np.full_like(self.__event_index_list, True) - # int(..) necessary because pyroot can not handle np.int64 - i_noise = int(self.__random_gen.choice(self.__event_index_list[station_mask])) - self._n_use_event[i_noise] += 1 - noise_event = self._noise_reader.get_event_by_index(i_noise) + noise_event, i_noise = self.__draw_noise_event(station_mask) station_id = noise_event.get_station_ids()[0] noise_station = noise_event.get_station(station_id) From ca85a56ec1a4f8ba5140c4c0807afe851efe6c97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Wed, 26 Apr 2023 14:15:36 +0200 Subject: [PATCH 250/418] Change tab spacing from 3 to 4 spaces in readRNOGDataMattak.py --- .../modules/io/RNO_G/readRNOGDataMattak.py | 1264 ++++++++--------- 1 file changed, 632 insertions(+), 632 deletions(-) diff --git a/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py b/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py index beabba213..7f0280bd5 100644 --- a/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py +++ b/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py @@ -17,677 +17,677 @@ def baseline_correction(wfs, n_bins=128, func=np.median): - """ - Simple baseline correction function. Determines baseline in discrete chuncks of "n_bins" with - the function specified (i.e., mean or median). - - Parameters - ---------- - - wfs: np.array(n_events, n_channels, n_samples) - Waveforms of several events/channels. - - n_bins: int - Number of samples/bins in one "chunck". If None, calculate median/mean over entire trace. (Default: 128) - - func: np.mean or np.median - Function to calculate pedestal - - Returns - ------- - - wfs_corrected: np.array(n_events, n_channels, n_samples) - Baseline/pedestal corrected waveforms - """ + """ + Simple baseline correction function. Determines baseline in discrete chuncks of "n_bins" with + the function specified (i.e., mean or median). + + Parameters + ---------- + + wfs: np.array(n_events, n_channels, n_samples) + Waveforms of several events/channels. + + n_bins: int + Number of samples/bins in one "chunck". If None, calculate median/mean over entire trace. (Default: 128) + + func: np.mean or np.median + Function to calculate pedestal - # Example: Get baselines in chunks of 128 bins - # wfs in (n_events, n_channels, 2048) - # np.split -> (16, n_events, n_channels, 128) each waveform split in 16 chuncks - # func -> (16, n_events, n_channels) pedestal for each chunck - if n_bins is not None: - baseline_values = func(np.split(wfs, 2048 // n_bins, axis=-1), axis=-1) - - # np.repeat -> (2048, n_events, n_channels) concatenate the 16 chuncks to one baseline - baseline_traces = np.repeat(baseline_values, n_bins % 2048, axis=0) - else: - baseline_values = func(wfs, axis=-1) - # np.repeat -> (2048, n_events, n_channels) concatenate the 16 chuncks to one baseline - baseline_traces = np.repeat(baseline_values, 2048, axis=0) - - # np.moveaxis -> (n_events, n_channels, 2048) - baseline_traces = np.moveaxis(baseline_traces, 0, -1) + Returns + ------- - return wfs - baseline_traces + wfs_corrected: np.array(n_events, n_channels, n_samples) + Baseline/pedestal corrected waveforms + """ + + # Example: Get baselines in chunks of 128 bins + # wfs in (n_events, n_channels, 2048) + # np.split -> (16, n_events, n_channels, 128) each waveform split in 16 chuncks + # func -> (16, n_events, n_channels) pedestal for each chunck + if n_bins is not None: + baseline_values = func(np.split(wfs, 2048 // n_bins, axis=-1), axis=-1) + + # np.repeat -> (2048, n_events, n_channels) concatenate the 16 chuncks to one baseline + baseline_traces = np.repeat(baseline_values, n_bins % 2048, axis=0) + else: + baseline_values = func(wfs, axis=-1) + # np.repeat -> (2048, n_events, n_channels) concatenate the 16 chuncks to one baseline + baseline_traces = np.repeat(baseline_values, 2048, axis=0) + + # np.moveaxis -> (n_events, n_channels, 2048) + baseline_traces = np.moveaxis(baseline_traces, 0, -1) + + return wfs - baseline_traces def get_time_offset(trigger_type): - """ - Mapping the offset between trace start time and trigger time (~ signal time). - Temporary use hard-coded values for each trigger type. In the future this - information might be time, station, and channel dependent and should come - from a database (or is already calibrated in mattak) - - Current values motivated by figures posted in PR https://github.com/nu-radio/NuRadioMC/pull/519 - - Parameters - ---------- - - trigger_type: str - Trigger type encoded as string from Mattak - - Returns - ------- - - time_offset: float - trace_start_time = trigger_time - time_offset - - """ - - time_offsets = { - "FORCE": 0, - "LT": 250 * units.ns, - "RADIANT": 475 * units.ns - } - - if trigger_type.startswith("RADIANT"): - trigger_type = "RADIANT" - - if trigger_type in time_offsets: - return time_offsets[trigger_type] - else: - raise KeyError(f"Unknown trigger type: {trigger_type}. Known are: FORCE, LT, RADIANT. Abort ....") - - + """ + Mapping the offset between trace start time and trigger time (~ signal time). + Temporary use hard-coded values for each trigger type. In the future this + information might be time, station, and channel dependent and should come + from a database (or is already calibrated in mattak) + + Current values motivated by figures posted in PR https://github.com/nu-radio/NuRadioMC/pull/519 + + Parameters + ---------- + + trigger_type: str + Trigger type encoded as string from Mattak + + Returns + ------- + + time_offset: float + trace_start_time = trigger_time - time_offset + + """ + + time_offsets = { + "FORCE": 0, + "LT": 250 * units.ns, + "RADIANT": 475 * units.ns + } + + if trigger_type.startswith("RADIANT"): + trigger_type = "RADIANT" + + if trigger_type in time_offsets: + return time_offsets[trigger_type] + else: + raise KeyError(f"Unknown trigger type: {trigger_type}. Known are: FORCE, LT, RADIANT. Abort ....") + + def all_files_in_directory(mattak_dir): - """ - Checks if all Mattak root files are in a directory. - Ignoring runinfo.root because (asaik) not all runs have those and information is currently not read by Mattak. - There are mattak directories which produce a ReferenceError when reading. They have a "combined.root" which is - apparently empty but are missing the daqstatus, pedestal, and header file. - - Parameters - ---------- - - mattak_dir: str - Path to a mattak directory - - Returns - ------- - - all_there: bool - True, if all "req_files" are there and waveforms.root or combined.root. Otherwise returns False. - """ - # one or the other has to be present - if not os.path.exists(os.path.join(mattak_dir, "waveforms.root")) and \ - not os.path.exists(os.path.join(mattak_dir, "combined.root")): - return False - - req_files = ["daqstatus.root", "headers.root", "pedestal.root"] - for file in req_files: - if not os.path.exists(os.path.join(mattak_dir, file)): - return False - - return True + """ + Checks if all Mattak root files are in a directory. + Ignoring runinfo.root because (asaik) not all runs have those and information is currently not read by Mattak. + There are mattak directories which produce a ReferenceError when reading. They have a "combined.root" which is + apparently empty but are missing the daqstatus, pedestal, and header file. + + Parameters + ---------- + + mattak_dir: str + Path to a mattak directory + + Returns + ------- + + all_there: bool + True, if all "req_files" are there and waveforms.root or combined.root. Otherwise returns False. + """ + # one or the other has to be present + if not os.path.exists(os.path.join(mattak_dir, "waveforms.root")) and \ + not os.path.exists(os.path.join(mattak_dir, "combined.root")): + return False + + req_files = ["daqstatus.root", "headers.root", "pedestal.root"] + for file in req_files: + if not os.path.exists(os.path.join(mattak_dir, file)): + return False + + return True class readRNOGData: - def begin(self, - data_dirs, - read_calibrated_data=False, - select_triggers=None, - select_runs=False, - apply_baseline_correction=True, - convert_to_voltage=True, - selectors=None, - run_table_path=None, - run_types=["physics"], - run_time_range=None, - max_trigger_rate=0 * units.Hz, - mattak_backend="auto", - log_level=logging.INFO): - """ - - Parameters - ---------- - - data_dirs: list of strings / string - Path to run directories (i.e. ".../stationXX/runXXX/") - - read_calibrated_data: bool - If True, read calibrated waveforms from Mattak.Dataset. If False, read "raw" ADC traces. - (temp. Default: False, this can/should be switched once the calibration in incorp. into Mattak) - - select_triggers: str or list(str) - Names of triggers which should be selected. Convinence interface instead of passing a selector - (see "selectors" below. (Default: None) - - select_runs: bool - If True, use information in run_table to select runs (based on run_type, run_time, trigger_rate, ...). - If the run_table is not available no selection is performed (and the programm is not interrupted, - only an error message is raised). See parameters to configure run selection. (Default: False) - - Other Parameters - ---------------- - - apply_baseline_correction: bool - Only applies when non-calibrated data are read. If true, correct for DC offset. - (Default: True) - - convert_to_voltage: bool - Only applies when non-calibrated data are read. If true, convert ADC to voltage. - (Default: True) - - selectors: list of lambdas - List of lambda(eventInfo) -> bool to pass to mattak.Dataset.iterate to select events. - Example: trigger_selector = lambda eventInfo: eventInfo.triggerType == "FORCE" - - run_table_path: str - Path to a run_table.cvs file. If None, the run table is queried from the DB. (Default: None) - - run_types: list - Used to select/reject runs from information in the RNO-G RunTable. List of run_types to be used. (Default: ['physics']) - - run_time_range: tuple - Specify a time range to select runs (it is sufficient that runs cover the time range partially). - Each value of the tuple has to be in a format which astropy.time.Time understands. A value can be None - which means that the lower or upper bound is unconstrained. If run_time_range is None no time selection is - applied. (Default: None) - - max_trigger_rate: float - Used to select/reject runs from information in the RNO-G RunTable. Maximum allowed trigger rate (per run) in Hz. - If 0, no cut is applied. (Default: 1 Hz) - - mattak_backend: str - Select a mattak backend. Options are "auto", "pyroot", "uproot". If "auto" is selected, pyroot is used if available otherwise - a "fallback" to uproot is used. (Default: "auto") - - log_level: enum - Set verbosity level of logger - """ - - t0 = time.time() - - self.logger = logging.getLogger('NuRadioReco.readRNOGData') - self.logger.setLevel(log_level) - - self._read_calibrated_data = read_calibrated_data - self._apply_baseline_correction = apply_baseline_correction - self._convert_to_voltage = convert_to_voltage - - # Temporary solution hard-coded values from Cosmin. Only used when uncalibrated data - # is read and convert_to_voltage is True. - self._adc_ref_voltage_range = 2.5 * units.volt - self._adc_n_bits = 12 - - self.__max_trigger_rate = max_trigger_rate - self.__run_types = run_types - - if run_time_range is not None: - convert_time = lambda t: None if t is None else astropy.time.Time(t) - self._time_low = convert_time(run_time_range[0]) - self._time_high = convert_time(run_time_range[1]) - else: - self._time_low = None - self._time_high = None - - self.__run_table = None - if select_runs: - if run_table_path is None: - try: - from rnog_data.runtable import RunTable - self.logger.debug("Access RunTable database ...") - try: - self.__run_table = RunTable().get_table() - except: - self.logger.error("No connect to RunTable database could be established. " - "Runs will not be filtered.") - except ImportError: - self.logger.error("Import of run table failed. You will not be able to select runs! \n" - "You can get the interface from GitHub: git@github.com:RNO-G/rnog-data-analysis-and-issues.git") - else: - import pandas - self.__run_table = pandas.read_csv(run_table_path) + def begin(self, + data_dirs, + read_calibrated_data=False, + select_triggers=None, + select_runs=False, + apply_baseline_correction=True, + convert_to_voltage=True, + selectors=None, + run_table_path=None, + run_types=["physics"], + run_time_range=None, + max_trigger_rate=0 * units.Hz, + mattak_backend="auto", + log_level=logging.INFO): + """ + + Parameters + ---------- + + data_dirs: list of strings / string + Path to run directories (i.e. ".../stationXX/runXXX/") - if select_runs and self.__run_table is not None: - self.logger.info("\n\tSelect runs with type: {}".format(", ".join(run_types)) + - f"\n\tSelect runs with max. trigger rate of {max_trigger_rate / units.Hz} Hz" - f"\n\tSelect runs which are between {self._time_low} - {self._time_high}") - - if not isinstance(data_dirs, (list, np.ndarray)): - data_dirs = [data_dirs] - - if selectors is not None: - if not isinstance(selectors, (list, np.ndarray)): - selectors = [selectors] - - self.logger.info(f"Found {len(selectors)} selector(s)") + read_calibrated_data: bool + If True, read calibrated waveforms from Mattak.Dataset. If False, read "raw" ADC traces. + (temp. Default: False, this can/should be switched once the calibration in incorp. into Mattak) - if select_triggers is not None: - if isinstance(select_triggers, str): - selectors.append(lambda eventInfo: eventInfo.triggerType == select_triggers) - else: - for select_trigger in select_triggers: - selectors.append(lambda eventInfo: eventInfo.triggerType == select_trigger) - - self._selectors = selectors - - self._time_begin = 0 - self._time_run = 0 - self.__counter = 0 - self.__skipped = 0 - - self._events_information = None - self._datasets = [] - self.__n_events_per_dataset = [] - - self.logger.info(f"Parse through {len(data_dirs)} directory/ies.") - - self.__skipped_runs = 0 - self.__n_runs = 0 - - for data_dir in data_dirs: - - if not os.path.exists(data_dir): - self.logger.error(f"The directory {data_dir} does not exist") - continue - - if not all_files_in_directory(data_dir): - self.logger.error(f"Incomplete directory: {data_dir}. Skip ...") - continue - - dataset = mattak.Dataset.Dataset(station=0, run=0, data_dir=data_dir, backend=mattak_backend) - - # filter runs/datasets based on - if select_runs and self.__run_table is not None and not self.__select_run(dataset): - self.__skipped_runs += 1 - continue - - self.__n_runs += 1 - self._datasets.append(dataset) - self.__n_events_per_dataset.append(dataset.N()) - - if not len(self._datasets): - err = "Found no valid datasets. Stop!" - self.logger.error(err) - raise FileNotFoundError(err) - - # keeps track which event index is in which dataset - self._event_idxs_datasets = np.cumsum(self.__n_events_per_dataset) - self._n_events_total = np.sum(self.__n_events_per_dataset) - self._time_begin = time.time() - t0 - - self.logger.info(f"Using the {self._datasets[0].backend} Mattak backend.") - self.logger.info(f"{self._n_events_total} events in {len(self._datasets)} runs/datasets have been found.") + select_triggers: str or list(str) + Names of triggers which should be selected. Convinence interface instead of passing a selector + (see "selectors" below. (Default: None) - if not self._n_events_total: - err = "No runs have been selected. Abort ..." - self.logger.error(err) - raise ValueError(err) - - - def __select_run(self, dataset): - """ Filter/select runs/datasets. - - Parameters - ---------- - - dataset: mattak.Dataset.Dataset - - select: bool - Return True to select an dataset, return False to reject/skip it. - """ - - # get first eventInfo - dataset.setEntries(0) - event_info = dataset.eventInfo() - - run_id = event_info.run - station_id = event_info.station - - run_info = self.__run_table.query(f"station == {station_id:d} & run == {run_id:d}") - - if not len(run_info): - self.logger.error(f"Run {run_id:d} (station {station_id:d}) not in run table. Reject...") - return False - - # "time_start/end" is stored in the isot format. datetime is much faster than astropy (~85ns vs 55 mus). - # But using datetime would mean to stip decimals because datetime can only handle mu sec precision and can not cope - # with the additional decimals for ns. - if self._time_low is not None: - time_end = astropy.time.Time(run_info["time_end"].values[0]) - if time_end < self._time_low: - self.logger.info(f"Reject station {station_id} run {run_id} because run ended before {self._time_low}") - return False - - if self._time_high is not None: - time_start = astropy.time.Time(run_info["time_start"].values[0]) - if time_start > self._time_high: - self.logger.info(f"Reject station {station_id} run {run_id} because run started time after {self._time_high}") - return False - - run_type = run_info["run_type"].values[0] - if not run_type in self.__run_types: - self.logger.info(f"Reject station {station_id} run {run_id} because of run type {run_type}") - return False - - trigger_rate = run_info["trigger_rate"].values[0] * units.Hz - if self.__max_trigger_rate and trigger_rate > self.__max_trigger_rate: - self.logger.info(f"Reject station {station_id} run {run_id} because trigger rate is to high ({trigger_rate / units.Hz} Hz)") - return False - - return True - - - def __get_n_events_of_prev_datasets(self, dataset_idx): - """ Get accumulated number of events from previous datasets """ - dataset_idx_prev = dataset_idx - 1 - return int(self._event_idxs_datasets[dataset_idx_prev]) if dataset_idx_prev >= 0 else 0 - - - def __get_dataset_for_event(self, event_idx): - """ Get correct dataset and set entry accordingly to event index - - Parameters - ---------- - - event_index: int - Same as in read_event(). - - Returns - ------- - - dataset: mattak.Dataset.Dataset - """ - # find correct dataset - dataset_idx = np.digitize(event_idx, self._event_idxs_datasets) - dataset = self._datasets[dataset_idx] - - event_idx_in_dataset = event_idx - self.__get_n_events_of_prev_datasets(dataset_idx) - dataset.setEntries(event_idx_in_dataset) # increment iterator -> point to new event + select_runs: bool + If True, use information in run_table to select runs (based on run_type, run_time, trigger_rate, ...). + If the run_table is not available no selection is performed (and the programm is not interrupted, + only an error message is raised). See parameters to configure run selection. (Default: False) - return dataset - - - def _filter_event(self, evtinfo, event_idx=None): - """ Filter an event base on its EventInfo and the configured selectors. - - Parameters - ---------- - - event_info: mattak.Dataset.EventInfo - The event info object for one event. - - event_index: int - Same as in read_event(). Only use for logger.info(). (Default: None) - - Returns - ------- - - skip: bool - Returns True to skip/reject event, return False to keep/read event - """ - if self._selectors is not None: - for selector in self._selectors: - if not selector(evtinfo): - self.logger.debug(f"Event {event_idx} (station {evtinfo.station}, run {evtinfo.run}, " - f"event number {evtinfo.eventNumber}) is skipped.") - self.__skipped += 1 - return True - - return False - - - def get_events_information(self, keys=["station", "run", "eventNumber"]): - """ Return information of all events from the EventInfo - - This function is useful to make a pre-selection of events before actually reading them in combination with - self.read_event(). - - Parameters - ---------- - - keys: list(str) - List of the information to receive from each event. Have to match the attributes (member variables) - of the mattak.Dataset.EventInfo class (examples are "station", "run", "triggerTime", "triggerType", "eventNumber", ...). - (Default: ["station", "run", "eventNumber"]) - - Returns - ------- - - data: dict - Keys of the dict are the event indecies (as used in self.read_event(event_index)). The values are dictinaries - them self containing the information specified with "keys" parameter. - """ - - # Read if dict is None ... - do_read = self._events_information is None - - if not do_read: - # ... or when it does not have the desired information - first_event_info = next(iter(self._events_information)) - for key in keys: - if key not in list(first_event_info.keys()): - do_read = True - - if do_read: - - self._events_information = {} - n_prev = 0 - for dataset in self._datasets: - dataset.setEntries((0, dataset.N())) + Other Parameters + ---------------- + + apply_baseline_correction: bool + Only applies when non-calibrated data are read. If true, correct for DC offset. + (Default: True) + + convert_to_voltage: bool + Only applies when non-calibrated data are read. If true, convert ADC to voltage. + (Default: True) + + selectors: list of lambdas + List of lambda(eventInfo) -> bool to pass to mattak.Dataset.iterate to select events. + Example: trigger_selector = lambda eventInfo: eventInfo.triggerType == "FORCE" - for idx, evtinfo in enumerate(dataset.eventInfo()): # returns a list - - event_idx = idx + n_prev # event index accross all datasets combined + run_table_path: str + Path to a run_table.cvs file. If None, the run table is queried from the DB. (Default: None) - if self._filter_event(evtinfo, event_idx): - continue + run_types: list + Used to select/reject runs from information in the RNO-G RunTable. List of run_types to be used. (Default: ['physics']) - self._events_information[event_idx] = {key: getattr(evtinfo, key) for key in keys} + run_time_range: tuple + Specify a time range to select runs (it is sufficient that runs cover the time range partially). + Each value of the tuple has to be in a format which astropy.time.Time understands. A value can be None + which means that the lower or upper bound is unconstrained. If run_time_range is None no time selection is + applied. (Default: None) - n_prev += dataset.N() - - return self._events_information - - - def _get_event(self, event_info, waveforms): - """ Return a NuRadioReco event - - Parameters - ---------- - - event_info: mattak.Dataset.EventInfo - The event info object for one event. - - waveforms: np.array(n_channel, n_samples) - Typically what dataset.wfs() returns (for one event!) - - Returns - ------- - - evt: NuRadioReco.framework.event - """ - - trigger_time = event_info.triggerTime - if math.isinf(trigger_time): - self.logger.error(f"Event {event_info.eventNumber} (st {event_info.station}, run {event_info.run}) " - "has inf trigger time. Skip event...") - return None - - evt = NuRadioReco.framework.event.Event(event_info.run, event_info.eventNumber) - station = NuRadioReco.framework.station.Station(event_info.station) - station.set_station_time(astropy.time.Time(trigger_time, format='unix')) - - trigger = NuRadioReco.framework.trigger.Trigger(event_info.triggerType) - trigger.set_triggered() - trigger.set_trigger_time(trigger_time) - station.set_trigger(trigger) - - for channel_id, wf in enumerate(waveforms): - channel = NuRadioReco.framework.channel.Channel(channel_id) - if self._read_calibrated_data: - channel.set_trace(wf * units.mV, event_info.sampleRate * units.GHz) - else: - # wf stores ADC counts + max_trigger_rate: float + Used to select/reject runs from information in the RNO-G RunTable. Maximum allowed trigger rate (per run) in Hz. + If 0, no cut is applied. (Default: 1 Hz) - if self._apply_baseline_correction: - # correct baseline - wf = baseline_correction(wf) + mattak_backend: str + Select a mattak backend. Options are "auto", "pyroot", "uproot". If "auto" is selected, pyroot is used if available otherwise + a "fallback" to uproot is used. (Default: "auto") + + log_level: enum + Set verbosity level of logger + """ + + t0 = time.time() + + self.logger = logging.getLogger('NuRadioReco.readRNOGData') + self.logger.setLevel(log_level) + + self._read_calibrated_data = read_calibrated_data + self._apply_baseline_correction = apply_baseline_correction + self._convert_to_voltage = convert_to_voltage + + # Temporary solution hard-coded values from Cosmin. Only used when uncalibrated data + # is read and convert_to_voltage is True. + self._adc_ref_voltage_range = 2.5 * units.volt + self._adc_n_bits = 12 + + self.__max_trigger_rate = max_trigger_rate + self.__run_types = run_types + + if run_time_range is not None: + convert_time = lambda t: None if t is None else astropy.time.Time(t) + self._time_low = convert_time(run_time_range[0]) + self._time_high = convert_time(run_time_range[1]) + else: + self._time_low = None + self._time_high = None + + self.__run_table = None + if select_runs: + if run_table_path is None: + try: + from rnog_data.runtable import RunTable + self.logger.debug("Access RunTable database ...") + try: + self.__run_table = RunTable().get_table() + except: + self.logger.error("No connect to RunTable database could be established. " + "Runs will not be filtered.") + except ImportError: + self.logger.error("Import of run table failed. You will not be able to select runs! \n" + "You can get the interface from GitHub: git@github.com:RNO-G/rnog-data-analysis-and-issues.git") + else: + import pandas + self.__run_table = pandas.read_csv(run_table_path) + + if select_runs and self.__run_table is not None: + self.logger.info("\n\tSelect runs with type: {}".format(", ".join(run_types)) + + f"\n\tSelect runs with max. trigger rate of {max_trigger_rate / units.Hz} Hz" + f"\n\tSelect runs which are between {self._time_low} - {self._time_high}") + + if not isinstance(data_dirs, (list, np.ndarray)): + data_dirs = [data_dirs] + + if selectors is not None: + if not isinstance(selectors, (list, np.ndarray)): + selectors = [selectors] - if self._convert_to_voltage: - # convert adc to voltage - wf *= (self._adc_ref_voltage_range / (2 ** (self._adc_n_bits) - 1)) - - channel.set_trace(wf, event_info.sampleRate * units.GHz) - - time_offset = get_time_offset(event_info.triggerType) - channel.set_trace_start_time(-time_offset) # relative to event/trigger time - - station.add_channel(channel) - - evt.set_station(station) - - return evt - - - @register_run() - def run(self): - """ - Loop over all events. - - Returns - ------- - - evt: generator(NuRadioReco.framework.event) - """ - event_idx = -1 - for dataset in self._datasets: - dataset.setEntries((0, dataset.N())) - - # read all event infos of the entier dataset (= run) - event_infos = dataset.eventInfo() - wfs = None - - for idx, evtinfo in enumerate(event_infos): # returns a list - event_idx += 1 + self.logger.info(f"Found {len(selectors)} selector(s)") + + self._selectors = selectors + + if select_triggers is not None: + if isinstance(select_triggers, str): + selectors.append(lambda eventInfo: eventInfo.triggerType == select_triggers) + else: + for select_trigger in select_triggers: + selectors.append(lambda eventInfo: eventInfo.triggerType == select_trigger) + + self._time_begin = 0 + self._time_run = 0 + self.__counter = 0 + self.__skipped = 0 + + self._events_information = None + self._datasets = [] + self.__n_events_per_dataset = [] + + self.logger.info(f"Parse through {len(data_dirs)} directory/ies.") + + self.__skipped_runs = 0 + self.__n_runs = 0 + + for data_dir in data_dirs: - self.logger.debug(f"Processing event number {event_idx} out of total {self._n_events_total}") - t0 = time.time() - - if self._filter_event(evtinfo, event_idx): - continue + if not os.path.exists(data_dir): + self.logger.error(f"The directory {data_dir} does not exist") + continue - # Just read wfs if necessary - if wfs is None: - wfs = dataset.wfs() - - waveforms_of_event = wfs[idx] + if not all_files_in_directory(data_dir): + self.logger.error(f"Incomplete directory: {data_dir}. Skip ...") + continue + + dataset = mattak.Dataset.Dataset(station=0, run=0, data_dir=data_dir, backend=mattak_backend) + + # filter runs/datasets based on + if select_runs and self.__run_table is not None and not self.__select_run(dataset): + self.__skipped_runs += 1 + continue - evt = self._get_event(evtinfo, waveforms_of_event) - if evt is None: - continue + self.__n_runs += 1 + self._datasets.append(dataset) + self.__n_events_per_dataset.append(dataset.N()) - self._time_run += time.time() - t0 - self.__counter += 1 - - yield evt - - - - def get_event_by_index(self, event_index): - """ Allows to read a specific event identifed by its index - - Parameters - ---------- - - event_index: int - The index of a particluar event. The index is the chronological number from 0 to - number of total events (across all datasets). - - Returns - ------- - - evt: NuRadioReco.framework.event - """ - - self.logger.debug(f"Processing event number {event_index} out of total {self._n_events_total}") - t0 = time.time() + if not len(self._datasets): + err = "Found no valid datasets. Stop!" + self.logger.error(err) + raise FileNotFoundError(err) + + # keeps track which event index is in which dataset + self._event_idxs_datasets = np.cumsum(self.__n_events_per_dataset) + self._n_events_total = np.sum(self.__n_events_per_dataset) + self._time_begin = time.time() - t0 + + self.logger.info(f"Using the {self._datasets[0].backend} Mattak backend.") + self.logger.info(f"{self._n_events_total} events in {len(self._datasets)} runs/datasets have been found.") + + if not self._n_events_total: + err = "No runs have been selected. Abort ..." + self.logger.error(err) + raise ValueError(err) + + + def __select_run(self, dataset): + """ Filter/select runs/datasets. + + Parameters + ---------- + + dataset: mattak.Dataset.Dataset + + select: bool + Return True to select an dataset, return False to reject/skip it. + """ + + # get first eventInfo + dataset.setEntries(0) + event_info = dataset.eventInfo() + + run_id = event_info.run + station_id = event_info.station + + run_info = self.__run_table.query(f"station == {station_id:d} & run == {run_id:d}") + + if not len(run_info): + self.logger.error(f"Run {run_id:d} (station {station_id:d}) not in run table. Reject...") + return False + + # "time_start/end" is stored in the isot format. datetime is much faster than astropy (~85ns vs 55 mus). + # But using datetime would mean to stip decimals because datetime can only handle mu sec precision and can not cope + # with the additional decimals for ns. + if self._time_low is not None: + time_end = astropy.time.Time(run_info["time_end"].values[0]) + if time_end < self._time_low: + self.logger.info(f"Reject station {station_id} run {run_id} because run ended before {self._time_low}") + return False + + if self._time_high is not None: + time_start = astropy.time.Time(run_info["time_start"].values[0]) + if time_start > self._time_high: + self.logger.info(f"Reject station {station_id} run {run_id} because run started time after {self._time_high}") + return False + + run_type = run_info["run_type"].values[0] + if not run_type in self.__run_types: + self.logger.info(f"Reject station {station_id} run {run_id} because of run type {run_type}") + return False + + trigger_rate = run_info["trigger_rate"].values[0] * units.Hz + if self.__max_trigger_rate and trigger_rate > self.__max_trigger_rate: + self.logger.info(f"Reject station {station_id} run {run_id} because trigger rate is to high ({trigger_rate / units.Hz} Hz)") + return False + + return True - dataset = self.__get_dataset_for_event(event_index) - event_info = dataset.eventInfo() # returns a single eventInfo - if self._filter_event(event_info, event_index): - return None + def __get_n_events_of_prev_datasets(self, dataset_idx): + """ Get accumulated number of events from previous datasets """ + dataset_idx_prev = dataset_idx - 1 + return int(self._event_idxs_datasets[dataset_idx_prev]) if dataset_idx_prev >= 0 else 0 + + + def __get_dataset_for_event(self, event_idx): + """ Get correct dataset and set entry accordingly to event index + + Parameters + ---------- + + event_index: int + Same as in read_event(). + + Returns + ------- + + dataset: mattak.Dataset.Dataset + """ + # find correct dataset + dataset_idx = np.digitize(event_idx, self._event_idxs_datasets) + dataset = self._datasets[dataset_idx] + + event_idx_in_dataset = event_idx - self.__get_n_events_of_prev_datasets(dataset_idx) + dataset.setEntries(event_idx_in_dataset) # increment iterator -> point to new event + + return dataset + + + def _filter_event(self, evtinfo, event_idx=None): + """ Filter an event base on its EventInfo and the configured selectors. + + Parameters + ---------- + + event_info: mattak.Dataset.EventInfo + The event info object for one event. + + event_index: int + Same as in read_event(). Only use for logger.info(). (Default: None) - # access data - waveforms = dataset.wfs() - - evt = self._get_event(event_info, waveforms) - - self._time_run += time.time() - t0 - self.__counter += 1 - - return evt - - - def get_event(self, run_nr, event_id): - """ Allows to read a specific event identifed by its id + Returns + ------- + + skip: bool + Returns True to skip/reject event, return False to keep/read event + """ + if self._selectors is not None: + for selector in self._selectors: + if not selector(evtinfo): + self.logger.debug(f"Event {event_idx} (station {evtinfo.station}, run {evtinfo.run}, " + f"event number {evtinfo.eventNumber}) is skipped.") + self.__skipped += 1 + return True + + return False + + + def get_events_information(self, keys=["station", "run", "eventNumber"]): + """ Return information of all events from the EventInfo + + This function is useful to make a pre-selection of events before actually reading them in combination with + self.read_event(). + + Parameters + ---------- + + keys: list(str) + List of the information to receive from each event. Have to match the attributes (member variables) + of the mattak.Dataset.EventInfo class (examples are "station", "run", "triggerTime", "triggerType", "eventNumber", ...). + (Default: ["station", "run", "eventNumber"]) + + Returns + ------- + + data: dict + Keys of the dict are the event indecies (as used in self.read_event(event_index)). The values are dictinaries + them self containing the information specified with "keys" parameter. + """ + + # Read if dict is None ... + do_read = self._events_information is None + + if not do_read: + # ... or when it does not have the desired information + first_event_info = next(iter(self._events_information)) + for key in keys: + if key not in list(first_event_info.keys()): + do_read = True + + if do_read: + + self._events_information = {} + n_prev = 0 + for dataset in self._datasets: + dataset.setEntries((0, dataset.N())) + + for idx, evtinfo in enumerate(dataset.eventInfo()): # returns a list + + event_idx = idx + n_prev # event index accross all datasets combined + + if self._filter_event(evtinfo, event_idx): + continue + + self._events_information[event_idx] = {key: getattr(evtinfo, key) for key in keys} + + n_prev += dataset.N() + + return self._events_information + + + def _get_event(self, event_info, waveforms): + """ Return a NuRadioReco event + + Parameters + ---------- + + event_info: mattak.Dataset.EventInfo + The event info object for one event. + + waveforms: np.array(n_channel, n_samples) + Typically what dataset.wfs() returns (for one event!) + + Returns + ------- + + evt: NuRadioReco.framework.event + """ + + trigger_time = event_info.triggerTime + if math.isinf(trigger_time): + self.logger.error(f"Event {event_info.eventNumber} (st {event_info.station}, run {event_info.run}) " + "has inf trigger time. Skip event...") + return None + + evt = NuRadioReco.framework.event.Event(event_info.run, event_info.eventNumber) + station = NuRadioReco.framework.station.Station(event_info.station) + station.set_station_time(astropy.time.Time(trigger_time, format='unix')) + + trigger = NuRadioReco.framework.trigger.Trigger(event_info.triggerType) + trigger.set_triggered() + trigger.set_trigger_time(trigger_time) + station.set_trigger(trigger) + + for channel_id, wf in enumerate(waveforms): + channel = NuRadioReco.framework.channel.Channel(channel_id) + if self._read_calibrated_data: + channel.set_trace(wf * units.mV, event_info.sampleRate * units.GHz) + else: + # wf stores ADC counts + + if self._apply_baseline_correction: + # correct baseline + wf = baseline_correction(wf) + + if self._convert_to_voltage: + # convert adc to voltage + wf *= (self._adc_ref_voltage_range / (2 ** (self._adc_n_bits) - 1)) + + channel.set_trace(wf, event_info.sampleRate * units.GHz) + + time_offset = get_time_offset(event_info.triggerType) + channel.set_trace_start_time(-time_offset) # relative to event/trigger time + + station.add_channel(channel) + + evt.set_station(station) + + return evt + + + @register_run() + def run(self): + """ + Loop over all events. + + Returns + ------- + + evt: generator(NuRadioReco.framework.event) + """ + event_idx = -1 + for dataset in self._datasets: + dataset.setEntries((0, dataset.N())) + + # read all event infos of the entier dataset (= run) + event_infos = dataset.eventInfo() + wfs = None + + for idx, evtinfo in enumerate(event_infos): # returns a list + event_idx += 1 + + self.logger.debug(f"Processing event number {event_idx} out of total {self._n_events_total}") + t0 = time.time() + + if self._filter_event(evtinfo, event_idx): + continue + + # Just read wfs if necessary + if wfs is None: + wfs = dataset.wfs() + + waveforms_of_event = wfs[idx] + + evt = self._get_event(evtinfo, waveforms_of_event) + if evt is None: + continue + + self._time_run += time.time() - t0 + self.__counter += 1 + + yield evt + + + + def get_event_by_index(self, event_index): + """ Allows to read a specific event identifed by its index + + Parameters + ---------- + + event_index: int + The index of a particluar event. The index is the chronological number from 0 to + number of total events (across all datasets). + + Returns + ------- + + evt: NuRadioReco.framework.event + """ + + self.logger.debug(f"Processing event number {event_index} out of total {self._n_events_total}") + t0 = time.time() + + dataset = self.__get_dataset_for_event(event_index) + event_info = dataset.eventInfo() # returns a single eventInfo + + if self._filter_event(event_info, event_index): + return None + + # access data + waveforms = dataset.wfs() + + evt = self._get_event(event_info, waveforms) + + self._time_run += time.time() - t0 + self.__counter += 1 + + return evt + + + def get_event(self, run_nr, event_id): + """ Allows to read a specific event identifed by its id - Parameters - ---------- - - run_nr: int - Run number + Parameters + ---------- + + run_nr: int + Run number - event_id: int - Event Id - - Returns - ------- + event_id: int + Event Id + + Returns + ------- - evt: NuRadioReco.framework.event - """ + evt: NuRadioReco.framework.event + """ - self.logger.debug(f"Processing event {event_id}") - t0 = time.time() + self.logger.debug(f"Processing event {event_id}") + t0 = time.time() - event_infos = self.get_events_information(keys=["eventNumber", "run"]) - event_idx_ids = np.array([[index, ele["eventNumber"], ele["run"]] for index, ele in event_infos.items()]) - mask = np.all([event_idx_ids[:, 1] == event_id, event_idx_ids[:, 2] == run_nr], axis=0) + event_infos = self.get_events_information(keys=["eventNumber", "run"]) + event_idx_ids = np.array([[index, ele["eventNumber"], ele["run"]] for index, ele in event_infos.items()]) + mask = np.all([event_idx_ids[:, 1] == event_id, event_idx_ids[:, 2] == run_nr], axis=0) - if not np.any(mask): - self.logger.info(f"Could not find event with id: {event_id}.") - return None - elif np.sum(mask) > 1: - self.logger.error(f"Found several events with the same id: {event_id}.") - raise ValueError(f"Found several events with the same id: {event_id}.") - else: - pass + if not np.any(mask): + self.logger.info(f"Could not find event with id: {event_id}.") + return None + elif np.sum(mask) > 1: + self.logger.error(f"Found several events with the same id: {event_id}.") + raise ValueError(f"Found several events with the same id: {event_id}.") + else: + pass - event_index = event_idx_ids[mask, 0][0] + event_index = event_idx_ids[mask, 0][0] - dataset = self.__get_dataset_for_event(event_index) - event_info = dataset.eventInfo() # returns a single eventInfo + dataset = self.__get_dataset_for_event(event_index) + event_info = dataset.eventInfo() # returns a single eventInfo - if self._filter_event(event_info, event_index): - return None + if self._filter_event(event_info, event_index): + return None - # access data - waveforms = dataset.wfs() + # access data + waveforms = dataset.wfs() - evt = self._get_event(event_info, waveforms) + evt = self._get_event(event_info, waveforms) - self._time_run += time.time() - t0 - self.__counter += 1 + self._time_run += time.time() - t0 + self.__counter += 1 - return evt + return evt - def end(self): - self.logger.info( - f"\n\tRead {self.__counter} events (skipped {self.__skipped} events)" - f"\n\tTime to initialize data sets : {self._time_begin:.2f}s" - f"\n\tTime to initialize all events : {self._time_run:.2f}s" - f"\n\tTime to per event : {self._time_run / self.__counter:.2f}s" - f"\n\tRead {self.__n_runs} runs, skipped {self.__skipped_runs} runs.") + def end(self): + self.logger.info( + f"\n\tRead {self.__counter} events (skipped {self.__skipped} events)" + f"\n\tTime to initialize data sets : {self._time_begin:.2f}s" + f"\n\tTime to initialize all events : {self._time_run:.2f}s" + f"\n\tTime to per event : {self._time_run / self.__counter:.2f}s" + f"\n\tRead {self.__n_runs} runs, skipped {self.__skipped_runs} runs.") From dbbb46ae719bb90f6b9e519fac9d180ac63302fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Wed, 26 Apr 2023 14:15:36 +0200 Subject: [PATCH 251/418] Change tab spacing from 3 to 4 spaces in readRNOGDataMattak.py --- NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py b/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py index 7f0280bd5..80d2357a4 100644 --- a/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py +++ b/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py @@ -632,11 +632,12 @@ def get_event_by_index(self, event_index): def get_event(self, run_nr, event_id): - """ Allows to read a specific event identifed by its id + + """ Allows to read a specific event identifed by run number and event id Parameters ---------- - + run_nr: int Run number From 933610d560f7ae34f5f87303cee42fb7b59cb5c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Wed, 26 Apr 2023 14:16:47 +0200 Subject: [PATCH 252/418] Add additional sanity check for sampling rate to _get_event --- NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py b/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py index 80d2357a4..335b5dc85 100644 --- a/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py +++ b/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py @@ -515,6 +515,12 @@ def _get_event(self, event_info, waveforms): "has inf trigger time. Skip event...") return None + sampling_rate = event_info.sampleRate + if sampling_rate == 0: + self.logger.error(f"Event {event_info.eventNumber} (st {event_info.station}, run {event_info.run}) " + f"has a sampling rate of {sampling_rate} GHz. Skip event...") + return None + evt = NuRadioReco.framework.event.Event(event_info.run, event_info.eventNumber) station = NuRadioReco.framework.station.Station(event_info.station) station.set_station_time(astropy.time.Time(trigger_time, format='unix')) @@ -527,7 +533,7 @@ def _get_event(self, event_info, waveforms): for channel_id, wf in enumerate(waveforms): channel = NuRadioReco.framework.channel.Channel(channel_id) if self._read_calibrated_data: - channel.set_trace(wf * units.mV, event_info.sampleRate * units.GHz) + channel.set_trace(wf * units.mV, sampling_rate * units.GHz) else: # wf stores ADC counts @@ -539,7 +545,7 @@ def _get_event(self, event_info, waveforms): # convert adc to voltage wf *= (self._adc_ref_voltage_range / (2 ** (self._adc_n_bits) - 1)) - channel.set_trace(wf, event_info.sampleRate * units.GHz) + channel.set_trace(wf, sampling_rate * units.GHz) time_offset = get_time_offset(event_info.triggerType) channel.set_trace_start_time(-time_offset) # relative to event/trigger time From 5c1455499caff9f0c5b68b443ada30e934e0fb0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Wed, 26 Apr 2023 14:38:59 +0200 Subject: [PATCH 253/418] Pass logging level to mattak --- NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py b/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py index 335b5dc85..d40189863 100644 --- a/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py +++ b/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py @@ -286,6 +286,7 @@ def begin(self, self.__skipped_runs = 0 self.__n_runs = 0 + verbose = log_level == logging.DEBUG for data_dir in data_dirs: if not os.path.exists(data_dir): @@ -296,7 +297,7 @@ def begin(self, self.logger.error(f"Incomplete directory: {data_dir}. Skip ...") continue - dataset = mattak.Dataset.Dataset(station=0, run=0, data_dir=data_dir, backend=mattak_backend) + dataset = mattak.Dataset.Dataset(station=0, run=0, data_dir=data_dir, backend=mattak_backend, verbose=verbose) # filter runs/datasets based on if select_runs and self.__run_table is not None and not self.__select_run(dataset): From edbef10044eb1ef497d858ef569f99a4f41d027b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Wed, 26 Apr 2023 18:44:51 +0200 Subject: [PATCH 254/418] Fixing bug in readers begin() method. rearange the begin method a bit --- .../modules/io/RNO_G/readRNOGDataMattak.py | 51 ++++++++++--------- 1 file changed, 27 insertions(+), 24 deletions(-) diff --git a/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py b/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py index d40189863..881ba3769 100644 --- a/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py +++ b/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py @@ -139,7 +139,7 @@ def begin(self, select_runs=False, apply_baseline_correction=True, convert_to_voltage=True, - selectors=None, + selectors=[], run_table_path=None, run_types=["physics"], run_time_range=None, @@ -219,18 +219,8 @@ def begin(self, # is read and convert_to_voltage is True. self._adc_ref_voltage_range = 2.5 * units.volt self._adc_n_bits = 12 - - self.__max_trigger_rate = max_trigger_rate - self.__run_types = run_types - - if run_time_range is not None: - convert_time = lambda t: None if t is None else astropy.time.Time(t) - self._time_low = convert_time(run_time_range[0]) - self._time_high = convert_time(run_time_range[1]) - else: - self._time_low = None - self._time_high = None - + + # Initialize run table for run selection self.__run_table = None if select_runs: if run_table_path is None: @@ -248,22 +238,29 @@ def begin(self, else: import pandas self.__run_table = pandas.read_csv(run_table_path) - + + # Set parameter for run selection + self.__max_trigger_rate = max_trigger_rate + self.__run_types = run_types + + if run_time_range is not None: + convert_time = lambda t: None if t is None else astropy.time.Time(t) + self._time_low = convert_time(run_time_range[0]) + self._time_high = convert_time(run_time_range[1]) + else: + self._time_low = None + self._time_high = None + if select_runs and self.__run_table is not None: self.logger.info("\n\tSelect runs with type: {}".format(", ".join(run_types)) + f"\n\tSelect runs with max. trigger rate of {max_trigger_rate / units.Hz} Hz" f"\n\tSelect runs which are between {self._time_low} - {self._time_high}") - if not isinstance(data_dirs, (list, np.ndarray)): - data_dirs = [data_dirs] - - if selectors is not None: - if not isinstance(selectors, (list, np.ndarray)): - selectors = [selectors] - - self.logger.info(f"Found {len(selectors)} selector(s)") - - self._selectors = selectors + # Initialize selectors for event filtering + if not isinstance(selectors, (list, np.ndarray)): + selectors = [selectors] + + self.logger.info(f"Found {len(selectors)} selector(s)") if select_triggers is not None: if isinstance(select_triggers, str): @@ -271,7 +268,10 @@ def begin(self, else: for select_trigger in select_triggers: selectors.append(lambda eventInfo: eventInfo.triggerType == select_trigger) + + self._selectors = selectors + # Read data self._time_begin = 0 self._time_run = 0 self.__counter = 0 @@ -286,6 +286,9 @@ def begin(self, self.__skipped_runs = 0 self.__n_runs = 0 + if not isinstance(data_dirs, (list, np.ndarray)): + data_dirs = [data_dirs] + verbose = log_level == logging.DEBUG for data_dir in data_dirs: From 7ad0d98e07bb44903f0a1c7976f5c2823608ed2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Wed, 26 Apr 2023 18:45:25 +0200 Subject: [PATCH 255/418] Import logger output --- NuRadioReco/modules/measured_noise/RNO_G/noiseImporter.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/NuRadioReco/modules/measured_noise/RNO_G/noiseImporter.py b/NuRadioReco/modules/measured_noise/RNO_G/noiseImporter.py index 287ca1ae8..70ce1e016 100644 --- a/NuRadioReco/modules/measured_noise/RNO_G/noiseImporter.py +++ b/NuRadioReco/modules/measured_noise/RNO_G/noiseImporter.py @@ -82,7 +82,8 @@ def begin(self, noise_folders, file_pattern="*", self.logger.info(f"Found {len(self.__noise_folders)}") if not len(self.__noise_folders): - raise ValueError + self.logger.error("No folders found") + raise FileNotFoundError("No folders found") if scramble_noise_file_order: self.__random_gen.shuffle(self.__noise_folders) From eacffe47522d314388e1e8e2c796ad83bb57f0e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Thu, 27 Apr 2023 12:29:53 +0200 Subject: [PATCH 256/418] Improve logging, change begin interface (introduce general mattak_kwargs) --- .../modules/io/RNO_G/readRNOGDataMattak.py | 49 +++++++++++-------- 1 file changed, 28 insertions(+), 21 deletions(-) diff --git a/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py b/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py index 881ba3769..b8d90a729 100644 --- a/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py +++ b/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py @@ -133,19 +133,19 @@ def all_files_in_directory(mattak_dir): class readRNOGData: def begin(self, - data_dirs, - read_calibrated_data=False, - select_triggers=None, - select_runs=False, - apply_baseline_correction=True, - convert_to_voltage=True, - selectors=[], - run_table_path=None, - run_types=["physics"], - run_time_range=None, - max_trigger_rate=0 * units.Hz, - mattak_backend="auto", - log_level=logging.INFO): + data_dirs, + read_calibrated_data=False, + select_triggers=None, + select_runs=False, + apply_baseline_correction=True, + convert_to_voltage=True, + selectors=[], + run_table_path=None, + run_types=["physics"], + run_time_range=None, + max_trigger_rate=0 * units.Hz, + mattak_kwargs={}, + log_level=logging.INFO): """ Parameters @@ -198,12 +198,14 @@ def begin(self, Used to select/reject runs from information in the RNO-G RunTable. Maximum allowed trigger rate (per run) in Hz. If 0, no cut is applied. (Default: 1 Hz) - mattak_backend: str - Select a mattak backend. Options are "auto", "pyroot", "uproot". If "auto" is selected, pyroot is used if available otherwise - a "fallback" to uproot is used. (Default: "auto") + mattak_kwargs: dict + Dictionary of arguments for mattak.Dataset.Dataset. (Default: {}) + Example: Select a mattak "backend". Options are "auto", "pyroot", "uproot". If "auto" is selected, + pyroot is used if available otherwise a "fallback" to uproot is used. (Default: "auto") log_level: enum - Set verbosity level of logger + Set verbosity level of logger. If logging.DEBUG, set mattak to verbose (unless specified in mattak_kwargs). + (Default: logging.INFO) """ t0 = time.time() @@ -289,7 +291,12 @@ def begin(self, if not isinstance(data_dirs, (list, np.ndarray)): data_dirs = [data_dirs] - verbose = log_level == logging.DEBUG + # Set verbose for mattak + if "verbose" in mattak_kwargs: + vabose = mattak_kwargs.pop("verbose") + else: + verbose = log_level == logging.DEBUG + for data_dir in data_dirs: if not os.path.exists(data_dir): @@ -300,7 +307,7 @@ def begin(self, self.logger.error(f"Incomplete directory: {data_dir}. Skip ...") continue - dataset = mattak.Dataset.Dataset(station=0, run=0, data_dir=data_dir, backend=mattak_backend, verbose=verbose) + dataset = mattak.Dataset.Dataset(station=0, run=0, data_dir=data_dir, verbose=verbose, **mattak_kwargs) # filter runs/datasets based on if select_runs and self.__run_table is not None and not self.__select_run(dataset): @@ -321,8 +328,8 @@ def begin(self, self._n_events_total = np.sum(self.__n_events_per_dataset) self._time_begin = time.time() - t0 - self.logger.info(f"Using the {self._datasets[0].backend} Mattak backend.") - self.logger.info(f"{self._n_events_total} events in {len(self._datasets)} runs/datasets have been found.") + self.logger.info(f"{self._n_events_total} events in {len(self._datasets)} runs/datasets " + f"have been found using the {self._datasets[0].backend} Mattak backend.") if not self._n_events_total: err = "No runs have been selected. Abort ..." From 1e19aa7aa16d93c24de35fb296e54e50fc1776ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Thu, 27 Apr 2023 13:34:07 +0200 Subject: [PATCH 257/418] fix whitespace in logger --- NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py b/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py index b8d90a729..b77895095 100644 --- a/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py +++ b/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py @@ -707,5 +707,5 @@ def end(self): f"\n\tRead {self.__counter} events (skipped {self.__skipped} events)" f"\n\tTime to initialize data sets : {self._time_begin:.2f}s" f"\n\tTime to initialize all events : {self._time_run:.2f}s" - f"\n\tTime to per event : {self._time_run / self.__counter:.2f}s" + f"\n\tTime to per event : {self._time_run / self.__counter:.2f}s" f"\n\tRead {self.__n_runs} runs, skipped {self.__skipped_runs} runs.") From e0940ab5c2a48462dac4b2112aae168019d766ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Fri, 28 Apr 2023 10:28:25 +0200 Subject: [PATCH 258/418] Remove one ws --- NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py | 1 - 1 file changed, 1 deletion(-) diff --git a/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py b/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py index b77895095..9e528af1e 100644 --- a/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py +++ b/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py @@ -649,7 +649,6 @@ def get_event_by_index(self, event_index): def get_event(self, run_nr, event_id): - """ Allows to read a specific event identifed by run number and event id Parameters From 055e058a5256be8829f09431f2833381f5c1909c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Fri, 28 Apr 2023 15:48:48 +0200 Subject: [PATCH 259/418] Start implementing support to read file by file --- .../modules/io/RNO_G/readRNOGDataMattak.py | 33 +++++++++++-------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py b/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py index 9e528af1e..e6d4d1ec8 100644 --- a/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py +++ b/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py @@ -133,7 +133,7 @@ def all_files_in_directory(mattak_dir): class readRNOGData: def begin(self, - data_dirs, + dirs_files, read_calibrated_data=False, select_triggers=None, select_runs=False, @@ -151,8 +151,8 @@ def begin(self, Parameters ---------- - data_dirs: list of strings / string - Path to run directories (i.e. ".../stationXX/runXXX/") + dirs_files: str, list(str) + Path to run directories (i.e. ".../stationXX/runXXX/") or path to root files (have to be "combined" mattak files). read_calibrated_data: bool If True, read calibrated waveforms from Mattak.Dataset. If False, read "raw" ADC traces. @@ -283,13 +283,13 @@ def begin(self, self._datasets = [] self.__n_events_per_dataset = [] - self.logger.info(f"Parse through {len(data_dirs)} directory/ies.") + self.logger.info(f"Parse through / read-in {len(dirs_files)} directory(ies) / file(s).") self.__skipped_runs = 0 self.__n_runs = 0 - if not isinstance(data_dirs, (list, np.ndarray)): - data_dirs = [data_dirs] + if not isinstance(dirs_files, (list, np.ndarray)): + dirs_files = [dirs_files] # Set verbose for mattak if "verbose" in mattak_kwargs: @@ -297,17 +297,22 @@ def begin(self, else: verbose = log_level == logging.DEBUG - for data_dir in data_dirs: + for dir_file in dirs_files: - if not os.path.exists(data_dir): - self.logger.error(f"The directory {data_dir} does not exist") + if not os.path.exists(dir_file): + self.logger.error(f"The directory/file {dir_file} does not exist") continue - if not all_files_in_directory(data_dir): - self.logger.error(f"Incomplete directory: {data_dir}. Skip ...") - continue - - dataset = mattak.Dataset.Dataset(station=0, run=0, data_dir=data_dir, verbose=verbose, **mattak_kwargs) + if os.path.isdir(dir_file): + + if not all_files_in_directory(dir_file): + self.logger.error(f"Incomplete directory: {dir_file}. Skip ...") + continue + + dataset = mattak.Dataset.Dataset(station=0, run=0, data_dir=dir_file, verbose=verbose, **mattak_kwargs) + else: + raise NotImplementedError("The option to read in files is not implemented yet") + # filter runs/datasets based on if select_runs and self.__run_table is not None and not self.__select_run(dataset): From 9491ae2a5b62da9bfe4f6434ddb57bd78e7a85ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Fri, 28 Apr 2023 16:51:00 +0200 Subject: [PATCH 260/418] Improve logger --- NuRadioReco/modules/measured_noise/RNO_G/noiseImporter.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NuRadioReco/modules/measured_noise/RNO_G/noiseImporter.py b/NuRadioReco/modules/measured_noise/RNO_G/noiseImporter.py index 70ce1e016..d3f18689f 100644 --- a/NuRadioReco/modules/measured_noise/RNO_G/noiseImporter.py +++ b/NuRadioReco/modules/measured_noise/RNO_G/noiseImporter.py @@ -103,7 +103,7 @@ def begin(self, noise_folders, file_pattern="*", self.logger.info("Get event informations ...") t0 = time.time() noise_information = self._noise_reader.get_events_information(keys=["station"]) - self.logger.info(f"... in {time.time() - t0:.2f}s") + self.logger.info(f"... of {len(noise_information)} (selected) events in {time.time() - t0:.2f}s") self.__event_index_list = np.array(list(noise_information.keys())) self.__station_id_list = np.array([ele["station"] for ele in noise_information.values()]) From ee79203e3088acbf90bf5fddfd58dc10a05271c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Fri, 28 Apr 2023 17:19:50 +0200 Subject: [PATCH 261/418] Check validity of eventInfo outside of _get_event to not unnecessarily read wfs --- .../modules/io/RNO_G/readRNOGDataMattak.py | 53 +++++++++++++++---- 1 file changed, 42 insertions(+), 11 deletions(-) diff --git a/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py b/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py index e6d4d1ec8..c3248581e 100644 --- a/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py +++ b/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py @@ -507,6 +507,37 @@ def get_events_information(self, keys=["station", "run", "eventNumber"]): return self._events_information + def _check_for_valid_information_in_event_info(self, event_info): + """ + Checks if certain information (sampling rate, trigger time) in mattak.Dataset.EventInfo are valid + + Parameters + ---------- + + event_info: mattak.Dataset.EventInfo + + Returns + ------- + + is_valid: bool + Returns True if all information valid, false otherwise + """ + + + if math.isinf(event_info.triggerTime): + self.logger.error(f"Event {event_info.eventNumber} (st {event_info.station}, run {event_info.run}) " + "has inf trigger time. Skip event...") + return False + + + if event_info.sampleRate == 0 or event_info.sampleRate is None: + self.logger.error(f"Event {event_info.eventNumber} (st {event_info.station}, run {event_info.run}) " + f"has a sampling rate of {event_info.sampleRate} GHz. Skip event...") + return False + + return True + + def _get_event(self, event_info, waveforms): """ Return a NuRadioReco event @@ -526,16 +557,7 @@ def _get_event(self, event_info, waveforms): """ trigger_time = event_info.triggerTime - if math.isinf(trigger_time): - self.logger.error(f"Event {event_info.eventNumber} (st {event_info.station}, run {event_info.run}) " - "has inf trigger time. Skip event...") - return None - sampling_rate = event_info.sampleRate - if sampling_rate == 0: - self.logger.error(f"Event {event_info.eventNumber} (st {event_info.station}, run {event_info.run}) " - f"has a sampling rate of {sampling_rate} GHz. Skip event...") - return None evt = NuRadioReco.framework.event.Event(event_info.run, event_info.eventNumber) station = NuRadioReco.framework.station.Station(event_info.station) @@ -600,6 +622,9 @@ def run(self): if self._filter_event(evtinfo, event_idx): continue + if not self._check_for_valid_information_in_event_info(evtinfo): + continue + # Just read wfs if necessary if wfs is None: wfs = dataset.wfs() @@ -607,8 +632,6 @@ def run(self): waveforms_of_event = wfs[idx] evt = self._get_event(evtinfo, waveforms_of_event) - if evt is None: - continue self._time_run += time.time() - t0 self.__counter += 1 @@ -641,6 +664,10 @@ def get_event_by_index(self, event_index): if self._filter_event(event_info, event_index): return None + + # check this before reading the wfs + if not self._check_for_valid_information_in_event_info(event_info): + return None # access data waveforms = dataset.wfs() @@ -694,6 +721,10 @@ def get_event(self, run_nr, event_id): if self._filter_event(event_info, event_index): return None + + # check this before reading the wfs + if not self._check_for_valid_information_in_event_info(event_info): + return None # access data waveforms = dataset.wfs() From e47964d234dfabd62c0a38fae73cedd16b485d2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Fri, 28 Apr 2023 17:56:01 +0200 Subject: [PATCH 262/418] Move logger to right position, add more logging --- NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py b/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py index c3248581e..22b0d2ce8 100644 --- a/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py +++ b/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py @@ -261,9 +261,7 @@ def begin(self, # Initialize selectors for event filtering if not isinstance(selectors, (list, np.ndarray)): selectors = [selectors] - - self.logger.info(f"Found {len(selectors)} selector(s)") - + if select_triggers is not None: if isinstance(select_triggers, str): selectors.append(lambda eventInfo: eventInfo.triggerType == select_triggers) @@ -272,12 +270,14 @@ def begin(self, selectors.append(lambda eventInfo: eventInfo.triggerType == select_trigger) self._selectors = selectors - + self.logger.info(f"Found {len(self._selectors)} selector(s)") + # Read data self._time_begin = 0 self._time_run = 0 self.__counter = 0 self.__skipped = 0 + self.__invalid = 0 self._events_information = None self._datasets = [] @@ -527,12 +527,14 @@ def _check_for_valid_information_in_event_info(self, event_info): if math.isinf(event_info.triggerTime): self.logger.error(f"Event {event_info.eventNumber} (st {event_info.station}, run {event_info.run}) " "has inf trigger time. Skip event...") + self.__invalid += 1 return False if event_info.sampleRate == 0 or event_info.sampleRate is None: self.logger.error(f"Event {event_info.eventNumber} (st {event_info.station}, run {event_info.run}) " f"has a sampling rate of {event_info.sampleRate} GHz. Skip event...") + self.__invalid += 1 return False return True @@ -739,8 +741,8 @@ def get_event(self, run_nr, event_id): def end(self): self.logger.info( - f"\n\tRead {self.__counter} events (skipped {self.__skipped} events)" + f"\n\tRead {self.__counter} events (skipped {self.__skipped} events, {self.__invalid} invalid events)" f"\n\tTime to initialize data sets : {self._time_begin:.2f}s" - f"\n\tTime to initialize all events : {self._time_run:.2f}s" + f"\n\tTime to read all events : {self._time_run:.2f}s" f"\n\tTime to per event : {self._time_run / self.__counter:.2f}s" f"\n\tRead {self.__n_runs} runs, skipped {self.__skipped_runs} runs.") From 47011bf1b80ecd409704737106bfb321c30d2ee1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Tue, 2 May 2023 14:49:31 +0200 Subject: [PATCH 263/418] Allow overwritting the sampling rate in the reader because some mattak files do not have that information --- .../modules/io/RNO_G/readRNOGDataMattak.py | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py b/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py index 22b0d2ce8..643b1d9fc 100644 --- a/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py +++ b/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py @@ -145,6 +145,7 @@ def begin(self, run_time_range=None, max_trigger_rate=0 * units.Hz, mattak_kwargs={}, + overwrite_sampling_rate=None, log_level=logging.INFO): """ @@ -201,7 +202,12 @@ def begin(self, mattak_kwargs: dict Dictionary of arguments for mattak.Dataset.Dataset. (Default: {}) Example: Select a mattak "backend". Options are "auto", "pyroot", "uproot". If "auto" is selected, - pyroot is used if available otherwise a "fallback" to uproot is used. (Default: "auto") + pyroot is used if available otherwise a "fallback" to uproot is used. (Default: "auto") + + overwrite_sampling_rate: float + Set sampling rate of the imported waveforms. This overwrites what is read out from runinfo (i.e., stored in the mattak files). + If None, nothing is overwritten and the sampling rate from the mattak file is used. (Default: None) + NOTE: This option might be necessary when old mattak files are read which have this not set. log_level: enum Set verbosity level of logger. If logging.DEBUG, set mattak to verbose (unless specified in mattak_kwargs). @@ -221,6 +227,8 @@ def begin(self, # is read and convert_to_voltage is True. self._adc_ref_voltage_range = 2.5 * units.volt self._adc_n_bits = 12 + + self._overwrite_sampling_rate = overwrite_sampling_rate # Initialize run table for run selection self.__run_table = None @@ -389,7 +397,7 @@ def __select_run(self, dataset): trigger_rate = run_info["trigger_rate"].values[0] * units.Hz if self.__max_trigger_rate and trigger_rate > self.__max_trigger_rate: - self.logger.info(f"Reject station {station_id} run {run_id} because trigger rate is to high ({trigger_rate / units.Hz} Hz)") + self.logger.info(f"Reject station {station_id} run {run_id} because trigger rate is to high ({trigger_rate / units.Hz:.2f} Hz)") return False return True @@ -531,9 +539,9 @@ def _check_for_valid_information_in_event_info(self, event_info): return False - if event_info.sampleRate == 0 or event_info.sampleRate is None: + if (event_info.sampleRate == 0 or event_info.sampleRate is None) and self._overwrite_sampling_rate is None: self.logger.error(f"Event {event_info.eventNumber} (st {event_info.station}, run {event_info.run}) " - f"has a sampling rate of {event_info.sampleRate} GHz. Skip event...") + f"has a sampling rate of {event_info.sampleRate:.2f} GHz. Skip event...") self.__invalid += 1 return False @@ -559,7 +567,10 @@ def _get_event(self, event_info, waveforms): """ trigger_time = event_info.triggerTime - sampling_rate = event_info.sampleRate + if self._overwrite_sampling_rate is not None: + sampling_rate = self._overwrite_sampling_rate + else: + sampling_rate = event_info.sampleRate evt = NuRadioReco.framework.event.Event(event_info.run, event_info.eventNumber) station = NuRadioReco.framework.station.Station(event_info.station) From f331d1945942d339bcf75cf0633a7f3fbf1f4cfa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Wed, 3 May 2023 18:19:07 +0200 Subject: [PATCH 264/418] Make conversion to int explicit in python --- NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py b/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py index 643b1d9fc..9c832f95b 100644 --- a/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py +++ b/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py @@ -727,7 +727,8 @@ def get_event(self, run_nr, event_id): else: pass - event_index = event_idx_ids[mask, 0][0] + # int(...) necessary to pass it to mattak + event_index = int(event_idx_ids[mask, 0][0]) dataset = self.__get_dataset_for_event(event_index) event_info = dataset.eventInfo() # returns a single eventInfo From 5c3fcb7183814b97ceb192328da5e1dbf63d4bae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Wed, 3 May 2023 18:23:56 +0200 Subject: [PATCH 265/418] Improve logger error output --- NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py b/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py index 9c832f95b..7c0c8ee84 100644 --- a/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py +++ b/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py @@ -541,7 +541,8 @@ def _check_for_valid_information_in_event_info(self, event_info): if (event_info.sampleRate == 0 or event_info.sampleRate is None) and self._overwrite_sampling_rate is None: self.logger.error(f"Event {event_info.eventNumber} (st {event_info.station}, run {event_info.run}) " - f"has a sampling rate of {event_info.sampleRate:.2f} GHz. Skip event...") + f"has a sampling rate of {event_info.sampleRate:.2f} GHz. Event is skipped ... " + f"You can avoid this by setting 'overwrite_sampling_rate' in the begin() method.") self.__invalid += 1 return False From fc51646b58eb658cfda9c69a5c4a9e27ab832d11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= <30903175+fschlueter@users.noreply.github.com> Date: Fri, 5 May 2023 19:01:20 +0200 Subject: [PATCH 266/418] Update readRNOGDataMattak.py: Fix typo --- NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py b/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py index 7c0c8ee84..4c4b8fede 100644 --- a/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py +++ b/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py @@ -301,7 +301,7 @@ def begin(self, # Set verbose for mattak if "verbose" in mattak_kwargs: - vabose = mattak_kwargs.pop("verbose") + verbose = mattak_kwargs.pop("verbose") else: verbose = log_level == logging.DEBUG From 6ea10e6dbf0dcf3e039c9d72ed16b03fde3ce7cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Fri, 5 May 2023 19:13:51 +0200 Subject: [PATCH 267/418] Add init func which imports the run table. add set_selector function and use it in begin() --- .../modules/io/RNO_G/readRNOGDataMattak.py | 99 +++++++++++-------- 1 file changed, 60 insertions(+), 39 deletions(-) diff --git a/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py b/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py index 4c4b8fede..a61dfa8fc 100644 --- a/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py +++ b/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py @@ -131,7 +131,36 @@ def all_files_in_directory(mattak_dir): class readRNOGData: + + def __init__(self, run_table_path=None): + """ + Parameters + ---------- + + run_table_path: str + Path to a run_table.cvs file. If None, the run table is queried from the DB. (Default: None) + """ + + # Initialize run table for run selection + self.__run_table = None + if run_table_path is None: + try: + from rnog_data.runtable import RunTable + self.logger.debug("Access RunTable database ...") + try: + self.__run_table = RunTable().get_table() + except: + self.logger.warn("No connect to RunTable database could be established. " + "Runs can not be filtered.") + except ImportError: + self.logger.warn("Import of run table failed. Runs can not be filtered.! \n" + "You can get the interface from GitHub: git@github.com:RNO-G/rnog-data-analysis-and-issues.git") + else: + import pandas + self.__run_table = pandas.read_csv(run_table_path) + + def begin(self, dirs_files, read_calibrated_data=False, @@ -140,7 +169,6 @@ def begin(self, apply_baseline_correction=True, convert_to_voltage=True, selectors=[], - run_table_path=None, run_types=["physics"], run_time_range=None, max_trigger_rate=0 * units.Hz, @@ -148,7 +176,6 @@ def begin(self, overwrite_sampling_rate=None, log_level=logging.INFO): """ - Parameters ---------- @@ -161,7 +188,7 @@ def begin(self, select_triggers: str or list(str) Names of triggers which should be selected. Convinence interface instead of passing a selector - (see "selectors" below. (Default: None) + (see "selectors" below). (Default: None) select_runs: bool If True, use information in run_table to select runs (based on run_type, run_time, trigger_rate, ...). @@ -182,10 +209,7 @@ def begin(self, selectors: list of lambdas List of lambda(eventInfo) -> bool to pass to mattak.Dataset.iterate to select events. Example: trigger_selector = lambda eventInfo: eventInfo.triggerType == "FORCE" - - run_table_path: str - Path to a run_table.cvs file. If None, the run table is queried from the DB. (Default: None) - + run_types: list Used to select/reject runs from information in the RNO-G RunTable. List of run_types to be used. (Default: ['physics']) @@ -230,25 +254,6 @@ def begin(self, self._overwrite_sampling_rate = overwrite_sampling_rate - # Initialize run table for run selection - self.__run_table = None - if select_runs: - if run_table_path is None: - try: - from rnog_data.runtable import RunTable - self.logger.debug("Access RunTable database ...") - try: - self.__run_table = RunTable().get_table() - except: - self.logger.error("No connect to RunTable database could be established. " - "Runs will not be filtered.") - except ImportError: - self.logger.error("Import of run table failed. You will not be able to select runs! \n" - "You can get the interface from GitHub: git@github.com:RNO-G/rnog-data-analysis-and-issues.git") - else: - import pandas - self.__run_table = pandas.read_csv(run_table_path) - # Set parameter for run selection self.__max_trigger_rate = max_trigger_rate self.__run_types = run_types @@ -266,19 +271,7 @@ def begin(self, f"\n\tSelect runs with max. trigger rate of {max_trigger_rate / units.Hz} Hz" f"\n\tSelect runs which are between {self._time_low} - {self._time_high}") - # Initialize selectors for event filtering - if not isinstance(selectors, (list, np.ndarray)): - selectors = [selectors] - - if select_triggers is not None: - if isinstance(select_triggers, str): - selectors.append(lambda eventInfo: eventInfo.triggerType == select_triggers) - else: - for select_trigger in select_triggers: - selectors.append(lambda eventInfo: eventInfo.triggerType == select_trigger) - - self._selectors = selectors - self.logger.info(f"Found {len(self._selectors)} selector(s)") + self.set_selectors(selectors, select_triggers) # Read data self._time_begin = 0 @@ -348,6 +341,34 @@ def begin(self, err = "No runs have been selected. Abort ..." self.logger.error(err) raise ValueError(err) + + + def set_selectors(self, selectors, select_triggers=None): + """ + Parameters + ---------- + + selectors: list of lambdas + List of lambda(eventInfo) -> bool to pass to mattak.Dataset.iterate to select events. + Example: trigger_selector = lambda eventInfo: eventInfo.triggerType == "FORCE" + + select_triggers: str or list(str) + Names of triggers which should be selected. Convinence interface instead of passing a selector. (Default: None) + """ + + # Initialize selectors for event filtering + if not isinstance(selectors, (list, np.ndarray)): + selectors = [selectors] + + if select_triggers is not None: + if isinstance(select_triggers, str): + selectors.append(lambda eventInfo: eventInfo.triggerType == select_triggers) + else: + for select_trigger in select_triggers: + selectors.append(lambda eventInfo: eventInfo.triggerType == select_trigger) + + self._selectors = selectors + self.logger.info(f"Set {len(self._selectors)} selector(s)") def __select_run(self, dataset): From 31376d0934badca50deb24e83cea660587e7a1be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Thu, 11 May 2023 15:43:23 +0200 Subject: [PATCH 268/418] Allow trigger types 'UNKNOWN' to be read in by the reader --- NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py b/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py index a61dfa8fc..ca4f27a98 100644 --- a/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py +++ b/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py @@ -86,16 +86,19 @@ def get_time_offset(trigger_type): time_offsets = { "FORCE": 0, "LT": 250 * units.ns, - "RADIANT": 475 * units.ns + "RADIANT": 475 * units.ns, + "UNKNOWN": 0 # Due to a firmware issue at the beginning of data taking the trigger types were not properly set. } + # Should have the same time offset ?! if trigger_type.startswith("RADIANT"): trigger_type = "RADIANT" if trigger_type in time_offsets: return time_offsets[trigger_type] else: - raise KeyError(f"Unknown trigger type: {trigger_type}. Known are: FORCE, LT, RADIANT. Abort ....") + known_trigger_types = ", ".join(time_offsets.keys()) + raise KeyError(f"Unknown trigger type: {trigger_type}. Known are: {known_trigger_types}. Abort ....") def all_files_in_directory(mattak_dir): From 1e98fd65aa588b3b48510b6963494a9f2441cf01 Mon Sep 17 00:00:00 2001 From: Alan Coleman Date: Mon, 15 May 2023 13:30:17 -0400 Subject: [PATCH 269/418] Added getter --- NuRadioMC/SignalGen/ARZ/ARZ.py | 37 ++++++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/NuRadioMC/SignalGen/ARZ/ARZ.py b/NuRadioMC/SignalGen/ARZ/ARZ.py index 4b8523200..efa1b3bd8 100644 --- a/NuRadioMC/SignalGen/ARZ/ARZ.py +++ b/NuRadioMC/SignalGen/ARZ/ARZ.py @@ -468,6 +468,38 @@ def set_interpolation_factor2(self, interp_factor): """ self._interp_factor2 = interp_factor + def get_shower_profile(self, shower_energy, shower_type, iN): + """ + Gets a charge-excess profile + + Parameters + ---------- + shower_energy: float + the energy of the shower + shower_type: string (default "HAD") + type of shower, either "HAD" (hadronic), "EM" (electromagnetic) or "TAU" (tau lepton induced) + iN: int + specify shower number + + Returns + ------- + efield_trace: two arrays of floats + slant depths and charge profile amplitudes + """ + + energies = np.array([*self._library[shower_type]]) + iE = np.argmin(np.abs(energies - shower_energy)) + + rescaling_factor = shower_energy / energies[iE] + + profiles = self._library[shower_type][energies[iE]] + N_profiles = len(profiles['charge_excess']) + profile_depth = profiles['depth'] + profile_ce = profiles['charge_excess'][iN] * rescaling_factor + + return profile_depth, profile_ce + + def get_time_trace(self, shower_energy, theta, N, dt, shower_type, n_index, R, shift_for_xmax=False, same_shower=False, iN=None, output_mode='trace', maximum_angle=20 * units.deg): """ @@ -483,10 +515,6 @@ def get_time_trace(self, shower_energy, theta, N, dt, shower_type, n_index, R, s number of samples in the time domain dt: float size of one time bin in units of time - profile_depth: array of floats - shower depth values of the charge excess profile - profile_ce: array of floats - charge-excess values of the charge excess profile shower_type: string (default "HAD") type of shower, either "HAD" (hadronic), "EM" (electromagnetic) or "TAU" (tau lepton induced) n_index: float (default 1.78) @@ -537,6 +565,7 @@ def get_time_trace(self, shower_energy, theta, N, dt, shower_type, n_index, R, s rescaling_factor = shower_energy / energies[iE] logger.info("shower energy of {:.3g}eV requested, closest available energy is {:.3g}eV. The amplitude of the charge-excess profile will be rescaled accordingly by a factor of {:.2f}".format(shower_energy / units.eV, energies[iE] / units.eV, rescaling_factor)) profiles = self._library[shower_type][energies[iE]] + N_profiles = len(profiles['charge_excess']) if(iN is None or np.isnan(iN)): From b03f3ff8e7802caf740b00c590c79b631a2b0caa Mon Sep 17 00:00:00 2001 From: Alan Coleman Date: Mon, 15 May 2023 13:34:40 -0400 Subject: [PATCH 270/418] Change log --- changelog.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/changelog.txt b/changelog.txt index 8d6735957..8f84eea2a 100644 --- a/changelog.txt +++ b/changelog.txt @@ -4,6 +4,7 @@ please update the categories "new features" and "bugfixes" before a pull request version 2.2.0-dev new features: +- added getting to query ARZ charge-excess profiles - upgrade to proposal v 7.5.0 with new NuRadioProposal interface and improved LPM treatment - add script to generate / download pre-calculated proposal tables for known detector configurations - adding default RadioPropa ice model object to medium with the feature to set a personlised object as alternative From 79cf83eb5ec131bb2378e5151e649b55de2a1c2f Mon Sep 17 00:00:00 2001 From: Alan Coleman Date: Mon, 15 May 2023 14:35:49 -0400 Subject: [PATCH 271/418] docstrings --- NuRadioMC/SignalGen/ARZ/ARZ.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/NuRadioMC/SignalGen/ARZ/ARZ.py b/NuRadioMC/SignalGen/ARZ/ARZ.py index efa1b3bd8..e860a021a 100644 --- a/NuRadioMC/SignalGen/ARZ/ARZ.py +++ b/NuRadioMC/SignalGen/ARZ/ARZ.py @@ -483,7 +483,7 @@ def get_shower_profile(self, shower_energy, shower_type, iN): Returns ------- - efield_trace: two arrays of floats + depth, excess: two arrays of floats slant depths and charge profile amplitudes """ @@ -493,7 +493,6 @@ def get_shower_profile(self, shower_energy, shower_type, iN): rescaling_factor = shower_energy / energies[iE] profiles = self._library[shower_type][energies[iE]] - N_profiles = len(profiles['charge_excess']) profile_depth = profiles['depth'] profile_ce = profiles['charge_excess'][iN] * rescaling_factor From 92be315d57d4ddf14057290fcda82edf4d8e38b8 Mon Sep 17 00:00:00 2001 From: Alan Coleman Date: Mon, 15 May 2023 15:32:30 -0400 Subject: [PATCH 272/418] more docstrings --- NuRadioMC/SignalGen/ARZ/ARZ.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/NuRadioMC/SignalGen/ARZ/ARZ.py b/NuRadioMC/SignalGen/ARZ/ARZ.py index e860a021a..5726776ec 100644 --- a/NuRadioMC/SignalGen/ARZ/ARZ.py +++ b/NuRadioMC/SignalGen/ARZ/ARZ.py @@ -63,7 +63,7 @@ def get_vector_potential( profile_ce: array of floats charge-excess values of the charge excess profile shower_type: string (default "HAD") - type of shower, either "HAD" (hadronic), "EM" (electromagnetic) or "TAU" (tau lepton induced) + type of shower, either "HAD" (hadronic) or "EM" (electromagnetic) n_index: float (default 1.78) index of refraction where the shower development takes place distance: float (default 1km) @@ -477,7 +477,7 @@ def get_shower_profile(self, shower_energy, shower_type, iN): shower_energy: float the energy of the shower shower_type: string (default "HAD") - type of shower, either "HAD" (hadronic), "EM" (electromagnetic) or "TAU" (tau lepton induced) + type of shower, either "HAD" (hadronic) or "EM" (electromagnetic) iN: int specify shower number @@ -515,7 +515,7 @@ def get_time_trace(self, shower_energy, theta, N, dt, shower_type, n_index, R, s dt: float size of one time bin in units of time shower_type: string (default "HAD") - type of shower, either "HAD" (hadronic), "EM" (electromagnetic) or "TAU" (tau lepton induced) + type of shower, either "HAD" (hadronic) or "EM" (electromagnetic) n_index: float (default 1.78) index of refraction where the shower development takes place R: float (default 1km) @@ -625,7 +625,7 @@ def get_time_trace(self, shower_energy, theta, N, dt, shower_type, n_index, R, s logger.error("Tau showers are not yet implemented") raise NotImplementedError("Tau showers are not yet implemented") else: - msg = "showers of type {} are not implemented. Use 'HAD', 'EM' or 'TAU'".format(shower_type) + msg = "showers of type {} are not implemented. Use 'HAD', 'EM'".format(shower_type) logger.error(msg) raise NotImplementedError(msg) if self._use_numba: @@ -697,7 +697,7 @@ def get_vector_potential_fast(self, shower_energy, theta, N, dt, profile_depth, profile_ce: array of floats charge-excess values of the charge excess profile shower_type: string (default "HAD") - type of shower, either "HAD" (hadronic), "EM" (electromagnetic) or "TAU" (tau lepton induced) + type of shower, either "HAD" (hadronic) or "EM" (electromagnetic) n_index: float (default 1.78) index of refraction where the shower development takes place distance: float (default 1km) @@ -1164,7 +1164,7 @@ def get_time_trace(self, shower_energy, theta, N, dt, shower_type, n_index, R, dt: float size of one time bin in units of time shower_type: string (default "HAD") - type of shower, either "HAD" (hadronic), "EM" (electromagnetic) or "TAU" (tau lepton induced) + type of shower, either "HAD" (hadronic) or "EM" (electromagnetic) n_index: float (default 1.78) index of refraction where the shower development takes place R: float (default 1km) From cbe2ff93500ba0c8617037046a00dc2258e822c9 Mon Sep 17 00:00:00 2001 From: Christian Glaser Date: Tue, 16 May 2023 14:08:51 +0000 Subject: [PATCH 273/418] this additional flag leads to errors on my end and does not seem to be needed --- NuRadioMC/SignalProp/CPPAnalyticRayTracing/setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NuRadioMC/SignalProp/CPPAnalyticRayTracing/setup.py b/NuRadioMC/SignalProp/CPPAnalyticRayTracing/setup.py index 932437653..adc09a364 100644 --- a/NuRadioMC/SignalProp/CPPAnalyticRayTracing/setup.py +++ b/NuRadioMC/SignalProp/CPPAnalyticRayTracing/setup.py @@ -16,7 +16,7 @@ Extension('wrapper', ['wrapper.pyx'], include_dirs=[numpy.get_include(), '../../utilities/', str(os.environ['GSLDIR']) + '/include/'], library_dirs=[str(os.environ['GSLDIR']) + '/lib/'], - extra_compile_args=['-O3',"-mfpmath=sse"], + extra_compile_args=['-O3'], libraries=['gsl', 'gslcblas'], language='c++' ), From 617eceff0753fc6478f3921b9155854b52b4254b Mon Sep 17 00:00:00 2001 From: Christian Glaser Date: Tue, 16 May 2023 14:09:34 +0000 Subject: [PATCH 274/418] remove print statement --- NuRadioMC/SignalProp/analyticraytracing.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NuRadioMC/SignalProp/analyticraytracing.py b/NuRadioMC/SignalProp/analyticraytracing.py index d9e3c670a..0ab533144 100644 --- a/NuRadioMC/SignalProp/analyticraytracing.py +++ b/NuRadioMC/SignalProp/analyticraytracing.py @@ -639,7 +639,7 @@ def dt(t, C_0, frequency): mask = frequency > 0 freqs = self.__get_frequencies_for_attenuation(frequency, max_detector_freq) gamma_turn, z_turn = self.get_turning_point(self.medium.n_ice ** 2 - C_0 ** -2) - print("_use_optimized_calculation", self._use_optimized_calculation) + self.__logger.info("_use_optimized_calculation", self._use_optimized_calculation) if self._use_optimized_calculation: # The integration of the attenuation factor along the path with scipy.quad is inefficient. The From a57c484e9efaafa495120d33f1544c36be70cf80 Mon Sep 17 00:00:00 2001 From: Christian Glaser Date: Tue, 16 May 2023 14:09:59 +0000 Subject: [PATCH 275/418] update reference file to new noise realizations --- .../1e18_output_noise_reference.hdf5 | Bin 104304 -> 104304 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/NuRadioMC/test/SingleEvents/1e18_output_noise_reference.hdf5 b/NuRadioMC/test/SingleEvents/1e18_output_noise_reference.hdf5 index 093452baabd9803736afe32ba06098068080cf08..83cbb5536a735ae36672ff27073bbf0e39446454 100644 GIT binary patch literal 104304 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 Y7gVpTS$05Px# literal 104304 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 From 0a549b27a5a94871c61c0b287d73e0374ed68b18 Mon Sep 17 00:00:00 2001 From: Sjoerd Bouma Date: Tue, 16 May 2023 17:33:50 +0200 Subject: [PATCH 276/418] re-update version number [ci skip] --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 0e5e01219..7fb653fb4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api" [tool.poetry] name = "NuRadioMC" -version = "2.1.8" +version = "2.2.0-dev" authors = ["Christian Glaser et al."] homepage = "https://github.com/nu-radio/NuRadioMC" documentation = "https://nu-radio.github.io/NuRadioMC/main.html" From c83ea2a250a7904fd6302e0fad64775c94b0e4da Mon Sep 17 00:00:00 2001 From: Christian Glaser Date: Tue, 16 May 2023 17:34:01 +0000 Subject: [PATCH 277/418] fix all occurences of np.complex --- NuRadioReco/detector/amp.py | 2 +- NuRadioReco/detector/antennapattern.py | 6 +++--- NuRadioReco/detector/filterresponse.py | 6 +++--- NuRadioReco/modules/channelGalacticNoiseAdder.py | 4 ++-- .../voltageToEfieldAnalyticConverterForNeutrinos.py | 8 ++++---- NuRadioReco/modules/voltageToEfieldConverter.py | 6 +++--- NuRadioReco/modules/voltageToEfieldConverterPerChannel.py | 2 +- NuRadioReco/utilities/bandpass_filter.py | 6 +++--- NuRadioReco/utilities/trace_utilities.py | 8 ++++---- 9 files changed, 24 insertions(+), 24 deletions(-) diff --git a/NuRadioReco/detector/amp.py b/NuRadioReco/detector/amp.py index 8133af0d6..04dadc714 100644 --- a/NuRadioReco/detector/amp.py +++ b/NuRadioReco/detector/amp.py @@ -25,7 +25,7 @@ def get_amp_response(frequencies, amp_name): get_phase = intp.interp1d(freqs2, np.unwrap(phase)) get_linmag = intp.interp1d(freqs, linmag) - amp_response = np.zeros_like(frequencies, dtype=np.complex) + amp_response = np.zeros_like(frequencies, dtype=complex) mask = (frequencies > max(freqs.min(), freqs2.min())) & (frequencies < min(freqs.max(), freqs2.max())) amp_response[mask] = get_linmag(frequencies[mask]) * np.exp(1j * get_phase(frequencies[mask])) return amp_response diff --git a/NuRadioReco/detector/antennapattern.py b/NuRadioReco/detector/antennapattern.py index 19f79a50e..2452428e1 100644 --- a/NuRadioReco/detector/antennapattern.py +++ b/NuRadioReco/detector/antennapattern.py @@ -64,7 +64,7 @@ def interpolate_linear_vectorized(x, x0, x1, y0, y1, interpolation_method='compl """ x = np.array(x) mask = x0 != x1 - result = np.zeros_like(x, dtype=np.complex) + result = np.zeros_like(x, dtype=complex) denominator = x1 - x0 if interpolation_method == 'complex': result[mask] = y0[mask] + (y1[mask] - y0[mask]) * (x[mask] - x0[mask]) / denominator[mask] @@ -1059,8 +1059,8 @@ def get_antenna_response_vectorized(self, freq, zenith, azimuth, orientation_the of the same length as the frequency input """ if self._notfound: - VEL = {'theta': np.ones(len(freq), dtype=np.complex), - 'phi': np.ones(len(freq), dtype=np.complex)} + VEL = {'theta': np.ones(len(freq), dtype=complex), + 'phi': np.ones(len(freq), dtype=complex)} return VEL if isinstance(freq, (float, int)): diff --git a/NuRadioReco/detector/filterresponse.py b/NuRadioReco/detector/filterresponse.py index 66dbd1d79..58008e251 100644 --- a/NuRadioReco/detector/filterresponse.py +++ b/NuRadioReco/detector/filterresponse.py @@ -24,7 +24,7 @@ def get_filter_response_mini_circuits(frequencies, filter_name): get_S21 = intp.interp1d(ff, S21) - response = np.zeros_like(frequencies, dtype=np.complex) + response = np.zeros_like(frequencies, dtype=complex) mask = (frequencies > ff.min()) & (frequencies < ff.max()) response[mask] = get_S21(frequencies[mask]) return response @@ -54,7 +54,7 @@ def get_filter_response_mini_circuits2(frequencies, filter_name): phase2 = -2 * np.pi * np.cumsum(get_group_delay(fff2) * df) get_phase = intp.interp1d(fff2, phase2) - response = np.zeros_like(frequencies, dtype=np.complex) + response = np.zeros_like(frequencies, dtype=complex) mask = (frequencies > max(ff.min(), ff2.min())) & (frequencies < min(ff.max(), ff2.max())) response[mask] = get_insertion_loss(frequencies[mask]) * np.exp(1j * get_phase(frequencies[mask])) return response @@ -83,7 +83,7 @@ def get_filter_response(frequencies, filter_name): get_phase = intp.interp1d(ff2, np.unwrap(phase)) get_insertion_loss = intp.interp1d(ff, insertion_loss) - response = np.zeros_like(frequencies, dtype=np.complex) + response = np.zeros_like(frequencies, dtype=complex) mask = (frequencies > max(ff.min(), ff2.min())) & (frequencies < min(ff.max(), ff2.max())) response[mask] = get_insertion_loss(frequencies[mask]) * np.exp(1j * get_phase(frequencies[mask])) return response diff --git a/NuRadioReco/modules/channelGalacticNoiseAdder.py b/NuRadioReco/modules/channelGalacticNoiseAdder.py index 0638fb423..9afafc989 100644 --- a/NuRadioReco/modules/channelGalacticNoiseAdder.py +++ b/NuRadioReco/modules/channelGalacticNoiseAdder.py @@ -122,7 +122,7 @@ def run( passband_filter = (freqs > passband[0]) & (freqs < passband[1]) noise_spec_sum = np.zeros_like(channel.get_frequency_spectrum()) flux_sum = np.zeros(freqs[passband_filter].shape) - efield_sum = np.zeros((3, freqs.shape[0]), dtype=np.complex) + efield_sum = np.zeros((3, freqs.shape[0]), dtype=complex) if self.__debug: plt.close('all') fig = plt.figure(figsize=(12, 8)) @@ -177,7 +177,7 @@ def run( ax_3.plot(freqs[passband_filter] / units.MHz, E / (units.V / units.m), c='k', alpha=.02) # assign random phases and polarizations to electric field - noise_spectrum = np.zeros((3, freqs.shape[0]), dtype=np.complex) + noise_spectrum = np.zeros((3, freqs.shape[0]), dtype=complex) phases = np.random.uniform(0, 2. * np.pi, len(S)) polarizations = np.random.uniform(0, 2. * np.pi, len(S)) diff --git a/NuRadioReco/modules/neutrinoDirectionReconstructor/voltageToEfieldAnalyticConverterForNeutrinos.py b/NuRadioReco/modules/neutrinoDirectionReconstructor/voltageToEfieldAnalyticConverterForNeutrinos.py index e672b51d6..07f7daa19 100644 --- a/NuRadioReco/modules/neutrinoDirectionReconstructor/voltageToEfieldAnalyticConverterForNeutrinos.py +++ b/NuRadioReco/modules/neutrinoDirectionReconstructor/voltageToEfieldAnalyticConverterForNeutrinos.py @@ -187,14 +187,14 @@ def minimizer(params, minimizer=True): order = 5 b, a = signal.butter(order, passband_high[use_channels[iA]], 'bandpass', analog=True) w, h = signal.freqs(b, a, ff[mask]) - f = np.zeros_like(ff, dtype=np.complex) + f = np.zeros_like(ff, dtype=complex) f[mask] = h trace_spectrum *= f order = 10 b, a = signal.butter(order, passband_low[use_channels[iA]], 'bandpass', analog=True) w, h = signal.freqs(b, a, ff[mask]) - f = np.zeros_like(ff, dtype=np.complex) + f = np.zeros_like(ff, dtype=complex) f[mask] = h trace_spectrum *= f @@ -352,8 +352,8 @@ def plotSimulatedVersusReconstructedTraces(nu_zenith, nu_azimuth, shower_energy, travel_distance = np.zeros((n_antennas, maxNumRayTracingSolPerChan)) attenuation = np.zeros((n_antennas, maxNumRayTracingSolPerChan, len(ff))) focusing = np.zeros((n_antennas, maxNumRayTracingSolPerChan, 1)) - reflection_coefficients_theta = np.ones((n_antennas, maxNumRayTracingSolPerChan), dtype=np.complex) - reflection_coefficients_phi = np.ones((n_antennas, maxNumRayTracingSolPerChan), dtype=np.complex) + reflection_coefficients_theta = np.ones((n_antennas, maxNumRayTracingSolPerChan), dtype=complex) + reflection_coefficients_phi = np.ones((n_antennas, maxNumRayTracingSolPerChan), dtype=complex) travel_time_min = float('inf') for iA, position in enumerate(antenna_positions): r = ray.ray_tracing(icemodel, attenuation_model=attenuation_model, n_frequencies_integration=25, n_reflections=n_reflections) diff --git a/NuRadioReco/modules/voltageToEfieldConverter.py b/NuRadioReco/modules/voltageToEfieldConverter.py index 2b66efa12..df6144a48 100644 --- a/NuRadioReco/modules/voltageToEfieldConverter.py +++ b/NuRadioReco/modules/voltageToEfieldConverter.py @@ -77,7 +77,7 @@ def get_array_of_channels(station, use_channels, det, zenith, azimuth, for iCh, trace in enumerate(traces): V_timedomain[iCh] = trace.get_trace() frequencies = traces[0].get_frequencies() # assumes that all channels have the same sampling rate - V = np.zeros((len(use_channels), len(frequencies)), dtype=np.complex) + V = np.zeros((len(use_channels), len(frequencies)), dtype=complex) for iCh, trace in enumerate(traces): V[iCh] = trace.get_frequency_spectrum() @@ -170,7 +170,7 @@ def run(self, evt, station, det, use_channels=None, use_MC_direction=False, forc E1[mask] = (V[0] * efield_antenna_factor[-1][1] - V[-1] * efield_antenna_factor[0][1])[mask] / denom[mask] E2[mask] = (V[-1] - efield_antenna_factor[-1][0] * E1)[mask] / efield_antenna_factor[-1][1][mask] # solve it in a vectorized way - efield3_f = np.zeros((2, n_frequencies), dtype=np.complex) + efield3_f = np.zeros((2, n_frequencies), dtype=complex) if force_Polarization == 'eTheta': efield3_f[:1, mask] = np.moveaxis(stacked_lstsq(np.moveaxis(efield_antenna_factor[:, 0, mask], 1, 0)[:, :, np.newaxis], np.moveaxis(V[:, mask], 1, 0)), 0, 1) elif force_Polarization == 'ePhi': @@ -178,7 +178,7 @@ def run(self, evt, station, det, use_channels=None, use_MC_direction=False, forc else: efield3_f[:, mask] = np.moveaxis(stacked_lstsq(np.moveaxis(efield_antenna_factor[:, :, mask], 2, 0), np.moveaxis(V[:, mask], 1, 0)), 0, 1) # add eR direction - efield3_f = np.array([np.zeros_like(efield3_f[0], dtype=np.complex), + efield3_f = np.array([np.zeros_like(efield3_f[0], dtype=complex), efield3_f[0], efield3_f[1]]) diff --git a/NuRadioReco/modules/voltageToEfieldConverterPerChannel.py b/NuRadioReco/modules/voltageToEfieldConverterPerChannel.py index d83319e16..bdc79caf8 100644 --- a/NuRadioReco/modules/voltageToEfieldConverterPerChannel.py +++ b/NuRadioReco/modules/voltageToEfieldConverterPerChannel.py @@ -65,7 +65,7 @@ def run(self, evt, station, det, pol=0): trace = channel.get_frequency_spectrum() mask1 = np.abs(efield_antenna_factor[iCh][0]) != 0 mask2 = np.abs(efield_antenna_factor[iCh][1]) != 0 - efield_spectrum = np.zeros((3, len(trace)), dtype=np.complex) + efield_spectrum = np.zeros((3, len(trace)), dtype=complex) efield_spectrum[1][mask1] = (1.0 - pol) ** 2 * trace[mask1] / efield_antenna_factor[iCh][0][mask1] efield_spectrum[2][mask2] = pol ** 2 * trace[mask2] / efield_antenna_factor[iCh][1][mask2] efield.set_frequency_spectrum(efield_spectrum, sampling_rate) diff --git a/NuRadioReco/utilities/bandpass_filter.py b/NuRadioReco/utilities/bandpass_filter.py index d02035e8a..b91700b55 100644 --- a/NuRadioReco/utilities/bandpass_filter.py +++ b/NuRadioReco/utilities/bandpass_filter.py @@ -48,21 +48,21 @@ def get_filter_response(frequencies, passband, filter_type, order, rp=None): f[np.where(frequencies > passband[1])] = 0. return f elif (filter_type == 'butter'): - f = np.zeros_like(frequencies, dtype=np.complex) + f = np.zeros_like(frequencies, dtype=complex) mask = frequencies > 0 b, a = scipy.signal.butter(order, *scipy_args, analog=True) w, h = scipy.signal.freqs(b, a, frequencies[mask]) f[mask] = h return f elif (filter_type == 'butterabs'): - f = np.zeros_like(frequencies, dtype=np.complex) + f = np.zeros_like(frequencies, dtype=complex) mask = frequencies > 0 b, a = scipy.signal.butter(order, *scipy_args, analog=True) w, h = scipy.signal.freqs(b, a, frequencies[mask]) f[mask] = h return np.abs(f) elif(filter_type == 'cheby1'): - f = np.zeros_like(frequencies, dtype=np.complex) + f = np.zeros_like(frequencies, dtype=complex) mask = frequencies > 0 b, a = scipy.signal.cheby1(order, rp, *scipy_args, analog=True) w, h = scipy.signal.freqs(b, a, frequencies[mask]) diff --git a/NuRadioReco/utilities/trace_utilities.py b/NuRadioReco/utilities/trace_utilities.py index ca0fe352d..57bc82fb4 100644 --- a/NuRadioReco/utilities/trace_utilities.py +++ b/NuRadioReco/utilities/trace_utilities.py @@ -32,7 +32,7 @@ def get_efield_antenna_factor(station, frequencies, channels, detector, zenith, antenna_pattern_provider: AntennaPatternProvider """ n_ice = ice.get_refractive_index(-0.01, detector.get_site(station.get_id())) - efield_antenna_factor = np.zeros((len(channels), 2, len(frequencies)), dtype=np.complex) # from antenna model in e_theta, e_phi + efield_antenna_factor = np.zeros((len(channels), 2, len(frequencies)), dtype=complex) # from antenna model in e_theta, e_phi for iCh, channel_id in enumerate(channels): zenith_antenna = zenith t_theta = 1. @@ -88,12 +88,12 @@ def get_channel_voltage_from_efield(station, electric_field, channels, detector, spectrum = electric_field.get_frequency_spectrum() efield_antenna_factor = get_efield_antenna_factor(station, frequencies, channels, detector, zenith, azimuth, antenna_pattern_provider) if return_spectrum: - voltage_spectrum = np.zeros((len(channels), len(frequencies)), dtype=np.complex) + voltage_spectrum = np.zeros((len(channels), len(frequencies)), dtype=complex) for i_ch, ch in enumerate(channels): voltage_spectrum[i_ch] = np.sum(efield_antenna_factor[i_ch] * np.array([spectrum[1], spectrum[2]]), axis=0) return voltage_spectrum else: - voltage_trace = np.zeros((len(channels), 2 * (len(frequencies) - 1)), dtype=np.complex) + voltage_trace = np.zeros((len(channels), 2 * (len(frequencies) - 1)), dtype=complex) for i_ch, ch in enumerate(channels): voltage_trace[i_ch] = fft.freq2time(np.sum(efield_antenna_factor[i_ch] * np.array([spectrum[1], spectrum[2]]), axis=0), electric_field.get_sampling_rate()) return np.real(voltage_trace) @@ -218,7 +218,7 @@ def apply_butterworth(spectrum, frequencies, passband, order=8): The filtered spectrum """ - f = np.zeros_like(frequencies, dtype=np.complex) + f = np.zeros_like(frequencies, dtype=complex) mask = frequencies > 0 b, a = scipy.signal.butter(order, passband, 'bandpass', analog=True) w, h = scipy.signal.freqs(b, a, frequencies[mask]) From 7a0cf4e55b530147525282f64b92b932ec278e2e Mon Sep 17 00:00:00 2001 From: Christian Glaser Date: Tue, 16 May 2023 17:35:49 +0000 Subject: [PATCH 278/418] also change np.bool --- NuRadioMC/EvtGen/generate_unforced.py | 2 +- NuRadioMC/EvtGen/generator.py | 2 +- .../A05visualization.py | 2 +- .../scripts/T05visualize_sim_output.py | 12 ++++---- NuRadioMC/simulation/simulation.py | 28 +++++++++---------- NuRadioMC/utilities/Veff.py | 16 +++++------ NuRadioMC/utilities/merge_hdf5.py | 2 +- .../electricFieldSignalReconstructor.py | 4 +-- .../modules/trigger/highLowThreshold.py | 4 +-- 9 files changed, 36 insertions(+), 36 deletions(-) diff --git a/NuRadioMC/EvtGen/generate_unforced.py b/NuRadioMC/EvtGen/generate_unforced.py index 3732d9909..718f3fe0f 100644 --- a/NuRadioMC/EvtGen/generate_unforced.py +++ b/NuRadioMC/EvtGen/generate_unforced.py @@ -328,7 +328,7 @@ def points_in_cylinder(pt1, pt2, r, q): 'flavors': [], 'energies': []} # calculate rotation matrix to transform position on area to 3D - mask_int = np.zeros_like(mask, dtype=np.bool) + mask_int = np.zeros_like(mask, dtype=bool) t0 = time.perf_counter() n_cylinder = 0 for j, i in enumerate(np.arange(n_events, dtype=int)[mask]): diff --git a/NuRadioMC/EvtGen/generator.py b/NuRadioMC/EvtGen/generator.py index 04e027021..ae68676dc 100644 --- a/NuRadioMC/EvtGen/generator.py +++ b/NuRadioMC/EvtGen/generator.py @@ -928,7 +928,7 @@ def generate_surface_muons(filename, n_events, Emin, Emax, if('fiducial_rmax' in attributes): mask_phi = mask_arrival_azimuth(data_sets, attributes['fiducial_rmax']) # this currently only works for cylindrical volumes else: - mask_phi = np.ones(len(data_sets["event_group_ids"]), dtype=np.bool) + mask_phi = np.ones(len(data_sets["event_group_ids"]), dtype=bool) # TODO: combine with `get_intersection_volume_neutrino` function for iE, event_id in enumerate(data_sets["event_group_ids"]): if not mask_phi[iE]: diff --git a/NuRadioMC/examples/03_station_coincidences/A05visualization.py b/NuRadioMC/examples/03_station_coincidences/A05visualization.py index 99095c5c0..e69c6f2d5 100644 --- a/NuRadioMC/examples/03_station_coincidences/A05visualization.py +++ b/NuRadioMC/examples/03_station_coincidences/A05visualization.py @@ -79,7 +79,7 @@ x2 = det.get_relative_position(101, iC) if(plot): ax.plot([x2[0]], [x2[1]], [x2[2]], 'ko') - if(j != 0 and (~(np.array(triggered_deep[iE], dtype=np.bool) & mask))[j]): + if(j != 0 and (~(np.array(triggered_deep[iE], dtype=bool) & mask))[j]): continue vertex = np.array([fin['xx'][iE], fin['yy'][iE], fin['zz'][iE]]) # print(fin.keys()) diff --git a/NuRadioMC/simulation/scripts/T05visualize_sim_output.py b/NuRadioMC/simulation/scripts/T05visualize_sim_output.py index a1c046cbf..9585974db 100644 --- a/NuRadioMC/simulation/scripts/T05visualize_sim_output.py +++ b/NuRadioMC/simulation/scripts/T05visualize_sim_output.py @@ -42,14 +42,14 @@ plot_folder = os.path.join(dirname, 'plots', filename, args.trigger_name[0]) if(not os.path.exists(plot_folder)): os.makedirs(plot_folder) - triggered = np.zeros(len(fin['multiple_triggers'][:, 0]), dtype=np.bool) + triggered = np.zeros(len(fin['multiple_triggers'][:, 0]), dtype=bool) for trigger in args.trigger_name[1:]: iTrigger = np.squeeze(np.argwhere(fin.attrs['trigger_names'] == trigger)) - triggered = triggered | np.array(fin['multiple_triggers'][:, iTrigger], dtype=np.bool) + triggered = triggered | np.array(fin['multiple_triggers'][:, iTrigger], dtype=bool) else: trigger_name = args.trigger_name[0] iTrigger = np.argwhere(fin.attrs['trigger_names'] == trigger_name) - triggered = np.array(fin['multiple_triggers'][:, iTrigger], dtype=np.bool) + triggered = np.array(fin['multiple_triggers'][:, iTrigger], dtype=bool) print("\tyou selected '{}'".format(trigger_name)) plot_folder = os.path.join(dirname, 'plots', filename, trigger_name) if(not os.path.exists(plot_folder)): @@ -147,14 +147,14 @@ def a(theta): if(len(args.trigger_name) > 1): print("trigger {} selected which is a combination of {}".format(args.trigger_name[0], args.trigger_name[1:])) trigger_name = args.trigger_name[0] - triggered = np.zeros(len(station['multiple_triggers'][:, 0]), dtype=np.bool) + triggered = np.zeros(len(station['multiple_triggers'][:, 0]), dtype=bool) for trigger in args.trigger_name[1:]: iTrigger = np.squeeze(np.argwhere(fin.attrs['trigger_names'] == trigger)) - triggered = triggered | np.array(station['multiple_triggers'][:, iTrigger], dtype=np.bool) + triggered = triggered | np.array(station['multiple_triggers'][:, iTrigger], dtype=bool) else: trigger_name = args.trigger_name[0] iTrigger = np.argwhere(fin.attrs['trigger_names'] == trigger_name) - triggered = np.array(station['multiple_triggers'][:, iTrigger], dtype=np.bool) + triggered = np.array(station['multiple_triggers'][:, iTrigger], dtype=bool) print("\tyou selected '{}'".format(trigger_name)) ########################### diff --git a/NuRadioMC/simulation/simulation.py b/NuRadioMC/simulation/simulation.py index a7a5fdebb..42a1d19fa 100644 --- a/NuRadioMC/simulation/simulation.py +++ b/NuRadioMC/simulation/simulation.py @@ -1150,12 +1150,12 @@ def _calculate_signal_properties(self): def _create_empty_multiple_triggers(self): if 'trigger_names' not in self._mout_attrs: self._mout_attrs['trigger_names'] = np.array([]) - self._mout['multiple_triggers'] = np.zeros((self._n_showers, 1), dtype=np.bool) + self._mout['multiple_triggers'] = np.zeros((self._n_showers, 1), dtype=bool) for station_id in self._station_ids: sg = self._mout_groups[station_id] n_showers = sg['launch_vectors'].shape[0] - sg['multiple_triggers'] = np.zeros((n_showers, 1), dtype=np.bool) - sg['triggered'] = np.zeros(n_showers, dtype=np.bool) + sg['multiple_triggers'] = np.zeros((n_showers, 1), dtype=bool) + sg['triggered'] = np.zeros(n_showers, dtype=bool) def _create_trigger_structures(self): @@ -1170,13 +1170,13 @@ def _create_trigger_structures(self): # simulated triggers is unknown at the beginning. So we check if the key already exists and if not, # we first create this data structure if 'multiple_triggers' not in self._mout: - self._mout['multiple_triggers'] = np.zeros((self._n_showers, len(self._mout_attrs['trigger_names'])), dtype=np.bool) + self._mout['multiple_triggers'] = np.zeros((self._n_showers, len(self._mout_attrs['trigger_names'])), dtype=bool) self._mout['trigger_times'] = np.nan * np.zeros_like(self._mout['multiple_triggers'], dtype=float) # for station_id in self._station_ids: # sg = self._mout_groups[station_id] -# sg['multiple_triggers'] = np.zeros((self._n_showers, len(self._mout_attrs['trigger_names'])), dtype=np.bool) +# sg['multiple_triggers'] = np.zeros((self._n_showers, len(self._mout_attrs['trigger_names'])), dtype=bool) elif extend_array: - tmp = np.zeros((self._n_showers, len(self._mout_attrs['trigger_names'])), dtype=np.bool) + tmp = np.zeros((self._n_showers, len(self._mout_attrs['trigger_names'])), dtype=bool) nx, ny = self._mout['multiple_triggers'].shape tmp[:, 0:ny] = self._mout['multiple_triggers'] self._mout['multiple_triggers'] = tmp @@ -1186,7 +1186,7 @@ def _create_trigger_structures(self): self._mout['trigger_times'] = tmp_t # for station_id in self._station_ids: # sg = self._mout_groups[station_id] -# tmp = np.zeros((self._n_showers, len(self._mout_attrs['trigger_names'])), dtype=np.bool) +# tmp = np.zeros((self._n_showers, len(self._mout_attrs['trigger_names'])), dtype=bool) # nx, ny = sg['multiple_triggers'].shape # tmp[:, 0:ny] = sg['multiple_triggers'] # sg['multiple_triggers'] = tmp @@ -1199,10 +1199,10 @@ def _save_triggers_to_hdf5(self, sg, local_shower_index, global_shower_index): # the information fo the current station and event group n_showers = sg['launch_vectors'].shape[0] if 'multiple_triggers' not in sg: - sg['multiple_triggers'] = np.zeros((n_showers, len(self._mout_attrs['trigger_names'])), dtype=np.bool) + sg['multiple_triggers'] = np.zeros((n_showers, len(self._mout_attrs['trigger_names'])), dtype=bool) sg['trigger_times'] = np.nan * np.zeros_like(sg['multiple_triggers'], dtype=float) elif extend_array: - tmp = np.zeros((n_showers, len(self._mout_attrs['trigger_names'])), dtype=np.bool) + tmp = np.zeros((n_showers, len(self._mout_attrs['trigger_names'])), dtype=bool) nx, ny = sg['multiple_triggers'].shape tmp[:, 0:ny] = sg['multiple_triggers'] sg['multiple_triggers'] = tmp @@ -1213,7 +1213,7 @@ def _save_triggers_to_hdf5(self, sg, local_shower_index, global_shower_index): self._output_event_group_ids[self._station_id].append(self._evt.get_run_number()) self._output_sub_event_ids[self._station_id].append(self._evt.get_id()) - multiple_triggers = np.zeros(len(self._mout_attrs['trigger_names']), dtype=np.bool) + multiple_triggers = np.zeros(len(self._mout_attrs['trigger_names']), dtype=bool) trigger_times = np.nan*np.zeros_like(multiple_triggers) for iT, trigger_name in enumerate(self._mout_attrs['trigger_names']): if self._station.has_trigger(trigger_name): @@ -1262,8 +1262,8 @@ def _create_meta_output_datastructures(self): self._mout = {} self._mout_attributes = {} self._mout['weights'] = np.zeros(self._n_showers) - self._mout['triggered'] = np.zeros(self._n_showers, dtype=np.bool) -# self._mout['multiple_triggers'] = np.zeros((self._n_showers, self._number_of_triggers), dtype=np.bool) + self._mout['triggered'] = np.zeros(self._n_showers, dtype=bool) +# self._mout['multiple_triggers'] = np.zeros((self._n_showers, self._number_of_triggers), dtype=bool) self._mout_attributes['trigger_names'] = None self._amplitudes = {} self._amplitudes_envelope = {} @@ -1289,7 +1289,7 @@ def _create_meta_output_datastructures(self): def _create_station_output_structure(self, n_showers, n_antennas): nS = self._raytracer.get_number_of_raytracing_solutions() # number of possible ray-tracing solutions sg = {} - sg['triggered'] = np.zeros(n_showers, dtype=np.bool) + sg['triggered'] = np.zeros(n_showers, dtype=bool) # we need the reference to the shower id to be able to find the correct shower in the upper level hdf5 file sg['shower_id'] = np.zeros(n_showers, dtype=int) * -1 sg['event_id_per_shower'] = np.zeros(n_showers, dtype=int) * -1 @@ -1424,7 +1424,7 @@ def _write_output_file(self, empty=False): # the multiple triggeres 2d array might have different number of entries per event # because the number of different triggers can increase dynamically # therefore we first create an array with the right size and then fill it - tmp = np.zeros((n_events_for_station, n_triggers), dtype=np.bool) + tmp = np.zeros((n_events_for_station, n_triggers), dtype=bool) for iE, values in enumerate(self._output_multiple_triggers_station[station_id]): tmp[iE] = values sg['multiple_triggers_per_event'] = tmp diff --git a/NuRadioMC/utilities/Veff.py b/NuRadioMC/utilities/Veff.py index 9ee5eaa14..00aecb933 100644 --- a/NuRadioMC/utilities/Veff.py +++ b/NuRadioMC/utilities/Veff.py @@ -335,35 +335,35 @@ def get_Veff_Aeff_single( return out for iT, trigger_name in enumerate(trigger_names): - triggered = np.array(fin['multiple_triggers'][:, iT], dtype=np.bool) + triggered = np.array(fin['multiple_triggers'][:, iT], dtype=bool) triggered = remove_duplicate_triggers(triggered, fin['event_group_ids']) out[veff_aeff][trigger_name] = get_veff_output(volume_proj_area, np.sum(weights[triggered]), n_events) for trigger_name, values in iteritems(trigger_combinations): indiv_triggers = values['triggers'] - triggered = np.zeros_like(fin['multiple_triggers'][:, 0], dtype=np.bool) + triggered = np.zeros_like(fin['multiple_triggers'][:, 0], dtype=bool) if isinstance(indiv_triggers, str): triggered = triggered | \ - np.array(fin['multiple_triggers'][:, trigger_names_dict[indiv_triggers]], dtype=np.bool) + np.array(fin['multiple_triggers'][:, trigger_names_dict[indiv_triggers]], dtype=bool) else: for indiv_trigger in indiv_triggers: triggered = triggered | \ - np.array(fin['multiple_triggers'][:, trigger_names_dict[indiv_trigger]], dtype=np.bool) + np.array(fin['multiple_triggers'][:, trigger_names_dict[indiv_trigger]], dtype=bool) if 'triggerAND' in values: triggered = triggered & \ - np.array(fin['multiple_triggers'][:, trigger_names_dict[values['triggerAND']]], dtype=np.bool) + np.array(fin['multiple_triggers'][:, trigger_names_dict[values['triggerAND']]], dtype=bool) if 'notriggers' in values: indiv_triggers = values['notriggers'] if(isinstance(indiv_triggers, str)): triggered = triggered & \ - ~np.array(fin['multiple_triggers'][:, trigger_names_dict[indiv_triggers]], dtype=np.bool) + ~np.array(fin['multiple_triggers'][:, trigger_names_dict[indiv_triggers]], dtype=bool) else: for indiv_trigger in indiv_triggers: triggered = triggered & \ - ~np.array(fin['multiple_triggers'][:, trigger_names_dict[indiv_trigger]], dtype=np.bool) + ~np.array(fin['multiple_triggers'][:, trigger_names_dict[indiv_trigger]], dtype=bool) if 'min_sigma' in values.keys(): if isinstance(values['min_sigma'], list): @@ -396,7 +396,7 @@ def get_Veff_Aeff_single( As = np.array(fin['max_amp_ray_solution']) max_amps = np.argmax(As[:, values['ray_channel']], axis=-1) sol = np.array(fin['ray_tracing_solution_type']) - mask = np.array([sol[i, values['ray_channel'], max_amps[i]] == values['ray_solution'] for i in range(len(max_amps))], dtype=np.bool) + mask = np.array([sol[i, values['ray_channel'], max_amps[i]] == values['ray_solution'] for i in range(len(max_amps))], dtype=bool) triggered = triggered & mask if 'n_reflections' in values.keys(): diff --git a/NuRadioMC/utilities/merge_hdf5.py b/NuRadioMC/utilities/merge_hdf5.py index cb31765d9..464f50733 100644 --- a/NuRadioMC/utilities/merge_hdf5.py +++ b/NuRadioMC/utilities/merge_hdf5.py @@ -266,7 +266,7 @@ def merge2(filenames, output_filename): # try: input_files = np.array(sorted(glob.glob(filename + '.part????'))) input_files = np.append(input_files, np.array(sorted(glob.glob(filename + '.part??????')))) - mask = np.array([os.path.getsize(x) > 1000 for x in input_files], dtype=np.bool) + mask = np.array([os.path.getsize(x) > 1000 for x in input_files], dtype=bool) if(np.sum(~mask)): logger.warning("{:d} files were deselected because their filesize was to small".format(np.sum(~mask))) input_args.append({'filenames': input_files[mask], 'output_filename': output_filename}) diff --git a/NuRadioReco/modules/electricFieldSignalReconstructor.py b/NuRadioReco/modules/electricFieldSignalReconstructor.py index 94252131b..9f4089d2b 100644 --- a/NuRadioReco/modules/electricFieldSignalReconstructor.py +++ b/NuRadioReco/modules/electricFieldSignalReconstructor.py @@ -98,9 +98,9 @@ def run(self, evt, station, det, debug=False): times = electric_field.get_times() mask_signal_window = (times > (signal_time - self.__signal_window_pre)) & (times < (signal_time + self.__signal_window_post)) - mask_noise_window = np.zeros_like(mask_signal_window, dtype=np.bool) + mask_noise_window = np.zeros_like(mask_signal_window, dtype=bool) if(self.__noise_window > 0): - mask_noise_window[int(np.round((-self.__noise_window - 141.) * electric_field.get_sampling_rate())):int(np.round(-141. * electric_field.get_sampling_rate()))] = np.ones(int(np.round(self.__noise_window * electric_field.get_sampling_rate())), dtype=np.bool) # the last n bins + mask_noise_window[int(np.round((-self.__noise_window - 141.) * electric_field.get_sampling_rate())):int(np.round(-141. * electric_field.get_sampling_rate()))] = np.ones(int(np.round(self.__noise_window * electric_field.get_sampling_rate())), dtype=bool) # the last n bins signal_energy_fluence = trace_utilities.get_electric_field_energy_fluence(trace, times, mask_signal_window, mask_noise_window) dt = times[1] - times[0] diff --git a/NuRadioReco/modules/trigger/highLowThreshold.py b/NuRadioReco/modules/trigger/highLowThreshold.py index c08e9d7c4..cff116833 100644 --- a/NuRadioReco/modules/trigger/highLowThreshold.py +++ b/NuRadioReco/modules/trigger/highLowThreshold.py @@ -32,7 +32,7 @@ def get_high_low_triggers(trace, high_threshold, low_threshold, the bins where the trigger condition is satisfied """ n_bins_coincidence = int(np.round(time_coincidence / dt)) + 1 - c = np.ones(n_bins_coincidence, dtype=np.bool) + c = np.ones(n_bins_coincidence, dtype=bool) logger.debug("length of trace {} bins, coincidence window {} bins".format(len(trace), len(c))) c2 = np.array([1, -1]) @@ -70,7 +70,7 @@ def get_majority_logic(tts, number_of_coincidences=2, time_coincidence=32 * unit if(n_bins_coincidence > n): # reduce coincidence window to maximum trace length n_bins_coincidence = n logger.debug("specified coincidence window longer than tracelenght, reducing coincidence window to trace length") - c = np.ones(n_bins_coincidence, dtype=np.bool) + c = np.ones(n_bins_coincidence, dtype=bool) for i in range(len(tts)): logger.debug("get_majority_logic() length of trace {} bins, coincidence window {} bins".format(len(tts[i]), len(c))) From ddcc3d245f8425078745720c8a79bd5b4fd05bac Mon Sep 17 00:00:00 2001 From: Christian Glaser Date: Tue, 16 May 2023 17:47:08 +0000 Subject: [PATCH 279/418] update reference value adapting to new noise --- NuRadioMC/test/Veff/1e18eV/T03check_output_noise.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NuRadioMC/test/Veff/1e18eV/T03check_output_noise.py b/NuRadioMC/test/Veff/1e18eV/T03check_output_noise.py index a78fe4bfc..f1ebfc01f 100755 --- a/NuRadioMC/test/Veff/1e18eV/T03check_output_noise.py +++ b/NuRadioMC/test/Veff/1e18eV/T03check_output_noise.py @@ -11,7 +11,7 @@ # the event generation has a fixed seed and I switched to Alvarez2000 (also no randomness) # thus, the Veff has no statistical scatter -Veff_mean = 8.17491 +Veff_mean = 7.86364 Veff_sigma = 0.0001 path = os.path.dirname(os.path.abspath(__file__)) From 4e9e248a83cd329e42201aa8851c7dc7ef9fc767 Mon Sep 17 00:00:00 2001 From: Christian Glaser Date: Tue, 16 May 2023 18:11:23 +0000 Subject: [PATCH 280/418] update reference values due to new noise reaslizations --- .../test/tiny_reconstruction/reference.json | 345 +----------------- 1 file changed, 1 insertion(+), 344 deletions(-) diff --git a/NuRadioReco/test/tiny_reconstruction/reference.json b/NuRadioReco/test/tiny_reconstruction/reference.json index 40c6b9def..968d3584b 100644 --- a/NuRadioReco/test/tiny_reconstruction/reference.json +++ b/NuRadioReco/test/tiny_reconstruction/reference.json @@ -1,344 +1 @@ -{ - "0" : { - "station_parameters" : { - "nu_zenith" : null, - "nu_azimuth" : null, - "nu_energy" : null, - "nu_flavor" : null, - "ccnc" : null, - "nu_vertex" : null, - "inelasticity" : null, - "triggered" : null, - "cr_energy" : null, - "cr_zenith" : null, - "cr_azimuth" : null, - "channels_max_amplitude" : 0.08853022471996891, - "zenith" : 0.79, - "azimuth" : 3.96, - "zenith_cr_templatefit" : null, - "zenith_nu_templatefit" : null, - "cr_xcorrelations" : null, - "nu_xcorrelations" : null, - "station_time" : null, - "cr_energy_em" : null, - "nu_inttype" : null, - "chi2_efield_time_direction_fit" : null, - "ndf_efield_time_direction_fit" : null, - "cr_xmax" : null, - "vertex_2D_fit" : null, - "distance_correlations" : null - }, - "sim_station_parameters" : { - "nu_zenith" : null, - "nu_azimuth" : null, - "nu_energy" : null, - "nu_flavor" : null, - "ccnc" : null, - "nu_vertex" : null, - "inelasticity" : null, - "triggered" : null, - "cr_energy" : 1.58489319246E18, - "cr_zenith" : null, - "cr_azimuth" : null, - "channels_max_amplitude" : null, - "zenith" : 0.7853981633974483, - "azimuth" : 3.957853280977215, - "zenith_cr_templatefit" : null, - "zenith_nu_templatefit" : null, - "cr_xcorrelations" : null, - "nu_xcorrelations" : null, - "station_time" : null, - "cr_energy_em" : 1.39187479744259994E18, - "nu_inttype" : null, - "chi2_efield_time_direction_fit" : null, - "ndf_efield_time_direction_fit" : null, - "cr_xmax" : 646.2024663, - "vertex_2D_fit" : null, - "distance_correlations" : null - }, - "channel_parameters" : { - "zenith" : [ null, null, null, null ], - "azimuth" : [ null, null, null, null ], - "maximum_amplitude" : [ 0.0873141653492205, 0.08853022471996891, 0.07885012049626394, 0.07486104950522432 ], - "SNR" : [ { - "integrated_power" : 0.0, - "peak_2_peak_amplitude" : 0.004149416647868447, - "peak_amplitude" : 0.004225325303006149, - "Seckel_2_noise" : 5 - }, { - "integrated_power" : 0.0, - "peak_2_peak_amplitude" : 0.0061325770929495016, - "peak_amplitude" : 0.006227798651940198, - "Seckel_2_noise" : 5 - }, { - "integrated_power" : 0.0, - "peak_2_peak_amplitude" : 0.0038091911965324092, - "peak_amplitude" : 0.0038590946944723325, - "Seckel_2_noise" : 5 - }, { - "integrated_power" : 0.0, - "peak_2_peak_amplitude" : 0.003328271897442733, - "peak_amplitude" : 0.0034583171387571744, - "Seckel_2_noise" : 5 - } ], - "maximum_amplitude_envelope" : [ 0.08772020520899446, 0.08892789858406401, 0.07966830072878535, 0.08297084302728261 ], - "P2P_amplitude" : [ 0.1724152251327864, 0.16341917302469117, 0.146681542086196, 0.1458075155635604 ], - "cr_xcorrelations" : [ null, null, null, null ], - "nu_xcorrelations" : [ null, null, null, null ], - "signal_time" : [ -168.2559785714568, -171.65597857145679, -183.2559785714568, -173.85597857145672 ], - "noise_rms" : [ 0.008836023847618458, 0.008955465322914774, 0.008881819339363746, 0.009304834436981291 ], - "signal_regions" : [ null, null, null, null ], - "noise_regions" : [ null, null, null, null ], - "signal_time_offset" : [ null, null, null, null ], - "signal_receiving_zenith" : [ null, null, null, null ], - "signal_ray_type" : [ null, null, null, null ], - "signal_receiving_azimuth" : [ null, null, null, null ] - }, - "electric_field_parameters" : { - "ray_path_type" : [ null, null ], - "polarization_angle" : [ 1.437014716504628, 1.505812376998251 ], - "polarization_angle_expectation" : [ 1.3259385237455839, -1.8156541298442093 ], - "signal_energy_fluence" : [ [ 0.0, 0.2505871320257097, 13.83446329404234 ], [ 0.0, 0.07493732342984019, 17.695470024342303 ] ], - "cr_spectrum_slope" : [ null, -5.071257963761185 ], - "zenith" : [ 0.79, 0.79 ], - "azimuth" : [ 3.96, 3.96 ], - "signal_time" : [ -254.95450631365475, null ], - "nu_vertex_distance" : [ null, null ], - "nu_viewing_angle" : [ null, null ], - "max_amp_antenna" : [ null, null ], - "max_amp_antenna_envelope" : [ null, null ], - "reflection_coefficient_theta" : [ null, null ], - "reflection_coefficient_phi" : [ null, null ], - "cr_spectrum_quadratic_term" : [ null, 3.7278692487503235 ], - "energy_fluence_ratios" : [ null, null ] - } - }, - "1" : { - "station_parameters" : { - "nu_zenith" : null, - "nu_azimuth" : null, - "nu_energy" : null, - "nu_flavor" : null, - "ccnc" : null, - "nu_vertex" : null, - "inelasticity" : null, - "triggered" : null, - "cr_energy" : null, - "cr_zenith" : null, - "cr_azimuth" : null, - "channels_max_amplitude" : 0.33359702926988355, - "zenith" : 0.78, - "azimuth" : 3.95, - "zenith_cr_templatefit" : null, - "zenith_nu_templatefit" : null, - "cr_xcorrelations" : null, - "nu_xcorrelations" : null, - "station_time" : null, - "cr_energy_em" : null, - "nu_inttype" : null, - "chi2_efield_time_direction_fit" : null, - "ndf_efield_time_direction_fit" : null, - "cr_xmax" : null, - "vertex_2D_fit" : null, - "distance_correlations" : null - }, - "sim_station_parameters" : { - "nu_zenith" : null, - "nu_azimuth" : null, - "nu_energy" : null, - "nu_flavor" : null, - "ccnc" : null, - "nu_vertex" : null, - "inelasticity" : null, - "triggered" : null, - "cr_energy" : 1.58489319246E18, - "cr_zenith" : null, - "cr_azimuth" : null, - "channels_max_amplitude" : null, - "zenith" : 0.7853981633974483, - "azimuth" : 3.957853280977215, - "zenith_cr_templatefit" : null, - "zenith_nu_templatefit" : null, - "cr_xcorrelations" : null, - "nu_xcorrelations" : null, - "station_time" : null, - "cr_energy_em" : 1.39187479744259994E18, - "nu_inttype" : null, - "chi2_efield_time_direction_fit" : null, - "ndf_efield_time_direction_fit" : null, - "cr_xmax" : 646.2024663, - "vertex_2D_fit" : null, - "distance_correlations" : null - }, - "channel_parameters" : { - "zenith" : [ null, null, null, null ], - "azimuth" : [ null, null, null, null ], - "maximum_amplitude" : [ 0.2835856575324592, 0.33359702926988355, 0.2791941553632823, 0.3256776186469762 ], - "SNR" : [ { - "integrated_power" : 0.0, - "peak_2_peak_amplitude" : 0.00291206901456176, - "peak_amplitude" : 0.002929725052658198, - "Seckel_2_noise" : 5 - }, { - "integrated_power" : 0.0, - "peak_2_peak_amplitude" : 0.00340572893988943, - "peak_amplitude" : 0.0034558407562806964, - "Seckel_2_noise" : 5 - }, { - "integrated_power" : 0.0, - "peak_2_peak_amplitude" : 0.006845057653623751, - "peak_amplitude" : 0.00701923788399404, - "Seckel_2_noise" : 5 - }, { - "integrated_power" : 0.0, - "peak_2_peak_amplitude" : 0.007164164413376706, - "peak_amplitude" : 0.007202262656811785, - "Seckel_2_noise" : 5 - } ], - "maximum_amplitude_envelope" : [ 0.3003272394395557, 0.3399598814912192, 0.29236891303881996, 0.35467083189765575 ], - "P2P_amplitude" : [ 0.5632116726571561, 0.6637288453900938, 0.554719957942302, 0.6479974651404222 ], - "cr_xcorrelations" : [ null, null, null, null ], - "nu_xcorrelations" : [ null, null, null, null ], - "signal_time" : [ 587.7440214285432, 589.9440214285432, 574.9440214285432, 571.3440214285433 ], - "noise_rms" : [ 0.009006474050937649, 0.008732105958313228, 0.007788519158762668, 0.009397032099363559 ], - "signal_regions" : [ null, null, null, null ], - "noise_regions" : [ null, null, null, null ], - "signal_time_offset" : [ null, null, null, null ], - "signal_receiving_zenith" : [ null, null, null, null ], - "signal_ray_type" : [ null, null, null, null ], - "signal_receiving_azimuth" : [ null, null, null, null ] - }, - "electric_field_parameters" : { - "ray_path_type" : [ null, null ], - "polarization_angle" : [ 1.423905497514318, 1.4409019604509443 ], - "polarization_angle_expectation" : [ 1.3232105351636871, -1.818382118426106 ], - "signal_energy_fluence" : [ [ 0.0, 6.607535268712784, 301.8361992200022 ], [ 0.0, 5.437314688159896, 318.63935252848177 ] ], - "cr_spectrum_slope" : [ null, -6.6760948093020485 ], - "zenith" : [ 0.78, 0.78 ], - "azimuth" : [ 3.95, 3.95 ], - "signal_time" : [ 499.91208204952255, null ], - "nu_vertex_distance" : [ null, null ], - "nu_viewing_angle" : [ null, null ], - "max_amp_antenna" : [ null, null ], - "max_amp_antenna_envelope" : [ null, null ], - "reflection_coefficient_theta" : [ null, null ], - "reflection_coefficient_phi" : [ null, null ], - "cr_spectrum_quadratic_term" : [ null, -2.215049003838984 ], - "energy_fluence_ratios" : [ null, null ] - } - }, - "2" : { - "station_parameters" : { - "nu_zenith" : null, - "nu_azimuth" : null, - "nu_energy" : null, - "nu_flavor" : null, - "ccnc" : null, - "nu_vertex" : null, - "inelasticity" : null, - "triggered" : null, - "cr_energy" : null, - "cr_zenith" : null, - "cr_azimuth" : null, - "channels_max_amplitude" : 0.28471716111983614, - "zenith" : 0.78, - "azimuth" : 3.95, - "zenith_cr_templatefit" : null, - "zenith_nu_templatefit" : null, - "cr_xcorrelations" : null, - "nu_xcorrelations" : null, - "station_time" : null, - "cr_energy_em" : null, - "nu_inttype" : null, - "chi2_efield_time_direction_fit" : null, - "ndf_efield_time_direction_fit" : null, - "cr_xmax" : null, - "vertex_2D_fit" : null, - "distance_correlations" : null - }, - "sim_station_parameters" : { - "nu_zenith" : null, - "nu_azimuth" : null, - "nu_energy" : null, - "nu_flavor" : null, - "ccnc" : null, - "nu_vertex" : null, - "inelasticity" : null, - "triggered" : null, - "cr_energy" : 1.58489319246E18, - "cr_zenith" : null, - "cr_azimuth" : null, - "channels_max_amplitude" : null, - "zenith" : 0.7853981633974483, - "azimuth" : 3.957853280977215, - "zenith_cr_templatefit" : null, - "zenith_nu_templatefit" : null, - "cr_xcorrelations" : null, - "nu_xcorrelations" : null, - "station_time" : null, - "cr_energy_em" : 1.39187479744259994E18, - "nu_inttype" : null, - "chi2_efield_time_direction_fit" : null, - "ndf_efield_time_direction_fit" : null, - "cr_xmax" : 646.2024663, - "vertex_2D_fit" : null, - "distance_correlations" : null - }, - "channel_parameters" : { - "zenith" : [ null, null, null, null ], - "azimuth" : [ null, null, null, null ], - "maximum_amplitude" : [ 0.2617580175047184, 0.27712092224880147, 0.2555336277305896, 0.28471716111983614 ], - "SNR" : [ { - "integrated_power" : 0.0, - "peak_2_peak_amplitude" : 0.0043472269995871535, - "peak_amplitude" : 0.0045710624556043215, - "Seckel_2_noise" : 5 - }, { - "integrated_power" : 0.0, - "peak_2_peak_amplitude" : 0.003710424290754701, - "peak_amplitude" : 0.0037252751132054716, - "Seckel_2_noise" : 5 - }, { - "integrated_power" : 0.0, - "peak_2_peak_amplitude" : 0.00777307702513199, - "peak_amplitude" : 0.007907951982053118, - "Seckel_2_noise" : 5 - }, { - "integrated_power" : 0.0, - "peak_2_peak_amplitude" : 0.008133561831805624, - "peak_amplitude" : 0.008336373693178935, - "Seckel_2_noise" : 5 - } ], - "maximum_amplitude_envelope" : [ 0.2653837960611956, 0.2969067177063586, 0.270376775534144, 0.298365691136913 ], - "P2P_amplitude" : [ 0.5188798774102936, 0.550291044285413, 0.5046288232897831, 0.5481116482309814 ], - "cr_xcorrelations" : [ null, null, null, null ], - "nu_xcorrelations" : [ null, null, null, null ], - "signal_time" : [ -134.05597857145676, -132.85597857145672, -146.85597857145672, -144.85597857145672 ], - "noise_rms" : [ 0.009190485861932177, 0.009505810656701827, 0.00886260343524874, 0.0091532389582909 ], - "signal_regions" : [ null, null, null, null ], - "noise_regions" : [ null, null, null, null ], - "signal_time_offset" : [ null, null, null, null ], - "signal_receiving_zenith" : [ null, null, null, null ], - "signal_ray_type" : [ null, null, null, null ], - "signal_receiving_azimuth" : [ null, null, null, null ] - }, - "electric_field_parameters" : { - "ray_path_type" : [ null, null ], - "polarization_angle" : [ 1.4819734258513997, 1.5006361258682528 ], - "polarization_angle_expectation" : [ 1.3232105351636871, -1.818382118426106 ], - "signal_energy_fluence" : [ [ 0.0, 2.5899529944532245, 326.5528775660024 ], [ 0.0, 2.0442071775847332, 413.9200130611196 ] ], - "cr_spectrum_slope" : [ null, -1.7873921532547352 ], - "zenith" : [ 0.78, 0.78 ], - "azimuth" : [ 3.95, 3.95 ], - "signal_time" : [ -193.88791795047757, null ], - "nu_vertex_distance" : [ null, null ], - "nu_viewing_angle" : [ null, null ], - "max_amp_antenna" : [ null, null ], - "max_amp_antenna_envelope" : [ null, null ], - "reflection_coefficient_theta" : [ null, null ], - "reflection_coefficient_phi" : [ null, null ], - "cr_spectrum_quadratic_term" : [ null, 0.4769503271885924 ], - "energy_fluence_ratios" : [ null, null ] - } - } -} \ No newline at end of file +{"0": {"station_parameters": {"nu_zenith": null, "nu_azimuth": null, "nu_energy": null, "nu_flavor": null, "ccnc": null, "nu_vertex": null, "inelasticity": null, "triggered": null, "cr_energy": null, "cr_zenith": null, "cr_azimuth": null, "channels_max_amplitude": 0.09219726935932945, "zenith": 0.76585400390625, "azimuth": 3.94125048828125, "zenith_cr_templatefit": null, "zenith_nu_templatefit": null, "cr_xcorrelations": null, "nu_xcorrelations": null, "station_time": null, "cr_energy_em": null, "nu_inttype": null, "chi2_efield_time_direction_fit": null, "ndf_efield_time_direction_fit": null, "cr_xmax": null, "vertex_2D_fit": null, "distance_correlations": null, "shower_energy": null, "viewing_angles": null}, "sim_station_parameters": {"nu_zenith": null, "nu_azimuth": null, "nu_energy": null, "nu_flavor": null, "ccnc": null, "nu_vertex": null, "inelasticity": null, "triggered": null, "cr_energy": 1.58489319246e+18, "cr_zenith": null, "cr_azimuth": null, "channels_max_amplitude": null, "zenith": 0.7853981633974483, "azimuth": 3.957853280977215, "zenith_cr_templatefit": null, "zenith_nu_templatefit": null, "cr_xcorrelations": null, "nu_xcorrelations": null, "station_time": null, "cr_energy_em": 1.3918747974426e+18, "nu_inttype": null, "chi2_efield_time_direction_fit": null, "ndf_efield_time_direction_fit": null, "cr_xmax": 646.2024663, "vertex_2D_fit": null, "distance_correlations": null, "shower_energy": null, "viewing_angles": null}, "channel_parameters": {"zenith": [null, null, null, null], "azimuth": [null, null, null, null], "maximum_amplitude": [0.0741114148547873, 0.07822416425569524, 0.08019365868532256, 0.09219726935932945], "SNR": [{"integrated_power": 0.0, "peak_2_peak_amplitude": 0.004780092071917627, "peak_amplitude": 0.00485887816779479, "Seckel_2_noise": 5}, {"integrated_power": 0.0, "peak_2_peak_amplitude": 0.0029781482057526206, "peak_amplitude": 0.0030899574970230446, "Seckel_2_noise": 5}, {"integrated_power": 0.0, "peak_2_peak_amplitude": 0.002963497087732319, "peak_amplitude": 0.0029912274254951183, "Seckel_2_noise": 5}, {"integrated_power": 0.0, "peak_2_peak_amplitude": 0.003315202825440897, "peak_amplitude": 0.0035027540130119802, "Seckel_2_noise": 5}], "maximum_amplitude_envelope": [0.0789854151249416, 0.0850534211758587, 0.08035990802734218, 0.09425391321371974], "P2P_amplitude": [0.13819712244096005, 0.15451260952068696, 0.15292399225172826, 0.17650992826729145], "cr_xcorrelations": [null, null, null, null], "nu_xcorrelations": [null, null, null, null], "signal_time": [-165.45597857145674, -169.65597857145679, -182.85597857145672, -181.05597857145676], "noise_rms": [0.009497729224153949, 0.008938569434903116, 0.008083395580028708, 0.009418626437748765], "signal_regions": [null, null, null, null], "noise_regions": [null, null, null, null], "signal_time_offset": [null, null, null, null], "signal_receiving_zenith": [null, null, null, null], "signal_ray_type": [null, null, null, null], "signal_receiving_azimuth": [null, null, null, null]}, "electric_field_parameters": {"ray_path_type": [null, null], "polarization_angle": [1.4654396095601694, 1.4895721505795514], "polarization_angle_expectation": [1.3193420263512765, -1.8222506272385168], "signal_energy_fluence": [[0.0, 0.1499228726724943, 13.406681586865194], [0.0, 0.1138089722425281, 17.17484362157034]], "cr_spectrum_slope": [null, -5.857288373436567], "zenith": [0.76585400390625, 0.76585400390625], "azimuth": [3.94125048828125, 3.94125048828125], "signal_time": [-256.0418188450112, null], "nu_vertex_distance": [null, null], "nu_viewing_angle": [null, null], "max_amp_antenna": [null, null], "max_amp_antenna_envelope": [null, null], "reflection_coefficient_theta": [null, null], "reflection_coefficient_phi": [null, null], "cr_spectrum_quadratic_term": [null, 5.585796124606195], "energy_fluence_ratios": [null, null]}}, "1": {"station_parameters": {"nu_zenith": null, "nu_azimuth": null, "nu_energy": null, "nu_flavor": null, "ccnc": null, "nu_vertex": null, "inelasticity": null, "triggered": null, "cr_energy": null, "cr_zenith": null, "cr_azimuth": null, "channels_max_amplitude": 0.34265971445728505, "zenith": 0.79, "azimuth": 3.96, "zenith_cr_templatefit": null, "zenith_nu_templatefit": null, "cr_xcorrelations": null, "nu_xcorrelations": null, "station_time": null, "cr_energy_em": null, "nu_inttype": null, "chi2_efield_time_direction_fit": null, "ndf_efield_time_direction_fit": null, "cr_xmax": null, "vertex_2D_fit": null, "distance_correlations": null, "shower_energy": null, "viewing_angles": null}, "sim_station_parameters": {"nu_zenith": null, "nu_azimuth": null, "nu_energy": null, "nu_flavor": null, "ccnc": null, "nu_vertex": null, "inelasticity": null, "triggered": null, "cr_energy": 1.58489319246e+18, "cr_zenith": null, "cr_azimuth": null, "channels_max_amplitude": null, "zenith": 0.7853981633974483, "azimuth": 3.957853280977215, "zenith_cr_templatefit": null, "zenith_nu_templatefit": null, "cr_xcorrelations": null, "nu_xcorrelations": null, "station_time": null, "cr_energy_em": 1.3918747974426e+18, "nu_inttype": null, "chi2_efield_time_direction_fit": null, "ndf_efield_time_direction_fit": null, "cr_xmax": 646.2024663, "vertex_2D_fit": null, "distance_correlations": null, "shower_energy": null, "viewing_angles": null}, "channel_parameters": {"zenith": [null, null, null, null], "azimuth": [null, null, null, null], "maximum_amplitude": [0.29720895105426465, 0.34265971445728505, 0.28631950709258547, 0.3355886336552229], "SNR": [{"integrated_power": 0.0, "peak_2_peak_amplitude": 0.006919176246584566, "peak_amplitude": 0.007147260712361315, "Seckel_2_noise": 5}, {"integrated_power": 0.0, "peak_2_peak_amplitude": 0.0047795421977155994, "peak_amplitude": 0.00483475221965112, "Seckel_2_noise": 5}, {"integrated_power": 0.0, "peak_2_peak_amplitude": 0.007958346991753162, "peak_amplitude": 0.00808818541204719, "Seckel_2_noise": 5}, {"integrated_power": 0.0, "peak_2_peak_amplitude": 0.006171263679930979, "peak_amplitude": 0.00634102083568216, "Seckel_2_noise": 5}], "maximum_amplitude_envelope": [0.30136927893948445, 0.3430368419418388, 0.2883085667945778, 0.3430413736731565], "P2P_amplitude": [0.5781561921741288, 0.6591005848543372, 0.5651166372487595, 0.6691483403791307], "cr_xcorrelations": [null, null, null, null], "nu_xcorrelations": [null, null, null, null], "signal_time": [583.9440214285432, 585.5440214285434, 570.5440214285434, 575.1440214285433], "noise_rms": [0.009359269057858015, 0.009003414652873262, 0.008341757854147532, 0.009479378300635246], "signal_regions": [null, null, null, null], "noise_regions": [null, null, null, null], "signal_time_offset": [null, null, null, null], "signal_receiving_zenith": [null, null, null, null], "signal_ray_type": [null, null, null, null], "signal_receiving_azimuth": [null, null, null, null]}, "electric_field_parameters": {"ray_path_type": [null, null], "polarization_angle": [1.4164838522395478, 1.4309598632203113], "polarization_angle_expectation": [1.3259385237455839, -1.8156541298442093], "signal_energy_fluence": [[0.0, 7.388558320124647, 305.36881995591784], [0.0, 6.420446226373949, 324.0685176647595]], "cr_spectrum_slope": [null, -6.704957977720079], "zenith": [0.79, 0.79], "azimuth": [3.96, 3.96], "signal_time": [500.04549368634525, null], "nu_vertex_distance": [null, null], "nu_viewing_angle": [null, null], "max_amp_antenna": [null, null], "max_amp_antenna_envelope": [null, null], "reflection_coefficient_theta": [null, null], "reflection_coefficient_phi": [null, null], "cr_spectrum_quadratic_term": [null, -2.2958549567008015], "energy_fluence_ratios": [null, null]}}, "2": {"station_parameters": {"nu_zenith": null, "nu_azimuth": null, "nu_energy": null, "nu_flavor": null, "ccnc": null, "nu_vertex": null, "inelasticity": null, "triggered": null, "cr_energy": null, "cr_zenith": null, "cr_azimuth": null, "channels_max_amplitude": 0.29293556379400426, "zenith": 0.78, "azimuth": 3.95, "zenith_cr_templatefit": null, "zenith_nu_templatefit": null, "cr_xcorrelations": null, "nu_xcorrelations": null, "station_time": null, "cr_energy_em": null, "nu_inttype": null, "chi2_efield_time_direction_fit": null, "ndf_efield_time_direction_fit": null, "cr_xmax": null, "vertex_2D_fit": null, "distance_correlations": null, "shower_energy": null, "viewing_angles": null}, "sim_station_parameters": {"nu_zenith": null, "nu_azimuth": null, "nu_energy": null, "nu_flavor": null, "ccnc": null, "nu_vertex": null, "inelasticity": null, "triggered": null, "cr_energy": 1.58489319246e+18, "cr_zenith": null, "cr_azimuth": null, "channels_max_amplitude": null, "zenith": 0.7853981633974483, "azimuth": 3.957853280977215, "zenith_cr_templatefit": null, "zenith_nu_templatefit": null, "cr_xcorrelations": null, "nu_xcorrelations": null, "station_time": null, "cr_energy_em": 1.3918747974426e+18, "nu_inttype": null, "chi2_efield_time_direction_fit": null, "ndf_efield_time_direction_fit": null, "cr_xmax": 646.2024663, "vertex_2D_fit": null, "distance_correlations": null, "shower_energy": null, "viewing_angles": null}, "channel_parameters": {"zenith": [null, null, null, null], "azimuth": [null, null, null, null], "maximum_amplitude": [0.2565625777544711, 0.2778654985637024, 0.2672414043783895, 0.29293556379400426], "SNR": [{"integrated_power": 0.0, "peak_2_peak_amplitude": 0.007948759818769018, "peak_amplitude": 0.008209754518559166, "Seckel_2_noise": 5}, {"integrated_power": 0.0, "peak_2_peak_amplitude": 0.002601223824751355, "peak_amplitude": 0.0026817225129317146, "Seckel_2_noise": 5}, {"integrated_power": 0.0, "peak_2_peak_amplitude": 0.008923287811149969, "peak_amplitude": 0.009007262903406938, "Seckel_2_noise": 5}, {"integrated_power": 0.0, "peak_2_peak_amplitude": 0.0068025654072232655, "peak_amplitude": 0.007054720375806741, "Seckel_2_noise": 5}], "maximum_amplitude_envelope": [0.2618281394747253, 0.28224029243565324, 0.26779467480180347, 0.2932426286212969], "P2P_amplitude": [0.5044222411860875, 0.547608219972491, 0.5318703949237792, 0.5851999240317709], "cr_xcorrelations": [null, null, null, null], "nu_xcorrelations": [null, null, null, null], "signal_time": [-102.65597857145667, -133.45597857145674, -148.2559785714567, -147.45597857145674], "noise_rms": [0.008359098917345579, 0.00848077598024109, 0.008989153845587915, 0.008201090181413125], "signal_regions": [null, null, null, null], "noise_regions": [null, null, null, null], "signal_time_offset": [null, null, null, null], "signal_receiving_zenith": [null, null, null, null], "signal_ray_type": [null, null, null, null], "signal_receiving_azimuth": [null, null, null, null]}, "electric_field_parameters": {"ray_path_type": [null, null], "polarization_angle": [1.4786245054415663, 1.5037562254029073], "polarization_angle_expectation": [1.3232105351636871, -1.818382118426106], "signal_energy_fluence": [[0.0, 2.8633662095356187, 335.1320229092165], [0.0, 1.9443851451542769, 431.3306782776532]], "cr_spectrum_slope": [null, -1.715922037957672], "zenith": [0.78, 0.78], "azimuth": [3.95, 3.95], "signal_time": [-193.88791795047757, null], "nu_vertex_distance": [null, null], "nu_viewing_angle": [null, null], "max_amp_antenna": [null, null], "max_amp_antenna_envelope": [null, null], "reflection_coefficient_theta": [null, null], "reflection_coefficient_phi": [null, null], "cr_spectrum_quadratic_term": [null, 0.5209156977104409], "energy_fluence_ratios": [null, null]}}} \ No newline at end of file From 417aec21e4a84391536815f7ffb9614605cb32ff Mon Sep 17 00:00:00 2001 From: Christian Glaser Date: Tue, 16 May 2023 18:19:17 +0000 Subject: [PATCH 281/418] update radiotools version with the same numpy fixes --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 7fb653fb4..e5e0b4292 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -25,7 +25,7 @@ tinydb = ">=4.1.1" tinydb-serialization = ">=2.1" aenum = "*" astropy = "*" -radiotools = ">=0.2" +radiotools = ">=0.2.1" cython = "*" dash = ">=2.0" future = "*" From 7f0d678681c0f1d0453df86b1836fe9d5029c5d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= <30903175+fschlueter@users.noreply.github.com> Date: Fri, 19 May 2023 12:06:04 +0200 Subject: [PATCH 282/418] Update readRNOGDataMattak.py Fix error logging: use updated git repo --- NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py b/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py index a61dfa8fc..f482735a2 100644 --- a/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py +++ b/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py @@ -155,7 +155,7 @@ def __init__(self, run_table_path=None): "Runs can not be filtered.") except ImportError: self.logger.warn("Import of run table failed. Runs can not be filtered.! \n" - "You can get the interface from GitHub: git@github.com:RNO-G/rnog-data-analysis-and-issues.git") + "You can get the interface from GitHub: git@github.com:RNO-G/rnog-runtable.git") else: import pandas self.__run_table = pandas.read_csv(run_table_path) From f84034b1f88a1880277149fe87e2b2322eeae174 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= <30903175+fschlueter@users.noreply.github.com> Date: Fri, 19 May 2023 13:40:39 +0200 Subject: [PATCH 283/418] Update readRNOGDataMattak.py Move logger to init --- .../modules/io/RNO_G/readRNOGDataMattak.py | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py b/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py index f482735a2..65c85addb 100644 --- a/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py +++ b/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py @@ -132,14 +132,20 @@ def all_files_in_directory(mattak_dir): class readRNOGData: - def __init__(self, run_table_path=None): + def __init__(self, run_table_path=None, log_level=logging.INFO): """ Parameters ---------- run_table_path: str Path to a run_table.cvs file. If None, the run table is queried from the DB. (Default: None) + + log_level: enum + Set verbosity level of logger. If logging.DEBUG, set mattak to verbose (unless specified in mattak_kwargs). + (Default: logging.INFO) """ + self.logger = logging.getLogger('NuRadioReco.readRNOGData') + self.logger.setLevel(log_level) # Initialize run table for run selection self.__run_table = None @@ -173,8 +179,7 @@ def begin(self, run_time_range=None, max_trigger_rate=0 * units.Hz, mattak_kwargs={}, - overwrite_sampling_rate=None, - log_level=logging.INFO): + overwrite_sampling_rate=None): """ Parameters ---------- @@ -232,17 +237,10 @@ def begin(self, Set sampling rate of the imported waveforms. This overwrites what is read out from runinfo (i.e., stored in the mattak files). If None, nothing is overwritten and the sampling rate from the mattak file is used. (Default: None) NOTE: This option might be necessary when old mattak files are read which have this not set. - - log_level: enum - Set verbosity level of logger. If logging.DEBUG, set mattak to verbose (unless specified in mattak_kwargs). - (Default: logging.INFO) """ t0 = time.time() - self.logger = logging.getLogger('NuRadioReco.readRNOGData') - self.logger.setLevel(log_level) - self._read_calibrated_data = read_calibrated_data self._apply_baseline_correction = apply_baseline_correction self._convert_to_voltage = convert_to_voltage From f6da08792988c03d906c58ef55394875c732d042 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Fri, 19 May 2023 13:50:05 +0200 Subject: [PATCH 284/418] Fix reader and example --- NuRadioReco/examples/RNO_data/read_data_example/read_rnog.py | 1 - NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/NuRadioReco/examples/RNO_data/read_data_example/read_rnog.py b/NuRadioReco/examples/RNO_data/read_data_example/read_rnog.py index 950e8c3cb..c215601bb 100644 --- a/NuRadioReco/examples/RNO_data/read_data_example/read_rnog.py +++ b/NuRadioReco/examples/RNO_data/read_data_example/read_rnog.py @@ -36,7 +36,6 @@ class EventInfo: rnog_reader.begin( list_of_root_files, selectors=selectors, - log_level=logging.INFO, # Currently false because Mattak does not contain calibrated data yet read_calibrated_data=False, # Only used when read_calibrated_data==False, performs a simple baseline subtraction each 128 bins diff --git a/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py b/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py index 65c85addb..27e432f56 100644 --- a/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py +++ b/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py @@ -294,7 +294,7 @@ def begin(self, if "verbose" in mattak_kwargs: verbose = mattak_kwargs.pop("verbose") else: - verbose = log_level == logging.DEBUG + verbose = self.logger.level == logging.DEBUG for dir_file in dirs_files: From f767843e064e42667dd637130e4ce534101a1a37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Fri, 19 May 2023 14:24:31 +0200 Subject: [PATCH 285/418] Catch exceptions when reading runs with mattak --- .../RNO_data/read_data_example/read_rnog.py | 6 ++-- .../modules/io/RNO_G/readRNOGDataMattak.py | 28 ++++++++++++------- 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/NuRadioReco/examples/RNO_data/read_data_example/read_rnog.py b/NuRadioReco/examples/RNO_data/read_data_example/read_rnog.py index c215601bb..2855cbe7e 100644 --- a/NuRadioReco/examples/RNO_data/read_data_example/read_rnog.py +++ b/NuRadioReco/examples/RNO_data/read_data_example/read_rnog.py @@ -9,7 +9,7 @@ list_of_root_files = sys.argv[1:-1] output_filename = sys.argv[-1] -rnog_reader = readRNOGDataMattak.readRNOGData() +rnog_reader = readRNOGDataMattak.readRNOGData(log_level=logging.DEBUG) writer = eventWriter.eventWriter() """ @@ -53,11 +53,9 @@ class EventInfo: writer.begin(filename=output_filename) -for i_event, event in enumerate(rnog_reader.run()): - +for i_event, event in enumerate(rnog_reader.run()): writer.run(event) -print(i_event) rnog_reader.end() writer.end() diff --git a/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py b/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py index 27e432f56..502c5185b 100644 --- a/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py +++ b/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py @@ -306,9 +306,13 @@ def begin(self, if not all_files_in_directory(dir_file): self.logger.error(f"Incomplete directory: {dir_file}. Skip ...") - continue - - dataset = mattak.Dataset.Dataset(station=0, run=0, data_dir=dir_file, verbose=verbose, **mattak_kwargs) + continue + + try: + dataset = mattak.Dataset.Dataset(station=0, run=0, data_dir=dir_file, verbose=verbose, **mattak_kwargs) + except Exception as e: + self.logger.error(f"The following Exeption was raised reading in the run: f{dir_file}. Skip that run ...: {e}") + continue else: raise NotImplementedError("The option to read in files is not implemented yet") @@ -474,7 +478,7 @@ def _filter_event(self, evtinfo, event_idx=None): for selector in self._selectors: if not selector(evtinfo): self.logger.debug(f"Event {event_idx} (station {evtinfo.station}, run {evtinfo.run}, " - f"event number {evtinfo.eventNumber}) is skipped.") + f"event number {evtinfo.eventNumber}) is skipped.") self.__skipped += 1 return True @@ -772,9 +776,13 @@ def get_event(self, run_nr, event_id): def end(self): - self.logger.info( - f"\n\tRead {self.__counter} events (skipped {self.__skipped} events, {self.__invalid} invalid events)" - f"\n\tTime to initialize data sets : {self._time_begin:.2f}s" - f"\n\tTime to read all events : {self._time_run:.2f}s" - f"\n\tTime to per event : {self._time_run / self.__counter:.2f}s" - f"\n\tRead {self.__n_runs} runs, skipped {self.__skipped_runs} runs.") + if self.__counter: + self.logger.info( + f"\n\tRead {self.__counter} events (skipped {self.__skipped} events, {self.__invalid} invalid events)" + f"\n\tTime to initialize data sets : {self._time_begin:.2f}s" + f"\n\tTime to read all events : {self._time_run:.2f}s" + f"\n\tTime to per event : {self._time_run / self.__counter:.2f}s" + f"\n\tRead {self.__n_runs} runs, skipped {self.__skipped_runs} runs.") + else: + self.logger.info( + f"\n\tRead {self.__counter} events (skipped {self.__skipped} events, {self.__invalid} invalid events)") \ No newline at end of file From 75cc622964f3254b6918c888207ce5af02d7a557 Mon Sep 17 00:00:00 2001 From: Alan Coleman Date: Mon, 22 May 2023 19:34:18 -0400 Subject: [PATCH 286/418] Update naming scheme to be consistent with analogToDigitalConverter --- NuRadioReco/utilities/noise.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/NuRadioReco/utilities/noise.py b/NuRadioReco/utilities/noise.py index 31bc02b4c..0fd45282b 100644 --- a/NuRadioReco/utilities/noise.py +++ b/NuRadioReco/utilities/noise.py @@ -274,8 +274,8 @@ def __init__(self, detector_filename, station_id, triggered_channels, self.pre_trigger_bins = int(pre_trigger_time * self.sampling_rate) self.n_samples_trigger = int(trace_length * self.sampling_rate) det_channel = self.det.get_channel(station_id, triggered_channels[0]) - self.adc_n_bits = det_channel["adc_nbits"] - self.adc_noise_n_bits = det_channel["adc_noise_nbits"] + self.adc_n_bits = det_channel["trigger_adc_nbits"] + self.adc_noise_n_bits = det_channel["trigger_adc_noise_nbits"] self.n_channels = len(triggered_channels) self.triggered_channels = triggered_channels @@ -317,7 +317,7 @@ def __init__(self, detector_filename, station_id, triggered_channels, self.filt = channelBandPassFilter.get_filter(self.ff, station_id, channel_id, self.det, passband=[96 * units.MHz, 100 * units.GHz], filter_type='cheby1', order=4, rp=0.1) self.filt *= channelBandPassFilter.get_filter(self.ff, station_id, channel_id, self.det, - passband=[0 * units.MHz, 220 * units.MHz], filter_type='cheby1', order=7, rp=0.1) + passband=[1 * units.MHz, 220 * units.MHz], filter_type='cheby1', order=7, rp=0.1) self.norm = np.trapz(np.abs(self.filt) ** 2, self.ff) self.amplitude = (self.max_freq - self.min_freq) ** 0.5 / self.norm ** 0.5 * self.Vrms print(f"Vrms = {self.Vrms:.3g}V, noise amplitude = {self.amplitude:.3g}V, bandwidth = {self.norm/units.MHz:.0f}MHz") From 6654b6674bb55c296348cfff6f3709a385a739f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Tue, 23 May 2023 10:56:55 +0200 Subject: [PATCH 287/418] Add specific Exceptions, add traceback information --- NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py b/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py index 502c5185b..ec741b626 100644 --- a/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py +++ b/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py @@ -14,6 +14,7 @@ from NuRadioReco.utilities import units import mattak.Dataset +import uproot # only needed to catch an exception def baseline_correction(wfs, n_bins=128, func=np.median): @@ -297,7 +298,7 @@ def begin(self, verbose = self.logger.level == logging.DEBUG for dir_file in dirs_files: - + if not os.path.exists(dir_file): self.logger.error(f"The directory/file {dir_file} does not exist") continue @@ -310,8 +311,11 @@ def begin(self, try: dataset = mattak.Dataset.Dataset(station=0, run=0, data_dir=dir_file, verbose=verbose, **mattak_kwargs) - except Exception as e: - self.logger.error(f"The following Exeption was raised reading in the run: f{dir_file}. Skip that run ...: {e}") + except (ReferenceError, uproot.exceptions.KeyInFileError) as e: + self.logger.error(f"The following exeption was raised reading in the run: {dir_file}. Skip that run ...:\n") + import traceback + traceback.print_exc() + print("") continue else: raise NotImplementedError("The option to read in files is not implemented yet") From ae9a23e6adf7c205e2e54c68ecacb1eb48bc8238 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Tue, 23 May 2023 10:58:11 +0200 Subject: [PATCH 288/418] fix log level comparison --- NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py b/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py index ec741b626..2217a319b 100644 --- a/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py +++ b/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py @@ -295,7 +295,7 @@ def begin(self, if "verbose" in mattak_kwargs: verbose = mattak_kwargs.pop("verbose") else: - verbose = self.logger.level == logging.DEBUG + verbose = self.logger.level >= logging.DEBUG for dir_file in dirs_files: From 97942ed7a4c02c86d46e52baa671d6ce5106b3a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Tue, 23 May 2023 11:01:12 +0200 Subject: [PATCH 289/418] Use more general exception --- NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py b/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py index 2217a319b..983d1f1d2 100644 --- a/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py +++ b/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py @@ -14,7 +14,6 @@ from NuRadioReco.utilities import units import mattak.Dataset -import uproot # only needed to catch an exception def baseline_correction(wfs, n_bins=128, func=np.median): @@ -311,7 +310,7 @@ def begin(self, try: dataset = mattak.Dataset.Dataset(station=0, run=0, data_dir=dir_file, verbose=verbose, **mattak_kwargs) - except (ReferenceError, uproot.exceptions.KeyInFileError) as e: + except (ReferenceError, KeyError) as e: self.logger.error(f"The following exeption was raised reading in the run: {dir_file}. Skip that run ...:\n") import traceback traceback.print_exc() From 309a2ba069aaa8e1b5f1c7931b580bd80800df5c Mon Sep 17 00:00:00 2001 From: Sjoerd Bouma Date: Tue, 23 May 2023 11:32:46 +0200 Subject: [PATCH 290/418] use logger for traceback --- NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py b/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py index 983d1f1d2..1ef173bd4 100644 --- a/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py +++ b/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py @@ -311,10 +311,7 @@ def begin(self, try: dataset = mattak.Dataset.Dataset(station=0, run=0, data_dir=dir_file, verbose=verbose, **mattak_kwargs) except (ReferenceError, KeyError) as e: - self.logger.error(f"The following exeption was raised reading in the run: {dir_file}. Skip that run ...:\n") - import traceback - traceback.print_exc() - print("") + self.logger.error(f"The following exeption was raised reading in the run: {dir_file}. Skip that run ...:\n", exc_info=e) continue else: raise NotImplementedError("The option to read in files is not implemented yet") From 99ec961414d9323946550c943d81952d359a7f3c Mon Sep 17 00:00:00 2001 From: Felix Date: Thu, 25 May 2023 19:04:20 +0200 Subject: [PATCH 291/418] Skip empty strings as noise folders. Might occure if noise folder not specified and causes the program to search uncontrolled for root files --- NuRadioReco/modules/measured_noise/RNO_G/noiseImporter.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/NuRadioReco/modules/measured_noise/RNO_G/noiseImporter.py b/NuRadioReco/modules/measured_noise/RNO_G/noiseImporter.py index d3f18689f..c0c781c8b 100644 --- a/NuRadioReco/modules/measured_noise/RNO_G/noiseImporter.py +++ b/NuRadioReco/modules/measured_noise/RNO_G/noiseImporter.py @@ -73,10 +73,13 @@ def begin(self, noise_folders, file_pattern="*", if not isinstance(noise_folders, list): noise_folders = [noise_folders] - + # find all subfolders noise_files = [] for noise_folder in noise_folders: + if noise_folder == "": + continue + noise_files += glob.glob(f"{noise_folder}/**/{file_pattern}root", recursive=True) self.__noise_folders = np.unique([os.path.dirname(e) for e in noise_files]) From 0894ca73a1bdab9046206194affc95a33466e9bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Tue, 30 May 2023 12:25:44 +0200 Subject: [PATCH 292/418] Fix bug in get_events_information which appears when calling that function twice --- NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py b/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py index fb19c7ed2..db2835ecb 100644 --- a/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py +++ b/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py @@ -515,7 +515,8 @@ def get_events_information(self, keys=["station", "run", "eventNumber"]): if not do_read: # ... or when it does not have the desired information - first_event_info = next(iter(self._events_information)) + first_event_info = self._events_information[list(self._events_information.keys())[0]] + for key in keys: if key not in list(first_event_info.keys()): do_read = True From ff9abb2123fdba7af1d7f044b4e43b37b646c6fe Mon Sep 17 00:00:00 2001 From: Christian Glaser Date: Thu, 1 Jun 2023 15:04:07 +0000 Subject: [PATCH 293/418] update documentation --- .../source/NuRadioMC/pages/HDF5_structure.rst | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/documentation/source/NuRadioMC/pages/HDF5_structure.rst b/documentation/source/NuRadioMC/pages/HDF5_structure.rst index 66ad8022e..5033fc573 100644 --- a/documentation/source/NuRadioMC/pages/HDF5_structure.rst +++ b/documentation/source/NuRadioMC/pages/HDF5_structure.rst @@ -114,8 +114,12 @@ is the number of showers (which may be larger than the number of events), and `` Station data ____________ In addition, the HDF5 file contains a key for each station in the simulation. -The station contains more detailed information for each event that triggered it: -``m_events`` and ``m_showers`` refer to the number of events and showers that triggered the station. +The station contains more detailed information for each station. Some parameters are per event and +some parameters are per shower. See https://doi.org/10.22323/1.395.1231 for a description of how showers relate to events. +``m_events`` and ``m_showers`` refer to the number of events and showers that triggered the station. NOTE: The simple table +structure of hdf5 files can not capture the complex relation between events and showers in all cases. Some fields can be ambiguous +(e.g. `trigger_times` that only lists the last trigger that a shower generated). +For more advanced analyses, please use the *.nur files. The ``event_group_id`` is the same as in the global dictionary. Therefore you can check for one event with an ``event_group_id`` which stations contain the same ``event_group_id`` and retrieve the information, which station triggered, with which amplitude, etc. The same approach works for ``shower_id``. @@ -151,4 +155,5 @@ station triggered, with which amplitude, etc. The same approach works for ``show ``travel_times`` | (``m_showers``, ``n_channels``, ``n_ray_tracing_solutions``) | The time travelled by each ray tracing solution to a specific channel ``triggered`` | (``m_showers``) | Whether each shower contributed to an event that satisfied any trigger condition ``triggered_per_event`` | (``m_events``) | Whether each event fulfilled any trigger condition. - ``trigger_times`` | (``m_showers``, ``n_triggers``) | The trigger times for each shower and trigger. + ``trigger_times`` | (``m_showers``, ``n_triggers``) | The trigger times for each shower and trigger. IMPORTANT: A shower can potentially generate multiple events. Then this field is ambiguous, as only a single trigger time per shower can be saved. In that case, the latest trigger time is saved into this field. + ``trigger_times_per_event`` | (``m_events``, ``n_triggers``) | The trigger times per event. From 381014c6219bc82489380c81aaa63cccaf18544f Mon Sep 17 00:00:00 2001 From: Sjoerd Bouma Date: Thu, 1 Jun 2023 18:25:56 +0200 Subject: [PATCH 294/418] escape asterisks to avoid confusing rst and added mattak to mock_imports --- NuRadioReco/modules/measured_noise/channelMeasuredNoiseAdder.py | 2 +- documentation/source/NuRadioMC/pages/HDF5_structure.rst | 2 +- documentation/source/conf.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/NuRadioReco/modules/measured_noise/channelMeasuredNoiseAdder.py b/NuRadioReco/modules/measured_noise/channelMeasuredNoiseAdder.py index 1cf89e2c2..b09c58a57 100644 --- a/NuRadioReco/modules/measured_noise/channelMeasuredNoiseAdder.py +++ b/NuRadioReco/modules/measured_noise/channelMeasuredNoiseAdder.py @@ -44,7 +44,7 @@ def begin(self, filenames=None, folder=None, file_pattern="*", including subdirectories. (Default: None) file_pattern: str - Use glob.glob(f"{folder}/**/{file_pattern}.nur", recursive=True) to search for files. (Default: "*") + Use ``glob.glob(f"{folder}/**/{file_pattern}.nur", recursive=True)`` to search for files. (Default: "*") random_seed: int, default: None Seed for the random number generator. By default, no seed is set. diff --git a/documentation/source/NuRadioMC/pages/HDF5_structure.rst b/documentation/source/NuRadioMC/pages/HDF5_structure.rst index 5033fc573..aaa4ee51f 100644 --- a/documentation/source/NuRadioMC/pages/HDF5_structure.rst +++ b/documentation/source/NuRadioMC/pages/HDF5_structure.rst @@ -119,7 +119,7 @@ some parameters are per shower. See https://doi.org/10.22323/1.395.1231 for a de ``m_events`` and ``m_showers`` refer to the number of events and showers that triggered the station. NOTE: The simple table structure of hdf5 files can not capture the complex relation between events and showers in all cases. Some fields can be ambiguous (e.g. `trigger_times` that only lists the last trigger that a shower generated). -For more advanced analyses, please use the *.nur files. +For more advanced analyses, please use the ``*.nur`` files. The ``event_group_id`` is the same as in the global dictionary. Therefore you can check for one event with an ``event_group_id`` which stations contain the same ``event_group_id`` and retrieve the information, which station triggered, with which amplitude, etc. The same approach works for ``shower_id``. diff --git a/documentation/source/conf.py b/documentation/source/conf.py index d24163148..262f1f463 100644 --- a/documentation/source/conf.py +++ b/documentation/source/conf.py @@ -239,7 +239,7 @@ autodoc_mock_imports = [ 'ROOT', 'mysql-python', 'pygdsm', 'MySQLdb', 'healpy', 'scripts', 'uproot', 'radiopropa', 'plotly', 'past', - 'nifty5' + 'nifty5', 'mattak' ] # Raise warnings if any cross-references are broken nitpicky = True From 9419e3597cb931bdf62358e0f35384a2719fe2ad Mon Sep 17 00:00:00 2001 From: Sjoerd Bouma Date: Fri, 23 Jun 2023 12:47:36 +0200 Subject: [PATCH 295/418] fix positions/orientations of LPDAs --- .../detector/RNO_G/RNO_single_station.json | 27 ++++++++++--------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/NuRadioReco/detector/RNO_G/RNO_single_station.json b/NuRadioReco/detector/RNO_G/RNO_single_station.json index e012f5a66..4b1935f19 100644 --- a/NuRadioReco/detector/RNO_G/RNO_single_station.json +++ b/NuRadioReco/detector/RNO_G/RNO_single_station.json @@ -236,12 +236,12 @@ "15": { "amp_type": "rno_surface", "ant_comment": "second arm south-east from DAQ, north-east position in arm, pointing side-downwards", - "ant_orientation_phi": 240.0, + "ant_orientation_phi": 120.0, "ant_orientation_theta": 135.0, "ant_position_x": -10.276, "ant_position_y": -4.2, "ant_position_z": -2.0, - "ant_rotation_phi": 330.0, + "ant_rotation_phi": 210.0, "ant_rotation_theta": 90.0, "ant_type": "createLPDA_100MHz_InfFirn_n1.4", "cab_time_delay": 19.8, @@ -258,7 +258,7 @@ "ant_position_x": -9.526, "ant_position_y": -5.5, "ant_position_z": -2.0, - "ant_rotation_phi": 330.0, + "ant_rotation_phi": 210.0, "ant_rotation_theta": 90.0, "ant_type": "createLPDA_100MHz_InfFirn_n1.4", "cab_time_delay": 19.8, @@ -270,12 +270,12 @@ "17": { "amp_type": "rno_surface", "ant_comment": "second arm south-east from DAQ, south-west position in arm, pointing side-downwards", - "ant_orientation_phi": 60.0, + "ant_orientation_phi": 300.0, "ant_orientation_theta": 135.0, "ant_position_x": -8.776, "ant_position_y": -6.8, "ant_position_z": -2, - "ant_rotation_phi": 330.0, + "ant_rotation_phi": 210.0, "ant_rotation_theta": 90.0, "ant_type": "createLPDA_100MHz_InfFirn_n1.4", "reference_channel": 0, @@ -286,12 +286,12 @@ "18": { "amp_type": "rno_surface", "ant_comment": "third arm south-west from DAQ, south-east position in arm, pointing side-downwards", - "ant_orientation_phi": 120.0, + "ant_orientation_phi": 240.0, "ant_orientation_theta": 135.0, "ant_position_x": 8.776, "ant_position_y": -6.8, "ant_position_z": -2.0, - "ant_rotation_phi": 210.0, + "ant_rotation_phi": 330.0, "ant_rotation_theta": 90.0, "ant_type": "createLPDA_100MHz_InfFirn_n1.4", "reference_channel": 0, @@ -306,7 +306,7 @@ "ant_position_x": 9.526, "ant_position_y": -5.5, "ant_position_z": -2.0, - "ant_rotation_phi": 210.0, + "ant_rotation_phi": 330.0, "ant_rotation_theta": 90.0, "ant_type": "createLPDA_100MHz_InfFirn_n1.4", "reference_channel": 0, @@ -316,12 +316,12 @@ "20": { "amp_type": "rno_surface", "ant_comment": "third arm south-west from DAQ, north-west position in arm, pointing side-downwards", - "ant_orientation_phi": 300.0, + "ant_orientation_phi": 60.0, "ant_orientation_theta": 135.0, - "ant_position_x": -10.276, - "ant_position_y": 4.2, + "ant_position_x": 10.276, + "ant_position_y": -4.2, "ant_position_z": -2.0, - "ant_rotation_phi": 210.0, + "ant_rotation_phi": 330.0, "ant_rotation_theta": 90.0, "ant_type": "createLPDA_100MHz_InfFirn_n1.4", "reference_channel": 0, @@ -381,7 +381,8 @@ "pos_northing": 0.0, "pos_site": "summit", "station_id": 11, - "station_type": null + "station_type": null, + "reference_station": 11 } } } From bbfafc2f00d482482d7edfc3a8cb316d702c40b7 Mon Sep 17 00:00:00 2001 From: Sjoerd Bouma Date: Sat, 24 Jun 2023 10:47:37 +0200 Subject: [PATCH 296/418] use NuRadioMC conventions for FFT normalization --- .../apps/trace_plots/channel_spectrum.py | 21 +++++++------------ .../apps/trace_plots/channel_time_trace.py | 6 +++--- .../apps/trace_plots/multi_channel_plot.py | 11 +++++----- 3 files changed, 16 insertions(+), 22 deletions(-) diff --git a/NuRadioReco/eventbrowser/apps/trace_plots/channel_spectrum.py b/NuRadioReco/eventbrowser/apps/trace_plots/channel_spectrum.py index 4b8bfd051..1909cf520 100644 --- a/NuRadioReco/eventbrowser/apps/trace_plots/channel_spectrum.py +++ b/NuRadioReco/eventbrowser/apps/trace_plots/channel_spectrum.py @@ -4,9 +4,9 @@ from NuRadioReco.utilities import units from NuRadioReco.eventbrowser.default_layout import default_layout import numpy as np -from dash import dcc +from dash import dcc, callback from dash.dependencies import State -from NuRadioReco.eventbrowser.app import app +# from NuRadioReco.eventbrowser.app import app import NuRadioReco.eventbrowser.dataprovider provider = NuRadioReco.eventbrowser.dataprovider.DataProvider() @@ -16,7 +16,7 @@ ] -@app.callback( +@callback( dash.dependencies.Output('channel-spectrum', 'figure'), [dash.dependencies.Input('trigger-trace', 'children'), dash.dependencies.Input('event-counter-slider', 'value'), @@ -33,18 +33,13 @@ def update_channel_spectrum(trigger, evt_counter, filename, station_id, juser_id station = evt.get_station(station_id) fig = plotly.subplots.make_subplots(rows=1, cols=1) for i, channel in enumerate(station.iter_channels()): - if channel.get_trace() is None: + spec = channel.get_frequency_spectrum() + if spec is None: continue - tt = channel.get_times() - dt = tt[1] - tt[0] - if channel.get_trace() is None: - continue - trace = channel.get_trace() - ff = np.fft.rfftfreq(len(tt), dt) - spec = np.abs(np.fft.rfft(trace, norm='ortho')) + freqs = channel.get_frequencies() fig.append_trace(plotly.graph_objs.Scatter( - x=ff / units.MHz, - y=spec / units.mV, + x=freqs / units.MHz, + y=np.abs(spec) / units.mV, opacity=0.7, marker={ 'color': colors[i % len(colors)], diff --git a/NuRadioReco/eventbrowser/apps/trace_plots/channel_time_trace.py b/NuRadioReco/eventbrowser/apps/trace_plots/channel_time_trace.py index ebe267dfe..f9a156e51 100644 --- a/NuRadioReco/eventbrowser/apps/trace_plots/channel_time_trace.py +++ b/NuRadioReco/eventbrowser/apps/trace_plots/channel_time_trace.py @@ -4,9 +4,9 @@ from NuRadioReco.utilities import units from NuRadioReco.eventbrowser.default_layout import default_layout import numpy as np -from dash import dcc +from dash import dcc, callback from dash.dependencies import State -from NuRadioReco.eventbrowser.app import app +# from NuRadioReco.eventbrowser.app import app import NuRadioReco.eventbrowser.dataprovider provider = NuRadioReco.eventbrowser.dataprovider.DataProvider() @@ -16,7 +16,7 @@ ] -@app.callback( +@callback( dash.dependencies.Output('time-trace', 'figure'), [dash.dependencies.Input('trigger-trace', 'children'), dash.dependencies.Input('event-counter-slider', 'value'), diff --git a/NuRadioReco/eventbrowser/apps/trace_plots/multi_channel_plot.py b/NuRadioReco/eventbrowser/apps/trace_plots/multi_channel_plot.py index bce94c7f3..b14008c23 100644 --- a/NuRadioReco/eventbrowser/apps/trace_plots/multi_channel_plot.py +++ b/NuRadioReco/eventbrowser/apps/trace_plots/multi_channel_plot.py @@ -12,10 +12,9 @@ from NuRadioReco.utilities import trace_utilities """ import numpy as np -from dash import html -from dash import dcc +from dash import dcc, html, callback from dash.dependencies import Input, Output, State -from NuRadioReco.eventbrowser.app import app +# from NuRadioReco.eventbrowser.app import app import os import NuRadioReco.detector.antennapattern import NuRadioReco.eventbrowser.dataprovider @@ -72,7 +71,7 @@ ] -@app.callback( +@callback( dash.dependencies.Output('dropdown-traces', 'options'), [dash.dependencies.Input('event-counter-slider', 'value'), dash.dependencies.Input('filename', 'value'), @@ -99,7 +98,7 @@ def get_dropdown_traces_options(evt_counter, filename, station_id, juser_id): return options -@app.callback( +@callback( Output('template-input-group', 'style'), [Input('dropdown-traces', 'value')] ) @@ -117,7 +116,7 @@ def get_L1(a): return l1 -@app.callback( +@callback( dash.dependencies.Output('time-traces', 'figure'), [dash.dependencies.Input('event-counter-slider', 'value'), dash.dependencies.Input('filename', 'value'), From f8e42395307ffe1639c1b6432748bcfa4ae395b6 Mon Sep 17 00:00:00 2001 From: Sjoerd Bouma Date: Thu, 6 Jul 2023 17:58:50 +0200 Subject: [PATCH 297/418] update eventbrowser root (RNO-G) reader --- NuRadioReco/eventbrowser/dataprovider_root.py | 66 ++++++++++++++++--- 1 file changed, 58 insertions(+), 8 deletions(-) diff --git a/NuRadioReco/eventbrowser/dataprovider_root.py b/NuRadioReco/eventbrowser/dataprovider_root.py index 0782ccb29..d5c8bd968 100644 --- a/NuRadioReco/eventbrowser/dataprovider_root.py +++ b/NuRadioReco/eventbrowser/dataprovider_root.py @@ -1,4 +1,23 @@ from NuRadioReco.modules.io.RNO_G.readRNOGDataMattak import readRNOGData +import os +import time +import numpy as np + +### we create a wrapper for readRNOGData to mirror the interface of the .nur reader +class readRNOG_wrapper(readRNOGData): + + def get_event_ids(self): + event_infos = self.get_events_information() + return np.array([(i['run'], i['eventNumber']) for i in event_infos.values()]) + + def get_event_i(self, i): + return self.get_event_by_index(i) + + def get_event(self, event_id): + return super().get_event(*event_id) + + def get_n_events(self): + return self._n_events_total class DataProviderRoot(object): @@ -9,18 +28,49 @@ def __new__(cls): DataProviderRoot.__instance = object.__new__(cls) return DataProviderRoot.__instance - def __init__(self): + def __init__(self, max_user_instances=12): + """" + Convenience wrapper for the root-based RNO-G data reader + + Parameters + ---------- + max_user_instances: int, default=12 + Each unique session id gets its own reader, up to a maximum + of ``max_user_instances`` concurrent readers. Subsequent + requests for new readers drop older readers. + + """ + self.__max_user_instances = max_user_instances self.__user_instances = {} def get_file_handler(self, user_id, filename): if filename is None: return if user_id not in self.__user_instances: - self.__user_instances[user_id] = readRNOGData.begin([filename]) - - if filename != self.__user_instances[user_id].get_filenames()[0]: + # create new reader for the new user + reader = readRNOG_wrapper() + self.__user_instances[user_id] = dict( + reader=reader, filename=None, + ) + if filename != self.__user_instances[user_id]['filename']: # user is requesting new file -> close current file and open new one - self.__user_instances[user_id] = readRNOGData.begin([filename]) - #TODO begin method does not exist in RNOGDataReader - #self.__user_instances[user_id].begin(filename) - return self.__user_instances[user_id] + reader = self.__user_instances[user_id]['reader'] + reader.begin([os.path.dirname(filename)]) + self.__user_instances[user_id] = dict( + reader=reader, filename=filename, + ) + + # update last access time + self.__user_instances[user_id]['last_access_time'] = time.time() + + # check if we exceed maximum number of concurrent sessions + if len(self.__user_instances) > self.__max_user_instances: + users = { + self.__user_instances[k]['last_access_time']:k + for k in self.__user_instances.keys() + } + users_by_access_time = sorted(users) + # drop oldest session + self.__user_instances.pop(users_by_access_time[0]) + + return self.__user_instances[user_id]['reader'] From 4f423f7a0bd63c76288e3aa7c5cdae4db3dfb115 Mon Sep 17 00:00:00 2001 From: Sjoerd Bouma Date: Mon, 10 Jul 2023 16:36:47 +0200 Subject: [PATCH 298/418] store fitted block offsets as a channelParameter, simplify interface --- NuRadioReco/framework/parameters.py | 1 + .../modules/RNO_G/channelBlockOffsetFitter.py | 146 ++++++------------ 2 files changed, 52 insertions(+), 95 deletions(-) diff --git a/NuRadioReco/framework/parameters.py b/NuRadioReco/framework/parameters.py index 575d7b402..b234ec112 100644 --- a/NuRadioReco/framework/parameters.py +++ b/NuRadioReco/framework/parameters.py @@ -57,6 +57,7 @@ class channelParameters(Enum): signal_receiving_zenith = 15 #: the zenith angle of direction at which the radio signal arrived at the antenna signal_ray_type = 16 #: type of the ray propagation path of the signal received by this channel. Options are direct, reflected and refracted signal_receiving_azimuth = 17 #: the azimuth angle of direction at which the radio signal arrived at the antenna + block_offsets = 18 #: 'block' or pedestal offsets. See `NuRadioReco.modules.RNO_G.channelBlockOffsetFitter` class electricFieldParameters(Enum): diff --git a/NuRadioReco/modules/RNO_G/channelBlockOffsetFitter.py b/NuRadioReco/modules/RNO_G/channelBlockOffsetFitter.py index 4467fd0d8..da0cd3e37 100644 --- a/NuRadioReco/modules/RNO_G/channelBlockOffsetFitter.py +++ b/NuRadioReco/modules/RNO_G/channelBlockOffsetFitter.py @@ -1,5 +1,17 @@ +""" +Module to remove 'block offsets' from RNO-G voltage traces. + +The function ``fit_block_offsets`` can be used standalone to perform an out-of-band +fit to the block offsets. Alternatively, the ``channelBlockOffsets`` class contains convenience +``add_offsets`` (to add block offsets in simulation) and ``remove_offsets`` methods that can be run +directly on a NuRadioMC/imported ``Event``. The added/removed block offsets are stored per channel +in the `NuRadioReco.framework.parameters.channelParameters.block_offsets` parameter. + +""" + from NuRadioReco.utilities import units, fft from NuRadioReco.framework.base_trace import BaseTrace +from NuRadioReco.framework.parameters import channelParameters # from iminuit import Minuit import numpy as np import scipy @@ -32,6 +44,9 @@ def add_offsets(self, event, station, offsets=1*units.mV, channel_ids=None): """ Add (simulated or reconstructed) block offsets to an event. + Added block offsets for each channel are stored in the + ``channelParameters.block_offsets`` parameter. + Parameters ---------- event: Event object | None @@ -68,119 +83,67 @@ def add_offsets(self, event, station, offsets=1*units.mV, channel_ids=None): ) else: add_offsets = offsets - if channel_id in self._offset_inject.keys(): - self._offset_inject[channel_id] += add_offsets + + # save the added offsets as a channelParameter + if channel.has_parameter(channelParameters.block_offsets): + block_offsets_old = channel.get_parameter(channelParameters.block_offsets) + channel.set_parameter(channelParameters.block_offsets, block_offsets_old + offsets) else: - self._offset_inject[channel_id] = add_offsets + channel.set_parameter(channelParameters.block_offsets, offsets) channel.set_trace( channel.get_trace() + np.repeat(add_offsets, self.block_size), channel.get_sampling_rate() ) - def remove_offsets(self, event, station, offsets='fit', channel_ids=None): + def remove_offsets(self, event, station, mode='fit', channel_ids=None): """ Remove block offsets from an event - Fits and removes the block offsets from an event. + Fits and removes the block offsets from an event. The removed + offsets are stored in the ``channelParameters.block_offsets`` + parameter. Parameters ---------- event: NuRadioReco.framework.event.Event | None station: NuRadioReco.framework.station.Station The station to remove the block offsets from - offsets: str - How to remove the offsets. Options are: - - - 'fit': fit the offsets out of band - - 'injected': if offsets were injected using the ``add_offsets`` - method, this removes those offsets. Otherwise, this does nothing. + mode: 'fit' | 'approximate' | 'stored' + + - 'fit' (default): fit the block offsets with a minimizer + - 'approximate' : use the first guess from the out-of-band component, + without any fitting (slightly faster) + - 'stored': use the block offsets already stored in the + ``channelParameters.block_offsets`` parameter. Will raise an error + if this parameter is not present. - Default: 'fit' channel_ids: list | None List of channel ids to remove offsets from. If None (default), remove offsets from all channels in ``station`` """ - if offsets=='fit': - if not len(self._offset_fit): - self.fit_offsets(event, station, channel_ids) - offsets = self._offset_fit - elif offsets=='injected': - if not len(self._offset_inject): - offsets = np.zeros(16) #TODO - ensure this works for different trace lengths - else: - offsets = self._offset_inject - - if isinstance(offsets, dict): - remove_offsets = {key: -offsets[key] for key in offsets.keys()} - else: - remove_offsets = -offsets - self.add_offsets(event, station, remove_offsets, channel_ids) - - def fit_offsets(self, event, station, channel_ids=None): - """ - Fit the block offsets using an out-of-band fit - - This function fits the block offsets present in a given - event / station using an out-of-band fit in frequency space. - - Parameters - ---------- - event: NuRadioReco.framework.event.Event | None - station: NuRadioReco.framework.station.Station - The station to fit the block offsets to - channel_ids: list | None - List of channel ids to fit block offsets for. If None (default), - fit offsets for all channels in ``station`` - - """ - block_size = self.block_size - if channel_ids is None: + if channel_ids is None: channel_ids = station.get_channel_ids() - for channel_id in channel_ids: - channel = station.get_channel(channel_id) - trace = channel.get_trace() - - block_offsets = fit_block_offsets( - trace, block_size, - channel.get_sampling_rate(), self._max_frequency - ) - self._offset_fit[channel_id] = block_offsets - def get_offsets(self, channel_id, offset_type='fit'): - """ - Return the block offsets for a given channel. - - Parameters - ---------- - channel_id: int - channel id that specifies the channel to return block offsets for - offset_type: str - Options: - - - 'fit': return the fitted block offsets - - 'injected': return the block offsets that were injected - using the ``add_offsets`` method. - - Returns - ------- - trace: BaseTrace - A :class:`NuRadioReco.framework.base_trace.BaseTrace` object with the same length as the channel trace, - containing only the block offsets. + offsets = {} + if mode == 'stored': # remove offsets stored in channelParameters.block_offsets + offsets = { + channel_id: -station.get_channel(channel_id).get_parameter(channelParameters.block_offsets) + for channel_id in channel_ids} + else: # fit & remove offsets + for channel_id in channel_ids: + channel = station.get_channel(channel_id) + trace = channel.get_trace() + + block_offsets = fit_block_offsets( + trace, self.block_size, + channel.get_sampling_rate(), self._max_frequency + ) + offsets[channel_id] = -block_offsets + + self.add_offsets(event, station, offsets, channel_ids) - """ - trace = BaseTrace() - if offset_type == 'fit': - trace.set_trace(np.repeat(self._offset_fit[channel_id], self.block_size), self.sampling_rate) - elif offset_type == 'injected': - trace.set_trace(np.repeat(self._offset_inject[channel_id], self.block_size), self.sampling_rate) - return trace - - def _pedestal_fit(self, a): - fit = np.sum(a[:, None] * self._const_fft_term, axis=0) - chi2 = np.sum(np.abs(fit-self._spectrum)**2) - return chi2 def fit_block_offsets( trace, block_size=128, sampling_rate=3.2*units.GHz, @@ -275,14 +238,7 @@ def pedestal_fit(a): chi2 = np.sum(np.abs(fit-spectrum_oob)**2) return chi2 - # self._spectrum = spectrum_oob res = scipy.optimize.minimize(pedestal_fit, a_guess, tol=tol).x - ### maybe TODO - include option to use Minuit, which seems a lot quicker? - # m = Minuit(self._pedestal_fit_minuit, a_guess * nufft_conversion_factor) - # m.errordef = 1 - # m.errors = 0.01 * np.ones_like(a_guess) - # m.migrad(ncall=20000) - # res = m.values block_offsets = np.zeros(len(res) + 1) block_offsets[:-1] = res From 256f21f23c3fc34bfe474dc816b50b2e934b1bc7 Mon Sep 17 00:00:00 2001 From: Sjoerd Bouma Date: Mon, 10 Jul 2023 16:37:26 +0200 Subject: [PATCH 299/418] update changelog --- changelog.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/changelog.txt b/changelog.txt index 8d6735957..1004f2da1 100644 --- a/changelog.txt +++ b/changelog.txt @@ -10,6 +10,7 @@ new features: - add positions array functionality to simple ice model in average and gradient functions - analytic ray tracing solutions are now sorted consistently from lowest to highest ray - added ability to generate high-low-triggered noise on a narrow band but return full-band waveforms +- added 'block offset' removal/simulation module for RNO-G bugfixes: - fixed/improved C++ raytracer not finding solutions for some near-horizontal or near-shadowzone vertices - fixed wrong number in Feldman-Cousins upper limit From e52667024750134f8dd9018d22ac9a5774a0dbff Mon Sep 17 00:00:00 2001 From: Sjoerd Bouma Date: Fri, 14 Jul 2023 16:42:34 +0200 Subject: [PATCH 300/418] fail only on sphinx errors (hopefully) --- documentation/Makefile | 2 +- documentation/make_docs.py | 17 ++++++++++++----- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/documentation/Makefile b/documentation/Makefile index 22f3d5479..4a3fdd9d1 100644 --- a/documentation/Makefile +++ b/documentation/Makefile @@ -2,7 +2,7 @@ # # You can set these variables from the command line. -SPHINXOPTS = +SPHINXOPTS = -w sphinx-debug.log SPHINXBUILD = sphinx-build SPHINXPROJ = NuRadio SOURCEDIR = source diff --git a/documentation/make_docs.py b/documentation/make_docs.py index f529dce94..c7d5a4235 100644 --- a/documentation/make_docs.py +++ b/documentation/make_docs.py @@ -113,11 +113,12 @@ subprocess.check_output(['make', 'clean']) sphinx_log = subprocess.run(['make', 'html'], stderr=subprocess.PIPE, stdout=pipe_stdout) - # errs = sphinx_log.stderr.decode().split('\n') - errs = re.split('\\x1b\[[0-9;]+m', sphinx_log.stderr.decode()) # split the errors - # output = sphinx_log.stdout.decode().split('\n') - - for err in errs: + # we write out all the sphinx errors to sphinx-debug.log, and parse these + with open('sphix-debug.log') as f: + errs_raw = f.read() + errs_sphinx = re.split('\\x1b\[[0-9;]+m', errs_raw) # split the errors + + for err in errs_sphinx: if not err.split(): # whitespace only continue for key in error_dict.keys(): @@ -131,6 +132,12 @@ continue fixable_errors += len(error_dict[key]['matches']) + # stderr includes non-sphinx errors/warnings raised during the build process + # we record these for debugging but don't fail on them + errs_other = re.split('\\x1b\[[0-9;]+m', sphinx_log.stderr.decode()) + errs_other = [err for err in errs_other if not err in errs_sphinx] + error_dict['other']['matches'] += errs_other + print(2*'\n'+78*'-') if fixable_errors: logger.warning("The documentation was not built without errors. Please fix the following errors!") From d83c8e275eddee2364fd2339060fdf91d5f29616 Mon Sep 17 00:00:00 2001 From: Sjoerd Bouma Date: Fri, 14 Jul 2023 16:44:16 +0200 Subject: [PATCH 301/418] fix typo --- documentation/make_docs.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/make_docs.py b/documentation/make_docs.py index c7d5a4235..596bfda7c 100644 --- a/documentation/make_docs.py +++ b/documentation/make_docs.py @@ -114,7 +114,7 @@ sphinx_log = subprocess.run(['make', 'html'], stderr=subprocess.PIPE, stdout=pipe_stdout) # we write out all the sphinx errors to sphinx-debug.log, and parse these - with open('sphix-debug.log') as f: + with open('sphinx-debug.log') as f: errs_raw = f.read() errs_sphinx = re.split('\\x1b\[[0-9;]+m', errs_raw) # split the errors From c583dad8f07a8aafe373d94e76bb0f436bbea139 Mon Sep 17 00:00:00 2001 From: Sjoerd Bouma Date: Fri, 14 Jul 2023 23:54:52 +0200 Subject: [PATCH 302/418] update / unpin numpydoc --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index e5e0b4292..9ca42050a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -45,7 +45,7 @@ numba = "*" [tool.poetry.dev-dependencies] Sphinx = "*" sphinx-rtd-theme = "*" -numpydoc = "1.1.0" +numpydoc = "*" proposal = "7.5.1" pygdsm = {git = "https://github.com/telegraphic/pygdsm"} nifty5 = {git = "https://gitlab.mpcdf.mpg.de/ift/nifty.git", branch="NIFTy_5"} From 69cc8715daa801254b02dd2e3bafaac674032019 Mon Sep 17 00:00:00 2001 From: Sjoerd Bouma Date: Sat, 15 Jul 2023 00:51:08 +0200 Subject: [PATCH 303/418] add new name of aenum Enum class to nitpick_ignore --- documentation/source/conf.py | 1 + 1 file changed, 1 insertion(+) diff --git a/documentation/source/conf.py b/documentation/source/conf.py index d24163148..8024feb9a 100644 --- a/documentation/source/conf.py +++ b/documentation/source/conf.py @@ -247,6 +247,7 @@ # this ignores some cross-reference errors inside docstrings # that we don't care about nitpick_ignore_regex = [ + ("py:class", "aenum._enum.Enum"), ("py:class", "aenum.Enum"), ("py:class", "tinydb_serialization.Serializer"), ("py:class", "radiopropa.ScalarField"), From fd11ed91b22420c2e851452f05d437b100a8cbe6 Mon Sep 17 00:00:00 2001 From: Sjoerd Bouma Date: Sat, 15 Jul 2023 00:52:19 +0200 Subject: [PATCH 304/418] remember to flush --- documentation/make_docs.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/documentation/make_docs.py b/documentation/make_docs.py index 596bfda7c..b7909c628 100644 --- a/documentation/make_docs.py +++ b/documentation/make_docs.py @@ -137,21 +137,21 @@ errs_other = re.split('\\x1b\[[0-9;]+m', sphinx_log.stderr.decode()) errs_other = [err for err in errs_other if not err in errs_sphinx] error_dict['other']['matches'] += errs_other - - print(2*'\n'+78*'-') + + errors_string = '\n'.join([ + f'[{key}]\n' + '\n'.join(value['matches']) + for key, value in error_dict.items() if len(value['matches']) + ]) + + print(2*'\n'+78*'-', flush=True) if fixable_errors: - logger.warning("The documentation was not built without errors. Please fix the following errors!") - for key, item in error_dict.items(): - if len(item['matches']): - print(f'[{key}]') - print('\n'.join(item['matches'])) + logger.error(f"The documentation was not built without errors. Please fix the following errors!\n{errors_string}") elif len(error_dict['other']['matches']): logger.warning(( "make_docs found some errors but doesn't know what to do with them.\n" - "The documentation may not be rejected, but consider fixing the following anyway:" + f"The documentation may not be rejected, but consider fixing the following anyway:\n{errors_string}" )) - print('\n'.join(error_dict['other']['matches'])) - print(78*'-'+2*'\n') + print(78*'-'+2*'\n', flush=True) if sphinx_log.returncode: logger.error("The documentation failed to build, make_docs will raise an error.") From 1b10f6775a447f1c941cbcb8b6af54b14cb6e05e Mon Sep 17 00:00:00 2001 From: Sjoerd Bouma Date: Sat, 15 Jul 2023 00:56:22 +0200 Subject: [PATCH 305/418] fix underline in docstring --- NuRadioMC/utilities/Veff.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NuRadioMC/utilities/Veff.py b/NuRadioMC/utilities/Veff.py index 00aecb933..eab3a500c 100644 --- a/NuRadioMC/utilities/Veff.py +++ b/NuRadioMC/utilities/Veff.py @@ -644,7 +644,7 @@ def get_Veff_Aeff_array(data): * array of unique trigger names Examples - --------- + -------- To plot the full sky effective volume for 'all_triggers' do From 7c4e85abb59ab3d2f1d361dac241c2848b6694c2 Mon Sep 17 00:00:00 2001 From: Sjoerd Bouma Date: Tue, 18 Jul 2023 12:28:31 +0200 Subject: [PATCH 306/418] hardcode sampling rate to 3.2 GHz for RNO-G --- NuRadioReco/eventbrowser/dataprovider_root.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NuRadioReco/eventbrowser/dataprovider_root.py b/NuRadioReco/eventbrowser/dataprovider_root.py index d5c8bd968..603696f47 100644 --- a/NuRadioReco/eventbrowser/dataprovider_root.py +++ b/NuRadioReco/eventbrowser/dataprovider_root.py @@ -55,7 +55,7 @@ def get_file_handler(self, user_id, filename): if filename != self.__user_instances[user_id]['filename']: # user is requesting new file -> close current file and open new one reader = self.__user_instances[user_id]['reader'] - reader.begin([os.path.dirname(filename)]) + reader.begin([os.path.dirname(filename)], overwrite_sampling_rate=3.2) #TODO - remove hardcoded sampling rate self.__user_instances[user_id] = dict( reader=reader, filename=filename, ) From c12262fa3b183657c3a50c99d6f2cc0128fb1c16 Mon Sep 17 00:00:00 2001 From: lpyras Date: Wed, 19 Jul 2023 13:29:20 +0200 Subject: [PATCH 307/418] add hash for SKALA antenna model. Model is updated to the full range of 0 to 360 degree rather than 0 359 degree. --- NuRadioReco/detector/antenna_models_hash.json | 21 ++++++++----------- 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/NuRadioReco/detector/antenna_models_hash.json b/NuRadioReco/detector/antenna_models_hash.json index f6ad37bec..8b18cdaea 100644 --- a/NuRadioReco/detector/antenna_models_hash.json +++ b/NuRadioReco/detector/antenna_models_hash.json @@ -42,16 +42,13 @@ "createLPDA_100MHz_z1cm_InAir_RG.pkl": "9202fa4842792b241366b38cd9a358c03f83acbd", "XFDTD_Hpol_150mmHole_n1.78.pkl": "cfa1e1d1ddbd146ca3b89c580e137e22300551c4", "XFDTD_Vpol_CrossFeed_150mmHole_n1.78.pkl": "5d87513779cf2cb5d3309a9bb89dbb163d656114", - "trislot_RNOG.pkl": "29ef63bc9f25da743dd85d33e5645fc6330f6675", - "RNOG_vpol_v1_n1.73.pkl": "4bd0b5941b31c6c39fd6b438f005075b025fee8d", - "RNOG_vpol_v1_n1.4.pkl": "1b8be66b64f241d26e34567167318aa85c396f2a", - "RNOG_vpol_4inch_half_1.73.pkl": - "f08d263233503f79e5be10c18bc7587b8b421c1d", - "RNOG_vpol_4inch_center_1.73.pkl": - "5f429ed9ed08175a7f75fd44422367d2278bf2e1", - "RNOG_vpol_4inch_wall_1.73.pkl": - "da24017eb80f7a68348a674be2c527457fe19992", - "RNOG_quadslot_v1_1.74.pkl": - "e9c4946dd2176489249c862f32ef272ab627dc28", - "RNOG_quadslot_v2_1.74.pkl": "b99d69578f8e7c006dcce3de51e26c4f463872b8" + "trislot_RNOG.pkl": "29ef63bc9f25da743dd85d33e5645fc6330f6675", + "RNOG_vpol_v1_n1.73.pkl": "4bd0b5941b31c6c39fd6b438f005075b025fee8d", + "RNOG_vpol_v1_n1.4.pkl": "1b8be66b64f241d26e34567167318aa85c396f2a", + "RNOG_vpol_4inch_half_1.73.pkl": "f08d263233503f79e5be10c18bc7587b8b421c1d", + "RNOG_vpol_4inch_center_1.73.pkl": "5f429ed9ed08175a7f75fd44422367d2278bf2e1", + "RNOG_vpol_4inch_wall_1.73.pkl": "da24017eb80f7a68348a674be2c527457fe19992", + "RNOG_quadslot_v1_1.74.pkl": "e9c4946dd2176489249c862f32ef272ab627dc28", + "RNOG_quadslot_v2_1.74.pkl": "b99d69578f8e7c006dcce3de51e26c4f463872b8", + "SKALA_InfFirn": "69b3007da083bb722a4494af97221917973ab297" } From 43ea9a8c11d1fc79cbab92363c4498da8578f971 Mon Sep 17 00:00:00 2001 From: Sjoerd Bouma Date: Wed, 19 Jul 2023 13:57:10 +0200 Subject: [PATCH 308/418] add toggle for log/linear scale to frequency spectra --- .../apps/trace_plots/channel_spectrum.py | 8 ++- .../apps/trace_plots/multi_channel_plot.py | 7 +- .../rec_electric_field_spectrum.py | 3 +- NuRadioReco/eventbrowser/apps/traces.py | 72 +++++++++++++++---- 4 files changed, 71 insertions(+), 19 deletions(-) diff --git a/NuRadioReco/eventbrowser/apps/trace_plots/channel_spectrum.py b/NuRadioReco/eventbrowser/apps/trace_plots/channel_spectrum.py index 1909cf520..943ef99a6 100644 --- a/NuRadioReco/eventbrowser/apps/trace_plots/channel_spectrum.py +++ b/NuRadioReco/eventbrowser/apps/trace_plots/channel_spectrum.py @@ -22,8 +22,10 @@ dash.dependencies.Input('event-counter-slider', 'value'), dash.dependencies.Input('filename', 'value'), dash.dependencies.Input('station-id-dropdown', 'value')], - [State('user_id', 'children')]) -def update_channel_spectrum(trigger, evt_counter, filename, station_id, juser_id): + [State('user_id', 'children'), + State('channel-spectrum-log-linear-switch', 'children')] + ) +def update_channel_spectrum(trigger, evt_counter, filename, station_id, juser_id, yscale): if filename is None or station_id is None: return {} user_id = json.loads(juser_id) @@ -50,5 +52,5 @@ def update_channel_spectrum(trigger, evt_counter, filename, station_id, juser_id fig['layout'].update(default_layout) fig['layout']['legend']['uirevision'] = filename fig['layout']['xaxis1'].update(title='frequency [MHz]') - fig['layout']['yaxis1'].update(title='amplitude [mV]') + fig['layout']['yaxis'].update(title='amplitude [mV]', type=yscale) return fig diff --git a/NuRadioReco/eventbrowser/apps/trace_plots/multi_channel_plot.py b/NuRadioReco/eventbrowser/apps/trace_plots/multi_channel_plot.py index b14008c23..da96f60bb 100644 --- a/NuRadioReco/eventbrowser/apps/trace_plots/multi_channel_plot.py +++ b/NuRadioReco/eventbrowser/apps/trace_plots/multi_channel_plot.py @@ -125,9 +125,11 @@ def get_L1(a): dash.dependencies.Input('station-id-dropdown', 'value'), dash.dependencies.Input('open-template-button', 'n_clicks_timestamp')], [State('user_id', 'children'), - State('template-directory-input', 'value')]) + State('template-directory-input', 'value'), + State('channel-spectrum-log-linear-switch', 'children')] +) def update_multi_channel_plot(evt_counter, filename, dropdown_traces, dropdown_info, station_id, - open_template_timestamp, juser_id, template_directory): + open_template_timestamp, juser_id, template_directory, yscale): if filename is None or station_id is None: return {} user_id = json.loads(juser_id) @@ -419,6 +421,7 @@ def update_multi_channel_plot(evt_counter, filename, dropdown_traces, dropdown_i fig['layout']['yaxis{:d}'.format(i * 2 + 1)].update( title='Ch. {}
    voltage [mV]'.format(channel_id) ) + fig['layout']['yaxis{:d}'.format(i * 2 + 2)].update(type=yscale) if channel.get_trace() is None: continue diff --git a/NuRadioReco/eventbrowser/apps/trace_plots/rec_electric_field_spectrum.py b/NuRadioReco/eventbrowser/apps/trace_plots/rec_electric_field_spectrum.py index 2085c79ba..c93a618c9 100644 --- a/NuRadioReco/eventbrowser/apps/trace_plots/rec_electric_field_spectrum.py +++ b/NuRadioReco/eventbrowser/apps/trace_plots/rec_electric_field_spectrum.py @@ -4,7 +4,7 @@ from NuRadioReco.utilities import units from NuRadioReco.eventbrowser.default_layout import default_layout import numpy as np -from dash import dcc +from dash import dcc, html from dash.dependencies import State from NuRadioReco.eventbrowser.app import app import NuRadioReco.eventbrowser.dataprovider @@ -12,6 +12,7 @@ provider = NuRadioReco.eventbrowser.dataprovider.DataProvider() layout = [ + html.Button(id='efield-spectrum-log-linear-switch', children='log'), dcc.Graph(id='efield-spectrum') ] diff --git a/NuRadioReco/eventbrowser/apps/traces.py b/NuRadioReco/eventbrowser/apps/traces.py index c14ccd20d..ecf75111e 100644 --- a/NuRadioReco/eventbrowser/apps/traces.py +++ b/NuRadioReco/eventbrowser/apps/traces.py @@ -1,5 +1,5 @@ from __future__ import absolute_import, division, print_function # , unicode_literals -from dash import html +from dash import html, no_update import NuRadioReco.eventbrowser.apps.trace_plots.rec_electric_field_trace import NuRadioReco.eventbrowser.apps.trace_plots.rec_electric_field_spectrum import NuRadioReco.eventbrowser.apps.trace_plots.channel_time_trace @@ -27,6 +27,9 @@ html.Div([ html.Div([ 'Electric Field Spectrum', + ' (y-scale: ', + html.Button(id='efield-spectrum-log-linear-switch', children='linear'), + ')', html.Button('Show', id='toggle_efield_spectrum', n_clicks=0, style={'float':'right'}) ], className='panel-heading'), html.Div(NuRadioReco.eventbrowser.apps.trace_plots.rec_electric_field_spectrum.layout, @@ -45,6 +48,9 @@ html.Div([ html.Div([ 'Channel Spectrum', + ' (y-scale: ', + html.Button(id='channel-spectrum-log-linear-switch', children='linear'), + ')', html.Button('Show', id='toggle_channel_spectrum', n_clicks=0, style={'float':'right'}) ], className='panel-heading'), html.Div(NuRadioReco.eventbrowser.apps.trace_plots.channel_spectrum.layout, @@ -60,7 +66,7 @@ ]) @app.callback( - [Output('channel_traces_layout', 'children'), + [Output('channel_traces_layout', 'style'), Output('toggle_channel_traces', 'children')], [Input('toggle_channel_traces', 'n_clicks')], State('toggle_channel_traces', 'children'), @@ -68,12 +74,12 @@ ) def toggle_channel_trace_plot(button_clicks, showhide): if showhide == 'Hide': - return [], 'Show' + return {'flex': '1', 'display': 'none'}, 'Show' else: - return NuRadioReco.eventbrowser.apps.trace_plots.channel_time_trace.layout, 'Hide' + return {'flex' : '1'}, 'Hide' @app.callback( - [Output('channel_spectrum_layout', 'children'), + [Output('channel_spectrum_layout', 'style'), Output('toggle_channel_spectrum', 'children')], [Input('toggle_channel_spectrum', 'n_clicks')], State('toggle_channel_spectrum', 'children'), @@ -81,12 +87,12 @@ def toggle_channel_trace_plot(button_clicks, showhide): ) def toggle_channel_spectrum_plot(button_clicks, showhide): if showhide == 'Hide': - return [], 'Show' + return {'flex': '1', 'display': 'none'}, 'Show' else: - return NuRadioReco.eventbrowser.apps.trace_plots.channel_spectrum.layout, 'Hide' + return {'flex': '1'}, 'Hide' @app.callback( - [Output('efield_traces_layout', 'children'), + [Output('efield_traces_layout', 'style'), Output('toggle_efield_traces', 'children')], [Input('toggle_efield_traces', 'n_clicks')], State('toggle_efield_traces', 'children'), @@ -94,12 +100,12 @@ def toggle_channel_spectrum_plot(button_clicks, showhide): ) def toggle_efield_traces_plot(button_clicks, showhide): if showhide == 'Hide': - return [], 'Show' + return {'flex': '1', 'display': 'none'}, 'Show' else: - return NuRadioReco.eventbrowser.apps.trace_plots.rec_electric_field_trace.layout, 'Hide' + return {'flex': '1'}, 'Hide' @app.callback( - [Output('efield_spectrum_layout', 'children'), + [Output('efield_spectrum_layout', 'style'), Output('toggle_efield_spectrum', 'children')], [Input('toggle_efield_spectrum', 'n_clicks')], State('toggle_efield_spectrum', 'children'), @@ -107,6 +113,46 @@ def toggle_efield_traces_plot(button_clicks, showhide): ) def toggle_efield_spectrum_plot(button_clicks, showhide): if showhide == 'Hide': - return [], 'Show' + return {'flex': '1', 'display': 'none'}, 'Show' else: - return NuRadioReco.eventbrowser.apps.trace_plots.rec_electric_field_spectrum.layout, 'Hide' \ No newline at end of file + return {'flex': '1'}, 'Hide' + +# callback to change frequency spectra between linear and log scale +@app.callback( + [Output('channel-spectrum', 'figure', allow_duplicate=True), # this is a 'duplicate' callback - requires dash >= 2.9 + Output('time-traces', 'figure', allow_duplicate=True), + Output('channel-spectrum-log-linear-switch', 'children'), + Output('efield-spectrum-log-linear-switch', 'children') + ], + [Input('channel-spectrum-log-linear-switch', 'n_clicks'), + Input('efield-spectrum-log-linear-switch', 'n_clicks')], + [State('channel-spectrum-log-linear-switch', 'children'), + State('channel-spectrum', 'figure'), + State('time-traces', 'figure'), + ], prevent_initial_call=True +) +def toggle_linear_log_scale(button_clicks, button_current_value, channel_spectrum, multichannel_plot): + outputs = [] + if button_current_value == 'linear': # switch to log + new_value = 'log' + else: + new_value = 'linear' + try: + channel_spectrum['layout']['yaxis']['type'] = new_value + outputs.append(channel_spectrum) + except KeyError: + outputs.append(no_update) + + try: + yaxes = [key for key in multichannel_plot['layout'].keys() if 'yaxis' in key] + yaxes = [key for key in yaxes if len(key)>5] # omit key 'yaxis' + yaxes_even = [key for key in yaxes if not (int(key.split('yaxis')[-1]) % 2)] + for yaxis in yaxes_even: + multichannel_plot['layout'][yaxis]['type'] = new_value + outputs.append(multichannel_plot) + except KeyError as e: + outputs.append(no_update) + + outputs.append(new_value) + outputs.append(new_value) + return outputs \ No newline at end of file From 3356e321d02a02940173d2fbf52cae2ec1bc0c49 Mon Sep 17 00:00:00 2001 From: lpyras Date: Wed, 19 Jul 2023 14:00:09 +0200 Subject: [PATCH 309/418] add dependencies to toml file, remove unused units, make docstrings nice --- NuRadioMC/utilities/muon_flux.py | 37 ++++++++++++++++++-------------- pyproject.toml | 3 +++ 2 files changed, 24 insertions(+), 16 deletions(-) diff --git a/NuRadioMC/utilities/muon_flux.py b/NuRadioMC/utilities/muon_flux.py index 5d65dfe8c..e3ba81c90 100644 --- a/NuRadioMC/utilities/muon_flux.py +++ b/NuRadioMC/utilities/muon_flux.py @@ -9,20 +9,10 @@ class MuonFlux: def __init__(self): - self.mc_cm = 1. - self.mc_m = 1e2 - self.mc_km = 1e3 * self.mc_m - self.mc_deg = 1. + self.mc_m = 1e2 self.mc_rad = 180. / np.pi - self.mc_eV = 1.e-9 - self.mc_GeV = 1 - self.mc_TeV = 1.e3 - self.mc_PeV = 1.e6 - self.mc_EeV = 1.e9 - - self.mc_s = 1 self.mc_ns = 1e-9 self.__buffer = {} @@ -32,6 +22,7 @@ def __init__(self): self.__buffer = pickle.load(fin) fin.close() + @lru_cache(maxsize=5000) def get_mu_flux(self, theta, altitude=3200, interaction_model='SIBYLL23C', primary_model=(crf.GlobalSplineFitBeta, None), particle_names=("total_mu+", "total_mu-")): @@ -39,7 +30,6 @@ def get_mu_flux(self, theta, altitude=3200, interaction_model='SIBYLL23C', prima The function get_mu_flux returns the muon flux at theta, for a given altitude, CR model, and hadronic interaction model. Parameters - ---------- energy: float energy in eV @@ -56,7 +46,6 @@ def get_mu_flux(self, theta, altitude=3200, interaction_model='SIBYLL23C', prima energy grid in eV flux: array of floats flux in NuRadioReco units 1/(area * time * energy * steradian) - """ altitude *= self.mc_m @@ -82,6 +71,7 @@ def get_mu_flux(self, theta, altitude=3200, interaction_model='SIBYLL23C', prima return e_grid, flux + def get_interp_angle_mu_flux(self, theta_min, theta_max, altitude=3200, n_steps=3, primary_model=(crf.GlobalSplineFitBeta, None), interaction_model='SIBYLL23C', particle_names=("total_mu+", "total_mu-")): """ @@ -91,7 +81,6 @@ def get_interp_angle_mu_flux(self, theta_min, theta_max, altitude=3200, n_steps= Returns zenith angle integrated flux in NuRadioReco units 1/(area * time * energy) Parameters - ---------- energy: float energy in eV @@ -134,7 +123,6 @@ def get_int_angle_mu_flux_buffered(self, energy, theta_min, theta_max, altitude= The function get_int_angle_mu_flux evalueates the integrated muon flux from theta_min to theta_max and caches the result. Parameters - ---------- energy: float energy in eV @@ -151,7 +139,6 @@ def get_int_angle_mu_flux_buffered(self, energy, theta_min, theta_max, altitude= ------- flux: float zenith angle integrated flux in NuRadioReco units 1/(area * time * energy) - """ params = (np.round(energy), np.round(theta_min, 6), np.round(theta_max, 6), np.round(altitude), @@ -168,8 +155,26 @@ def get_int_angle_mu_flux_buffered(self, energy, theta_min, theta_max, altitude= pickle.dump(self.__buffer, fout, protocol=4) return self.__buffer[params] + def get_e_grid(self, theta_deg=50, interaction_model='SIBYLL23C', primary_model=(crf.GlobalSplineFitBeta, None)): + """ + Returns the energy grid for a given interaction model and primary model. Usually this is the same for all zenith angles. + + Parameters + ---------- + theta_deg: float + minimum zenith angle in rad + interaction_model: str + hadronic interaction model + primary_model: tuple + cosmic ray model + + Returns + ------- + energies: array of floats + energy grid in eV + """ mceq = MCEqRun(interaction_model=interaction_model, primary_model=primary_model, theta_deg=theta_deg) e_grid = mceq.e_grid / self.mc_eV return e_grid \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index b3b89eac1..b6a67a148 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -50,9 +50,12 @@ proposal = "7.5.1" pygdsm = {git = "https://github.com/telegraphic/pygdsm"} nifty5 = {git = "https://gitlab.mpcdf.mpg.de/ift/nifty.git", branch="NIFTy_5"} pypocketfft = {git = "https://gitlab.mpcdf.mpg.de/mtr/pypocketfft"} +MCEq = "*" +crflux = "*" [tool.poetry.extras] documentation = ["Sphinx", "sphinx-rtd-theme", "numpydoc"] proposal = ["proposal"] galacticnoise = ['pygdsm'] ift_reco = ['nifty5', 'pypocketfft'] +muon_flux_calc = ['MCEq', crflux] \ No newline at end of file From 4d181888ee8625bd269fb4ebfe0143ec271993ad Mon Sep 17 00:00:00 2001 From: lpyras Date: Wed, 19 Jul 2023 14:01:30 +0200 Subject: [PATCH 310/418] fix typo --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index b6a67a148..ed3ff0617 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -58,4 +58,4 @@ documentation = ["Sphinx", "sphinx-rtd-theme", "numpydoc"] proposal = ["proposal"] galacticnoise = ['pygdsm'] ift_reco = ['nifty5', 'pypocketfft'] -muon_flux_calc = ['MCEq', crflux] \ No newline at end of file +muon_flux_calc = ['MCEq', 'crflux'] \ No newline at end of file From eb140eb3bf6c9bc6000ff8c86a62023fe46d88ff Mon Sep 17 00:00:00 2001 From: Sjoerd Bouma Date: Thu, 20 Jul 2023 15:55:58 +0200 Subject: [PATCH 311/418] remove duplicate entry, add missing n --- NuRadioReco/detector/antenna_models_hash.json | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/NuRadioReco/detector/antenna_models_hash.json b/NuRadioReco/detector/antenna_models_hash.json index 8b18cdaea..ef85bad7f 100644 --- a/NuRadioReco/detector/antenna_models_hash.json +++ b/NuRadioReco/detector/antenna_models_hash.json @@ -16,7 +16,6 @@ "dip7cm_z200m_InFirn_RG.pkl": "49ea79abe0784f216ffc4c88db540785a38b87d9", "dip7cm_InfAir.pkl": "407ab67708d750c1c0e6bb83f4a3b41168fc7d1b", "dip7cm_z270mm_InAir.pkl": "a669d71b79d653c4ea8eb6ab3cbb17bb9026ff9d", - "dip7cm_z260mm_InFirn_RG.pkl": "d72fe75ae0f16f9e40d69796aa015e528735d2ec", "dip7cm_z1m_InAir.pkl": "1c5e4f65bd15b227fb2eebe1e61c1813509ebd97", "dip7cm_z1m_InAir_RG_NearHorizontalHD.pkl": "6a08c240e8162b8193da91e1528d301f9a017e3a", "dip7cm_z1m_InAir_RG_NearHorizontalHD2.pkl": "e880c00f3087ed3b3f8276d78645b4ea13217721", @@ -45,10 +44,10 @@ "trislot_RNOG.pkl": "29ef63bc9f25da743dd85d33e5645fc6330f6675", "RNOG_vpol_v1_n1.73.pkl": "4bd0b5941b31c6c39fd6b438f005075b025fee8d", "RNOG_vpol_v1_n1.4.pkl": "1b8be66b64f241d26e34567167318aa85c396f2a", - "RNOG_vpol_4inch_half_1.73.pkl": "f08d263233503f79e5be10c18bc7587b8b421c1d", - "RNOG_vpol_4inch_center_1.73.pkl": "5f429ed9ed08175a7f75fd44422367d2278bf2e1", - "RNOG_vpol_4inch_wall_1.73.pkl": "da24017eb80f7a68348a674be2c527457fe19992", - "RNOG_quadslot_v1_1.74.pkl": "e9c4946dd2176489249c862f32ef272ab627dc28", - "RNOG_quadslot_v2_1.74.pkl": "b99d69578f8e7c006dcce3de51e26c4f463872b8", + "RNOG_vpol_4inch_half_n1.73.pkl": "f08d263233503f79e5be10c18bc7587b8b421c1d", + "RNOG_vpol_4inch_center_n1.73.pkl": "5f429ed9ed08175a7f75fd44422367d2278bf2e1", + "RNOG_vpol_4inch_wall_n1.73.pkl": "da24017eb80f7a68348a674be2c527457fe19992", + "RNOG_quadslot_v1_n1.74.pkl": "e9c4946dd2176489249c862f32ef272ab627dc28", + "RNOG_quadslot_v2_n1.74.pkl": "b99d69578f8e7c006dcce3de51e26c4f463872b8", "SKALA_InfFirn": "69b3007da083bb722a4494af97221917973ab297" } From ade6005f49b07ff76e054c4950fafe3f592234ef Mon Sep 17 00:00:00 2001 From: Sjoerd Bouma Date: Thu, 20 Jul 2023 16:07:14 +0200 Subject: [PATCH 312/418] remove spurious cable delays --- NuRadioReco/detector/RNO_G/RNO_single_station.json | 5 ----- 1 file changed, 5 deletions(-) diff --git a/NuRadioReco/detector/RNO_G/RNO_single_station.json b/NuRadioReco/detector/RNO_G/RNO_single_station.json index 4b1935f19..d89458930 100644 --- a/NuRadioReco/detector/RNO_G/RNO_single_station.json +++ b/NuRadioReco/detector/RNO_G/RNO_single_station.json @@ -194,7 +194,6 @@ "ant_rotation_phi": 90.0, "ant_rotation_theta": 90.0, "ant_type": "createLPDA_100MHz_InfFirn_n1.4", - "cab_time_delay": 19.8, "reference_channel": 0, "channel_id": 12, "station_id": 11 @@ -211,7 +210,6 @@ "ant_rotation_phi": 90.0, "ant_rotation_theta": 90.0, "ant_type": "createLPDA_100MHz_InfFirn_n1.4", - "cab_time_delay": 19.8, "reference_channel": 0, "channel_id": 13, "station_id": 11 @@ -228,7 +226,6 @@ "ant_rotation_phi": 90.0, "ant_rotation_theta": 90.0, "ant_type": "createLPDA_100MHz_InfFirn_n1.4", - "cab_time_delay": 19.8, "reference_channel": 0, "channel_id": 14, "station_id": 11 @@ -244,7 +241,6 @@ "ant_rotation_phi": 210.0, "ant_rotation_theta": 90.0, "ant_type": "createLPDA_100MHz_InfFirn_n1.4", - "cab_time_delay": 19.8, "reference_channel": 0, "channel_id": 15, "station_id": 11 @@ -261,7 +257,6 @@ "ant_rotation_phi": 210.0, "ant_rotation_theta": 90.0, "ant_type": "createLPDA_100MHz_InfFirn_n1.4", - "cab_time_delay": 19.8, "reference_channel": 0, "channel_id": 16, "station_id": 11 From 0f6a61710444f8ea2dcd3eeb8091892459e7e5a3 Mon Sep 17 00:00:00 2001 From: Sjoerd Bouma Date: Mon, 24 Jul 2023 15:51:44 +0200 Subject: [PATCH 313/418] add log/linear toggle to frequency spectra --- .../trace_plots/rec_electric_field_spectrum.py | 8 ++++---- NuRadioReco/eventbrowser/apps/traces.py | 17 ++++++++++------- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/NuRadioReco/eventbrowser/apps/trace_plots/rec_electric_field_spectrum.py b/NuRadioReco/eventbrowser/apps/trace_plots/rec_electric_field_spectrum.py index c93a618c9..8cd87ecb7 100644 --- a/NuRadioReco/eventbrowser/apps/trace_plots/rec_electric_field_spectrum.py +++ b/NuRadioReco/eventbrowser/apps/trace_plots/rec_electric_field_spectrum.py @@ -12,7 +12,6 @@ provider = NuRadioReco.eventbrowser.dataprovider.DataProvider() layout = [ - html.Button(id='efield-spectrum-log-linear-switch', children='log'), dcc.Graph(id='efield-spectrum') ] @@ -23,8 +22,9 @@ dash.dependencies.Input('event-counter-slider', 'value'), dash.dependencies.Input('filename', 'value'), dash.dependencies.Input('station-id-dropdown', 'value')], - [State('user_id', 'children')]) -def update_efield_spectrum(trigger, evt_counter, filename, station_id, juser_id): + [State('user_id', 'children'), + State('channel-spectrum-log-linear-switch', 'children')]) +def update_efield_spectrum(trigger, evt_counter, filename, station_id, juser_id, yscale): if filename is None or station_id is None: return {} user_id = json.loads(juser_id) @@ -62,5 +62,5 @@ def update_efield_spectrum(trigger, evt_counter, filename, station_id, juser_id) ), 1, 1) fig['layout'].update(default_layout) fig['layout']['xaxis1'].update(title='frequency [MHz]') - fig['layout']['yaxis1'].update(title='amplitude [mV/m]') + fig['layout']['yaxis'].update(title='amplitude [mV/m]', type=yscale) return fig diff --git a/NuRadioReco/eventbrowser/apps/traces.py b/NuRadioReco/eventbrowser/apps/traces.py index ecf75111e..7eea639d2 100644 --- a/NuRadioReco/eventbrowser/apps/traces.py +++ b/NuRadioReco/eventbrowser/apps/traces.py @@ -119,7 +119,8 @@ def toggle_efield_spectrum_plot(button_clicks, showhide): # callback to change frequency spectra between linear and log scale @app.callback( - [Output('channel-spectrum', 'figure', allow_duplicate=True), # this is a 'duplicate' callback - requires dash >= 2.9 + [Output('efield-spectrum', 'figure', allow_duplicate=True), # this is a 'duplicate' callback - requires dash >= 2.9 + Output('channel-spectrum', 'figure', allow_duplicate=True), # this is a 'duplicate' callback - requires dash >= 2.9 Output('time-traces', 'figure', allow_duplicate=True), Output('channel-spectrum-log-linear-switch', 'children'), Output('efield-spectrum-log-linear-switch', 'children') @@ -127,21 +128,23 @@ def toggle_efield_spectrum_plot(button_clicks, showhide): [Input('channel-spectrum-log-linear-switch', 'n_clicks'), Input('efield-spectrum-log-linear-switch', 'n_clicks')], [State('channel-spectrum-log-linear-switch', 'children'), + State('efield-spectrum', 'figure'), State('channel-spectrum', 'figure'), State('time-traces', 'figure'), ], prevent_initial_call=True ) -def toggle_linear_log_scale(button_clicks, button_current_value, channel_spectrum, multichannel_plot): +def toggle_linear_log_scale(button_clicks, button2_clicks, button_current_value, efield_spectrum, channel_spectrum, multichannel_plot): outputs = [] if button_current_value == 'linear': # switch to log new_value = 'log' else: new_value = 'linear' - try: - channel_spectrum['layout']['yaxis']['type'] = new_value - outputs.append(channel_spectrum) - except KeyError: - outputs.append(no_update) + for spectrum_plot in [efield_spectrum, channel_spectrum]: + try: + spectrum_plot['layout']['yaxis']['type'] = new_value + outputs.append(spectrum_plot) + except KeyError: + outputs.append(no_update) try: yaxes = [key for key in multichannel_plot['layout'].keys() if 'yaxis' in key] From cebd3cf69b93a2336fd5925d568ef88a5aae787e Mon Sep 17 00:00:00 2001 From: Sjoerd Bouma Date: Mon, 24 Jul 2023 15:55:28 +0200 Subject: [PATCH 314/418] update dash version --- NuRadioReco/eventbrowser/index.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/NuRadioReco/eventbrowser/index.py b/NuRadioReco/eventbrowser/index.py index ad6242136..aa8a9bcd0 100644 --- a/NuRadioReco/eventbrowser/index.py +++ b/NuRadioReco/eventbrowser/index.py @@ -424,9 +424,11 @@ def update_event_info_time(event_i, filename, station_id, juser_id): if __name__ == '__main__': - if int(dash.__version__.split('.')[0]) < 2: - print( - 'WARNING: Dash version 2.0.0 or newer is required, you are running version {}. Please update.'.format( + dash_version = [int(i) for i in dash.__version__.split('.')] + if dash_version[0] <= 2: + if (dash_version[1] < 9) or (dash_version[0] < 2): + print( + 'WARNING: Dash version 2.9.2 or newer is required, you are running version {}. Please update.'.format( dash.__version__)) if not parsed_args.debug: werkzeug_logger = logging.getLogger('werkzeug') From 08197d6bd5ac00b5438227a1a5c504fc6dc01242 Mon Sep 17 00:00:00 2001 From: Christian Glaser Date: Fri, 28 Jul 2023 10:49:27 +0000 Subject: [PATCH 315/418] update references --- README.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 98bd87634..dc91d9203 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,15 @@ Also please visit https://nu-radio.github.io/NuRadioMC/Introduction/pages/contri ## Publications builing up on NuRadioMC/Reco NuRadioMC is used in an increasing number of studies. To get an overview for what NuRadioMC can be used for, please have a look at the following publications or see [here](https://inspirehep.net/literature?sort=mostrecent&size=25&page=1&q=refersto%3Arecid%3A1738571%20or%20refersto%3Arecid%3A1725583): - +* ARIANNA collaboration (A. Anker et al.), "Developing New Analysis Tools for Near Surface Radio-based Neutrino Detectors", [arXiv:2307.07188](https://arxiv.org/abs/2307.07188) +* L. Pyras, C. Glaser S. Hallmann and A. Nelles, "Atmospheric muons at PeV energies in radio neutrino detectors", [arXiv:2307.04736](https://arxiv.org/abs/2307.04736) +* I. Plaisier, S. Bouma, A. Nelles, "Reconstructing the arrival direction of neutrinos in deep in-ice radio detectors", [arXiv:2302.00054](https://arxiv.org/abs/2302.00054) +* S. Bouma, A. Nelles for the IceCube-Gen2 collaboration, "Direction reconstruction performance for IceCube-Gen2 Radio", [PoS(ICRC2023)1045](https://pos.sissa.it/444/1045/pdf) +* F. Schlüter and S. Toscano for the IceCube-Gen2 collaboration, "Estimating the coincidence rate between the optical and radio array of IceCube-Gen2", [PoS(ICRC2023)1022](https://pos.sissa.it/444/1022/pdf) +* C. Glaser, A. Coleman and T. Glusenkamp, "NuRadioOpt: Optimization of Radio Detectors of Ultra-High Energy Neutrinos through Deep Learning and Differential Programming", [PoS(ICRC2023)1114](https://pos.sissa.it/444/1114/pdf) +* A. Coleman and C. Glaser for the RNO-G collaboration, "Enhancing the Sensitivity of RNO-G Using a Machine-learning Based Trigger", [PoS(ICRC2023)1100](https://pos.sissa.it/444/1100/pdf) +* N. Heyer, C. Glaser and T. Glusenkamp for the IceCube-Gen2 collaboration, "Deep Learning Based Event Reconstruction for the IceCube-Gen2 Radio Detector" [PoS(ICRC2023)1102](https://pos.sissa.it/444/1102/pdf) +* N. Heyer and C. Glaser, "Impact of Birefringence on In-Ice Radio Detectors of ultra-high-energy Neutrinos", [PoS(ICRC2023)1101](https://pos.sissa.it/444/1101/pdf) * V. B. Valera, M. Bustamante and C. Glaser, “Near-future discovery of the diffuse flux of ultra-high-energy cosmic neutrinos”, Phys. Rev. D 107, 043019 [arXiv:2210.03756](https://arxiv.org/abs/2210.03756) * Alfonso Garcia Soto, Diksha Garg, Mary Hall Reno, Carlos A. Argüelles, "Probing Quantum Gravity with Elastic Interactions of Ultra-High-Energy Neutrinos", Phys. Rev. D 107, 033009 (2023) [arXiv:2209.06282](https://arxiv.org/abs/2209.06282) * Damiano F. G. Fiorillo, Mauricio Bustamante, Victor B. Valera, "Near-future discovery of point sources of ultra-high-energy neutrinos", JCAP 03 (2023) 026 [arXiv:2205.15985](https://arxiv.org/abs/2205.15985) From d85d47ada9f75a13cc743795971d4a9fe13d8291 Mon Sep 17 00:00:00 2001 From: Anna Nelles Date: Sat, 29 Jul 2023 17:33:56 +0900 Subject: [PATCH 316/418] Update README.md --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index dc91d9203..7e503dae8 100644 --- a/README.md +++ b/README.md @@ -44,7 +44,9 @@ NuRadioMC is used in an increasing number of studies. To get an overview for wha * C. Glaser, A. Coleman and T. Glusenkamp, "NuRadioOpt: Optimization of Radio Detectors of Ultra-High Energy Neutrinos through Deep Learning and Differential Programming", [PoS(ICRC2023)1114](https://pos.sissa.it/444/1114/pdf) * A. Coleman and C. Glaser for the RNO-G collaboration, "Enhancing the Sensitivity of RNO-G Using a Machine-learning Based Trigger", [PoS(ICRC2023)1100](https://pos.sissa.it/444/1100/pdf) * N. Heyer, C. Glaser and T. Glusenkamp for the IceCube-Gen2 collaboration, "Deep Learning Based Event Reconstruction for the IceCube-Gen2 Radio Detector" [PoS(ICRC2023)1102](https://pos.sissa.it/444/1102/pdf) -* N. Heyer and C. Glaser, "Impact of Birefringence on In-Ice Radio Detectors of ultra-high-energy Neutrinos", [PoS(ICRC2023)1101](https://pos.sissa.it/444/1101/pdf) +* N. Heyer and C. Glaser, "Impact of Birefringence on In-Ice Radio Detectors of ultra-high-energy Neutrinos", [PoS(ICRC2023)1101](https://pos.sissa.it/444/1101/pdf) +* J. Henrichs, A. Nelles for the RNO-G Collaboration, "Searching for cosmic-ray air showers with RNO-G", [PoS(ICRC2023)259](https://pos.sissa.it/444/259/pdf) +* B. Oeyen for the RNO-G Collaboration, "The interplay of ice-firn model and station calibration in RNO-G", [PoS(ICRC2023)1042](https://pos.sissa.it/444/1042/pdf) * V. B. Valera, M. Bustamante and C. Glaser, “Near-future discovery of the diffuse flux of ultra-high-energy cosmic neutrinos”, Phys. Rev. D 107, 043019 [arXiv:2210.03756](https://arxiv.org/abs/2210.03756) * Alfonso Garcia Soto, Diksha Garg, Mary Hall Reno, Carlos A. Argüelles, "Probing Quantum Gravity with Elastic Interactions of Ultra-High-Energy Neutrinos", Phys. Rev. D 107, 033009 (2023) [arXiv:2209.06282](https://arxiv.org/abs/2209.06282) * Damiano F. G. Fiorillo, Mauricio Bustamante, Victor B. Valera, "Near-future discovery of point sources of ultra-high-energy neutrinos", JCAP 03 (2023) 026 [arXiv:2205.15985](https://arxiv.org/abs/2205.15985) From cd0b94e5d5bb02a720f9c1dc760ef4a7ba2ac36e Mon Sep 17 00:00:00 2001 From: Christian Glaser Date: Sat, 29 Jul 2023 08:40:55 +0000 Subject: [PATCH 317/418] add TDR --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 7e503dae8..6cd3a5159 100644 --- a/README.md +++ b/README.md @@ -36,6 +36,7 @@ Also please visit https://nu-radio.github.io/NuRadioMC/Introduction/pages/contri ## Publications builing up on NuRadioMC/Reco NuRadioMC is used in an increasing number of studies. To get an overview for what NuRadioMC can be used for, please have a look at the following publications or see [here](https://inspirehep.net/literature?sort=mostrecent&size=25&page=1&q=refersto%3Arecid%3A1738571%20or%20refersto%3Arecid%3A1725583): +* IceCube-Gen2 collaboration, [IceCube-Gen2 Technical Design Report](https://icecube-gen2.wisc.edu/science/publications/TDR) * ARIANNA collaboration (A. Anker et al.), "Developing New Analysis Tools for Near Surface Radio-based Neutrino Detectors", [arXiv:2307.07188](https://arxiv.org/abs/2307.07188) * L. Pyras, C. Glaser S. Hallmann and A. Nelles, "Atmospheric muons at PeV energies in radio neutrino detectors", [arXiv:2307.04736](https://arxiv.org/abs/2307.04736) * I. Plaisier, S. Bouma, A. Nelles, "Reconstructing the arrival direction of neutrinos in deep in-ice radio detectors", [arXiv:2302.00054](https://arxiv.org/abs/2302.00054) From 7f6edaf6c73588fa1ee0a0ae3b0bcf302b358785 Mon Sep 17 00:00:00 2001 From: Christian Glaser Date: Mon, 31 Jul 2023 01:28:58 +0000 Subject: [PATCH 318/418] update readme --- README.md | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 6cd3a5159..40b658acd 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,13 @@ -# NuRadioMC/NuRadioReco -A Monte Carlo simulation package for radio neutrino detectors and reconstruction framework for radio detectors of high-energy neutrinos and cosmic-rays +# NuRadioMC +A Monte Carlo simulation package for radio neutrino detectors + +#NuRadioReco +Reconstruction and detector simulation framework for radio detectors of high-energy neutrinos and cosmic-rays. (NuRadioReco is independet of NuRadioMC +and used by NuRadioMC for the detector and trigger simulation. To simplify the development and continuous integration testing, both codes are developed +in the same github repository.) The documentation can be found at https://nu-radio.github.io/NuRadioMC/main.html -If you want to keep up to date, consider signing up to the following email lists: - * user email list, will be used to announce new versions and major improvements etc. Subscribe via https://lists.uu.se/sympa/subscribe/physics-astro-nuradiomc - * developer email list, will be used to discuss the future development of NuRadioMC/Reco. Subscribe via: https://lists.uu.se/sympa/subscribe/physics-astro-nuradiomc-dev If you're using NuRadioMC for your research, please cite @@ -16,7 +18,6 @@ and for the detector simulation and event reconstruction part * C. Glaser, A. Nelles, I. Plaisier, C. Welling et al., "NuRadioReco: A reconstruction framework for radio neutrino detectors", [Eur. Phys. J. C (2019) 79: 464](https://dx.doi.org/10.1140/epjc/s10052-019-6971-5), [arXiv:1903.07023](https://arxiv.org/abs/1903.07023) - NuRadioMC is continuously improved and new features are being added. The following papers document new features (in reverse chronological order): * N. Heyer and C. Glaser, “First-principle calculation of birefringence effects for in-ice radio detection of neutrinos”, [arXiv:2205.06169](https://arxiv.org/abs/2205.15872) (adds birefringence modelling to NuRadioMC) @@ -28,7 +29,6 @@ NuRadioMC is continuously improved and new features are being added. The followi * D. García-Fernández, C. Glaser and A. Nelles, “The signatures of secondary leptons in radio-neutrino detectors in ice”, [Phys. Rev. D 102, 083011](https://dx.doi.org/10.1103/PhysRevD.102.083011), [arXiv:2003.13442](https://arxiv.org/abs/2003.13442) (addition of secondary interactions of muons and taus) - If you would like to contribute, please contact @cg-laser or @anelles for permissions to work on NuRadioMC. We work with pull requests only that can be merged after review. Also please visit https://nu-radio.github.io/NuRadioMC/Introduction/pages/contributing.html for details on our workflow and coding conventions. @@ -73,3 +73,8 @@ NuRadioMC is used in an increasing number of studies. To get an overview for wha * C. Glaser, S. Barwick, "An improved trigger for Askaryan radio detectors", [JINST 16 (2021) 05, T05001](https://doi.org/10.1088/1748-0221/16/05/T05001), [arXiv:2011.12997](https://arxiv.org/abs/2011.12997) * RNO-G collaboration, "Design and Sensitivity of the Radio Neutrino Observatory in Greenland (RNO-G)", [JINST 16 (2021) 03, P03025](https://doi.org/10.1088/1748-0221/16/03/P03025) [arXiv:2010.12279](https://arxiv.org/abs/2010.12279) * ARIANNA collaboration, "Probing the angular and polarization reconstruction of the ARIANNA detector at the South Pole", [JINST 15 (2020) 09, P09039](https://doi.org/10.1088/1748-0221/15/09/P09039), [arXiv:2006.03027](https://arxiv.org/abs/2006.03027) + + +If you want to keep up to date, consider signing up to the following email lists: + * user email list, will be used to announce new versions and major improvements etc. Subscribe via https://lists.uu.se/sympa/subscribe/physics-astro-nuradiomc + * developer email list, will be used to discuss the future development of NuRadioMC/Reco. Subscribe via: https://lists.uu.se/sympa/subscribe/physics-astro-nuradiomc-dev From f37f92100eb58a6b5804b9c519c52fc9266e592f Mon Sep 17 00:00:00 2001 From: Christian Glaser Date: Tue, 1 Aug 2023 01:06:17 +0000 Subject: [PATCH 319/418] add another reference --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 40b658acd..8e378e2b8 100644 --- a/README.md +++ b/README.md @@ -48,6 +48,7 @@ NuRadioMC is used in an increasing number of studies. To get an overview for wha * N. Heyer and C. Glaser, "Impact of Birefringence on In-Ice Radio Detectors of ultra-high-energy Neutrinos", [PoS(ICRC2023)1101](https://pos.sissa.it/444/1101/pdf) * J. Henrichs, A. Nelles for the RNO-G Collaboration, "Searching for cosmic-ray air showers with RNO-G", [PoS(ICRC2023)259](https://pos.sissa.it/444/259/pdf) * B. Oeyen for the RNO-G Collaboration, "The interplay of ice-firn model and station calibration in RNO-G", [PoS(ICRC2023)1042](https://pos.sissa.it/444/1042/pdf) +* P. Windischhofer, C. Welling and C. Deaconu, "Eisvogel: Exact and efficient calculations of radio emissions from in-ice neutrino showers", [PoS(ICRC2023)1157](https://pos.sissa.it/444/1157/) * V. B. Valera, M. Bustamante and C. Glaser, “Near-future discovery of the diffuse flux of ultra-high-energy cosmic neutrinos”, Phys. Rev. D 107, 043019 [arXiv:2210.03756](https://arxiv.org/abs/2210.03756) * Alfonso Garcia Soto, Diksha Garg, Mary Hall Reno, Carlos A. Argüelles, "Probing Quantum Gravity with Elastic Interactions of Ultra-High-Energy Neutrinos", Phys. Rev. D 107, 033009 (2023) [arXiv:2209.06282](https://arxiv.org/abs/2209.06282) * Damiano F. G. Fiorillo, Mauricio Bustamante, Victor B. Valera, "Near-future discovery of point sources of ultra-high-energy neutrinos", JCAP 03 (2023) 026 [arXiv:2205.15985](https://arxiv.org/abs/2205.15985) From 810fae9404665ab82f924db7706f96dfc381a4ed Mon Sep 17 00:00:00 2001 From: Christian Glaser Date: Thu, 3 Aug 2023 10:04:40 +0000 Subject: [PATCH 320/418] fix layout --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8e378e2b8..33188362c 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # NuRadioMC A Monte Carlo simulation package for radio neutrino detectors -#NuRadioReco +# NuRadioReco Reconstruction and detector simulation framework for radio detectors of high-energy neutrinos and cosmic-rays. (NuRadioReco is independet of NuRadioMC and used by NuRadioMC for the detector and trigger simulation. To simplify the development and continuous integration testing, both codes are developed in the same github repository.) From 732d72905a1b23f949e09dba065ac2a4dc0e65db Mon Sep 17 00:00:00 2001 From: Christian Glaser Date: Thu, 3 Aug 2023 10:06:24 +0000 Subject: [PATCH 321/418] update layout --- README.md | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 33188362c..f249f748a 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,6 @@ -# NuRadioMC -A Monte Carlo simulation package for radio neutrino detectors - -# NuRadioReco -Reconstruction and detector simulation framework for radio detectors of high-energy neutrinos and cosmic-rays. (NuRadioReco is independet of NuRadioMC +# NuRadioMC and NuRadioReco +NuRadioMC: A Monte Carlo simulation package for radio neutrino detectors. +NuRadioReco: A reconstruction and detector simulation framework for radio detectors of high-energy neutrinos and cosmic-rays. (NuRadioReco is independet of NuRadioMC and used by NuRadioMC for the detector and trigger simulation. To simplify the development and continuous integration testing, both codes are developed in the same github repository.) From 362fd3b696a8e7fe16d80c7c1f9fbc8c591ddcd8 Mon Sep 17 00:00:00 2001 From: Christian Glaser Date: Thu, 3 Aug 2023 10:07:08 +0000 Subject: [PATCH 322/418] layout --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index f249f748a..385697f19 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ # NuRadioMC and NuRadioReco NuRadioMC: A Monte Carlo simulation package for radio neutrino detectors. + NuRadioReco: A reconstruction and detector simulation framework for radio detectors of high-energy neutrinos and cosmic-rays. (NuRadioReco is independet of NuRadioMC and used by NuRadioMC for the detector and trigger simulation. To simplify the development and continuous integration testing, both codes are developed in the same github repository.) From 920c01ec5543eae3596ed5a9466223f4783b511d Mon Sep 17 00:00:00 2001 From: Sjoerd Bouma Date: Fri, 4 Aug 2023 09:17:39 +0200 Subject: [PATCH 323/418] correct number of samples in triggerTimeAdjuster --- NuRadioReco/modules/triggerTimeAdjuster.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/NuRadioReco/modules/triggerTimeAdjuster.py b/NuRadioReco/modules/triggerTimeAdjuster.py index 9c8567ce2..002b30eb5 100644 --- a/NuRadioReco/modules/triggerTimeAdjuster.py +++ b/NuRadioReco/modules/triggerTimeAdjuster.py @@ -67,7 +67,11 @@ def run(self, event, station, detector): trace = channel.get_trace() trace_length = len(trace) - number_of_samples = int(detector.get_number_of_samples(station.get_id(), channel.get_id()) * channel.get_sampling_rate() / detector.get_sampling_frequency(station.get_id(), channel.get_id())) + number_of_samples = int( + 2 * np.ceil( # this should ensure that 1) the number of samples is even and 2) resampling to the detector sampling rate results in the correct number of samples (note that 2) can only be guaranteed if the detector sampling rate is lower than the current sampling rate) + detector.get_number_of_samples(station.get_id(), channel.get_id()) / 2 + * channel.get_sampling_rate() / detector.get_sampling_frequency(station.get_id(), channel.get_id()) + )) if number_of_samples > trace.shape[0]: logger.error("Input has fewer samples than desired output. Channels has only {} samples but {} samples are requested.".format( trace.shape[0], number_of_samples)) From 949e9b37855281021721af61904ec64ae48fb401 Mon Sep 17 00:00:00 2001 From: Christian Glaser Date: Fri, 4 Aug 2023 12:25:37 +0000 Subject: [PATCH 324/418] add option to trace from ice into air. --- NuRadioMC/SignalProp/analyticraytracing.py | 152 +++++++++++++-------- 1 file changed, 98 insertions(+), 54 deletions(-) diff --git a/NuRadioMC/SignalProp/analyticraytracing.py b/NuRadioMC/SignalProp/analyticraytracing.py index bac2c061b..4ba7bccb3 100644 --- a/NuRadioMC/SignalProp/analyticraytracing.py +++ b/NuRadioMC/SignalProp/analyticraytracing.py @@ -40,6 +40,8 @@ print("check NuRadioMC/NuRadioMC/SignalProp/CPPAnalyticRayTracing for manual compilation") cpp_available = False +cpp_available = False + """ analytic ray tracing solution """ @@ -132,11 +134,10 @@ def __init__(self, medium, attenuation_model="SP1", self.__logger.setLevel(log_level) self.__n_frequencies_integration = n_frequencies_integration self.__use_optimized_start_values = use_optimized_start_values - + self._use_optimized_calculation = self.attenuation_model in speedup_attenuation_models if overwrite_speedup is not None: self._use_optimized_calculation = overwrite_speedup - def n(self, z): """ @@ -590,19 +591,18 @@ def __get_frequencies_for_attenuation(self, frequency, max_detector_freq): self.__logger.debug(f"calculating attenuation for frequencies {freqs}") return freqs - - def get_attenuation_along_path(self, x1, x2, C_0, frequency, max_detector_freq, + def get_attenuation_along_path(self, x1, x2, C_0, frequency, max_detector_freq, reflection=0, reflection_case=1): - + attenuation = np.ones_like(frequency) output = f"calculating attenuation for n_ref = {int(reflection):d}: " - for iS, segment in enumerate(self.get_path_segments(x1, x2, C_0, reflection, + for iS, segment in enumerate(self.get_path_segments(x1, x2, C_0, reflection, reflection_case)): - - # we can only integrate upward going rays, so if the ray starts downwardgoing, + + # we can only integrate upward going rays, so if the ray starts downwardgoing, # we need to mirror - if iS == 0 and reflection_case == 2: + if iS == 0 and reflection_case == 2: x11, x1, x22, x2, C_0, C_1 = segment x1t = copy.copy(x11) x2t = copy.copy(x2) @@ -612,20 +612,20 @@ def get_attenuation_along_path(self, x1, x2, C_0, frequency, max_detector_freq, x1 = x1t else: x11, x1, x22, x2, C_0, C_1 = segment - + if cpp_available: mask = frequency > 0 freqs = self.__get_frequencies_for_attenuation(frequency, max_detector_freq) tmp = np.zeros_like(freqs) for i, f in enumerate(freqs): tmp[i] = wrapper.get_attenuation_along_path( - x1, x2, C_0, f, self.medium.n_ice, self.medium.delta_n, + x1, x2, C_0, f, self.medium.n_ice, self.medium.delta_n, self.medium.z_0, self.attenuation_model_int) - + self.__logger.debug(tmp) tmp_attenuation = np.ones_like(frequency) tmp_attenuation[mask] = np.interp(frequency[mask], freqs, tmp) - + else: x2_mirrored = self.get_z_mirrored(x1, x2, C_0) @@ -633,7 +633,7 @@ def get_attenuation_along_path(self, x1, x2, C_0, frequency, max_detector_freq, def dt(t, C_0, frequency): z = self.get_z_unmirrored(t, C_0) return self.ds(t, C_0) / attenuation_util.get_attenuation_length(z, frequency, self.attenuation_model) - + # to speed up things we only calculate the attenuation for a few frequencies # and interpolate linearly between them mask = frequency > 0 @@ -642,41 +642,41 @@ def dt(t, C_0, frequency): self.__logger.info("_use_optimized_calculation", self._use_optimized_calculation) if self._use_optimized_calculation: - # The integration of the attenuation factor along the path with scipy.quad is inefficient. The + # The integration of the attenuation factor along the path with scipy.quad is inefficient. The # reason for this is that attenuation profile is varying a lot with depth. Hence, to improve - # performance we sum over discrete segments with loss of some accuracy. + # performance we sum over discrete segments with loss of some accuracy. # However, when a path becomes to horizontal (i.e., at the turning point of an refracted ray) # the calculation via a discrete sum becomes to inaccurate. This is because we describe the # path as a function of dz (vertical distance) and have the sum over discrete bins in dz. To avoid that - # we fall back to a numerical integration with scipy.quad only around the turning point. However, instead + # we fall back to a numerical integration with scipy.quad only around the turning point. However, instead # of integrating over dt (the exponent of the attenuation factor), we integrate only over ds (the path length) - # and evaluate the attenuation (as function of depth and frequency) for the central depth of this segment + # and evaluate the attenuation (as function of depth and frequency) for the central depth of this segment # (because this is what takes time) # For more details and comparisons see PR #507 : https://github.com/nu-radio/NuRadioMC/pull/507 - # define the width of the vertical (!) segments over which we sum. + # define the width of the vertical (!) segments over which we sum. # Since we use linspace the actual width will differ slightly dx = 10 # define the vertical window around a turning point within we will fall back to a numerical integration int_window_size = 20 - + # Check if a turning point "z_turn" is within our ray path or close to it (i.e., right behind the antenna) # if so we need to fallback to numerical integration fallback = False if x1[1] - int_window_size / 2 < z_turn and z_turn < x2_mirrored[1] + int_window_size / 2: fallback = True - + if fallback: # If we need the fallback, make sure that the turning point is in the middle of a segment (unless it is at # the edge of a path). Otherwise the segment next to the turning point will be inaccurate - int_window = [max(x1[1], z_turn - int_window_size / 2), + int_window = [max(x1[1], z_turn - int_window_size / 2), min(z_turn + int_window_size / 2, x2_mirrored[1])] # Merge two arrays which start and stop at int_window (and thus include it). The width might be slightly different segments = np.append(get_segments(x1[1], int_window[0], dx), get_segments(int_window[1], x2_mirrored[1], dx)) else: segments = get_segments(x1[1], x2_mirrored[1], dx) - + # get the actual width of each segment and their center dx_actuals = np.diff(segments) mid_points = segments[:-1] + dx_actuals / 2 @@ -691,19 +691,19 @@ def dt(t, C_0, frequency): # find segment which contains z_turn idx = np.digitize(z_turn, segments) - 1 - + # if z_turn is outside of segments if idx == len(segments) - 1: idx -= 1 elif idx == -1: idx = 0 - + att_int = np.array( [integrate.quad(self.ds, segments[idx], segments[idx + 1], args=(C_0), epsrel=1e-2, points=[z_turn])[0] / attenuation_util.get_attenuation_length(z_turn, f, self.attenuation_model) for f in freqs]) - + attenuation_exp_tmp[:, idx] = att_int - + # sum over all segments attenuation_exp = np.sum(attenuation_exp_tmp, axis=1) @@ -711,26 +711,25 @@ def dt(t, C_0, frequency): points = None if x1[1] < z_turn and z_turn < x2_mirrored[1]: points = [z_turn] - + attenuation_exp = np.array([integrate.quad(dt, x1[1], x2_mirrored[1], args=( C_0, f), epsrel=1e-2, points=points)[0] for f in freqs]) tmp = np.exp(-1 * attenuation_exp) - + tmp_attenuation = np.ones_like(frequency) tmp_attenuation[mask] = np.interp(frequency[mask], freqs, tmp) self.__logger.info("calculating attenuation from ({:.0f}, {:.0f}) to ({:.0f}, {:.0f}) = ({:.0f}, {:.0f}) = a factor {}".format( x1[0], x1[1], x2[0], x2[1], x2_mirrored[0], x2_mirrored[1], 1 / tmp_attenuation)) - + iF = len(frequency) // 3 output += f"adding attenuation for path segment {iS:d} -> {tmp_attenuation[iF]:.2g} at {frequency[iF]/units.MHz:.0f} MHz, " - + attenuation *= tmp_attenuation - + self.__logger.info(output) return attenuation - def get_path_segments(self, x1, x2, C_0, reflection=0, reflection_case=1): """ Calculates the different segments of the path that makes up the full ray tracing path @@ -903,9 +902,16 @@ def get_path(self, x1, x2, C_0, n_points=1000): gamma = self.get_gamma(z[mask]) zs[mask] = z[mask] res[mask] = self.get_y(gamma, C_0, C_1) - gamma = self.get_gamma(2 * z_turn - z[~mask]) - res[~mask] = 2 * y_turn - self.get_y(gamma, C_0, C_1) - zs[~mask] = 2 * z_turn - z[~mask] + if x2[1] > 0: # treat ice to air case + zenith_reflection = self.get_reflection_angle(x1, x2, C_0) + n_1 = self.medium.get_index_of_refraction([y_turn, 0, z_turn]) + zenith_air = NuRadioReco.utilities.geometryUtilities.get_fresnel_angle(zenith_reflection, n_1=n_1, n_2=1) + zs[~mask] = z[~mask] + res[~mask] = zs[~mask] * np.tan(zenith_air) + y_turn + else: + gamma = self.get_gamma(2 * z_turn - z[~mask]) + res[~mask] = 2 * y_turn - self.get_y(gamma, C_0, C_1) + zs[~mask] = 2 * z_turn - z[~mask] self.__logger.debug('turning points for C_0 = {:.2f}, b= {:.2f}, gamma = {:.4f}, z = {:.1f}, y_turn = {:.0f}'.format( C_0, self.__b, gamma_turn, z_turn, y_turn)) @@ -1023,7 +1029,7 @@ def get_delta_y(self, C_0, x1, x2, C0range=None, reflection=0, reflection_case=2 if(reflection > 0 and reflection_case == 2): y_turn = self.get_y_turn(C_0, x1) dy = y_turn - x1[0] - self.__logger.debug("relaction case 2: shifting x1 {} to {}".format(x1, x1[0] - 2 * dy)) + self.__logger.debug("reflection case 2: shifting x1 {} to {}".format(x1, x1[0] - 2 * dy)) x1[0] = x1[0] - 2 * dy for i in range(reflection): @@ -1052,7 +1058,7 @@ def get_delta_y(self, C_0, x1, x2, C0range=None, reflection=0, reflection_case=2 # 3) reflected ray, i.e. after the ray reaches the surface gamma_turn, z_turn = self.get_turning_point(c) y_turn = self.get_y(gamma_turn, C_0, C_1) - if(z_turn < x2[1]): # turning points is deeper that x2 positions, can't reach target + if(z_turn < min(x2[1], 0)): # turning points is deeper that x2 positions, can't reach target # the minimizer has problems finding the minimum if inf is returned here. Therefore, we return the distance # between the turning point and the target point + 10 x the distance between the z position of the turning points # and the target position. This results in a objective function that has the solutions as the only minima and @@ -1076,18 +1082,35 @@ def get_delta_y(self, C_0, x1, x2, C0range=None, reflection=0, reflection_case=2 'we have a direct ray, y({:.1f}) = {:.1f} -> {:.1f} away from {:.1f}, turning point = y={:.1f}, z={:.2f}, x0 = {:.1f} {:.1f}'.format(x2[1], y2_fit, diff, x2[0], y_turn, z_turn, x1[0], x1[1])) return diff else: - # now it's a bit more complicated. we need to transform the coordinates to - # be on the mirrored part of the function - z_mirrored = x2[1] - gamma = self.get_gamma(z_mirrored) - self.__logger.debug("get_y( {}, {}, {})".format(gamma, C_0, C_1)) - y2_raw = self.get_y(gamma, C_0, C_1) - y2_fit = 2 * y_turn - y2_raw - diff = (x2[0] - y2_fit) - self.__logger.debug('we have a reflected/refracted ray, y({:.1f}) = {:.1f} ({:.1f}) -> {:.1f} away from {:.1f} (gamma = {:.5g})'.format( - z_mirrored, y2_fit, y2_raw, diff, x2[0], gamma)) - return -1 * diff + if(x2[1] > 0): # first treat the ice to air case + # Do nothing if ray is refracted. If ray is reflected, don't mirror but do straight line upwards + if(z_turn == 0): + zenith_reflection = self.get_reflection_angle(x1, x2, C_0, reflection, reflection_case) + n_1 = self.medium.get_index_of_refraction([y_turn, 0, z_turn]) + zenith_air = NuRadioReco.utilities.geometryUtilities.get_fresnel_angle(zenith_reflection, n_1=n_1, n_2=1) + if(zenith_air is None): + diff = x2[0] + self.__logger.debug(f"not refracting into air") + return diff + z = (x2[0] - y_turn) / np.tan(zenith_air) + diff = x2[1] - z + self.__logger.debug(f"touching surface at {zenith_reflection/units.deg:.1f}deg -> {zenith_air/units.deg:.1f}deg -> x2 = {x2} diff {diff:.2f}") + return diff + else: + # now it's a bit more complicated. we need to transform the coordinates to + # be on the mirrored part of the function + z_mirrored = x2[1] + gamma = self.get_gamma(z_mirrored) + self.__logger.debug("get_y( {}, {}, {})".format(gamma, C_0, C_1)) + y2_raw = self.get_y(gamma, C_0, C_1) + y2_fit = 2 * y_turn - y2_raw + diff = (x2[0] - y2_fit) + + self.__logger.debug('we have a reflected/refracted ray, y({:.1f}) = {:.1f} ({:.1f}) -> {:.1f} away from {:.1f} (gamma = {:.5g})'.format( + z_mirrored, y2_fit, y2_raw, diff, x2[0], gamma)) + + return -1 * diff def determine_solution_type(self, x1, x2, C_0): """ returns the type of the solution @@ -1162,6 +1185,27 @@ def find_solutions(self, x1, x2, plot=False, reflection=0, reflection_case=1): results = [] C0s = [] # intermediate storage of results + if(x2[1] > 0): + # special case of ice to air ray tracing. There is always one unique solution between C_0 = inf and C_0 that + # skims the surface. Therefore, we can find the solution using an efficient root finding algorithm. + logC0_start = 1 # infinity is bad, 1 is steep enough + C_0_stop, th_start = self.get_surf_skim_angle(x1) + C_0_stop /= 2 # for some reason, the get_surf_skim_angle function does not give the correct angle. The launch angle + # needs to be slightly steeper + logC0_stop = np.log(C_0_stop) + result = optimize.brentq(self.obj_delta_y, logC0_start, logC0_stop, args=(x1, x2, reflection, reflection_case)) + + C_0 = self.get_C0_from_log(result) + C0s.append(C_0) + solution_type = self.determine_solution_type(x1, x2, C_0) + self.__logger.info("found {} solution C0 = {:.2f}".format(solution_types[solution_type], C_0)) + results.append({'type': solution_type, + 'C0': C_0, + 'C1': self.get_C_1(x1, C_0), + 'reflection': reflection, + 'reflection_case': reflection_case}) + return results + # calculate optimal start value. The objective function becomes infinity if the turning point is below the z # position of the observer. We calculate the corresponding value so that the minimization starts at one edge # of the objective function @@ -1697,7 +1741,7 @@ class describing the index-of-refraction profile self.__logger.setLevel(log_level) from NuRadioMC.utilities.medium_base import IceModelSimple - if not isinstance(medium,IceModelSimple): + if not isinstance(medium, IceModelSimple): self.__logger.error("The analytic raytracer can only handle ice model of the type 'IceModelSimple'") raise TypeError("The analytic raytracer can only handle ice model of the type 'IceModelSimple'") @@ -1709,7 +1753,7 @@ class describing the index-of-refraction profile config=config, detector=detector) self.set_config(config=config) - + self._r2d = ray_tracing_2D(self._medium, self._attenuation_model, log_level=log_level, n_frequencies_integration=self._n_frequencies_integration, **ray_tracing_2D_kwards) @@ -1751,8 +1795,8 @@ def set_start_and_end_point(self, x1, x2): if(self._X2[2] < self._X1[2]): self._swap = True self.__logger.debug('swap = True') - self._X2 = np.array(x1, dtype =float) - self._X1 = np.array(x2, dtype =float) + self._X2 = np.array(x1, dtype=float) + self._X1 = np.array(x2, dtype=float) dX = self._X2 - self._X1 self._dPhi = -np.arctan2(dX[1], dX[0]) @@ -2089,7 +2133,7 @@ def get_focusing(self, iS, dz=-1. * units.cm, limit=2.): lauVec1 = self._r1.get_launch_vector(iS) lauAng1 = np.arccos(lauVec1[2] / np.sqrt(lauVec1[0] ** 2 + lauVec1[1] ** 2 + lauVec1[2] ** 2)) focusing = np.sqrt(distance / np.sin(recAng) * np.abs((lauAng1 - lauAng) / (recPos1[2] - recPos[2]))) - if (self.get_results()[iS]['reflection'] != self._r1.get_results()[iS]['reflection'] + if (self.get_results()[iS]['reflection'] != self._r1.get_results()[iS]['reflection'] or self.get_results()[iS]['reflection_case'] != self._r1.get_results()[iS]['reflection_case']): self.__logger.error("Number or type of reflections are different between solutions - focusing correction may not be reliable.") else: From a429a8b09f92f1665b1a41f869f7c021c7660bbb Mon Sep 17 00:00:00 2001 From: Christian Glaser Date: Fri, 4 Aug 2023 12:26:06 +0000 Subject: [PATCH 325/418] add example of ice to air tracing --- NuRadioMC/SignalProp/examples/E02ToAir.py | 71 +++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 NuRadioMC/SignalProp/examples/E02ToAir.py diff --git a/NuRadioMC/SignalProp/examples/E02ToAir.py b/NuRadioMC/SignalProp/examples/E02ToAir.py new file mode 100644 index 000000000..a9661e74e --- /dev/null +++ b/NuRadioMC/SignalProp/examples/E02ToAir.py @@ -0,0 +1,71 @@ +import matplotlib.pyplot as plt +import numpy as np +import time +from NuRadioMC.SignalProp import analyticraytracing as ray +from NuRadioReco.utilities import units +from NuRadioMC.utilities import medium +import logging +from radiotools import helper as hp +from radiotools import plthelpers as php +logging.basicConfig(level=logging.INFO) +logger = logging.getLogger('raytracing') +# ray.cpp_available=False + +x1 = np.array([0, 0., -149.]) * units.m +x2 = np.array([200, 0., 100]) * units.m +x3 = np.array([500, 0., 100]) * units.m +x4 = np.array([1000, 0., 100]) * units.m +x5 = np.array([10000, 0., 100]) * units.m +N = 4 + +receive_vectors = np.zeros((N, 2, 3)) * np.nan +ray_tracing_C0 = np.zeros((N, 2)) * np.nan +ray_tracing_C1 = np.zeros((N, 2)) * np.nan +ray_tracing_solution_type = np.zeros((N, 2), dtype=int) * np.nan +travel_times = np.zeros((N, 2)) * np.nan +travel_distances = np.zeros((N, 2)) * np.nan + +ice = medium.southpole_simple() + +lss = ['-', '--', ':'] +colors = ['b', 'g', 'r'] +fig, ax = plt.subplots(1, 1) +ax.plot(x1[0], x1[2], 'ko') +for i, x in enumerate([x2, x3, x4, x5]): + print('finding solutions for ', x) + r = ray.ray_tracing(ice, log_level=logging.DEBUG) + r.set_start_and_end_point(x1, x) + r.find_solutions() + if(r.has_solution()): + for iS in range(r.get_number_of_solutions()): + ray_tracing_C0[i, iS] = r.get_results()[iS]['C0'] + ray_tracing_solution_type[i, iS] = r.get_solution_type(iS) + print(" Solution %d, Type %d: " % (iS, ray_tracing_solution_type[i, iS])) + R = r.get_path_length(iS) # calculate path length + T = r.get_travel_time(iS) # calculate travel time + print(" Ray Distance %.3f and Travel Time %.3f" % (R / units.m, T / units.ns)) + receive_vector = r.get_receive_vector(iS) + receive_vectors[i, iS] = receive_vector + zenith, azimuth = hp.cartesian_to_spherical(*receive_vector) + print(" Receiving Zenith %.3f and Azimuth %.3f " % (zenith / units.deg, azimuth / units.deg)) + + # to readout the actual trace, we have to flatten to 2D + dX = x - x1 + dPhi = -np.arctan2(dX[1], dX[0]) + c, s = np.cos(dPhi), np.sin(dPhi) + R = np.array(((c, -s, 0), (s, c, 0), (0, 0, 1))) + X1r = x1 + X2r = np.dot(R, x - x1) + x1 + x1_2d = np.array([X1r[0], X1r[2]]) + x2_2d = np.array([X2r[0], X2r[2]]) + r_2d = ray.ray_tracing_2D(ice) + yy, zz = r_2d.get_path(x1_2d, x2_2d, ray_tracing_C0[i, iS]) + ax.plot(yy, zz, '{}'.format(php.get_color_linestyle(i)), label='{} C0 = {:.4f}'.format(ray_tracing_solution_type[i, iS], ray_tracing_C0[i, iS])) + ax.plot(x2_2d[0], x2_2d[1], '{}{}-'.format('d', php.get_color(i))) + +ax.legend() +ax.set_xlabel("y [m]") +ax.set_ylabel("z [m]") +fig.tight_layout() +fig.savefig('example_to_air.png') +plt.show() From fd05d4af6bbbfa12e94d875d92f4652aaeba0bb2 Mon Sep 17 00:00:00 2001 From: Christian Glaser Date: Fri, 4 Aug 2023 12:37:50 +0000 Subject: [PATCH 326/418] make use of CPP version optional --- NuRadioMC/SignalProp/examples/E02ToAir.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NuRadioMC/SignalProp/examples/E02ToAir.py b/NuRadioMC/SignalProp/examples/E02ToAir.py index a9661e74e..ff39d3bf5 100644 --- a/NuRadioMC/SignalProp/examples/E02ToAir.py +++ b/NuRadioMC/SignalProp/examples/E02ToAir.py @@ -33,7 +33,7 @@ ax.plot(x1[0], x1[2], 'ko') for i, x in enumerate([x2, x3, x4, x5]): print('finding solutions for ', x) - r = ray.ray_tracing(ice, log_level=logging.DEBUG) + r = ray.ray_tracing(ice, log_level=logging.DEBUG, use_cpp=False) r.set_start_and_end_point(x1, x) r.find_solutions() if(r.has_solution()): From b7424efdf44d402b02be672dd41aac92d2c9a985 Mon Sep 17 00:00:00 2001 From: Christian Glaser Date: Sat, 5 Aug 2023 06:07:15 +0000 Subject: [PATCH 327/418] add calculation of travel times and propagation distances for ice to air case --- NuRadioMC/SignalProp/analyticraytracing.py | 95 +++++++++++++++------- 1 file changed, 66 insertions(+), 29 deletions(-) diff --git a/NuRadioMC/SignalProp/analyticraytracing.py b/NuRadioMC/SignalProp/analyticraytracing.py index 4ba7bccb3..485fd7f26 100644 --- a/NuRadioMC/SignalProp/analyticraytracing.py +++ b/NuRadioMC/SignalProp/analyticraytracing.py @@ -40,7 +40,6 @@ print("check NuRadioMC/NuRadioMC/SignalProp/CPPAnalyticRayTracing for manual compilation") cpp_available = False -cpp_available = False """ analytic ray tracing solution @@ -94,7 +93,8 @@ def __init__(self, medium, attenuation_model="SP1", log_level=logging.WARNING, n_frequencies_integration=25, use_optimized_start_values=False, - overwrite_speedup=None): + overwrite_speedup=None, + use_cpp=cpp_available): """ initialize 2D analytic ray tracing class @@ -119,6 +119,9 @@ def __init__(self, medium, attenuation_model="SP1", speedup_attenuation_models (i.e., "GL3"). With this argument you can explicitly activate or deactivate (True or False) if you want to use the optimization. (Default: None, i.e., use optimization if ice model is listed in speedup_attenuation_models) + use_cpp: bool + if True, use CPP implementation of minimization routines + default: True if CPP version is available """ self.medium = medium @@ -138,6 +141,7 @@ def __init__(self, medium, attenuation_model="SP1", self._use_optimized_calculation = self.attenuation_model in speedup_attenuation_models if overwrite_speedup is not None: self._use_optimized_calculation = overwrite_speedup + self.use_cpp = use_cpp def n(self, z): """ @@ -437,18 +441,32 @@ def get_path_direct(z1, z2): # z0 above z_deep, z1 below z_deep return int2 - int1 - int_diff - if(solution_type == 1): - tmp += get_path_direct(x1[1], x2[1]) - else: - if(solution_type == 3): - z_turn = 0 - else: - gamma_turn, z_turn = self.get_turning_point(self.medium.n_ice ** 2 - C_0 ** -2) - # print('solution type {:d}, zturn = {:.1f}'.format(solution_type, z_turn)) + # first treat special case of ice to air propagation + if(x2[1] > 0): + z_turn = 0 + y_turn = self.get_y(self.get_gamma(z_turn), C_0, self.get_C_1(x1, C_0)) + d_air = ((x2[0] - y_turn) ** 2 + (x2[1]) ** 2) ** 0.5 try: - tmp += get_path_direct(x1[1], z_turn) + get_path_direct(x2[1], z_turn) + ttmp = get_path_direct(x1[1], z_turn) + tmp += ttmp + d_air + self.__logger.info("calculating travel distance from ({:.0f}, {:.0f}) to ({:.0f}, {:.0f}) = {:.2f} m in ice + {:.2f} m in air".format( + x1[0], x1[1], x2[0], x2[1], ttmp / units.m, d_air / units.m)) except: tmp += None + + else: + if(solution_type == 1): + tmp += get_path_direct(x1[1], x2[1]) + else: + if(solution_type == 3): + z_turn = 0 + else: + gamma_turn, z_turn = self.get_turning_point(self.medium.n_ice ** 2 - C_0 ** -2) + # print('solution type {:d}, zturn = {:.1f}'.format(solution_type, z_turn)) + try: + tmp += get_path_direct(x1[1], z_turn) + get_path_direct(x2[1], z_turn) + except: + tmp += None return tmp @@ -558,24 +576,38 @@ def get_ToF_direct(z1, z2): # z0 above z_deep, z1 below z_deep return int2 - int1 - int_diff - if(solution_type == 1): - ttmp = get_ToF_direct(x1[1], x2[1]) - tmp += ttmp - self.__logger.info("calculating travel time from ({:.0f}, {:.0f}) to ({:.0f}, {:.0f}) = {:.2f} ns".format( - x1[0], x1[1], x2[0], x2[1], ttmp / units.ns)) - else: - if(solution_type == 3): - z_turn = 0 - else: - gamma_turn, z_turn = self.get_turning_point(self.medium.n_ice ** 2 - C_0 ** -2) - # print('solution type {:d}, zturn = {:.1f}'.format(solution_type, z_turn)) + # first treat special case of ice to air propagation + if(x2[1] > 0): + z_turn = 0 + y_turn = self.get_y(self.get_gamma(z_turn), C_0, self.get_C_1(x1, C_0)) + t_air = ((x2[0] - y_turn) ** 2 + (x2[1]) ** 2) ** 0.5 / speed_of_light try: - ttmp = get_ToF_direct(x1[1], z_turn) + get_ToF_direct(x2[1], z_turn) + ttmp = get_ToF_direct(x1[1], z_turn) + tmp += ttmp + t_air + self.__logger.info("calculating travel time from ({:.0f}, {:.0f}) to ({:.0f}, {:.0f}) = {:.2f} ns in ice + {:.2f} ns in air".format( + x1[0], x1[1], x2[0], x2[1], ttmp / units.ns, t_air / units.ns)) + except: + tmp += None + + else: + if(solution_type == 1): + ttmp = get_ToF_direct(x1[1], x2[1]) tmp += ttmp self.__logger.info("calculating travel time from ({:.0f}, {:.0f}) to ({:.0f}, {:.0f}) = {:.2f} ns".format( x1[0], x1[1], x2[0], x2[1], ttmp / units.ns)) - except: - tmp += None + else: + if(solution_type == 3): + z_turn = 0 + else: + gamma_turn, z_turn = self.get_turning_point(self.medium.n_ice ** 2 - C_0 ** -2) + # print('solution type {:d}, zturn = {:.1f}'.format(solution_type, z_turn)) + try: + ttmp = get_ToF_direct(x1[1], z_turn) + get_ToF_direct(x2[1], z_turn) + tmp += ttmp + self.__logger.info("calculating travel time from ({:.0f}, {:.0f}) to ({:.0f}, {:.0f}) = {:.2f} ns".format( + x1[0], x1[1], x2[0], x2[1], ttmp / units.ns)) + except: + tmp += None return tmp def __get_frequencies_for_attenuation(self, frequency, max_detector_freq): @@ -613,7 +645,7 @@ def get_attenuation_along_path(self, x1, x2, C_0, frequency, max_detector_freq, else: x11, x1, x22, x2, C_0, C_1 = segment - if cpp_available: + if self.use_cpp: mask = frequency > 0 freqs = self.__get_frequencies_for_attenuation(frequency, max_detector_freq) tmp = np.zeros_like(freqs) @@ -1170,7 +1202,7 @@ def find_solutions(self, x1, x2, plot=False, reflection=0, reflection_case=1): self.__logger.error("a solution for {:d} reflection(s) off the bottom reflective layer is requested, but ice model does not specify a reflective layer".format(reflection)) raise AttributeError("a solution for {:d} reflection(s) off the bottom reflective layer is requested, but ice model does not specify a reflective layer".format(reflection)) - if(cpp_available): + if(self.use_cpp): # t = time.time() # print("find solutions", x1, x2, self.medium.n_ice, self.medium.delta_n, self.medium.z_0, reflection, reflection_case, self.medium.reflection) tmp_reflection = copy.copy(self.medium.reflection) @@ -1689,7 +1721,8 @@ class ray_tracing(ray_tracing_base): def __init__(self, medium, attenuation_model="SP1", log_level=logging.WARNING, n_frequencies_integration=100, n_reflections=0, config=None, - detector=None, ray_tracing_2D_kwards={}): + detector=None, ray_tracing_2D_kwards={}, + use_cpp=cpp_available): """ class initilization @@ -1736,6 +1769,10 @@ class describing the index-of-refraction profile ray_tracing_2D_kwards: dict Additional arguments which are passed to ray_tracing_2D + use_cpp: bool + if True, use CPP implementation of minimization routines + default: True if CPP version is available + """ self.__logger = logging.getLogger('ray_tracing_analytic') self.__logger.setLevel(log_level) @@ -1756,7 +1793,7 @@ class describing the index-of-refraction profile self._r2d = ray_tracing_2D(self._medium, self._attenuation_model, log_level=log_level, n_frequencies_integration=self._n_frequencies_integration, - **ray_tracing_2D_kwards) + **ray_tracing_2D_kwards, use_cpp=use_cpp) self._swap = None self._dPhi = None From ba1b0dc250075522a11df6b89c1029dfe6ebd28e Mon Sep 17 00:00:00 2001 From: Christian Glaser Date: Sat, 5 Aug 2023 06:23:54 +0000 Subject: [PATCH 328/418] add calculation of travel and propagation times/distances to numerical integrator --- NuRadioMC/SignalProp/analyticraytracing.py | 57 +++++++++++++++------- NuRadioMC/SignalProp/examples/E02ToAir.py | 4 +- 2 files changed, 43 insertions(+), 18 deletions(-) diff --git a/NuRadioMC/SignalProp/analyticraytracing.py b/NuRadioMC/SignalProp/analyticraytracing.py index 485fd7f26..667d93a51 100644 --- a/NuRadioMC/SignalProp/analyticraytracing.py +++ b/NuRadioMC/SignalProp/analyticraytracing.py @@ -354,16 +354,28 @@ def get_path_length(self, x1, x2, C_0, reflection=0, reflection_case=1): x1 = x1t else: x11, x1, x22, x2, C_0, C_1 = segment - x2_mirrored = self.get_z_mirrored(x1, x2, C_0) - gamma_turn, z_turn = self.get_turning_point(self.medium.n_ice ** 2 - C_0 ** -2) + + # first treat special case of ice to air propagation + z_int = None points = None - if(x1[1] < z_turn and z_turn < x2_mirrored[1]): - points = [z_turn] - path_length = integrate.quad(self.ds, x1[1], x2_mirrored[1], args=(C_0), points=points, epsabs=1e-4, epsrel=1.49e-08, limit=50) - self.__logger.info("calculating path length ({}) from ({:.0f}, {:.0f}) to ({:.2f}, {:.2f}) = ({:.2f}, {:.2f}) = {:.2f} m".format(solution_types[self.determine_solution_type(x1, x2, C_0)], x1[0], x1[1], x2[0], x2[1], - x2_mirrored[0], - x2_mirrored[1], - path_length[0] / units.m)) + if(x2[1] > 0): + # we need to integrat only until the ray touches the surface + z_turn = 0 + y_turn = self.get_y(self.get_gamma(z_turn), C_0, self.get_C_1(x1, C_0)) + d_air = ((x2[0] - y_turn) ** 2 + (x2[1]) ** 2) ** 0.5 + tmp += d_air + z_int = z_turn + self.__logger.info(f"adding additional propagation path through air of {d_air/units.m:.1f}m") + else: + x2_mirrored = self.get_z_mirrored(x1, x2, C_0) + gamma_turn, z_turn = self.get_turning_point(self.medium.n_ice ** 2 - C_0 ** -2) + if(x1[1] < z_turn and z_turn < x2_mirrored[1]): + points = [z_turn] + z_int = x2_mirrored[1] + path_length = integrate.quad(self.ds, x1[1], z_int, args=(C_0), points=points, + epsabs=1e-4, epsrel=1.49e-08, limit=50) + self.__logger.info(f"calculating path length ({solution_types[self.determine_solution_type(x1, x2, C_0)]}) \ + from ({x1[0]:.0f}, {x1[1]:.0f}) to ({x2[0]:.2f}, {x2[1]:.2f}) = {path_length[0] / units.m:.2f} m") tmp += path_length[0] return tmp @@ -483,18 +495,29 @@ def get_travel_time(self, x1, x2, C_0, reflection=0, reflection_case=1): x1 = x1t else: x11, x1, x22, x2, C_0, C_1 = segment - + + # first treat special case of ice to air propagation + z_int = None + points = None x2_mirrored = self.get_z_mirrored(x1, x2, C_0) - + if(x2[1] > 0): + # we need to integrat only until the ray touches the surface + z_turn = 0 + y_turn = self.get_y(self.get_gamma(z_turn), C_0, self.get_C_1(x1, C_0)) + T_air = ((x2[0] - y_turn) ** 2 + (x2[1]) ** 2) ** 0.5 / speed_of_light + tmp += T_air + z_int = z_turn + self.__logger.info(f"adding additional propagation path through air of {T_air/units.ns:.1f}ns") + else: + gamma_turn, z_turn = self.get_turning_point(self.medium.n_ice ** 2 - C_0 ** -2) + if(x1[1] < z_turn and z_turn < x2_mirrored[1]): + points = [z_turn] + z_int = x2_mirrored[1] def dt(t, C_0): z = self.get_z_unmirrored(t, C_0) return self.ds(t, C_0) / speed_of_light * self.n(z) - - gamma_turn, z_turn = self.get_turning_point(self.medium.n_ice ** 2 - C_0 ** -2) - points = None - if(x1[1] < z_turn and z_turn < x2_mirrored[1]): - points = [z_turn] - travel_time = integrate.quad(dt, x1[1], x2_mirrored[1], args=(C_0), points=points, epsabs=1e-10, epsrel=1.49e-08, limit=500) + travel_time = integrate.quad(dt, x1[1], z_int, args=(C_0), points=points, + epsabs=1e-10, epsrel=1.49e-08, limit=500) self.__logger.info("calculating travel time from ({:.0f}, {:.0f}) to ({:.0f}, {:.0f}) = ({:.0f}, {:.0f}) = {:.2f} ns".format( x1[0], x1[1], x2[0], x2[1], x2_mirrored[0], x2_mirrored[1], travel_time[0] / units.ns)) tmp += travel_time[0] diff --git a/NuRadioMC/SignalProp/examples/E02ToAir.py b/NuRadioMC/SignalProp/examples/E02ToAir.py index ff39d3bf5..b05fb532c 100644 --- a/NuRadioMC/SignalProp/examples/E02ToAir.py +++ b/NuRadioMC/SignalProp/examples/E02ToAir.py @@ -42,8 +42,10 @@ ray_tracing_solution_type[i, iS] = r.get_solution_type(iS) print(" Solution %d, Type %d: " % (iS, ray_tracing_solution_type[i, iS])) R = r.get_path_length(iS) # calculate path length + R2 = r.get_path_length(iS, analytic=False) # calculate path length T = r.get_travel_time(iS) # calculate travel time - print(" Ray Distance %.3f and Travel Time %.3f" % (R / units.m, T / units.ns)) + T2 = r.get_travel_time(iS, analytic=False) # calculate travel time + print(f" Ray Distance {R/units.m:.3f}m {R2/units.m:.3f}m and Travel Time {T/units.ns:.3f}ns {T2/units.ns:.3f}ns") receive_vector = r.get_receive_vector(iS) receive_vectors[i, iS] = receive_vector zenith, azimuth = hp.cartesian_to_spherical(*receive_vector) From e527ed5ef15319977a9889fe3d9e83cb354226bd Mon Sep 17 00:00:00 2001 From: Christian Glaser Date: Sat, 5 Aug 2023 06:29:45 +0000 Subject: [PATCH 329/418] add info when using CPP ray tracer or not --- NuRadioMC/SignalProp/analyticraytracing.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/NuRadioMC/SignalProp/analyticraytracing.py b/NuRadioMC/SignalProp/analyticraytracing.py index 667d93a51..d5250d446 100644 --- a/NuRadioMC/SignalProp/analyticraytracing.py +++ b/NuRadioMC/SignalProp/analyticraytracing.py @@ -24,7 +24,7 @@ try: from NuRadioMC.SignalProp.CPPAnalyticRayTracing import wrapper cpp_available = True - print("using CPP version of ray tracer") + print("CPP version of ray tracer is available") except: print("trying to compile the CPP extension on-the-fly") try: @@ -34,7 +34,7 @@ "install.sh")) from NuRadioMC.SignalProp.CPPAnalyticRayTracing import wrapper cpp_available = True - print("compilation was successful, using CPP version of ray tracer") + print("compilation was successful, CPP version of ray tracer is available") except: print("compilation was not successful, using python version of ray tracer") print("check NuRadioMC/NuRadioMC/SignalProp/CPPAnalyticRayTracing for manual compilation") @@ -1813,6 +1813,11 @@ class describing the index-of-refraction profile config=config, detector=detector) self.set_config(config=config) + + if use_cpp: + self.__logger.warning(f"using CPP version of ray tracer") + else: + self.__logger.warning(f"using python version of ray tracer") self._r2d = ray_tracing_2D(self._medium, self._attenuation_model, log_level=log_level, n_frequencies_integration=self._n_frequencies_integration, From da0c1c351bfe9786e53c326a273c21c654ddcd94 Mon Sep 17 00:00:00 2001 From: Christian Glaser Date: Sat, 5 Aug 2023 06:47:53 +0000 Subject: [PATCH 330/418] add calculation of attenuation for to air case --- NuRadioMC/SignalProp/analyticraytracing.py | 13 ++++++++++--- NuRadioMC/SignalProp/examples/E02ToAir.py | 3 +++ NuRadioMC/SignalProp/examples/example_3d.py | 2 ++ NuRadioMC/test/SignalProp/T01test_python_vs_cpp.py | 3 +-- 4 files changed, 16 insertions(+), 5 deletions(-) diff --git a/NuRadioMC/SignalProp/analyticraytracing.py b/NuRadioMC/SignalProp/analyticraytracing.py index d5250d446..a70c3c972 100644 --- a/NuRadioMC/SignalProp/analyticraytracing.py +++ b/NuRadioMC/SignalProp/analyticraytracing.py @@ -667,6 +667,13 @@ def get_attenuation_along_path(self, x1, x2, C_0, frequency, max_detector_freq, x1 = x1t else: x11, x1, x22, x2, C_0, C_1 = segment + + # treat special ice to air case. Attenuation in air can be neglected, so only + # calculate attenuation until the ray reaches the surface + if x2[1] > 0: + z_turn = 0 + y_turn = self.get_y(self.get_gamma(z_turn), C_0, self.get_C_1(x1, C_0)) + x2 = [y_turn, z_turn] if self.use_cpp: mask = frequency > 0 @@ -694,7 +701,7 @@ def dt(t, C_0, frequency): mask = frequency > 0 freqs = self.__get_frequencies_for_attenuation(frequency, max_detector_freq) gamma_turn, z_turn = self.get_turning_point(self.medium.n_ice ** 2 - C_0 ** -2) - self.__logger.info("_use_optimized_calculation", self._use_optimized_calculation) + self.__logger.info(f"_use_optimized_calculation {self._use_optimized_calculation}") if self._use_optimized_calculation: # The integration of the attenuation factor along the path with scipy.quad is inefficient. The @@ -1815,9 +1822,9 @@ class describing the index-of-refraction profile self.set_config(config=config) if use_cpp: - self.__logger.warning(f"using CPP version of ray tracer") + self.__logger.debug(f"using CPP version of ray tracer") else: - self.__logger.warning(f"using python version of ray tracer") + self.__logger.debug(f"using python version of ray tracer") self._r2d = ray_tracing_2D(self._medium, self._attenuation_model, log_level=log_level, n_frequencies_integration=self._n_frequencies_integration, diff --git a/NuRadioMC/SignalProp/examples/E02ToAir.py b/NuRadioMC/SignalProp/examples/E02ToAir.py index b05fb532c..a8a54f633 100644 --- a/NuRadioMC/SignalProp/examples/E02ToAir.py +++ b/NuRadioMC/SignalProp/examples/E02ToAir.py @@ -51,6 +51,9 @@ zenith, azimuth = hp.cartesian_to_spherical(*receive_vector) print(" Receiving Zenith %.3f and Azimuth %.3f " % (zenith / units.deg, azimuth / units.deg)) + att = r.get_attenuation(iS, np.array([100, 200]) * units.MHz) + print(att) + # to readout the actual trace, we have to flatten to 2D dX = x - x1 dPhi = -np.arctan2(dX[1], dX[0]) diff --git a/NuRadioMC/SignalProp/examples/example_3d.py b/NuRadioMC/SignalProp/examples/example_3d.py index 43d43ce9a..a78a006bc 100644 --- a/NuRadioMC/SignalProp/examples/example_3d.py +++ b/NuRadioMC/SignalProp/examples/example_3d.py @@ -43,6 +43,8 @@ R = r.get_path_length(iS) # calculate path length T = r.get_travel_time(iS) # calculate travel time print(" Ray Distance %.3f and Travel Time %.3f" % (R / units.m, T / units.ns)) + + receive_vector = r.get_receive_vector(iS) receive_vectors[i, iS] = receive_vector zenith, azimuth = hp.cartesian_to_spherical(*receive_vector) diff --git a/NuRadioMC/test/SignalProp/T01test_python_vs_cpp.py b/NuRadioMC/test/SignalProp/T01test_python_vs_cpp.py index 9664a2b48..68a7be284 100644 --- a/NuRadioMC/test/SignalProp/T01test_python_vs_cpp.py +++ b/NuRadioMC/test/SignalProp/T01test_python_vs_cpp.py @@ -50,10 +50,9 @@ results_C0s_python = np.zeros((n_events, 2)) results_A_python = np.zeros((n_events, 2, n_freqs)) -ray.cpp_available = False t_start = time.time() for iX, x in enumerate(points): - r = ray.ray_tracing(ice) + r = ray.ray_tracing(ice, use_cpp=False) r.set_start_and_end_point(x, x_receiver) r.find_solutions() if(r.has_solution()): From e72d84380e331348a13cff5f60b73b20c1f316ef Mon Sep 17 00:00:00 2001 From: Alan Coleman <74733466+colemanalan@users.noreply.github.com> Date: Tue, 22 Aug 2023 11:17:51 +0200 Subject: [PATCH 331/418] Expand the phased-array noise gen (#546) * Allow for the generation of long waveforms using roll operation * Add parameters to make the simulation fully customizable * Allow to turn off digitization * Return the triggered beam as well * Allow to set upsampling factor --------- Co-authored-by: Alan --- NuRadioReco/utilities/noise.py | 156 ++++++++++++++++++++++----------- 1 file changed, 107 insertions(+), 49 deletions(-) diff --git a/NuRadioReco/utilities/noise.py b/NuRadioReco/utilities/noise.py index 0fd45282b..01648bd76 100644 --- a/NuRadioReco/utilities/noise.py +++ b/NuRadioReco/utilities/noise.py @@ -232,7 +232,11 @@ class thermalNoiseGeneratorPhasedArray(): def __init__(self, detector_filename, station_id, triggered_channels, Vrms, threshold, ref_index, noise_type="rayleigh", log_level=logging.WARNING, - pre_trigger_time=100 * units.ns, trace_length=512 * units.ns): + pre_trigger_time=100 * units.ns, trace_length=512 * units.ns, filt=None, + upsampling=2, window_length=16 * units.ns, step_size=8 * units.ns, + main_low_angle=np.deg2rad(-59.54968597864437), + main_high_angle=np.deg2rad(59.54968597864437), + n_beams=11, quantize=True): """ Efficient algorithms to generate thermal noise fluctuations that fulfill a phased array trigger @@ -248,24 +252,44 @@ def __init__(self, detector_filename, station_id, triggered_channels, the RMS noise threshold: float the trigger threshold (assuming a symmetric high and low threshold) - trigger_time: float - the trigger time (time when the trigger completes) - filt: array of floats - the filter that should be applied after noise generation (needs to match frequency binning) + ref_index: float + reference refractive index for calculating time delays of the beams + + Other Parameters + ---------------- noise_type: string the type of the noise, can be * "rayleigh" (default) * "noise" - pre_trigger_time: float + log_level: logging enum, default warn + the print level for this module + pre_trigger_time: float, default 100 ns the time in the trace before the trigger happens - trace_length: float + trace_length: float, default 512 ns the total trace length + filt: array of complex values, default None + the filter that should be applied after noise generation (needs to match frequency binning in upsampled domain) + if `None`, a default filter is calculated from 96 to 220 MHz + upsampling: int, default 2 + factor by which the waveforms will be upsampled before calculating time delays and beamforming + window_length: float, default 16 ns + time interval of the integration window + step_size: float, default 8 ns + duration of a stride between window calcuations + main_low_angle: float, default -59.5 deg + angle (radians) of the lowest beam + main_high_angle: float 59.5 deg + angle (radians) of the highest beam + n_beams: int, default 11 + number of beams to calculate + quantize: bool, default True + If set to true, the conversion to and from ADC will be performed to mimic digitizations """ logger.setLevel(log_level) self.debug = False self.max_amp = 0 - self.upsampling = 2 + self.upsampling = upsampling self.det = detector.GenericDetector(json_filename=detector_filename) self.det.update(datetime.datetime(2018, 10, 1)) self.n_samples = self.det.get_number_of_samples(station_id, triggered_channels[0]) # assuming same settings for all channels @@ -273,9 +297,16 @@ def __init__(self, detector_filename, station_id, triggered_channels, self.pre_trigger_bins = int(pre_trigger_time * self.sampling_rate) self.n_samples_trigger = int(trace_length * self.sampling_rate) - det_channel = self.det.get_channel(station_id, triggered_channels[0]) - self.adc_n_bits = det_channel["trigger_adc_nbits"] - self.adc_noise_n_bits = det_channel["trigger_adc_noise_nbits"] + + if self.n_samples_trigger > self.n_samples: + raise ValueError(f"Requested `trace_length` of {trace_length/units.ns:.1f}ns ({self.n_samples_trigger} bins)" + + f" is longer than the number of samples specified in the detector file ({self.n_samples} bins)") + + self.quantize = quantize + if self.quantize: + det_channel = self.det.get_channel(station_id, triggered_channels[0]) + self.adc_n_bits = det_channel["trigger_adc_nbits"] + self.adc_noise_n_bits = det_channel["trigger_adc_noise_nbits"] self.n_channels = len(triggered_channels) self.triggered_channels = triggered_channels @@ -288,12 +319,10 @@ def __init__(self, detector_filename, station_id, triggered_channels, for channel_id in triggered_channels: cable_delays[channel_id] = self.det.get_cable_delay(station_id, channel_id) - main_low_angle = np.deg2rad(-59.54968597864437) - main_high_angle = np.deg2rad(59.54968597864437) - phasing_angles_4ant = np.arcsin(np.linspace(np.sin(main_low_angle), np.sin(main_high_angle), 11)) + phasing_angles = np.arcsin(np.linspace(np.sin(main_low_angle), np.sin(main_high_angle), n_beams)) cspeed = constants.c * units.m / units.s - self.beam_time_delays = np.zeros((len(phasing_angles_4ant), self.n_channels), dtype=np.int) - for iBeam, angle in enumerate(phasing_angles_4ant): + self.beam_time_delays = np.zeros((len(phasing_angles), self.n_channels), dtype=np.int) + for iBeam, angle in enumerate(phasing_angles): delays = [] for key in self.ant_z: @@ -312,21 +341,36 @@ def __init__(self, detector_filename, station_id, triggered_channels, self.max_freq = 0.5 * self.sampling_rate * self.upsampling self.dt = 1. / self.sampling_rate self.ff = np.fft.rfftfreq(self.n_samples * self.upsampling, 1. / (self.sampling_rate * self.upsampling)) - import NuRadioReco.modules.channelBandPassFilter - channelBandPassFilter = NuRadioReco.modules.channelBandPassFilter.channelBandPassFilter() - self.filt = channelBandPassFilter.get_filter(self.ff, station_id, channel_id, self.det, - passband=[96 * units.MHz, 100 * units.GHz], filter_type='cheby1', order=4, rp=0.1) - self.filt *= channelBandPassFilter.get_filter(self.ff, station_id, channel_id, self.det, - passband=[1 * units.MHz, 220 * units.MHz], filter_type='cheby1', order=7, rp=0.1) + + # Construct a default filter if one is not supplied + if filt is None: + import NuRadioReco.modules.channelBandPassFilter + channelBandPassFilter = NuRadioReco.modules.channelBandPassFilter.channelBandPassFilter() + self.filt = channelBandPassFilter.get_filter(self.ff, station_id, channel_id, self.det, + passband=[96 * units.MHz, 100 * units.GHz], filter_type='cheby1', order=4, rp=0.1) + self.filt *= channelBandPassFilter.get_filter(self.ff, station_id, channel_id, self.det, + passband=[1 * units.MHz, 220 * units.MHz], filter_type='cheby1', order=7, rp=0.1) + else: + if len(filt) != len(self.ff): + raise ValueError(f"Frequency filter supplied has {len(filt)} bins. It should match the upsampled" + + f" frequency binning of {len(self.ff)} bins from {self.ff[0] / units.MHz:.0f} to {self.ff[-1] / units.MHz:.0f} MHz") + self.filt = np.array(filt) + self.norm = np.trapz(np.abs(self.filt) ** 2, self.ff) self.amplitude = (self.max_freq - self.min_freq) ** 0.5 / self.norm ** 0.5 * self.Vrms - print(f"Vrms = {self.Vrms:.3g}V, noise amplitude = {self.amplitude:.3g}V, bandwidth = {self.norm/units.MHz:.0f}MHz") - print(f"frequency range {self.min_freq/units.MHz}MHz - {self.max_freq/units.MHz}MHz") + logger.info(f"Vrms = {self.Vrms:.3g}V, noise amplitude = {self.amplitude:.3g}V, bandwidth = {self.norm / units.MHz:.0f}MHz") + logger.info(f"frequency range {self.min_freq / units.MHz}MHz - {self.max_freq / units.MHz}MHz") - self.adc_ref_voltage = self.Vrms * (2 ** (self.adc_n_bits - 1) - 1) / (2 ** (self.adc_noise_n_bits - 1) - 1) + if self.quantize: + self.adc_ref_voltage = self.Vrms * (2 ** (self.adc_n_bits - 1) - 1) / (2 ** (self.adc_noise_n_bits - 1) - 1) - self.window = int(16 * units.ns * self.sampling_rate * 2.0) - self.step = int(8 * units.ns * self.sampling_rate * 2.0) + self.window = int(window_length * self.sampling_rate * self.upsampling) + self.step = int(step_size * self.sampling_rate * self.upsampling) + + if self.window >= self.pre_trigger_bins: + logger.warning(f"Pre-trigger time ({pre_trigger_time / units.ns:0.2} ns, {self.pre_trigger_bins} bins)" + + f" is within one window ({self.window} bins) of the beginning of the waveform" + + " it is recommended to choose a larger value to avoid clipping effects") self.noise = channelGenericNoiseAdder.channelGenericNoiseAdder() @@ -348,7 +392,10 @@ def __generation(self): spec *= self.filt trace = fft.freq2time(spec, self.sampling_rate * self.upsampling) - self._traces[iCh] = perfect_floor_comparator(trace, self.adc_n_bits, self.adc_ref_voltage) + if self.quantize: + self._traces[iCh] = perfect_floor_comparator(trace, self.adc_n_bits, self.adc_ref_voltage) + else: + self._traces[iCh] = trace def __phasing(self): """ separated phasing part for PA noise trigger """ @@ -391,8 +438,8 @@ def __triggering(self): if self.max_amp > self.threshold: sliding_windows = np.array(sliding_windows) tmp = np.argwhere(sliding_windows > self.threshold) - triggered_step = tmp[0][0] - triggered_bin = tmp[0][2] * (self.window + triggered_step * steps_per_window) + triggered_step, triggered_beam, triggered_bin = tmp[0] + triggered_bin *= (self.window + triggered_step * steps_per_window) if(self.debug): # check in which beam the trigger condition was fulfilled sliding_windows = np.concatenate(sliding_windows, axis=1) @@ -402,15 +449,15 @@ def __triggering(self): if is_triggered: logger.info(f"triggered at beam {iBeam}") import matplotlib.pyplot as plt - fig, ax = plt.subplots(5, 1, sharex=True) + fig, ax = plt.subplots(self.n_channels + 1, 1, sharex=True) for iCh in range(self.n_channels): ax[iCh].plot(self._traces[iCh]) logger.info(f"{self._traces[iCh].std():.2f}") - ax[4].plot(self._phased_traces[iBeam]) + ax[self.n_channels].plot(self._phased_traces[iBeam]) fig.tight_layout() plt.show() - return True, triggered_bin - return False, None + return True, triggered_bin, triggered_beam + return False, None, None def __triggering_strided(self): """ separated trigger part for PA noise trigger using np.lib.stride_tricks.as_strided """ @@ -426,18 +473,19 @@ def __triggering_strided(self): # self.max_amp = max(squared_mean.max(), self.max_amp) self.max_amp = max(squared_mean.max(), self.max_amp) if True in (squared_mean > self.threshold): - logger.info(f"triggered at beam {iBeam}") + triggered_bin = np.where(squared_mean > self.threshold)[0,0] + logger.debug(f"triggered at beam {iBeam}") if(self.debug): import matplotlib.pyplot as plt - fig, ax = plt.subplots(5, 1, sharex=True) + fig, ax = plt.subplots(self.n_channels+1, 1, sharex=True) for iCh in range(self.n_channels): ax[iCh].plot(self._traces[iCh]) logger.info(f"{self._traces[iCh].std():.2f}") - ax[4].plot(self._phased_traces[iBeam]) + ax[self.n_channels].plot(self._phased_traces[iBeam]) fig.tight_layout() plt.show() - return True - return False + return True, triggered_bin, iBeam + return False, None, None def generate_noise(self, phasing_mode="slice", trigger_mode="binned_sum", debug=False): """ @@ -455,7 +503,7 @@ def generate_noise(self, phasing_mode="slice", trigger_mode="binned_sum", debug= generate debug plot Returns ------- - np.array of shape (n_channels, n_samples) + np.array of shape (n_channels, n_samples), index of triggered bin, index of triggered beam """ self.debug = debug @@ -496,10 +544,10 @@ def generate_noise(self, phasing_mode="slice", trigger_mode="binned_sum", debug= tstart = time.process_time() if trigger_mode == "binned_sum": - is_triggered, triggered_bin = self.__triggering() + is_triggered, triggered_bin, triggered_beam = self.__triggering() elif trigger_mode == "stride": # more time consuming attempt to do triggering compared to taking binned sums - is_triggered = self.__triggering_strided() + is_triggered, triggered_bin, triggered_beam = self.__triggering_strided() else: logger.error(f"Requested trigger_mode {trigger_mode}. Only 'binned_sum' and 'stride' are allowed") raise NotImplementedError(f"Requested trigger_mode {trigger_mode}. Only 'binned_sum' and 'stride' are supported") @@ -508,14 +556,21 @@ def generate_noise(self, phasing_mode="slice", trigger_mode="binned_sum", debug= dt_triggering += time.process_time() - tstart if is_triggered: - triggered_bin = triggered_bin // 2 # the trace is cut in the downsampled version. Therefore, triggered bin is factor of two smaller. + triggered_bin = triggered_bin // self.upsampling # the trace is cut in the downsampled version. Therefore, triggered bin is factor of two smaller. i_low = triggered_bin - self.pre_trigger_bins i_high = i_low + self.n_samples_trigger - if (i_low >= 0) and (i_high < self.n_samples): - # traces need to be downsampled - # resample and use axis -1 since trace might be either shape (N) for analytic trace or shape (3,N) for E-field - self._traces = scipy.signal.resample(self._traces, np.shape(self._traces)[-1] // self.upsampling, axis=-1) - return self._traces[:, i_low:i_high], self._phased_traces + + # traces need to be downsampled + # resample and use axis -1 since trace might be either shape (N) for analytic trace or shape (3,N) for E-field + self._traces = scipy.signal.resample(self._traces, np.shape(self._traces)[-1] // self.upsampling, axis=-1) + + if (i_low >= 0) and (i_high < self.n_samples): # If range is directly a subset of the waveform + return self._traces[:, i_low:i_high], self._phased_traces, triggered_beam + + # Otherwise, roll the waveforms. Safe as long as noise is generated in the freq domain + self._phased_traces = np.roll(self._phased_traces, -i_low * self.upsampling, axis=-1) + self._traces = np.roll(self._traces, -i_low, axis=-1) + return self._traces[:, :self.n_samples_trigger], self._phased_traces, triggered_beam def generate_noise2(self, debug=False): """ @@ -538,7 +593,10 @@ def generate_noise2(self, debug=False): spec *= self.filt trace = fft.freq2time(spec, self.sampling_rate * self.upsampling) - traces[iCh] = perfect_floor_comparator(trace, self.adc_n_bits, self.adc_ref_voltage) + if self.quantize: + self._traces[iCh] = perfect_floor_comparator(trace, self.adc_n_bits, self.adc_ref_voltage) + else: + self._traces[iCh] = trace shifts = np.zeros(self.n_channels, dtype=np.int) shifted_traces = copy.copy(traces) From d90079cce2b59635e4da6565f127553eae81cb45 Mon Sep 17 00:00:00 2001 From: Sjoerd Bouma Date: Tue, 22 Aug 2023 18:07:33 +0200 Subject: [PATCH 332/418] fix dy/dz in air, use_cpp inherited also for focusing correction, promote focusing correction failure to warning --- NuRadioMC/SignalProp/analyticraytracing.py | 43 ++++++++++++++++++---- 1 file changed, 35 insertions(+), 8 deletions(-) diff --git a/NuRadioMC/SignalProp/analyticraytracing.py b/NuRadioMC/SignalProp/analyticraytracing.py index a70c3c972..759156a11 100644 --- a/NuRadioMC/SignalProp/analyticraytracing.py +++ b/NuRadioMC/SignalProp/analyticraytracing.py @@ -252,7 +252,14 @@ def get_y_diff(self, z_raw, C_0): """ derivative dy(z)/dz """ - + correct_for_air = False + # if we are above the ice surface, the analytic expression below + # does not apply. Therefore, we instead calculate dy/dz at z=0 where it is still valid + # and then correct this using Snell's law + if z_raw > 0: # we are above the ice surface, where the below expression does not apply + z_raw_copy = copy.copy(z_raw) + z_raw = 0 + correct_for_air = True z = self.get_z_unmirrored(z_raw, C_0) c = self.medium.n_ice ** 2 - C_0 ** -2 B = (0.2e1 * np.sqrt(c) * np.sqrt(-self.__b * self.medium.delta_n * np.exp(z / self.medium.z_0) + self.medium.delta_n ** @@ -263,7 +270,12 @@ def get_y_diff(self, z_raw, C_0): E = (E1 + E2 + c) res = (-np.sqrt(c) * np.exp(z / self.medium.z_0) * self.__b * self.medium.delta_n + 0.2e1 * np.sqrt(-self.__b * self.medium.delta_n * np.exp(z / self.medium.z_0) + self.medium.delta_n ** 2 * np.exp(0.2e1 * z / self.medium.z_0) + c) * c + 0.2e1 * c ** 1.5) / B * E ** -0.5 * (D ** (-0.5)) - + if correct_for_air: + n_surface = self.medium.get_index_of_refraction([0,0,0]) + theta_ice = np.arctan(res) + theta_air = np.arcsin(n_surface * np.sin(theta_ice)) + res = np.tan(theta_air) + z_raw = z_raw_copy if(z != z_raw): res *= -1 return res @@ -1251,10 +1263,15 @@ def find_solutions(self, x1, x2, plot=False, reflection=0, reflection_case=1): # special case of ice to air ray tracing. There is always one unique solution between C_0 = inf and C_0 that # skims the surface. Therefore, we can find the solution using an efficient root finding algorithm. logC0_start = 1 # infinity is bad, 1 is steep enough - C_0_stop, th_start = self.get_surf_skim_angle(x1) - C_0_stop /= 2 # for some reason, the get_surf_skim_angle function does not give the correct angle. The launch angle - # needs to be slightly steeper - logC0_stop = np.log(C_0_stop) + C_0_stop = self.get_C_0_from_angle(np.arcsin(1/self.medium.get_index_of_refraction([0, x1[0], x1[1]])), x1[1]).x[0] + # C_0_stop, th_start = self.get_surf_skim_angle(x1) + # C_0_stop *= (1-1e-8) # for some reason, the get_surf_skim_angle function does not give the correct angle. The launch angle + # # needs to be slightly steeper + logC0_stop = np.log(C_0_stop - 1/self.medium.n_ice) + self.__logger.warning( + "C0: {}, {} start: {} stop: {}".format( + logC0_start, logC0_stop, *[self.obj_delta_y(logC0, x1, x2, reflection, reflection_case) for logC0 in [logC0_start, logC0_stop]] + )) result = optimize.brentq(self.obj_delta_y, logC0_start, logC0_stop, args=(x1, x2, reflection, reflection_case)) C_0 = self.get_C0_from_log(result) @@ -1821,6 +1838,7 @@ class describing the index-of-refraction profile detector=detector) self.set_config(config=config) + self.use_cpp = use_cpp if use_cpp: self.__logger.debug(f"using CPP version of ray tracer") else: @@ -2179,10 +2197,13 @@ def get_focusing(self, iS, dz=-1. * units.cm, limit=2.): focusing: float gain of the signal at the receiver due to the focusing effect """ + self.__logger.warning("We're trying to focus here!") recVec = self.get_receive_vector(iS) recVec = -1.0 * recVec + # recAng = np.arcsin(recVec[2] / np.linalg.norm(recVec)) recAng = np.arccos(recVec[2] / np.sqrt(recVec[0] ** 2 + recVec[1] ** 2 + recVec[2] ** 2)) lauVec = self.get_launch_vector(iS) + # lauAng = np.arcsin(lauVec[2] / np.linalg.norm(lauVec)) lauAng = np.arccos(lauVec[2] / np.sqrt(lauVec[0] ** 2 + lauVec[1] ** 2 + lauVec[2] ** 2)) distance = self.get_path_length(iS) # we need to be careful here. If X1 (the emitter) is above the X2 (the receiver) the positions are swapped @@ -2198,19 +2219,25 @@ def get_focusing(self, iS, dz=-1. * units.cm, limit=2.): recPos1 = np.array([self._X2[0], self._X2[1], self._X2[2] + dz]) if not hasattr(self, "_r1"): self._r1 = ray_tracing(self._medium, self._attenuation_model, logging.WARNING, - self._n_frequencies_integration, self._n_reflections) + self._n_frequencies_integration, self._n_reflections, use_cpp=self.use_cpp) self._r1.set_start_and_end_point(vetPos, recPos1) self._r1.find_solutions() if iS < self._r1.get_number_of_solutions(): lauVec1 = self._r1.get_launch_vector(iS) + # lauAng1 = np.arcsin(lauVec1[2] / np.linalg.norm(lauVec1)) lauAng1 = np.arccos(lauVec1[2] / np.sqrt(lauVec1[0] ** 2 + lauVec1[1] ** 2 + lauVec1[2] ** 2)) + self.__logger.warning( + "focusing: receive angle {:.2f} / launch angle {:.2f} / d_launch_angle {:.4f}".format( + recAng / units.deg, lauAng / units.deg, (lauAng1-lauAng) / units.deg + ) + ) focusing = np.sqrt(distance / np.sin(recAng) * np.abs((lauAng1 - lauAng) / (recPos1[2] - recPos[2]))) if (self.get_results()[iS]['reflection'] != self._r1.get_results()[iS]['reflection'] or self.get_results()[iS]['reflection_case'] != self._r1.get_results()[iS]['reflection_case']): self.__logger.error("Number or type of reflections are different between solutions - focusing correction may not be reliable.") else: focusing = 1.0 - self.__logger.info("too few ray tracing solutions, setting focusing factor to 1") + self.__logger.warning("too few ray tracing solutions, setting focusing factor to 1") self.__logger.debug(f'amplification due to focusing of solution {iS:d} = {focusing:.3f}') if(focusing > limit): self.__logger.info(f"amplification due to focusing is {focusing:.1f}x -> limiting amplification factor to {limit:.1f}x") From 87bd2bbcd02a405f0f250180fbb426d888d322f1 Mon Sep 17 00:00:00 2001 From: Sjoerd Bouma Date: Tue, 22 Aug 2023 18:09:47 +0200 Subject: [PATCH 333/418] forgot to change one logger output to debug [ci skip] --- NuRadioMC/SignalProp/analyticraytracing.py | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/NuRadioMC/SignalProp/analyticraytracing.py b/NuRadioMC/SignalProp/analyticraytracing.py index 759156a11..0b0f7acda 100644 --- a/NuRadioMC/SignalProp/analyticraytracing.py +++ b/NuRadioMC/SignalProp/analyticraytracing.py @@ -1264,9 +1264,6 @@ def find_solutions(self, x1, x2, plot=False, reflection=0, reflection_case=1): # skims the surface. Therefore, we can find the solution using an efficient root finding algorithm. logC0_start = 1 # infinity is bad, 1 is steep enough C_0_stop = self.get_C_0_from_angle(np.arcsin(1/self.medium.get_index_of_refraction([0, x1[0], x1[1]])), x1[1]).x[0] - # C_0_stop, th_start = self.get_surf_skim_angle(x1) - # C_0_stop *= (1-1e-8) # for some reason, the get_surf_skim_angle function does not give the correct angle. The launch angle - # # needs to be slightly steeper logC0_stop = np.log(C_0_stop - 1/self.medium.n_ice) self.__logger.warning( "C0: {}, {} start: {} stop: {}".format( @@ -2197,13 +2194,10 @@ def get_focusing(self, iS, dz=-1. * units.cm, limit=2.): focusing: float gain of the signal at the receiver due to the focusing effect """ - self.__logger.warning("We're trying to focus here!") recVec = self.get_receive_vector(iS) recVec = -1.0 * recVec - # recAng = np.arcsin(recVec[2] / np.linalg.norm(recVec)) recAng = np.arccos(recVec[2] / np.sqrt(recVec[0] ** 2 + recVec[1] ** 2 + recVec[2] ** 2)) lauVec = self.get_launch_vector(iS) - # lauAng = np.arcsin(lauVec[2] / np.linalg.norm(lauVec)) lauAng = np.arccos(lauVec[2] / np.sqrt(lauVec[0] ** 2 + lauVec[1] ** 2 + lauVec[2] ** 2)) distance = self.get_path_length(iS) # we need to be careful here. If X1 (the emitter) is above the X2 (the receiver) the positions are swapped @@ -2224,9 +2218,8 @@ def get_focusing(self, iS, dz=-1. * units.cm, limit=2.): self._r1.find_solutions() if iS < self._r1.get_number_of_solutions(): lauVec1 = self._r1.get_launch_vector(iS) - # lauAng1 = np.arcsin(lauVec1[2] / np.linalg.norm(lauVec1)) lauAng1 = np.arccos(lauVec1[2] / np.sqrt(lauVec1[0] ** 2 + lauVec1[1] ** 2 + lauVec1[2] ** 2)) - self.__logger.warning( + self.__logger.debug( "focusing: receive angle {:.2f} / launch angle {:.2f} / d_launch_angle {:.4f}".format( recAng / units.deg, lauAng / units.deg, (lauAng1-lauAng) / units.deg ) From 5cebd1a03941fbfdcb63412d4beb5d93f974506c Mon Sep 17 00:00:00 2001 From: Alan Coleman <74733466+colemanalan@users.noreply.github.com> Date: Wed, 23 Aug 2023 16:31:45 +0200 Subject: [PATCH 334/418] Fixed small comparison (#561) * Fixed comparison --- NuRadioReco/modules/analogToDigitalConverter.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NuRadioReco/modules/analogToDigitalConverter.py b/NuRadioReco/modules/analogToDigitalConverter.py index 528666cf8..5fcd9b30d 100644 --- a/NuRadioReco/modules/analogToDigitalConverter.py +++ b/NuRadioReco/modules/analogToDigitalConverter.py @@ -296,7 +296,7 @@ def get_digital_trace(self, station, det, channel, if trigger_filter is not None: trace_fft = np.fft.rfft(trace) - if(len(trace_fft) != trigger_filter): + if len(trace_fft) != len(trigger_filter): raise ValueError("Wrong filter length to apply to traces") trace = np.fft.irfft(trace_fft * trigger_filter) From b6df25fb6762c00c4020360dd0724d4c393f83dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Mon, 28 Aug 2023 11:27:20 +0200 Subject: [PATCH 335/418] Fix call of __new__ method --- .../detector/detector_browser/detector_provider.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/NuRadioReco/detector/detector_browser/detector_provider.py b/NuRadioReco/detector/detector_browser/detector_provider.py index 004acaf21..61ca880f4 100644 --- a/NuRadioReco/detector/detector_browser/detector_provider.py +++ b/NuRadioReco/detector/detector_browser/detector_provider.py @@ -29,8 +29,9 @@ def set_detector(self, filename, assume_inf, antenna_by_depth): filename: string Path to the .json file containing the detector description """ - self.__detector = NuRadioReco.detector.detector.Detector.__new__(NuRadioReco.detector.detector.Detector) - self.__detector.__init__(source='json', json_filename=filename, assume_inf=assume_inf, antenna_by_depth=antenna_by_depth) + self.__detector = NuRadioReco.detector.detector.Detector.__new__( + NuRadioReco.detector.detector.Detector, source='json', json_filename=filename, assume_inf=assume_inf, + antenna_by_depth=antenna_by_depth) def set_generic_detector(self, filename, default_station, default_channel, assume_inf, antenna_by_depth): """ @@ -46,8 +47,9 @@ def set_generic_detector(self, filename, default_station, default_channel, assum ID of the channel to be set as default channel """ import NuRadioReco.detector.generic_detector - self.__detector = NuRadioReco.detector.generic_detector.GenericDetector.__new__(NuRadioReco.detector.generic_detector.GenericDetector) - self.__detector.__init__(filename, default_station, default_channel, assume_inf=assume_inf, antenna_by_depth=antenna_by_depth) + self.__detector = NuRadioReco.detector.generic_detector.GenericDetector.__new__( + NuRadioReco.detector.generic_detector.GenericDetector, filename, default_station, + default_channel, assume_inf=assume_inf, antenna_by_depth=antenna_by_depth) def set_event_file(self, filename): """ From dbe19e38688e8330d8613e85792f3c1bc4c4f57e Mon Sep 17 00:00:00 2001 From: Sjoerd Bouma Date: Mon, 28 Aug 2023 14:37:18 +0200 Subject: [PATCH 336/418] add kwarg in_air get_y_diff and other ray tracing functions to distinguish ice-to-air case --- NuRadioMC/SignalProp/analyticraytracing.py | 39 +++++++++++----------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/NuRadioMC/SignalProp/analyticraytracing.py b/NuRadioMC/SignalProp/analyticraytracing.py index 0b0f7acda..3fb6140c0 100644 --- a/NuRadioMC/SignalProp/analyticraytracing.py +++ b/NuRadioMC/SignalProp/analyticraytracing.py @@ -248,7 +248,7 @@ def get_y(self, gamma, C_0, C_1): result = self.medium.z_0 * (self.medium.n_ice ** 2 * C_0 ** 2 - 1) ** -0.5 * np.log(logargument) + C_1 return result - def get_y_diff(self, z_raw, C_0): + def get_y_diff(self, z_raw, C_0, in_air=False): """ derivative dy(z)/dz """ @@ -256,11 +256,11 @@ def get_y_diff(self, z_raw, C_0): # if we are above the ice surface, the analytic expression below # does not apply. Therefore, we instead calculate dy/dz at z=0 where it is still valid # and then correct this using Snell's law - if z_raw > 0: # we are above the ice surface, where the below expression does not apply - z_raw_copy = copy.copy(z_raw) - z_raw = 0 + if (not in_air) or (z_raw < 0): + z = self.get_z_unmirrored(z_raw, C_0) + else: # we are above the ice surface, where the below expression does not apply + z = 0 correct_for_air = True - z = self.get_z_unmirrored(z_raw, C_0) c = self.medium.n_ice ** 2 - C_0 ** -2 B = (0.2e1 * np.sqrt(c) * np.sqrt(-self.__b * self.medium.delta_n * np.exp(z / self.medium.z_0) + self.medium.delta_n ** 2 * np.exp(0.2e1 * z / self.medium.z_0) + c) - self.__b * self.medium.delta_n * np.exp(z / self.medium.z_0) + 0.2e1 * c) @@ -271,11 +271,10 @@ def get_y_diff(self, z_raw, C_0): res = (-np.sqrt(c) * np.exp(z / self.medium.z_0) * self.__b * self.medium.delta_n + 0.2e1 * np.sqrt(-self.__b * self.medium.delta_n * np.exp(z / self.medium.z_0) + self.medium.delta_n ** 2 * np.exp(0.2e1 * z / self.medium.z_0) + c) * c + 0.2e1 * c ** 1.5) / B * E ** -0.5 * (D ** (-0.5)) if correct_for_air: - n_surface = self.medium.get_index_of_refraction([0,0,0]) + n_surface = self.n(0) theta_ice = np.arctan(res) theta_air = np.arcsin(n_surface * np.sin(theta_ice)) res = np.tan(theta_air) - z_raw = z_raw_copy if(z != z_raw): res *= -1 return res @@ -865,7 +864,7 @@ def get_path_segments(self, x1, x2, C_0, reflection=0, reflection_case=1): x1 = x2 return tmp - def get_angle(self, x, x_start, C_0, reflection=0, reflection_case=1): + def get_angle(self, x, x_start, C_0, reflection=0, reflection_case=1, in_air=False): """ calculates the angle with respect to the positive z-axis of the ray path at position x @@ -890,17 +889,17 @@ def get_angle(self, x, x_start, C_0, reflection=0, reflection_case=1): x_start = last_segment[1] z = self.get_z_mirrored(x_start, x, C_0)[1] - dy = self.get_y_diff(z, C_0) + dy = self.get_y_diff(z, C_0, in_air=in_air) angle = np.arctan(dy) if(angle < 0): angle = np.pi + angle return angle def get_launch_angle(self, x1, C_0, reflection=0, reflection_case=1): - return self.get_angle(x1, x1, C_0, reflection, reflection_case) + return self.get_angle(x1, x1, C_0, reflection, reflection_case, in_air=x1[1]>0) def get_receive_angle(self, x1, x2, C_0, reflection=0, reflection_case=1): - return np.pi - self.get_angle(x2, x1, C_0, reflection, reflection_case) + return np.pi - self.get_angle(x2, x1, C_0, reflection, reflection_case, in_air=x2[1]>0) def get_reflection_angle(self, x1, x2, C_0, reflection=0, reflection_case=1): """ @@ -931,7 +930,7 @@ def get_reflection_angle(self, x1, x2, C_0, reflection=0, reflection_case=1): gamma_turn, z_turn = self.get_turning_point(c) y_turn = self.get_y_turn(C_0, x1) if((z_turn >= 0) and (y_turn > x11[0]) and (y_turn < x22[0])): # for the first track segment we need to check if turning point is right of start point (otherwise we have a downward going ray that does not have a turning point), and for the last track segment we need to check that the turning point is left of the stop position. - r = self.get_angle(np.array([y_turn, 0]), x1, C_0) + r = self.get_angle(np.array([y_turn, 0]), x1, C_0, in_air=(x2[1]>0)) self.__logger.debug( "reflecting off surface at y = {:.1f}m, reflection angle = {:.1f}deg".format(y_turn, r / units.deg)) output.append(r) @@ -1265,8 +1264,8 @@ def find_solutions(self, x1, x2, plot=False, reflection=0, reflection_case=1): logC0_start = 1 # infinity is bad, 1 is steep enough C_0_stop = self.get_C_0_from_angle(np.arcsin(1/self.medium.get_index_of_refraction([0, x1[0], x1[1]])), x1[1]).x[0] logC0_stop = np.log(C_0_stop - 1/self.medium.n_ice) - self.__logger.warning( - "C0: {}, {} start: {} stop: {}".format( + self.__logger.debug( + "Looking for ice-air solutions between C0 ({}, {}) with delta_y ({}, {})".format( logC0_start, logC0_stop, *[self.obj_delta_y(logC0, x1, x2, reflection, reflection_case) for logC0 in [logC0_start, logC0_stop]] )) result = optimize.brentq(self.obj_delta_y, logC0_start, logC0_stop, args=(x1, x2, reflection, reflection_case)) @@ -1389,11 +1388,11 @@ def plot_result(self, x1, x2, C_0, ax): # ax.plot(x2[1], x2[0], 'd') ax.legend() - def get_angle_from_C_0(self, C_0, z_pos, angoff=0): + def get_angle_from_C_0(self, C_0, z_pos, angoff=0, in_air=False): logC_0 = np.log(C_0 - 1. / self.medium.n_ice) - return self.get_angle_from_logC_0(logC_0, z_pos, angoff) + return self.get_angle_from_logC_0(logC_0, z_pos, angoff, in_air=in_air) - def get_angle_from_logC_0(self, logC_0, z_pos, angoff=0): + def get_angle_from_logC_0(self, logC_0, z_pos, angoff=0, in_air=False): ''' argument angoff is provided so that the function can be used for minimization in get_C_0_from_angle(), @@ -1416,7 +1415,7 @@ def get_angle_from_logC_0(self, logC_0, z_pos, angoff=0): C_0 = self.get_C0_from_log(logC_0) - dydz = self.get_y_diff(z_pos, C_0) + dydz = self.get_y_diff(z_pos, C_0, in_air=in_air) # dydz = self.get_dydz_analytic(C_0, z_pos) angle = np.arctan(dydz) @@ -1424,7 +1423,7 @@ def get_angle_from_logC_0(self, logC_0, z_pos, angoff=0): return angle - angoff - def get_C_0_from_angle(self, anglaunch, z_pos): + def get_C_0_from_angle(self, anglaunch, z_pos, in_air=False): ''' Find parameter C0 corresponding to a given launch angle and z-position of a ray. @@ -1447,7 +1446,7 @@ def get_C_0_from_angle(self, anglaunch, z_pos): logC_0_start = np.log(C_0_start - 1. / self.medium.n_ice) # result = optimize.root(self.get_angle_from_C_0,np.pi/4.,args=(z_pos,anglaunch)) - result = optimize.root(self.get_angle_from_logC_0, logC_0_start, args=(z_pos, anglaunch)) + result = optimize.root(self.get_angle_from_logC_0, logC_0_start, args=(z_pos, anglaunch, 0, in_air)) # want to return the complete instance of the result class; result value result.x[0] is logC_0, # but we want C_0, so replace it in the result class. This may not be good practice but it seems to be From 713cee27746ceb2bcae386a077a889f44a83899c Mon Sep 17 00:00:00 2001 From: Mitja Desmet Date: Tue, 29 Aug 2023 10:46:43 +0200 Subject: [PATCH 337/418] Fixed raise statements and PEP8 compliance --- NuRadioReco/detector/generic_detector.py | 122 ++++++++++++++--------- 1 file changed, 75 insertions(+), 47 deletions(-) diff --git a/NuRadioReco/detector/generic_detector.py b/NuRadioReco/detector/generic_detector.py index a26d3ebcb..06ab2cb62 100644 --- a/NuRadioReco/detector/generic_detector.py +++ b/NuRadioReco/detector/generic_detector.py @@ -24,7 +24,7 @@ class GenericDetector(NuRadioReco.detector.detector_base.DetectorBase): also be defined. The default channel has to be part of the default station. It works the same way as the default station: Any property missing from one of the other channels will be taken from the default channel. - The GenericDetector also ignores commission and decommision times and should + The GenericDetector also ignores commission and decommission times and should therefore not be used for real data, but only for simulation studies. This detector only accepts json detector descriptions or dictionary. """ @@ -73,7 +73,7 @@ def __init__(self, json_filename, default_station=None, default_channel=None, de If 'dictionary' is passed to the parameter source, the dictionary passed to this parameter will be used for the detector description. assume_inf : Bool - Default to True, if true forces antenna madels to have infinite boundary conditions, otherwise the antenna + Default to True, if true forces antenna models to have infinite boundary conditions, otherwise the antenna madel will be determined by the station geometry. antenna_by_depth: bool (default True) if True the antenna model is determined automatically depending on the depth of the antenna. @@ -86,50 +86,72 @@ def __init__(self, json_filename, default_station=None, default_channel=None, de if (default_station is None) and (default_channel is None) and (default_device is None): # load detector super(GenericDetector, self).__init__(source=source, json_filename=json_filename, - dictionary=dictionary, assume_inf=assume_inf, - antenna_by_depth=antenna_by_depth) + dictionary=dictionary, assume_inf=assume_inf, + antenna_by_depth=antenna_by_depth) else: if source == "json": - # load json as dictionary and pass that to the detector, this is needed in order to not overwrite the json - # when updating the table to include reference_station/channel/device + # load json as dictionary and pass that to the detector, this is needed in order to not overwrite the + # json when updating the table to include reference_station/channel/device with open(json_filename, "r") as json_input: dictionary = json.load(json_input) super(GenericDetector, self).__init__(source="dictionary", json_filename=None, - dictionary=dictionary, assume_inf=assume_inf, - antenna_by_depth=antenna_by_depth) + dictionary=dictionary, assume_inf=assume_inf, + antenna_by_depth=antenna_by_depth) if default_station is not None: - logger.warning("DeprecationWarning: replace default_station by setting a 'reference_station' for each station in the detector description. This allows to define multiple default station types") + logger.warning( + "DeprecationWarning: replace default_station by setting a 'reference_station' for each station in " + "the detector description. This allows to define multiple default station types") # fill default station info into 'reference_station' field for all stations in detector for sta in self._stations: if 'reference_station' in sta.keys(): - logger.warning(f"Station already has a reference station {sta['reference_station']}. Ignoring deprecated 'default_station'") + logger.warning( + f"Station already has a reference station {sta['reference_station']}. Ignoring deprecated " + f"'default_station'") else: - logger.warning(f"Setting deprecated 'default_station' as reference station ({default_station}) as requested") + logger.warning( + f"Setting deprecated 'default_station' as reference station ({default_station}) " + f"as requested") Station = Query() - self._stations.update({'reference_station': default_station}, (Station.station_id == sta["station_id"])) + self._stations.update({'reference_station': default_station}, + (Station.station_id == sta["station_id"])) if default_channel is not None: - logger.warning("DeprecationWarning: replace default_channel by setting a 'reference_channel' for each channel in the detector description. This allows to define multiple default channel types") + logger.warning( + "DeprecationWarning: replace default_channel by setting a 'reference_channel' for each channel in " + "the detector description. This allows to define multiple default channel types") # fill default channel info into 'reference_channel' field for all channels in detector for chan in self._channels: if 'reference_channel' in chan.keys(): - logger.warning(f"Channel already has a reference channel {chan['reference_channel']}. Ignoring deprecated 'default_channel'") + logger.warning( + f"Channel already has a reference channel {chan['reference_channel']}. Ignoring " + f"deprecated 'default_channel'") else: - logger.warning(f"Setting deprecated 'default_channel' as reference channel ({default_channel}) as requested") + logger.warning( + f"Setting deprecated 'default_channel' as reference channel ({default_channel}) " + f"as requested") Channel = Query() - self._channels.update({'reference_channel': default_channel}, (Channel.station_id == chan["station_id"]) & (Channel.channel_id == chan["channel_id"])) + self._channels.update({'reference_channel': default_channel}, + (Channel.station_id == chan["station_id"]) & ( + Channel.channel_id == chan["channel_id"])) if default_device is not None: - logger.warning("DeprecationWarning: replace default_device by setting a 'reference_device' for each device in the detector description. This allows to define multiple default device types") + logger.warning( + "DeprecationWarning: replace default_device by setting a 'reference_device' for each device in " + "the detector description. This allows to define multiple default device types") # fill default device info into 'reference_device' field for all devices in detector for dev in self._buffered_devices: if 'reference_device' in dev.keys(): - logger.warning(f"Device already has a reference device {dev['reference_device']}. Ignoring deprecated 'default_device'") + logger.warning( + f"Device already has a reference device {dev['reference_device']}. Ignoring deprecated " + f"'default_device'") else: - logger.warning(f"Setting deprecated 'default_device' as reference device ({default_device}) as requested") + logger.warning( + f"Setting deprecated 'default_device' as reference device ({default_device}) as requested") Device = Query() - self._devices.update({'reference_device': default_device}, (Device.station_id == dev["station_id"]) & (Device.device_id == dev["device_id"])) + self._devices.update({'reference_device': default_device}, + (Device.station_id == dev["station_id"]) & ( + Device.device_id == dev["device_id"])) self.__default_station = default_station # TODO maybe these dicts/lists can be omitted # a lookup with one reference station for each station in the detector description @@ -144,7 +166,8 @@ def __init__(self, json_filename, default_station=None, default_channel=None, de self.__reference_stations = {} Station = Query() for reference_station_id in self.__reference_station_ids: - self.__reference_stations[reference_station_id] = self._stations.get((Station.station_id == reference_station_id)) + self.__reference_stations[reference_station_id] = self._stations.get( + (Station.station_id == reference_station_id)) self.__station_changes_for_event = [] self.__run_number = None @@ -155,32 +178,31 @@ def __init__(self, json_filename, default_station=None, default_channel=None, de for sta in self._stations.all(): if "reference_station" in sta: ref = self._stations.get( - (Station.station_id == sta["reference_station"])) + (Station.station_id == sta["reference_station"])) if ref is None: raise ValueError( 'The reference station {} was not found in the detector description'.format( - ref["reference_station"])) + sta["reference_station"])) Channel = Query() for chan in self._channels.all(): if "reference_channel" in chan: ref = self._channels.get( - (Channel.station_id == chan["station_id"]) & (Channel.channel_id == chan["reference_channel"])) + (Channel.station_id == chan["station_id"]) & (Channel.channel_id == chan["reference_channel"])) if ref is None: raise ValueError( 'The reference channel {} of station {} was not found in the detector description'.format( - ref["reference_channel"], ref["station_id"])) + chan["reference_channel"], chan["station_id"])) Device = Query() for dev in self._devices.all(): - if "reference_device" in dev: - ref = self._devices.get( + if "reference_device" in dev: + ref = self._devices.get( (Device.station_id == dev["station_id"]) & (Device.channel_id == dev["reference_device"])) - if ref is None: - raise ValueError( - 'The reference device {} of station {} was not found in the detector description'.format( - ref["reference_device"], ref["station_id"])) - + if ref is None: + raise ValueError( + 'The reference device {} of station {} was not found in the detector description'.format( + dev["reference_device"], dev["station_id"])) def _get_station(self, station_id): if station_id not in self._buffered_stations.keys(): @@ -188,7 +210,9 @@ def _get_station(self, station_id): res = copy.copy(self._buffered_stations[station_id]) if self.__run_number is not None and self.__event_id is not None: for change in self.__station_changes_for_event: - if change['station_id'] == station_id and change['run_number'] == self.__run_number and change['event_id'] == self.__event_id: + if change['station_id'] == station_id and \ + change['run_number'] == self.__run_number and \ + change['event_id'] == self.__event_id: for name, value in change['properties'].items(): res[name] = value return res @@ -228,14 +252,16 @@ def _query_channels(self, station_id, raw=False): new_channel['station_id'] = station_id res.append(new_channel) - # now we look if there are reference fields to fill. Will use reference_station_id, which is either the station or the reference + # now we look if there are reference fields to fill. Will use reference_station_id, which is either the + # station or the reference for channel in res: if 'reference_channel' in channel: # add to dictionary to keep track of reference channels TODO this is not really needed? self.__reference_channel_ids[(station_id, channel['channel_id'])] = channel['reference_channel'] # there is a reference, so we have to get it ref_chan = self._channels.get( - (Channel.station_id == reference_station_id) & (Channel.channel_id == channel['reference_channel'])) + (Channel.station_id == reference_station_id) & ( + Channel.channel_id == channel['reference_channel'])) for key in ref_chan.keys(): if key not in channel.keys() and key != 'station_id' and key != 'channel_id': channel[key] = ref_chan[key] @@ -262,14 +288,15 @@ def _query_devices(self, station_id, raw=False): new_device['station_id'] = station_id res.append(new_device) - # now we look if there are reference fields to fill. Will use reference_station_id, which is either the station or the reference + # now we look if there are reference fields to fill. Will use reference_station_id, which is either the + # station or the reference for device in res: if 'reference_device' in device: # add to dictionary to keep track of reference devices TODO this is not really needed? self.__reference_device_ids[(station_id, device['device_id'])] = device['reference_device'] # there is a reference, so we have to get it ref_dev = self._devices.get( - (Device.station_id == reference_station_id) & (Device.device_id == device['reference_device'])) + (Device.station_id == reference_station_id) & (Device.device_id == device['reference_device'])) for key in ref_dev.keys(): if key not in device.keys() and key != 'station_id' and key != 'device_id': device[key] = ref_dev[key] @@ -313,11 +340,14 @@ def add_generic_station(self, station_dict): reference station """ if "reference_station" not in station_dict and self.__default_station is not None: - logger.warning('DeprecationWarning: Generating a station via `add_generic_station` that has no "reference_station" specified.') - logger.warning(f'DeprecationWarning: Taking the deprecated "default_station" ({self.__default_station}) as "reference_station".') + logger.warning( + 'DeprecationWarning: Generating a station via `add_generic_station` that has no "reference_station" ' + 'specified.') + logger.warning( + f'DeprecationWarning: Taking the deprecated "default_station" ({self.__default_station}) as ' + f'"reference_station".') station_dict["reference_station"] = self.__default_station - if station_dict['station_id'] in self._buffered_stations.keys(): logger.warning('Station with ID {} already exists in buffer. Cannot add station with same ID'.format( station_dict['station_id'])) @@ -347,7 +377,6 @@ def add_generic_station(self, station_dict): new_device['station_id'] = station_dict['station_id'] self._buffered_devices[station_dict['station_id']][device['device_id']] = new_device - def add_station_properties_for_event(self, properties, station_id, run_number, event_id): """ Adds an entry to the list of event-specific changes to the detector @@ -423,7 +452,7 @@ def get_reference_station_id(self, station_id): """ Get the properties of the reference station """ - return self.__reference_station_ids[station_id] + return self.__reference_station_ids[station_id] def get_reference_stations(self): """ @@ -439,7 +468,7 @@ def get_default_station(self): def get_reference_station_ids(self): """ - Get the whole diectionary of reference stations + Get the whole dictionary of reference stations """ return self.__reference_station_ids @@ -455,22 +484,21 @@ def get_default_station_id(self): logger.warning( f'more than one station id set as "reference station": {self.__reference_station_ids},\ continue with first entry: {self.__reference_station_ids[0]}') - return self.__reference_station_ids[0] + return self.__reference_station_ids[0] def get_default_channel(self): """ Get the properties of the default channel """ logger.warning("The use of 'default_channel' is deprecated. returning None") - return None #self.__default_channel + return None # self.__default_channel def get_default_channel_id(self): """ Get the ID of the default channel """ logger.warning("The use of 'default_channel' is deprecated. returning None") - return None #self.__default_channel_id - + return None # self.__default_channel_id def get_raw_station(self, station_id): """ From e139231d70ce172da8a7899cdefe1e54a32ac561 Mon Sep 17 00:00:00 2001 From: Mitja Desmet Date: Tue, 29 Aug 2023 12:50:22 +0200 Subject: [PATCH 338/418] Check for reference channel in reference station if not found --- NuRadioReco/detector/generic_detector.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/NuRadioReco/detector/generic_detector.py b/NuRadioReco/detector/generic_detector.py index 06ab2cb62..84e163f8a 100644 --- a/NuRadioReco/detector/generic_detector.py +++ b/NuRadioReco/detector/generic_detector.py @@ -190,9 +190,16 @@ def __init__(self, json_filename, default_station=None, default_channel=None, de ref = self._channels.get( (Channel.station_id == chan["station_id"]) & (Channel.channel_id == chan["reference_channel"])) if ref is None: - raise ValueError( - 'The reference channel {} of station {} was not found in the detector description'.format( - chan["reference_channel"], chan["station_id"])) + # Check if reference channel sits in reference station + reference_station_id = self.__lookuptable_reference_station[chan["station_id"]] + ref = self._channels.get( + (Channel.station_id == reference_station_id) & + (Channel.channel_id == chan["reference_channel"]) + ) + if ref is None: + raise ValueError( + 'The reference channel {} of station {} was not found in the detector description'.format( + chan["reference_channel"], chan["station_id"])) Device = Query() for dev in self._devices.all(): From 57f5a44c9efc5e57f1d8fd0b28859a089c34ed5e Mon Sep 17 00:00:00 2001 From: Sjoerd Bouma Date: Wed, 30 Aug 2023 12:11:58 +0200 Subject: [PATCH 339/418] forgot to pass through optional kwarg --- NuRadioReco/modules/RNO_G/channelBlockOffsetFitter.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/NuRadioReco/modules/RNO_G/channelBlockOffsetFitter.py b/NuRadioReco/modules/RNO_G/channelBlockOffsetFitter.py index da0cd3e37..130aed3df 100644 --- a/NuRadioReco/modules/RNO_G/channelBlockOffsetFitter.py +++ b/NuRadioReco/modules/RNO_G/channelBlockOffsetFitter.py @@ -138,7 +138,8 @@ def remove_offsets(self, event, station, mode='fit', channel_ids=None): block_offsets = fit_block_offsets( trace, self.block_size, - channel.get_sampling_rate(), self._max_frequency + channel.get_sampling_rate(), self._max_frequency, + mode=mode ) offsets[channel_id] = -block_offsets From 27b4530ffcebb20c7cea89892b84e2a4d27784c0 Mon Sep 17 00:00:00 2001 From: Mitja Desmet Date: Wed, 30 Aug 2023 17:23:53 +0200 Subject: [PATCH 340/418] Updated changelog.txt --- changelog.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/changelog.txt b/changelog.txt index 367f7063f..e11f84c4b 100644 --- a/changelog.txt +++ b/changelog.txt @@ -9,6 +9,8 @@ new features: - add uniform ice model with 1.78 refractive index bugfixes: +- updated reference channel check in GenericDetector to look into the reference station when the channel +is not found in the current station version 2.1.6 From d48a0ef09b43ef2c4a0e6b1c9319419cfa17df88 Mon Sep 17 00:00:00 2001 From: Sjoerd Bouma Date: Fri, 1 Sep 2023 02:03:49 +0200 Subject: [PATCH 341/418] remove spurious in_air argument for reflection angle --- NuRadioMC/SignalProp/analyticraytracing.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/NuRadioMC/SignalProp/analyticraytracing.py b/NuRadioMC/SignalProp/analyticraytracing.py index 3fb6140c0..436d6fcd6 100644 --- a/NuRadioMC/SignalProp/analyticraytracing.py +++ b/NuRadioMC/SignalProp/analyticraytracing.py @@ -888,7 +888,10 @@ def get_angle(self, x, x_start, C_0, reflection=0, reflection_case=1, in_air=Fal last_segment = self.get_path_segments(x_start, x, C_0, reflection, reflection_case)[-1] x_start = last_segment[1] - z = self.get_z_mirrored(x_start, x, C_0)[1] + if in_air: + z = x[1] + else: + z = self.get_z_mirrored(x_start, x, C_0)[1] dy = self.get_y_diff(z, C_0, in_air=in_air) angle = np.arctan(dy) if(angle < 0): @@ -930,7 +933,7 @@ def get_reflection_angle(self, x1, x2, C_0, reflection=0, reflection_case=1): gamma_turn, z_turn = self.get_turning_point(c) y_turn = self.get_y_turn(C_0, x1) if((z_turn >= 0) and (y_turn > x11[0]) and (y_turn < x22[0])): # for the first track segment we need to check if turning point is right of start point (otherwise we have a downward going ray that does not have a turning point), and for the last track segment we need to check that the turning point is left of the stop position. - r = self.get_angle(np.array([y_turn, 0]), x1, C_0, in_air=(x2[1]>0)) + r = self.get_angle(np.array([y_turn, 0]), x1, C_0) self.__logger.debug( "reflecting off surface at y = {:.1f}m, reflection angle = {:.1f}deg".format(y_turn, r / units.deg)) output.append(r) @@ -1446,7 +1449,7 @@ def get_C_0_from_angle(self, anglaunch, z_pos, in_air=False): logC_0_start = np.log(C_0_start - 1. / self.medium.n_ice) # result = optimize.root(self.get_angle_from_C_0,np.pi/4.,args=(z_pos,anglaunch)) - result = optimize.root(self.get_angle_from_logC_0, logC_0_start, args=(z_pos, anglaunch, 0, in_air)) + result = optimize.root(self.get_angle_from_logC_0, logC_0_start, args=(z_pos, anglaunch, in_air)) # want to return the complete instance of the result class; result value result.x[0] is logC_0, # but we want C_0, so replace it in the result class. This may not be good practice but it seems to be From 94cb5a92d3d193eebc11eda47c44ba418c67c0bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Tue, 5 Sep 2023 20:20:49 +0200 Subject: [PATCH 342/418] This allows to specify root files to be read with the mattak reader instead of directories. Because the mattak library can not handle this so far we have to employ some diry hack. Create a temp directory and link the file in question to a the file combined.root within the directory. Simple and naive housekeeing included --- .../modules/io/RNO_G/readRNOGDataMattak.py | 54 +++++++++++++++---- 1 file changed, 43 insertions(+), 11 deletions(-) diff --git a/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py b/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py index db2835ecb..17246eec1 100644 --- a/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py +++ b/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py @@ -15,6 +15,18 @@ from NuRadioReco.utilities import units import mattak.Dataset +import string +import random + +def create_random_directory_path(prefix="/tmp/", n=7): + + # using random.choices() + # generating random strings + res = ''.join(random.choices(string.ascii_lowercase + string.digits, k=n)) + path = os.path.join(prefix, "readRNOGData_" + res) + + return path + def baseline_correction(wfs, n_bins=128, func=np.median): """ @@ -152,6 +164,8 @@ def __init__(self, run_table_path=None, log_level=logging.INFO): # Initialize run table for run selection self.__run_table = None + + self.__temporary_dirs = [] if run_table_path is None: try: @@ -310,14 +324,28 @@ def begin(self, if not all_files_in_directory(dir_file): self.logger.error(f"Incomplete directory: {dir_file}. Skip ...") continue - - try: - dataset = mattak.Dataset.Dataset(station=0, run=0, data_dir=dir_file, verbose=verbose, **mattak_kwargs) - except (ReferenceError, KeyError) as e: - self.logger.error(f"The following exeption was raised reading in the run: {dir_file}. Skip that run ...:\n", exc_info=e) - continue else: - raise NotImplementedError("The option to read in files is not implemented yet") + + path = create_random_directory_path() + self.logger.debug(f"Create temporary directory: {path}") + if os.path.exists(path): + raise ValueError(f"Temporary directory {path} already exists.") + + os.mkdir(path) + self.__temporary_dirs.append(path) + + self.logger.debug(f"Create symlink for {dir_file}") + os.symlink(dir_file, os.path.join(path, "combined.root")) + + dir_file = path + + # raise NotImplementedError("The option to read in files is not implemented yet") + + try: + dataset = mattak.Dataset.Dataset(station=0, run=0, data_dir=dir_file, verbose=verbose, **mattak_kwargs) + except (ReferenceError, KeyError) as e: + self.logger.error(f"The following exeption was raised reading in the run: {dir_file}. Skip that run ...:\n", exc_info=e) + continue # filter runs/datasets based on @@ -557,8 +585,7 @@ def _check_for_valid_information_in_event_info(self, event_info): is_valid: bool Returns True if all information valid, false otherwise """ - - + if math.isinf(event_info.triggerTime): self.logger.error(f"Event {event_info.eventNumber} (st {event_info.station}, run {event_info.run}) " "has inf trigger time. Skip event...") @@ -568,7 +595,7 @@ def _check_for_valid_information_in_event_info(self, event_info): if (event_info.sampleRate == 0 or event_info.sampleRate is None) and self._overwrite_sampling_rate is None: self.logger.error(f"Event {event_info.eventNumber} (st {event_info.station}, run {event_info.run}) " - f"has a sampling rate of {event_info.sampleRate:.2f} GHz. Event is skipped ... " + f"has a sampling rate of {event_info.sampleRate} GHz. Event is skipped ... " f"You can avoid this by setting 'overwrite_sampling_rate' in the begin() method.") self.__invalid += 1 return False @@ -789,4 +816,9 @@ def end(self): f"\n\tRead {self.__n_runs} runs, skipped {self.__skipped_runs} runs.") else: self.logger.info( - f"\n\tRead {self.__counter} events (skipped {self.__skipped} events, {self.__invalid} invalid events)") \ No newline at end of file + f"\n\tRead {self.__counter} events (skipped {self.__skipped} events, {self.__invalid} invalid events)") + + for d in self.__temporary_dirs: + self.logger.debug(f"Remove temporary folder: {d}") + os.unlink(os.path.join(d, "combined.root")) + os.rmdir(d) From 931ee4204fb3c7fde0a8bdf1fd1df72951d1164b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Wed, 6 Sep 2023 16:22:11 +0200 Subject: [PATCH 343/418] Add some docstrings and comments --- .../modules/io/RNO_G/readRNOGDataMattak.py | 34 +++++++++++++++---- 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py b/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py index 17246eec1..f7585aa31 100644 --- a/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py +++ b/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py @@ -18,9 +18,26 @@ import string import random + def create_random_directory_path(prefix="/tmp/", n=7): + """ + Produces a path for a temporary directory with a n letter random suffix + + Parameters + ---------- + + prefix: str + Path prefix, i.e., root directory. (Defaut: /tmp/) + + n: int + Number of letters for the random suffix. (Default: 7) + + Returns + ------- - # using random.choices() + path: str + Return path (e.g, /tmp/readRNOGData_XXXXXXX) + """ # generating random strings res = ''.join(random.choices(string.ascii_lowercase + string.digits, k=n)) path = os.path.join(prefix, "readRNOGData_" + res) @@ -325,6 +342,10 @@ def begin(self, self.logger.error(f"Incomplete directory: {dir_file}. Skip ...") continue else: + # Providing direct paths to a Mattak combined.root file is not supported by the mattak library yet. + # It only accepts directry paths in which it will look for a file called `combined.root` (or waveforms.root if + # it is not a combined file). To work around this: Create a tmp directory under `/tmp/`, link the file you want to + # read into this directory with the the name `combined.root`, use this path to read the run. path = create_random_directory_path() self.logger.debug(f"Create temporary directory: {path}") @@ -332,14 +353,13 @@ def begin(self, raise ValueError(f"Temporary directory {path} already exists.") os.mkdir(path) - self.__temporary_dirs.append(path) + self.__temporary_dirs.append(path) # for housekeeping self.logger.debug(f"Create symlink for {dir_file}") os.symlink(dir_file, os.path.join(path, "combined.root")) - dir_file = path + dir_file = path # set path to e.g. /tmp/NuRadioReco_XXXXXXX/combined.root - # raise NotImplementedError("The option to read in files is not implemented yet") try: dataset = mattak.Dataset.Dataset(station=0, run=0, data_dir=dir_file, verbose=verbose, **mattak_kwargs) @@ -347,7 +367,6 @@ def begin(self, self.logger.error(f"The following exeption was raised reading in the run: {dir_file}. Skip that run ...:\n", exc_info=e) continue - # filter runs/datasets based on if select_runs and self.__run_table is not None and not self.__select_run(dataset): self.__skipped_runs += 1 @@ -816,8 +835,9 @@ def end(self): f"\n\tRead {self.__n_runs} runs, skipped {self.__skipped_runs} runs.") else: self.logger.info( - f"\n\tRead {self.__counter} events (skipped {self.__skipped} events, {self.__invalid} invalid events)") - + f"\n\tRead {self.__counter} events (skipped {self.__skipped} events, {self.__invalid} invalid events)") + + # Clean up links and temporary directories. for d in self.__temporary_dirs: self.logger.debug(f"Remove temporary folder: {d}") os.unlink(os.path.join(d, "combined.root")) From 162f0140817d228f0814c7e954be41ddebd745a9 Mon Sep 17 00:00:00 2001 From: Sjoerd Bouma Date: Tue, 12 Sep 2023 16:15:11 +0200 Subject: [PATCH 344/418] remove commented import --- NuRadioReco/modules/RNO_G/channelBlockOffsetFitter.py | 1 - 1 file changed, 1 deletion(-) diff --git a/NuRadioReco/modules/RNO_G/channelBlockOffsetFitter.py b/NuRadioReco/modules/RNO_G/channelBlockOffsetFitter.py index 130aed3df..9b62a7aeb 100644 --- a/NuRadioReco/modules/RNO_G/channelBlockOffsetFitter.py +++ b/NuRadioReco/modules/RNO_G/channelBlockOffsetFitter.py @@ -12,7 +12,6 @@ from NuRadioReco.utilities import units, fft from NuRadioReco.framework.base_trace import BaseTrace from NuRadioReco.framework.parameters import channelParameters -# from iminuit import Minuit import numpy as np import scipy From 065c941af04d6f71de109eafee5289097ecf8162 Mon Sep 17 00:00:00 2001 From: Jean-Marco Alameddine Date: Wed, 13 Sep 2023 11:58:43 +0200 Subject: [PATCH 345/418] upgrade proposal to version 7.6.2 --- documentation/source/Introduction/pages/installation.rst | 2 +- pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/documentation/source/Introduction/pages/installation.rst b/documentation/source/Introduction/pages/installation.rst index 6d5f298b9..62fd29dda 100644 --- a/documentation/source/Introduction/pages/installation.rst +++ b/documentation/source/Introduction/pages/installation.rst @@ -189,7 +189,7 @@ These packages are recommended to be able to use all of NuRadioMC/NuRadioReco's .. code-block:: bash - pip install proposal==7.5.1 + pip install proposal==7.6.2 Note that the pip installation for this version of proposal may not work on all systems, in particular: diff --git a/pyproject.toml b/pyproject.toml index 9ca42050a..8b2eed0b6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -46,7 +46,7 @@ numba = "*" Sphinx = "*" sphinx-rtd-theme = "*" numpydoc = "*" -proposal = "7.5.1" +proposal = "7.6.2" pygdsm = {git = "https://github.com/telegraphic/pygdsm"} nifty5 = {git = "https://gitlab.mpcdf.mpg.de/ift/nifty.git", branch="NIFTy_5"} pypocketfft = {git = "https://gitlab.mpcdf.mpg.de/mtr/pypocketfft"} From 065d198f0f1d03e40453143d4d169df1d8fc922e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Mon, 18 Sep 2023 16:47:12 +0200 Subject: [PATCH 346/418] Remove non built-in objects for the __modules_event list which gets serialised together with the event. In this case the optional detector argument of the eventWriter caused the issue. Also adding entries to __modules_event before acutally running the module. In this case the eventWriter will already appear in that list the first time it is called. --- NuRadioReco/framework/event.py | 41 ++++++++++++++++++++---------- NuRadioReco/modules/base/module.py | 28 +++++++++++++------- 2 files changed, 47 insertions(+), 22 deletions(-) diff --git a/NuRadioReco/framework/event.py b/NuRadioReco/framework/event.py index 80530be6c..d269012fd 100644 --- a/NuRadioReco/framework/event.py +++ b/NuRadioReco/framework/event.py @@ -12,6 +12,10 @@ logger = logging.getLogger('Event') +def is_builtin_class_instance(obj): + return obj.__class__.__module__ == '__builtin__' + + class Event: def __init__(self, run_number, event_id): @@ -41,7 +45,12 @@ def register_module_event(self, instance, name, kwargs): kwargs: the key word arguments of the run method """ - + key_to_be_dropped = [key for key in kwargs + if not is_builtin_class_instance(kwargs[key])] + + for key in key_to_be_dropped: + kwargs.pop(key) + self.__modules_event.append([name, instance, kwargs]) def register_module_station(self, station_id, instance, name, kwargs): @@ -59,8 +68,15 @@ def register_module_station(self, station_id, instance, name, kwargs): kwargs: the key word arguments of the run method """ - if(station_id not in self.__modules_station): + if station_id not in self.__modules_station: self.__modules_station[station_id] = [] + + key_to_be_dropped = [key for key in kwargs + if not is_builtin_class_instance(kwargs[key])] + + for key in key_to_be_dropped: + kwargs.pop(key) + iE = len(self.__modules_event) self.__modules_station[station_id].append([iE, name, instance, kwargs]) @@ -427,21 +443,18 @@ def serialize(self, mode): commit_hash = NuRadioReco.utilities.version.get_NuRadioMC_commit_hash() self.set_parameter(parameters.eventParameters.hash_NuRadioMC, commit_hash) except: + logger.warning("Event is serialized without commit hash!") self.set_parameter(parameters.eventParameters.hash_NuRadioMC, None) for station in self.get_stations(): stations_pkl.append(station.serialize(mode)) - showers_pkl = [] - for shower in self.get_showers(): - showers_pkl.append(shower.serialize()) - sim_showers_pkl = [] - for shower in self.get_sim_showers(): - sim_showers_pkl.append(shower.serialize()) - particles_pkl = [] - for particle in self.get_particles(): - particles_pkl.append(particle.serialize()) + showers_pkl = [shower.serialize() for shower in self.get_showers()] + sim_showers_pkl = [shower.serialize() for shower in self.get_sim_showers()] + particles_pkl = [particle.serialize() for particle in self.get_particles()] + hybrid_info = self.__hybrid_information.serialize() + modules_out_event = [] for value in self.__modules_event: # remove module instances (this will just blow up the file size) modules_out_event.append([value[0], None, value[2]]) @@ -489,9 +502,11 @@ def deserialize(self, data_pkl): particle = NuRadioReco.framework.particle.Particle(None) particle.deserialize(particle_pkl) self.add_particle(particle) + self.__hybrid_information = NuRadioReco.framework.hybrid_information.HybridInformation() if 'hybrid_info' in data.keys(): self.__hybrid_information.deserialize(data['hybrid_info']) + self._parameters = data['_parameters'] self.__run_number = data['__run_number'] self._id = data['_id'] @@ -500,7 +515,7 @@ def deserialize(self, data_pkl): if 'generator_info' in data.keys(): self._generator_info = data['generator_info'] - if("__modules_event" in data): + if "__modules_event" in data: self.__modules_event = data['__modules_event'] - if("__modules_station" in data): + if "__modules_station" in data: self.__modules_station = data['__modules_station'] diff --git a/NuRadioReco/modules/base/module.py b/NuRadioReco/modules/base/module.py index 50818fa93..3df0e7af6 100644 --- a/NuRadioReco/modules/base/module.py +++ b/NuRadioReco/modules/base/module.py @@ -39,20 +39,21 @@ def register_run_method(self, *args, **kwargs): # generator, so not sure how to access the event. evt = None station = None + # find out type of module automatically - if(len(args) == 1): - if(isinstance(args[0], NuRadioReco.framework.event.Event)): + if len(args) == 1: + if isinstance(args[0], NuRadioReco.framework.event.Event): module_level = "event" evt = args[0] else: # this is a module that creats events module_level = "reader" - elif(len(args) >= 2): - if(isinstance(args[0], NuRadioReco.framework.event.Event) and isinstance(args[1], NuRadioReco.framework.base_station.BaseStation)): + elif len(args) >= 2: + if isinstance(args[0], NuRadioReco.framework.event.Event) and isinstance(args[1], NuRadioReco.framework.base_station.BaseStation): module_level = "station" evt = args[0] station = args[1] - elif(isinstance(args[0], NuRadioReco.framework.event.Event)): + elif isinstance(args[0], NuRadioReco.framework.event.Event): module_level = "event" evt = args[0] else: @@ -64,18 +65,27 @@ def register_run_method(self, *args, **kwargs): module_level = "reader" start = timer() - res = run(self, *args, **kwargs) - if(module_level == "event"): + + # Currently we are not storing the args with which the module is called. Typically those are the event and/or station + # on which the module is run which should not be stored here. The danger is if other data is passed as args + # kwargs["args"] = args # otherwise we do not store the args + + if module_level == "event": evt.register_module_event(self, self.__class__.__name__, kwargs) - elif(module_level == "station"): + elif module_level == "station": evt.register_module_station(station.get_id(), self, self.__class__.__name__, kwargs) - elif(module_level == "reader"): + elif module_level == "reader": # not sure what to do... function returns generator, not sure how to access the event... pass + + res = run(self, *args, **kwargs) + end = timer() + if self not in register_run_method.time: # keep track of timing of modules. We use the module instance as key to time different module instances separately. register_run_method.time[self] = 0 register_run_method.time[self] += (end - start) + return res register_run_method.time = {} From ebc50dbc6a03fa17945538062cf98bbca2dc65cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Tue, 19 Sep 2023 11:44:07 +0200 Subject: [PATCH 347/418] Fix how to select keys which have to be dropped. Add warnings for dropped keys --- NuRadioReco/framework/event.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/NuRadioReco/framework/event.py b/NuRadioReco/framework/event.py index d269012fd..77ea8176c 100644 --- a/NuRadioReco/framework/event.py +++ b/NuRadioReco/framework/event.py @@ -12,8 +12,8 @@ logger = logging.getLogger('Event') -def is_builtin_class_instance(obj): - return obj.__class__.__module__ == '__builtin__' +def is_serializable(obj): + return obj.__class__.__module__ == 'builtins' or obj.__class__.__module__ == "numpy" class Event: @@ -46,9 +46,10 @@ def register_module_event(self, instance, name, kwargs): the key word arguments of the run method """ key_to_be_dropped = [key for key in kwargs - if not is_builtin_class_instance(kwargs[key])] + if not is_serializable(kwargs[key])] for key in key_to_be_dropped: + logger.warn(f"Dropping \"{key}\" of type {type(kwargs[key])} from kwargs of __modules_event") kwargs.pop(key) self.__modules_event.append([name, instance, kwargs]) @@ -72,9 +73,10 @@ def register_module_station(self, station_id, instance, name, kwargs): self.__modules_station[station_id] = [] key_to_be_dropped = [key for key in kwargs - if not is_builtin_class_instance(kwargs[key])] + if not is_serializable(kwargs[key])] for key in key_to_be_dropped: + logger.warn(f"Dropping \"{key}\" of type {type(kwargs[key])} from kwargs of __modules_station") kwargs.pop(key) iE = len(self.__modules_event) From ac3785e2286841c32332fc3836646961efcc9172 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Tue, 19 Sep 2023 11:50:34 +0200 Subject: [PATCH 348/418] Add doc strings --- NuRadioReco/framework/event.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/NuRadioReco/framework/event.py b/NuRadioReco/framework/event.py index 77ea8176c..a1a211015 100644 --- a/NuRadioReco/framework/event.py +++ b/NuRadioReco/framework/event.py @@ -45,10 +45,13 @@ def register_module_event(self, instance, name, kwargs): kwargs: the key word arguments of the run method """ - key_to_be_dropped = [key for key in kwargs + + # Not every kwargs argument passed to a run(..) method is serializable. Example is a detector object. + # Drop all arguments for which this is the case + keys_to_be_dropped = [key for key in kwargs if not is_serializable(kwargs[key])] - for key in key_to_be_dropped: + for key in keys_to_be_dropped: logger.warn(f"Dropping \"{key}\" of type {type(kwargs[key])} from kwargs of __modules_event") kwargs.pop(key) @@ -72,10 +75,12 @@ def register_module_station(self, station_id, instance, name, kwargs): if station_id not in self.__modules_station: self.__modules_station[station_id] = [] - key_to_be_dropped = [key for key in kwargs + # Not every kwargs argument passed to a run(..) method is serializable. Example is a detector object. + # Drop all arguments for which this is the case + keys_to_be_dropped = [key for key in kwargs if not is_serializable(kwargs[key])] - for key in key_to_be_dropped: + for key in keys_to_be_dropped: logger.warn(f"Dropping \"{key}\" of type {type(kwargs[key])} from kwargs of __modules_station") kwargs.pop(key) From f929b44844d331af82b911e108b361b3d36f3dce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Tue, 19 Sep 2023 12:03:28 +0200 Subject: [PATCH 349/418] Add line breaks to test.sh --- .../examples/test_radio_emitting_pulser_example.sh | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/NuRadioMC/test/examples/test_radio_emitting_pulser_example.sh b/NuRadioMC/test/examples/test_radio_emitting_pulser_example.sh index 582f7b17b..2645e463e 100755 --- a/NuRadioMC/test/examples/test_radio_emitting_pulser_example.sh +++ b/NuRadioMC/test/examples/test_radio_emitting_pulser_example.sh @@ -1,8 +1,16 @@ #!/bin/bash set -e python NuRadioMC/examples/05_pulser_calibration_measurement/radioEmitting_pulser_calibration/A01generate_pulser_events.py -python NuRadioMC/examples/05_pulser_calibration_measurement/radioEmitting_pulser_calibration/runARA02.py emitter_event_list.hdf5 NuRadioMC/examples/05_pulser_calibration_measurement/radioEmitting_pulser_calibration/ARA02Alt.json NuRadioMC/examples/05_pulser_calibration_measurement/radioEmitting_pulser_calibration/config.yaml output.hdf5 output.nur -python NuRadioMC/test/examples/validate_radio_emitter_allmost_equal.py output.hdf5 NuRadioMC/test/examples/radio_emitter_output_reference.hdf5 + +python NuRadioMC/examples/05_pulser_calibration_measurement/radioEmitting_pulser_calibration/runARA02.py \ + emitter_event_list.hdf5 \ + NuRadioMC/examples/05_pulser_calibration_measurement/radioEmitting_pulser_calibration/ARA02Alt.json \ + NuRadioMC/examples/05_pulser_calibration_measurement/radioEmitting_pulser_calibration/config.yaml \ + output.hdf5 output.nur + +python NuRadioMC/test/examples/validate_radio_emitter_allmost_equal.py output.hdf5 \ + NuRadioMC/test/examples/radio_emitter_output_reference.hdf5 + rm emitter_event_list.hdf5 # rm output.hdf5 rm output.nur From 5e0a2c6e43a04a08138c4103f703786771bc8a4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Tue, 19 Sep 2023 12:41:36 +0200 Subject: [PATCH 350/418] Avoid overwriting of function __scan_files(). Correctly implement logic of argument parse_detector. Add some more debugging and error logging. Some refactoring --- NuRadioReco/modules/io/NuRadioRecoio.py | 123 ++++++++++++------ .../modules/io/event_parser_factory.py | 32 ++++- 2 files changed, 110 insertions(+), 45 deletions(-) diff --git a/NuRadioReco/modules/io/NuRadioRecoio.py b/NuRadioReco/modules/io/NuRadioRecoio.py index 8aa4c1728..6b6fef736 100644 --- a/NuRadioReco/modules/io/NuRadioRecoio.py +++ b/NuRadioReco/modules/io/NuRadioRecoio.py @@ -3,8 +3,12 @@ import NuRadioReco.detector.detector import NuRadioReco.detector.generic_detector import NuRadioReco.modules.io.event_parser_factory + import numpy as np +import astropy.time + import logging + import time import os @@ -41,14 +45,16 @@ def __init__(self, filenames, parse_header=True, parse_detector=True, fail_on_ve buffer_size: int the size of the read buffer in bytes (default 100MB) """ - if(not isinstance(filenames, list)): + if not isinstance(filenames, list): filenames = [filenames] + self.__file_scanned = False self.logger = logging.getLogger('NuRadioReco.NuRadioRecoio') self.logger.info("initializing NuRadioRecoio with file {}".format(filenames)) t = time.time() if log_level is not None: self.logger.setLevel(log_level) + # Initialize attributes self._filenames = None self.__n_events = None @@ -76,43 +82,45 @@ def __init__(self, filenames, parse_header=True, parse_detector=True, fail_on_ve self.logger.info("... finished in {:.0f} seconds".format(time.time() - t)) def _get_file(self, iF): - if(iF not in self.__open_files): + if iF not in self.__open_files: self.logger.debug("file {} is not yet open, opening file".format(iF)) self.__open_files[iF] = {} self.__open_files[iF]['file'] = open(self._filenames[iF], 'rb', buffering=self.__buffer_size) # 100 MB buffering self.__open_files[iF]['time'] = time.time() self.__check_file_version(iF) - if(len(self.__open_files) > self.__max_open_files): + + if len(self.__open_files) > self.__max_open_files: self.logger.debug("more than {} file are open, closing oldest file".format(self.__max_open_files)) tnow = time.time() iF_close = 0 for key, value in self.__open_files.items(): - if(value['time'] < tnow): + if value['time'] < tnow: tnow = value['time'] iF_close = key self.logger.debug("closing file {} that was opened at {}".format(iF_close, tnow)) self.__open_files[iF_close]['file'].close() del self.__open_files[iF_close] + return self.__open_files[iF]['file'] def __check_file_version(self, iF): self.__file_version = int.from_bytes(self._get_file(iF).read(6), 'little') self.__file_version_minor = int.from_bytes(self._get_file(iF).read(6), 'little') - if (self.__file_version == 0): + if self.__file_version == 0: self.logger.error( f"File might be corrupt, file has version {self.__file_version}.{self.__file_version} " f"but current version is {VERSION}.{VERSION_MINOR}. " f"This might indicate the file is empty. The file size is {os.stat(self._filenames[iF]).st_size} B.") - elif (self.__file_version > VERSION): + elif self.__file_version > VERSION: self.logger.error( f"File might be corrupt, file has version {self.__file_version}.{self.__file_version} " f"but current version is {VERSION}.{VERSION_MINOR}. " f"This might indicate the file is empty. The file size is {os.stat(self._filenames[iF]).st_size} B.") - elif(self.__file_version == 1): + elif self.__file_version == 1: self.logger.error( "data file not readable. File has version {}.{} but current version is {}.{}".format( self.__file_version, @@ -121,9 +129,10 @@ def __check_file_version(self, iF): VERSION_MINOR ) ) - if(self.__fail_on_version_mismatch): + if self.__fail_on_version_mismatch: raise IOError - elif(self.__file_version_minor != VERSION_MINOR): + + elif self.__file_version_minor != VERSION_MINOR: self.logger.error( "Data file might not readable, File has version {}.{} but current version is {}.{}".format( self.__file_version, @@ -132,10 +141,13 @@ def __check_file_version(self, iF): VERSION_MINOR ) ) - if(self.__fail_on_minor_version_mismatch): + if self.__fail_on_minor_version_mismatch: raise IOError - self.__scan_files = NuRadioReco.modules.io.event_parser_factory.scan_files_function(self.__file_version, self.__file_version_minor) - self.__iter_events = NuRadioReco.modules.io.event_parser_factory.iter_events_function(self.__file_version, self.__file_version_minor) + + self.__scan_files_versioned = NuRadioReco.modules.io.event_parser_factory.scan_files_function( + self.__file_version, self.__file_version_minor) + self.__iter_events = NuRadioReco.modules.io.event_parser_factory.iter_events_function( + self.__file_version, self.__file_version_minor) def openFile(self, filenames): self._filenames = filenames @@ -151,7 +163,7 @@ def openFile(self, filenames): self._event_specific_detector_changes = {} self.__event_headers = {} - if(self.__parse_header): + if self.__parse_header: self.__scan_files() def close_files(self): @@ -178,7 +190,6 @@ def _parse_event_header(self, evt_header): self.__event_headers[station_id][key] = [] if key == stnp.station_time: - import astropy.time station_time = None if value is not None: if isinstance(value, dict): @@ -200,11 +211,21 @@ def _parse_event_header(self, evt_header): def __scan_files(self): current_byte = 12 # skip datafile header iF = 0 + iF_prev = None while True: + if iF_prev != iF: + self.logger.info(f"Start scanning file {iF} ...") + iF_prev = iF + self._get_file(iF).seek(current_byte) - continue_loop, iF, current_byte = self.__scan_files(self, iF, current_byte) + continue_loop, iF, current_byte = self.__scan_files_versioned(self, iF, current_byte) + + if iF_prev != iF: + self.logger.info(f"Finished scanning file {iF_prev}.") + if not continue_loop: break + self.logger.info(f"Finished scanning file {iF}. Finished all") self.__event_ids = np.array(self.__event_ids) self.__file_scanned = True @@ -221,16 +242,18 @@ def __scan_files(self): self.__event_headers[station_id][key] = np.array(value) def get_header(self): - if(not self.__file_scanned): + if not self.__file_scanned: self.__scan_files() + return self.__event_headers def get_event_ids(self): """ returns a list of (run, eventid) tuples of all events contained in the data file """ - if(not self.__file_scanned): + if not self.__file_scanned: self.__scan_files() + return self.__event_ids def get_event_i(self, event_number): @@ -239,18 +262,20 @@ def get_event_i(self, event_number): self.logger.debug("read lock waiting 1ms") self.__read_lock = True - if(not self.__file_scanned): + if not self.__file_scanned: self.__scan_files() - if(event_number < 0 or event_number >= self.get_n_events()): + + if event_number < 0 or event_number >= self.get_n_events(): self.logger.error('event number {} out of bounds, only {} present in file'.format(event_number, self.get_n_events())) self.__read_lock = False return None + # determine in which file event i is istart = 0 file_id = 0 for iF in range(len(self._filenames)): istop = istart + len(self._bytes_start[iF]) - if((event_number >= istart) and (event_number < istop)): + if (event_number >= istart) and (event_number < istop): file_id = iF event_id = event_number - istart break @@ -265,24 +290,22 @@ def get_event_i(self, event_number): self._current_file_id = file_id self._current_event_id = event.get_id() self._current_run_number = event.get_run_number() - # # If the event file contains a detector description that is a - # # generic detector, it might have event-specific properties and we - # # need to set the detector to the right event - if self._current_file_id in self.__detectors.keys(): - if 'generic_detector' in self._detector_dicts[self._current_file_id]: - if self._detector_dicts[self._current_file_id]['generic_detector']: - self.__detectors[self._current_file_id].set_event(self._current_run_number, self._current_event_id) + + self.__set_event_to_detector() return event def get_event(self, event_id): - if(not self.__file_scanned): + if not self.__file_scanned: self.__scan_files() + mask = (self.__event_ids[:, 0] == event_id[0]) & (self.__event_ids[:, 1] == event_id[1]) - if(np.sum(mask) == 0): + if np.sum(mask) == 0: self.logger.error('event number {} not found in file'.format(event_id)) return None - elif(np.sum(mask) > 1): + + elif np.sum(mask) > 1: self.logger.warning(f"{np.sum(mask):d} events with the same run event id pair found. Returning first occurence.") + self._current_run_number = event_id[0] self._current_event_id = event_id[1] i = np.argwhere(mask)[0][0] @@ -294,11 +317,17 @@ def get_events(self): for event in self.__iter_events(self): self._current_event_id = event.get_id() self._current_run_number = event.get_run_number() - if self._current_file_id in self.__detectors.keys(): - if 'generic_detector' in self._detector_dicts[self._current_file_id]: - if self._detector_dicts[self._current_file_id]['generic_detector']: - self.__detectors[self._current_file_id].set_event(self._current_run_number, self._current_event_id) + self.__set_event_to_detector() yield event + + def __set_event_to_detector(self): + # If the event file contains a detector description that is a + # generic detector, it might have event-specific properties and we + # need to set the detector to the right event + if self._current_file_id in self.__detectors.keys(): + if 'generic_detector' in self._detector_dicts[self._current_file_id]: + if self._detector_dicts[self._current_file_id]['generic_detector']: + self.__detectors[self._current_file_id].set_event(self._current_run_number, self._current_event_id) def get_detector(self): """ @@ -307,13 +336,22 @@ def get_detector(self): files with different detectors are read, the detector for the last returned event is given. """ + + if not self.__parse_detector: + self.logger.warn(f"You called \"get_detector\", however, \"parse_detector\" is set to false. Return None!") + return None + # Check if detector object for current file already exists if self._current_file_id not in self.__detectors.keys(): # Detector object for current file does not exist, so we create it if self._current_file_id not in self._detector_dicts: - self.__scan_files() # Maybe we just forgot to scan the file + + if not self.__file_scanned: + self.__scan_files() # Maybe we just forgot to scan the file + if self._current_file_id not in self._detector_dicts: raise AttributeError('The current file does not contain a detector description.') + detector_dict = self._detector_dicts[self._current_file_id] if 'generic_detector' in detector_dict.keys(): if detector_dict['generic_detector']: @@ -325,29 +363,36 @@ def get_detector(self): detector_dict['default_station'] = None if 'default_channel' not in detector_dict: detector_dict['default_channel'] = None - self.__detectors[self._current_file_id].__init__(source='dictionary', json_filename='', dictionary=detector_dict, default_station=detector_dict['default_station'], default_channel=detector_dict['default_channel']) + self.__detectors[self._current_file_id].__init__( + source='dictionary', json_filename='', dictionary=detector_dict, + default_station=detector_dict['default_station'], default_channel=detector_dict['default_channel']) + if self._current_file_id in self._event_specific_detector_changes.keys(): for change in self._event_specific_detector_changes[self._current_file_id]: self.__detectors[self._current_file_id].add_station_properties_for_event( properties=change['properties'], station_id=change['station_id'], run_number=change['run_number'], - event_id=change['event_id'] - ) + event_id=change['event_id']) + self.__detectors[self._current_file_id].set_event(self._current_run_number, self._current_event_id) return self.__detectors[self._current_file_id] + # Detector is a normal detector self.__detectors[self._current_file_id] = NuRadioReco.detector.detector.Detector.__new__(NuRadioReco.detector.detector.Detector) self.__detectors[self._current_file_id].__init__(source='dictionary', json_filename='', dictionary=self._detector_dicts[self._current_file_id]) + # Detector object for current file already exists. If it is a generic detector, # we update it to the run number and ID of the last event that was requested # (in case there are event-specific changes) and return it if 'generic_detector' in self._detector_dicts[self._current_file_id].keys(): if self._detector_dicts[self._current_file_id]['generic_detector']: self.__detectors[self._current_file_id].set_event(self._current_run_number, self._current_event_id) + return self.__detectors[self._current_file_id] def get_n_events(self): - if(not self.__file_scanned): + if not self.__file_scanned: self.__scan_files() + return self.__n_events diff --git a/NuRadioReco/modules/io/event_parser_factory.py b/NuRadioReco/modules/io/event_parser_factory.py index 1f0a02326..a0a33224a 100644 --- a/NuRadioReco/modules/io/event_parser_factory.py +++ b/NuRadioReco/modules/io/event_parser_factory.py @@ -9,11 +9,16 @@ def scan_files_function(version_major, version_minor): specifying the first version that function is for """ def scan_files_2_0(self, iF, current_byte): + + if self.__parse_detector: + self.logger(f"Scanning a file of version 2.0 which does not contain a detector object. " + f"However, \"parse_detector\" is true.") + bytes_to_read_hex = self._get_file(iF).read(6) bytes_to_read = int.from_bytes(bytes_to_read_hex, 'little') - if(bytes_to_read == 0): + if bytes_to_read == 0: # we are at the end of the file - if(iF < (len(self._filenames) - 1)): # are there more files to be parsed? + if iF < (len(self._filenames) - 1): # are there more files to be parsed? iF += 1 current_byte = 12 # skip datafile header self._get_file(iF).seek(current_byte) @@ -25,6 +30,7 @@ def scan_files_2_0(self, iF, current_byte): self._bytes_length.append([]) else: return False, iF, current_byte + current_byte += 6 self._bytes_start_header[iF].append(current_byte) self._bytes_length_header[iF].append(bytes_to_read) @@ -48,9 +54,9 @@ def scan_files_2_2(self, iF, current_byte): current_byte += 6 bytes_to_read_hex = self._get_file(iF).read(6) bytes_to_read = int.from_bytes(bytes_to_read_hex, 'little') - if(bytes_to_read == 0): + if bytes_to_read == 0: # we are at the end of the file - if(iF < (len(self._filenames) - 1)): # are there more files to be parsed? + if iF < (len(self._filenames) - 1): # are there more files to be parsed? iF += 1 current_byte = 12 # skip datafile header self._get_file(iF).seek(current_byte) @@ -65,8 +71,11 @@ def scan_files_2_2(self, iF, current_byte): current_byte += 6 else: return False, iF, current_byte + current_byte += 6 if object_type == 0: # object is an event + self.logger.debug("Read Event ...") + self._bytes_start_header[iF].append(current_byte) self._bytes_length_header[iF].append(bytes_to_read) current_byte += bytes_to_read @@ -80,18 +89,23 @@ def scan_files_2_2(self, iF, current_byte): bytes_to_read = int.from_bytes(bytes_to_read_hex, 'little') self._bytes_start[iF].append(current_byte) self._bytes_length[iF].append(bytes_to_read) - elif object_type == 1: # object is detector info + + elif object_type == 1 and self.__parse_detector: # object is detector info + self.logger.debug("Read detector ...") + detector_dict = pickle.loads(self._get_file(iF).read(bytes_to_read)) if 'generic_detector' not in detector_dict.keys(): is_generic_detector = False else: is_generic_detector = detector_dict['generic_detector'] + if iF not in self._detector_dicts.keys(): self._detector_dicts[iF] = { 'generic_detector': is_generic_detector, 'channels': {}, 'stations': {} } + if is_generic_detector: # add default_station and default_channel to the dict to support older files using these if 'default_station' not in detector_dict: @@ -100,24 +114,28 @@ def scan_files_2_2(self, iF, current_byte): detector_dict['default_channel'] = None self._detector_dicts[iF]['default_station'] = detector_dict['default_station'] self._detector_dicts[iF]['default_channel'] = detector_dict['default_channel'] + for station in detector_dict['stations'].values(): if len(self._detector_dicts[iF]['stations'].keys()) == 0: index = 0 else: index = max(self._detector_dicts[iF]['stations'].keys()) + 1 self._detector_dicts[iF]['stations'][index] = station + for channel in detector_dict['channels'].values(): if len(self._detector_dicts[iF]['channels'].keys()) == 0: index = 0 else: index = max(self._detector_dicts[iF]['channels'].keys()) + 1 self._detector_dicts[iF]['channels'][index] = channel + elif object_type == 2: # object is list of event-specific changes to the detector changes_dict = pickle.loads(self._get_file(iF).read(bytes_to_read)) if iF not in self._event_specific_detector_changes.keys(): self._event_specific_detector_changes[iF] = [] for change in changes_dict: self._event_specific_detector_changes[iF].append(change) + current_byte += bytes_to_read return True, iF, current_byte @@ -126,10 +144,12 @@ def scan_files_2_2(self, iF, current_byte): return scan_files_2_0 else: return scan_files_2_2 + elif version_major == 0: raise ValueError(f'File version is {version_major}.{version_major} which might indicate the file is empty') else: - raise ValueError('File version {}.{} is not supported. Major version needs to be 2 but is {}.'.format(version_major, version_minor, version_major)) + raise ValueError('File version {}.{} is not supported. Major version needs to be 2 but is {}.'.format( + version_major, version_minor, version_major)) From ec978b73d425ee502c2627cd07c8feea279fa9f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Tue, 19 Sep 2023 12:56:28 +0200 Subject: [PATCH 351/418] Formatted with autopep8 --in-place --aggressive --max-line-length 120 NuRadioReco/modules/io/NuRadioRecoio.py --- NuRadioReco/modules/io/NuRadioRecoio.py | 86 ++++++++++++++----------- 1 file changed, 47 insertions(+), 39 deletions(-) diff --git a/NuRadioReco/modules/io/NuRadioRecoio.py b/NuRadioReco/modules/io/NuRadioRecoio.py index 6b6fef736..5dd7d8d68 100644 --- a/NuRadioReco/modules/io/NuRadioRecoio.py +++ b/NuRadioReco/modules/io/NuRadioRecoio.py @@ -47,14 +47,14 @@ def __init__(self, filenames, parse_header=True, parse_detector=True, fail_on_ve """ if not isinstance(filenames, list): filenames = [filenames] - + self.__file_scanned = False self.logger = logging.getLogger('NuRadioReco.NuRadioRecoio') self.logger.info("initializing NuRadioRecoio with file {}".format(filenames)) t = time.time() if log_level is not None: self.logger.setLevel(log_level) - + # Initialize attributes self._filenames = None self.__n_events = None @@ -85,10 +85,11 @@ def _get_file(self, iF): if iF not in self.__open_files: self.logger.debug("file {} is not yet open, opening file".format(iF)) self.__open_files[iF] = {} - self.__open_files[iF]['file'] = open(self._filenames[iF], 'rb', buffering=self.__buffer_size) # 100 MB buffering + self.__open_files[iF]['file'] = open( + self._filenames[iF], 'rb', buffering=self.__buffer_size) # 100 MB buffering self.__open_files[iF]['time'] = time.time() self.__check_file_version(iF) - + if len(self.__open_files) > self.__max_open_files: self.logger.debug("more than {} file are open, closing oldest file".format(self.__max_open_files)) tnow = time.time() @@ -100,7 +101,7 @@ def _get_file(self, iF): self.logger.debug("closing file {} that was opened at {}".format(iF_close, tnow)) self.__open_files[iF_close]['file'].close() del self.__open_files[iF_close] - + return self.__open_files[iF]['file'] def __check_file_version(self, iF): @@ -119,7 +120,6 @@ def __check_file_version(self, iF): f"but current version is {VERSION}.{VERSION_MINOR}. " f"This might indicate the file is empty. The file size is {os.stat(self._filenames[iF]).st_size} B.") - elif self.__file_version == 1: self.logger.error( "data file not readable. File has version {}.{} but current version is {}.{}".format( @@ -131,7 +131,7 @@ def __check_file_version(self, iF): ) if self.__fail_on_version_mismatch: raise IOError - + elif self.__file_version_minor != VERSION_MINOR: self.logger.error( "Data file might not readable, File has version {}.{} but current version is {}.{}".format( @@ -143,7 +143,7 @@ def __check_file_version(self, iF): ) if self.__fail_on_minor_version_mismatch: raise IOError - + self.__scan_files_versioned = NuRadioReco.modules.io.event_parser_factory.scan_files_function( self.__file_version, self.__file_version_minor) self.__iter_events = NuRadioReco.modules.io.event_parser_factory.iter_events_function( @@ -194,16 +194,17 @@ def _parse_event_header(self, evt_header): if value is not None: if isinstance(value, dict): station_time = astropy.time.Time(value["value"], format=value["format"]) - # For backward compatibility, we also keep supporting station times stored as astropy.time objects + # For backward compatibility, we also keep supporting station times stored + # as astropy.time objects elif isinstance(value, astropy.time.Time): station_time = value else: err = f"Station time not stored as dict or astropy.time.Time: ({type(value)})" self.logger.error(err) raise ValueError(err) - + station_time.format = 'isot' - + self.__event_headers[station_id][key].append(station_time) else: self.__event_headers[station_id][key].append(value) @@ -216,10 +217,10 @@ def __scan_files(self): if iF_prev != iF: self.logger.info(f"Start scanning file {iF} ...") iF_prev = iF - + self._get_file(iF).seek(current_byte) continue_loop, iF, current_byte = self.__scan_files_versioned(self, iF, current_byte) - + if iF_prev != iF: self.logger.info(f"Finished scanning file {iF_prev}.") @@ -244,7 +245,7 @@ def __scan_files(self): def get_header(self): if not self.__file_scanned: self.__scan_files() - + return self.__event_headers def get_event_ids(self): @@ -253,23 +254,25 @@ def get_event_ids(self): """ if not self.__file_scanned: self.__scan_files() - + return self.__event_ids def get_event_i(self, event_number): - while(self.__read_lock): + while self.__read_lock: time.sleep(1) self.logger.debug("read lock waiting 1ms") self.__read_lock = True if not self.__file_scanned: self.__scan_files() - + if event_number < 0 or event_number >= self.get_n_events(): - self.logger.error('event number {} out of bounds, only {} present in file'.format(event_number, self.get_n_events())) + self.logger.error( + 'event number {} out of bounds, only {} present in file'.format( + event_number, self.get_n_events())) self.__read_lock = False return None - + # determine in which file event i is istart = 0 file_id = 0 @@ -290,22 +293,23 @@ def get_event_i(self, event_number): self._current_file_id = file_id self._current_event_id = event.get_id() self._current_run_number = event.get_run_number() - + self.__set_event_to_detector() return event def get_event(self, event_id): if not self.__file_scanned: self.__scan_files() - + mask = (self.__event_ids[:, 0] == event_id[0]) & (self.__event_ids[:, 1] == event_id[1]) if np.sum(mask) == 0: self.logger.error('event number {} not found in file'.format(event_id)) return None - + elif np.sum(mask) > 1: - self.logger.warning(f"{np.sum(mask):d} events with the same run event id pair found. Returning first occurence.") - + self.logger.warning( + f"{np.sum(mask):d} events with the same run event id pair found. Returning first occurence.") + self._current_run_number = event_id[0] self._current_event_id = event_id[1] i = np.argwhere(mask)[0][0] @@ -319,7 +323,7 @@ def get_events(self): self._current_run_number = event.get_run_number() self.__set_event_to_detector() yield event - + def __set_event_to_detector(self): # If the event file contains a detector description that is a # generic detector, it might have event-specific properties and we @@ -336,37 +340,39 @@ def get_detector(self): files with different detectors are read, the detector for the last returned event is given. """ - + if not self.__parse_detector: self.logger.warn(f"You called \"get_detector\", however, \"parse_detector\" is set to false. Return None!") return None - + # Check if detector object for current file already exists if self._current_file_id not in self.__detectors.keys(): # Detector object for current file does not exist, so we create it if self._current_file_id not in self._detector_dicts: - + if not self.__file_scanned: self.__scan_files() # Maybe we just forgot to scan the file if self._current_file_id not in self._detector_dicts: raise AttributeError('The current file does not contain a detector description.') - + detector_dict = self._detector_dicts[self._current_file_id] if 'generic_detector' in detector_dict.keys(): if detector_dict['generic_detector']: # Detector is a generic detector, so we have to consider default # station/channel and event-specific changes - self.__detectors[self._current_file_id] = NuRadioReco.detector.generic_detector.GenericDetector.__new__(NuRadioReco.detector.generic_detector.GenericDetector) - # the use of default_station and default_channel is deprecated. Allow to set it for now, to ensure backward compatibility + self.__detectors[self._current_file_id] = NuRadioReco.detector.generic_detector.GenericDetector.__new__( + NuRadioReco.detector.generic_detector.GenericDetector) + # the use of default_station and default_channel is deprecated. Allow to + # set it for now, to ensure backward compatibility if 'default_station' not in detector_dict: detector_dict['default_station'] = None if 'default_channel' not in detector_dict: detector_dict['default_channel'] = None self.__detectors[self._current_file_id].__init__( - source='dictionary', json_filename='', dictionary=detector_dict, + source='dictionary', json_filename='', dictionary=detector_dict, default_station=detector_dict['default_station'], default_channel=detector_dict['default_channel']) - + if self._current_file_id in self._event_specific_detector_changes.keys(): for change in self._event_specific_detector_changes[self._current_file_id]: self.__detectors[self._current_file_id].add_station_properties_for_event( @@ -374,21 +380,23 @@ def get_detector(self): station_id=change['station_id'], run_number=change['run_number'], event_id=change['event_id']) - + self.__detectors[self._current_file_id].set_event(self._current_run_number, self._current_event_id) return self.__detectors[self._current_file_id] - + # Detector is a normal detector - self.__detectors[self._current_file_id] = NuRadioReco.detector.detector.Detector.__new__(NuRadioReco.detector.detector.Detector) - self.__detectors[self._current_file_id].__init__(source='dictionary', json_filename='', dictionary=self._detector_dicts[self._current_file_id]) - + self.__detectors[self._current_file_id] = NuRadioReco.detector.detector.Detector.__new__( + NuRadioReco.detector.detector.Detector) + self.__detectors[self._current_file_id].__init__( + source='dictionary', json_filename='', dictionary=self._detector_dicts[self._current_file_id]) + # Detector object for current file already exists. If it is a generic detector, # we update it to the run number and ID of the last event that was requested # (in case there are event-specific changes) and return it if 'generic_detector' in self._detector_dicts[self._current_file_id].keys(): if self._detector_dicts[self._current_file_id]['generic_detector']: self.__detectors[self._current_file_id].set_event(self._current_run_number, self._current_event_id) - + return self.__detectors[self._current_file_id] def get_n_events(self): From 1b07486c6cce80a46c57b6b9ff68ae9f6525cffc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Tue, 19 Sep 2023 14:05:23 +0200 Subject: [PATCH 352/418] autopep8 auto formatting --- .../modules/io/coreas/readCoREASShower.py | 41 ++++++---- NuRadioReco/modules/io/eventWriter.py | 74 ++++++++++++------- 2 files changed, 75 insertions(+), 40 deletions(-) diff --git a/NuRadioReco/modules/io/coreas/readCoREASShower.py b/NuRadioReco/modules/io/coreas/readCoREASShower.py index a9ee174e5..d22bb5e5a 100644 --- a/NuRadioReco/modules/io/coreas/readCoREASShower.py +++ b/NuRadioReco/modules/io/coreas/readCoREASShower.py @@ -60,12 +60,13 @@ def run(self): Reads in a CoREAS file and returns an event containing all simulated stations """ - while (self.__current_input_file < len(self.__input_files)): + while self.__current_input_file < len(self.__input_files): t = time.time() t_per_event = time.time() - filesize = os.path.getsize(self.__input_files[self.__current_input_file]) - if(filesize < 18456 * 2): # based on the observation that a file with such a small filesize is corrupt + filesize = os.path.getsize( + self.__input_files[self.__current_input_file]) + if filesize < 18456 * 2: # based on the observation that a file with such a small filesize is corrupt logger.warning( "file {} seems to be corrupt, skipping to next file".format( self.__input_files[self.__current_input_file] @@ -74,9 +75,11 @@ def run(self): self.__current_input_file += 1 continue - logger.info('Reading %s ...' % self.__input_files[self.__current_input_file]) + logger.info('Reading %s ...' % + self.__input_files[self.__current_input_file]) - corsika = h5py.File(self.__input_files[self.__current_input_file], "r") + corsika = h5py.File( + self.__input_files[self.__current_input_file], "r") logger.info("using coreas simulation {} with E={:2g} theta = {:.0f}".format( self.__input_files[self.__current_input_file], corsika['inputs'].attrs["ERANGE"][0] * units.GeV, corsika['inputs'].attrs["THETAP"][0])) @@ -88,13 +91,15 @@ def run(self): self.__ascending_run_and_event_number) self.__ascending_run_and_event_number += 1 else: - evt = NuRadioReco.framework.event.Event(corsika['inputs'].attrs['RUNNR'], corsika['inputs'].attrs['EVTNR']) + evt = NuRadioReco.framework.event.Event( + corsika['inputs'].attrs['RUNNR'], corsika['inputs'].attrs['EVTNR']) evt.__event_time = f_coreas.attrs["GPSSecs"] # create sim shower, no core is set since no external detector description is given sim_shower = coreas.make_sim_shower(corsika) - sim_shower.set_parameter(shp.core, np.array([0, 0, f_coreas.attrs["CoreCoordinateVertical"] / 100])) # set core + sim_shower.set_parameter(shp.core, np.array( + [0, 0, f_coreas.attrs["CoreCoordinateVertical"] / 100])) # set core evt.add_sim_shower(sim_shower) # initialize coordinate transformation @@ -103,20 +108,26 @@ def run(self): # add simulated pulses as sim station for idx, (name, observer) in enumerate(f_coreas['observers'].items()): - station_id = antenna_id(name, idx) # returns proper station id if possible + # returns proper station id if possible + station_id = antenna_id(name, idx) station = NuRadioReco.framework.station.Station(station_id) if self.__det is None: - sim_station = coreas.make_sim_station(station_id, corsika, observer, channel_ids=[0, 1, 2]) + sim_station = coreas.make_sim_station( + station_id, corsika, observer, channel_ids=[0, 1, 2]) else: - sim_station = coreas.make_sim_station(station_id, corsika, observer, channel_ids=self.__det.get_channel_ids(self.__det.get_default_station_id())) + sim_station = coreas.make_sim_station( + station_id, corsika, observer, channel_ids=self.__det.get_channel_ids(self.__det.get_default_station_id())) station.set_sim_station(sim_station) evt.set_station(station) if self.__det is not None: position = observer.attrs['position'] antenna_position = np.zeros(3) - antenna_position[0], antenna_position[1], antenna_position[2] = -position[1] * units.cm, position[0] * units.cm, position[2] * units.cm - antenna_position = cs.transform_from_magnetic_to_geographic(antenna_position) + antenna_position[0], antenna_position[1], antenna_position[2] = - \ + position[1] * units.cm, position[0] * \ + units.cm, position[2] * units.cm + antenna_position = cs.transform_from_magnetic_to_geographic( + antenna_position) if not self.__det.has_station(station_id): self.__det.add_generic_station({ 'station_id': station_id, @@ -147,8 +158,10 @@ def end(self): logger.setLevel(logging.INFO) dt = timedelta(seconds=self.__t) logger.info("total time used by this module is {}".format(dt)) - logger.info("\tcreate event structure {}".format(timedelta(seconds=self.__t_event_structure))) - logger.info("per event {}".format(timedelta(seconds=self.__t_per_event))) + logger.info("\tcreate event structure {}".format( + timedelta(seconds=self.__t_event_structure))) + logger.info("per event {}".format( + timedelta(seconds=self.__t_per_event))) return dt diff --git a/NuRadioReco/modules/io/eventWriter.py b/NuRadioReco/modules/io/eventWriter.py index 0204943bd..51454e344 100644 --- a/NuRadioReco/modules/io/eventWriter.py +++ b/NuRadioReco/modules/io/eventWriter.py @@ -12,12 +12,14 @@ def get_header(evt): header = {'stations': {}} for iS, station in enumerate(evt.get_stations()): header['stations'][station.get_id()] = station.get_parameters().copy() - header['stations'][station.get_id()][stnp.station_time] = station.get_station_time_dict() + header['stations'][station.get_id( + )][stnp.station_time] = station.get_station_time_dict() if station.has_sim_station(): header['stations'][station.get_id()]['sim_station'] = {} - header['stations'][station.get_id()]['sim_station'] = station.get_sim_station().get_parameters().copy() - + header['stations'][station.get_id()]['sim_station'] = station.get_sim_station( + ).get_parameters().copy() + header['event_id'] = (evt.get_run_number(), evt.get_id()) return header @@ -26,6 +28,7 @@ class eventWriter: """ save events to file """ + def __init__(self): # initialize attributes self.__filename = None @@ -44,7 +47,8 @@ def __init__(self): def __write_fout_header(self): if self.__number_of_files > 1: - self.__fout = open("{}_part{:02d}.nur".format(self.__filename, self.__number_of_files), 'wb') + self.__fout = open("{}_part{:02d}.nur".format( + self.__filename, self.__number_of_files), 'wb') else: self.__fout = open("{}.nur".format(self.__filename), 'wb') b = bytearray() @@ -76,10 +80,11 @@ def begin(self, filename, max_file_size=1024, check_for_duplicates=False, events self.__filename = filename[:-4] else: self.__filename = filename - + if filename.endswith('.ari'): - logger.warning('The file ending .ari for NuRadioReco files is deprecated. Please use .nur instead.') - + logger.warning( + 'The file ending .ari for NuRadioReco files is deprecated. Please use .nur instead.') + self.__check_for_duplicates = check_for_duplicates self.__number_of_events = 0 self.__current_file_size = 0 @@ -87,8 +92,10 @@ def begin(self, filename, max_file_size=1024, check_for_duplicates=False, events self.__max_file_size = max_file_size * 1024 * 1024 # in bytes self.__stored_stations = [] self.__stored_channels = [] - self.__event_ids_and_runs = [] # Remember which event IDs are already in file to catch duplicates - self.__header_written = False # Remember if we still have to write the current file header + # Remember which event IDs are already in file to catch duplicates + self.__event_ids_and_runs = [] + # Remember if we still have to write the current file header + self.__header_written = False self.__events_per_file = events_per_file @register_run() @@ -134,13 +141,16 @@ def run(self, evt, det=None, mode=None): self.__events_in_current_file += 1 if det is not None: - detector_dict = self.__get_detector_dict(evt, det) # returns None if detector is already saved + # returns None if detector is already saved + detector_dict = self.__get_detector_dict(evt, det) if detector_dict is not None: - detector_bytearray = self.__get_detector_bytearray(detector_dict) + detector_bytearray = self.__get_detector_bytearray( + detector_dict) self.__fout.write(detector_bytearray) self.__current_file_size += detector_bytearray.__sizeof__() if isinstance(det, generic_detector.GenericDetector): - changes_bytearray = self.__get_detector_changes_byte_array(evt, det) + changes_bytearray = self.__get_detector_changes_byte_array( + evt, det) if changes_bytearray is not None: self.__fout.write(changes_bytearray) self.__current_file_size += changes_bytearray.__sizeof__() @@ -148,8 +158,9 @@ def run(self, evt, det=None, mode=None): logger.debug("current file size is {} bytes, event number {}".format(self.__current_file_size, self.__number_of_events)) - if(self.__current_file_size > self.__max_file_size or self.__events_in_current_file == self.__events_per_file): - logger.info("current output file exceeds max file size -> closing current output file and opening new one") + if self.__current_file_size > self.__max_file_size or self.__events_in_current_file == self.__events_per_file: + logger.info( + "current output file exceeds max file size -> closing current output file and opening new one") self.__current_file_size = 0 self.__fout.close() self.__number_of_files += 1 @@ -207,7 +218,8 @@ def __get_detector_dict(self, event, det): for channel in station.iter_channels(): if not self.__is_channel_already_in_file(station.get_id(), channel.get_id(), station.get_station_time()): if not is_generic_detector: - channel_description = det.get_channel(station.get_id(), channel.get_id()) + channel_description = det.get_channel( + station.get_id(), channel.get_id()) self.__stored_channels.append({ 'station_id': station.get_id(), 'channel_id': channel.get_id(), @@ -215,10 +227,11 @@ def __get_detector_dict(self, event, det): 'decommission_time': channel_description['decommission_time'] }) else: - channel_description = det.get_raw_channel(station.get_id(), channel.get_id()) + channel_description = det.get_raw_channel( + station.get_id(), channel.get_id()) self.__stored_channels.append({ - 'station_id': station.get_id(), - 'channel_id': channel.get_id() + 'station_id': station.get_id(), + 'channel_id': channel.get_id() }) det_dict['channels'][str(i_channel)] = channel_description i_channel += 1 @@ -227,16 +240,20 @@ def __get_detector_dict(self, event, det): if is_generic_detector: for reference_station_id in det.get_reference_station_ids(): if not self.__is_station_already_in_file(reference_station_id, None): - station_description = det.get_raw_station(reference_station_id) + station_description = det.get_raw_station( + reference_station_id) self.__stored_stations.append({ 'station_id': reference_station_id }) - det_dict['stations'][str(i_station)] = station_description + det_dict['stations'][str( + i_station)] = station_description i_station += 1 for channel_id in det.get_channel_ids(reference_station_id): if not self.__is_channel_already_in_file(reference_station_id, channel_id, None): - channel_description = det.get_raw_channel(reference_station_id, channel_id) - det_dict['channels'][str(i_channel)] = channel_description + channel_description = det.get_raw_channel( + reference_station_id, channel_id) + det_dict['channels'][str( + i_channel)] = channel_description self.__stored_channels.append({ 'station_id': reference_station_id, 'channel_id': channel_id @@ -281,7 +298,8 @@ def __is_channel_already_in_file(self, station_id, channel_id, station_time): return False def __get_detector_changes_byte_array(self, event, det): - changes = det.get_station_properties_for_event(event.get_run_number(), event.get_id()) + changes = det.get_station_properties_for_event( + event.get_run_number(), event.get_id()) if len(changes) == 0: return None changes_string = pickle.dumps(changes, protocol=4) @@ -300,9 +318,12 @@ def __check_for_duplicate_ids(self, run_number, event_id): Checks if an event with the same ID and run number has already been written to the file and throws an error if that is the case. """ - if(self.__check_for_duplicates): + if self.__check_for_duplicates: if [run_number, event_id] in self.__event_ids_and_runs: - raise ValueError("An event with ID {} and run number {} already exists in the file\nif you don't want unique event ids enforced you can turn it of by passing `check_for_duplicates=True` to the begin method.".format(event_id, run_number)) + raise ValueError("An event with ID {} and run number {} already exists in the " + "file\nif you don't want unique event ids enforced you can " + "turn it of by passing `check_for_duplicates=True` to the " + "begin method.".format(event_id, run_number)) return def end(self): @@ -310,5 +331,6 @@ def end(self): self.__fout.close() logger.info(f"closing file {self.__filename}.") else: - logger.warning(f"file {self.__filename} does not exist and won't be closed.") + logger.warning( + f"file {self.__filename} does not exist and won't be closed.") return self.__number_of_events From a8e9167bcaba292e77c3f9b795a6fd36bd1e4b25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= <30903175+fschlueter@users.noreply.github.com> Date: Wed, 20 Sep 2023 14:39:34 +0200 Subject: [PATCH 353/418] Update readCoREASShower.py fix style --- NuRadioReco/modules/io/coreas/readCoREASShower.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/NuRadioReco/modules/io/coreas/readCoREASShower.py b/NuRadioReco/modules/io/coreas/readCoREASShower.py index d22bb5e5a..c0bd0dd1b 100644 --- a/NuRadioReco/modules/io/coreas/readCoREASShower.py +++ b/NuRadioReco/modules/io/coreas/readCoREASShower.py @@ -117,17 +117,17 @@ def run(self): station_id, corsika, observer, channel_ids=[0, 1, 2]) else: sim_station = coreas.make_sim_station( - station_id, corsika, observer, channel_ids=self.__det.get_channel_ids(self.__det.get_default_station_id())) + station_id, corsika, observer, + channel_ids=self.__det.get_channel_ids(self.__det.get_default_station_id())) + station.set_sim_station(sim_station) evt.set_station(station) + if self.__det is not None: position = observer.attrs['position'] - antenna_position = np.zeros(3) - antenna_position[0], antenna_position[1], antenna_position[2] = - \ - position[1] * units.cm, position[0] * \ - units.cm, position[2] * units.cm - antenna_position = cs.transform_from_magnetic_to_geographic( - antenna_position) + antenna_position = np.array([-position[1], position[0], position[2]]) * units.cm + antenna_position = cs.transform_from_magnetic_to_geographic(antenna_position) + if not self.__det.has_station(station_id): self.__det.add_generic_station({ 'station_id': station_id, From b3449db77879558e8f5105a43d1e654d420a1201 Mon Sep 17 00:00:00 2001 From: AJ <52336270+aj-nielsen@users.noreply.github.com> Date: Sun, 24 Sep 2023 14:31:23 -0700 Subject: [PATCH 354/418] Update changelog.txt --- changelog.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/changelog.txt b/changelog.txt index e37cade64..1d442f744 100644 --- a/changelog.txt +++ b/changelog.txt @@ -2,6 +2,10 @@ Changelog - to keep track of all relevant changes please update the categories "new features" and "bugfixes" before a pull request merge! +version 2.2.1-dev +bugfix: +-in antennapattern.py, fixed line 1410; was masking frequencies <= 0 instead of frequencies < 0, causing NaN errors + version 2.2.0-dev new features: - added getting to query ARZ charge-excess profiles From 9d8cb3a52689de16248532deb77ee1675901760d Mon Sep 17 00:00:00 2001 From: AJ <52336270+aj-nielsen@users.noreply.github.com> Date: Sun, 24 Sep 2023 14:36:46 -0700 Subject: [PATCH 355/418] Update antennapattern.py Bugfix --- NuRadioReco/detector/antennapattern.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NuRadioReco/detector/antennapattern.py b/NuRadioReco/detector/antennapattern.py index 2452428e1..3403a4cb0 100644 --- a/NuRadioReco/detector/antennapattern.py +++ b/NuRadioReco/detector/antennapattern.py @@ -1395,7 +1395,7 @@ def _get_antenna_response_vectorized_raw(self, freq, theta, phi, group_delay='fr # Assuming simple cosine, sine falls-off for dummy module H_eff_t = np.zeros_like(Gain) - fmask = freq >= 0 + fmask = freq > 0 H_eff_t[fmask] = Gain[fmask] * max_gain_cross * 1 / freq[fmask] H_eff_t *= np.cos(theta) * np.sin(phi) H_eff_t *= constants.c * units.m / units.s * Z_ant / Z_0 / np.pi From 781dd08b691d9b08f62d1a870964dbdbd99da67e Mon Sep 17 00:00:00 2001 From: AJ <52336270+aj-nielsen@users.noreply.github.com> Date: Sun, 24 Sep 2023 14:37:51 -0700 Subject: [PATCH 356/418] Update changelog.txt --- changelog.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelog.txt b/changelog.txt index 1d442f744..72d7dfc0e 100644 --- a/changelog.txt +++ b/changelog.txt @@ -4,7 +4,7 @@ please update the categories "new features" and "bugfixes" before a pull request version 2.2.1-dev bugfix: --in antennapattern.py, fixed line 1410; was masking frequencies <= 0 instead of frequencies < 0, causing NaN errors +-in antennapattern.py, fixed line 1398; was masking frequencies >= 0 instead of frequencies > 0, causing NaN errors version 2.2.0-dev new features: From 3d58f050089818db5f400a2ddd6abd9e71f15b2e Mon Sep 17 00:00:00 2001 From: Sjoerd Bouma Date: Mon, 25 Sep 2023 13:04:17 +0200 Subject: [PATCH 357/418] treat offsets given as dict correctly --- NuRadioReco/modules/RNO_G/channelBlockOffsetFitter.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/NuRadioReco/modules/RNO_G/channelBlockOffsetFitter.py b/NuRadioReco/modules/RNO_G/channelBlockOffsetFitter.py index 9b62a7aeb..7dce7929a 100644 --- a/NuRadioReco/modules/RNO_G/channelBlockOffsetFitter.py +++ b/NuRadioReco/modules/RNO_G/channelBlockOffsetFitter.py @@ -76,12 +76,12 @@ def add_offsets(self, event, station, offsets=1*units.mV, channel_ids=None): channel = station.get_channel(channel_id) if isinstance(offsets, dict): add_offsets = offsets[channel_id] - elif len(np.atleast_1d(offsets)) == 1: - add_offsets = np.random.normal( - 0, offsets, (channel.get_number_of_samples() // self.block_size) - ) else: add_offsets = offsets + if len(np.atleast_1d(add_offsets)) == 1: + add_offsets = np.random.normal( + 0, add_offsets, (channel.get_number_of_samples() // self.block_size) + ) # save the added offsets as a channelParameter if channel.has_parameter(channelParameters.block_offsets): From 98f51e4f7d3a53cf1e8ad31f0109b14015b02ecc Mon Sep 17 00:00:00 2001 From: Sjoerd Bouma Date: Mon, 25 Sep 2023 13:07:50 +0200 Subject: [PATCH 358/418] save the microseconds --- NuRadioReco/modules/RNO_G/channelBlockOffsetFitter.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/NuRadioReco/modules/RNO_G/channelBlockOffsetFitter.py b/NuRadioReco/modules/RNO_G/channelBlockOffsetFitter.py index 7dce7929a..e686e3b75 100644 --- a/NuRadioReco/modules/RNO_G/channelBlockOffsetFitter.py +++ b/NuRadioReco/modules/RNO_G/channelBlockOffsetFitter.py @@ -205,10 +205,7 @@ def fit_block_offsets( filtered_trace = fft.freq2time(filtered_trace_fft, sampling_rate) # obtain guesses for block offsets - a_guess = np.array([ - np.mean(filtered_trace[i*block_size:(i+1)*block_size]) - for i in range(n_blocks) - ]) + a_guess = np.mean(np.split(filtered_trace, n_blocks), axis=1) if mode == 'approximate': block_offsets = a_guess elif mode == 'fit': From 8a77811310c3a5a05d66d0f972aa44693ce436f5 Mon Sep 17 00:00:00 2001 From: Sjoerd Bouma Date: Mon, 25 Sep 2023 14:11:11 +0200 Subject: [PATCH 359/418] add different block offsets fit options to mattak reader and store the offsets --- .../modules/io/RNO_G/readRNOGDataMattak.py | 53 ++++++++++++++----- 1 file changed, 40 insertions(+), 13 deletions(-) diff --git a/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py b/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py index db2835ecb..fbed78970 100644 --- a/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py +++ b/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py @@ -6,17 +6,19 @@ import math from NuRadioReco.modules.base.module import register_run +from NuRadioReco.modules.RNO_G.channelBlockOffsetFitter import channelBlockOffsets import NuRadioReco.framework.event import NuRadioReco.framework.station import NuRadioReco.framework.channel import NuRadioReco.framework.trigger +import NuRadioReco.framework.parameters from NuRadioReco.utilities import units import mattak.Dataset -def baseline_correction(wfs, n_bins=128, func=np.median): +def baseline_correction(wfs, n_bins=128, func=np.median, return_offsets=False): """ Simple baseline correction function. Determines baseline in discrete chuncks of "n_bins" with the function specified (i.e., mean or median). @@ -33,11 +35,17 @@ def baseline_correction(wfs, n_bins=128, func=np.median): func: np.mean or np.median Function to calculate pedestal + return_offsets: bool, default False + if True, additionally return the baseline offsets + Returns ------- wfs_corrected: np.array(n_events, n_channels, n_samples) Baseline/pedestal corrected waveforms + + baseline_values: np.array of shape (n_samples // n_bins, n_events, n_channels) + (Only if return_offsets==True) The baseline offsets """ # Example: Get baselines in chunks of 128 bins @@ -57,8 +65,12 @@ def baseline_correction(wfs, n_bins=128, func=np.median): # np.moveaxis -> (n_events, n_channels, 2048) baseline_traces = np.moveaxis(baseline_traces, 0, -1) + if return_offsets: + return wfs - baseline_traces, baseline_values + return wfs - baseline_traces +blockoffsetfitter = channelBlockOffsets() def get_time_offset(trigger_type): """ @@ -175,7 +187,7 @@ def begin(self, read_calibrated_data=False, select_triggers=None, select_runs=False, - apply_baseline_correction=True, + apply_baseline_correction='median', convert_to_voltage=True, selectors=[], run_types=["physics"], @@ -206,9 +218,16 @@ def begin(self, Other Parameters ---------------- - apply_baseline_correction: bool - Only applies when non-calibrated data are read. If true, correct for DC offset. - (Default: True) + apply_baseline_correction: 'median' | 'approximate' | 'fit' | 'none' + Only applies when non-calibrated data are read. Removes the DC (baseline) + block offsets (pedestals). + Options are: + + * 'median' (Default) - subtract the median of each block + * 'approximate' - apply a bandpass filter before calculating the median of each block + * 'fit' - do a full out-of-band fit to determine the block offsets; for more details, + see ``NuRadioReco.modules.RNO_G.channelBlockOffsetFitter`` + * 'none' - do not apply a baseline correction convert_to_voltage: bool Only applies when non-calibrated data are read. If true, convert ADC to voltage. @@ -245,6 +264,12 @@ def begin(self, t0 = time.time() self._read_calibrated_data = read_calibrated_data + baseline_correction_valid_options = ['median', 'approximate', 'fit', 'none'] + if apply_baseline_correction.lower() not in baseline_correction_valid_options: + raise ValueError( + f"Value for apply_baseline_correction ({apply_baseline_correction}) not recognized. " + f"Valid options are {baseline_correction_valid_options}" + ) self._apply_baseline_correction = apply_baseline_correction self._convert_to_voltage = convert_to_voltage @@ -614,17 +639,17 @@ def _get_event(self, event_info, waveforms): if self._read_calibrated_data: channel.set_trace(wf * units.mV, sampling_rate * units.GHz) else: - # wf stores ADC counts - - if self._apply_baseline_correction: - # correct baseline - wf = baseline_correction(wf) - + # wf stores ADC counts if self._convert_to_voltage: # convert adc to voltage wf *= (self._adc_ref_voltage_range / (2 ** (self._adc_n_bits) - 1)) - + + if self._apply_baseline_correction == 'median': + # correct baseline + wf, offsets = baseline_correction(wf, return_offsets=True) + channel.set_trace(wf, sampling_rate * units.GHz) + channel.set_parameter(NuRadioReco.framework.parameters.channelParameters.block_offsets, offsets) time_offset = get_time_offset(event_info.triggerType) channel.set_trace_start_time(-time_offset) # relative to event/trigger time @@ -632,7 +657,9 @@ def _get_event(self, event_info, waveforms): station.add_channel(channel) evt.set_station(station) - + if self._apply_baseline_correction in ['fit', 'approximate'] and not self._read_calibrated_data: + blockoffsetfitter.remove_offsets(evt, station, mode=self._apply_baseline_correction) + return evt From 87a505d379e438ca0af39f31dc9fb576d3f3960e Mon Sep 17 00:00:00 2001 From: Sjoerd Bouma Date: Mon, 25 Sep 2023 14:12:10 +0200 Subject: [PATCH 360/418] change *= to prevent error due to Type change from int to float --- NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py b/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py index fbed78970..247bdb0b0 100644 --- a/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py +++ b/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py @@ -642,7 +642,7 @@ def _get_event(self, event_info, waveforms): # wf stores ADC counts if self._convert_to_voltage: # convert adc to voltage - wf *= (self._adc_ref_voltage_range / (2 ** (self._adc_n_bits) - 1)) + wf = wf * (self._adc_ref_voltage_range / (2 ** (self._adc_n_bits) - 1)) if self._apply_baseline_correction == 'median': # correct baseline From 23843233f3f3ef89391639e8f85592ddc0575b21 Mon Sep 17 00:00:00 2001 From: Sjoerd Bouma Date: Mon, 25 Sep 2023 14:19:45 +0200 Subject: [PATCH 361/418] store offsets only if they are actually computed --- NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py b/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py index 247bdb0b0..f31c1f80c 100644 --- a/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py +++ b/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py @@ -647,9 +647,9 @@ def _get_event(self, event_info, waveforms): if self._apply_baseline_correction == 'median': # correct baseline wf, offsets = baseline_correction(wf, return_offsets=True) + channel.set_parameter(NuRadioReco.framework.parameters.channelParameters.block_offsets, offsets) channel.set_trace(wf, sampling_rate * units.GHz) - channel.set_parameter(NuRadioReco.framework.parameters.channelParameters.block_offsets, offsets) time_offset = get_time_offset(event_info.triggerType) channel.set_trace_start_time(-time_offset) # relative to event/trigger time From eac872a1e03e150e76c97f81f97bc8a857b59982 Mon Sep 17 00:00:00 2001 From: AJ <52336270+aj-nielsen@users.noreply.github.com> Date: Mon, 25 Sep 2023 13:08:15 -0700 Subject: [PATCH 362/418] Update changelog.txt Moved bugfix comment under 2.2.0-dev --- changelog.txt | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/changelog.txt b/changelog.txt index 72d7dfc0e..3916060ef 100644 --- a/changelog.txt +++ b/changelog.txt @@ -2,10 +2,6 @@ Changelog - to keep track of all relevant changes please update the categories "new features" and "bugfixes" before a pull request merge! -version 2.2.1-dev -bugfix: --in antennapattern.py, fixed line 1398; was masking frequencies >= 0 instead of frequencies > 0, causing NaN errors - version 2.2.0-dev new features: - added getting to query ARZ charge-excess profiles @@ -21,6 +17,8 @@ new features: bugfixes: - fixed/improved C++ raytracer not finding solutions for some near-horizontal or near-shadowzone vertices - fixed wrong number in Feldman-Cousins upper limit +- in antennapattern.py, fixed line 1398; was masking frequencies >= 0 instead of frequencies > 0, causing NaN errors + version 2.1.8 bugfixes: From 633710324c8bd55b6fd964772de0021d52b69597 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= Date: Mon, 25 Sep 2023 22:40:57 +0200 Subject: [PATCH 363/418] Rename __parse_detector to _parse_detector. Downgrade logger.info() to logger.debug. Downgrade raise error to warning and return none --- NuRadioReco/modules/io/NuRadioRecoio.py | 13 +++++++------ NuRadioReco/modules/io/event_parser_factory.py | 4 ++-- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/NuRadioReco/modules/io/NuRadioRecoio.py b/NuRadioReco/modules/io/NuRadioRecoio.py index 5dd7d8d68..0544ac553 100644 --- a/NuRadioReco/modules/io/NuRadioRecoio.py +++ b/NuRadioReco/modules/io/NuRadioRecoio.py @@ -73,7 +73,7 @@ def __init__(self, filenames, parse_header=True, parse_detector=True, fail_on_ve self.__fail_on_version_mismatch = fail_on_version_mismatch self.__fail_on_minor_version_mismatch = fail_on_minor_version_mismatch self.__parse_header = parse_header - self.__parse_detector = parse_detector + self._parse_detector = parse_detector self.__read_lock = False self.__max_open_files = max_open_files self.__buffer_size = buffer_size @@ -215,18 +215,18 @@ def __scan_files(self): iF_prev = None while True: if iF_prev != iF: - self.logger.info(f"Start scanning file {iF} ...") + self.logger.debug(f"Start scanning file {iF} ...") iF_prev = iF self._get_file(iF).seek(current_byte) continue_loop, iF, current_byte = self.__scan_files_versioned(self, iF, current_byte) if iF_prev != iF: - self.logger.info(f"Finished scanning file {iF_prev}.") + self.logger.debug(f"Finished scanning file {iF_prev}.") if not continue_loop: break - self.logger.info(f"Finished scanning file {iF}. Finished all") + self.logger.debug(f"Finished scanning file {iF}. Finished all") self.__event_ids = np.array(self.__event_ids) self.__file_scanned = True @@ -341,7 +341,7 @@ def get_detector(self): event is given. """ - if not self.__parse_detector: + if not self._parse_detector: self.logger.warn(f"You called \"get_detector\", however, \"parse_detector\" is set to false. Return None!") return None @@ -354,7 +354,8 @@ def get_detector(self): self.__scan_files() # Maybe we just forgot to scan the file if self._current_file_id not in self._detector_dicts: - raise AttributeError('The current file does not contain a detector description.') + self.logger.warn('The current file does not contain a detector description. Return None') + return None detector_dict = self._detector_dicts[self._current_file_id] if 'generic_detector' in detector_dict.keys(): diff --git a/NuRadioReco/modules/io/event_parser_factory.py b/NuRadioReco/modules/io/event_parser_factory.py index a0a33224a..abe9fd68b 100644 --- a/NuRadioReco/modules/io/event_parser_factory.py +++ b/NuRadioReco/modules/io/event_parser_factory.py @@ -10,7 +10,7 @@ def scan_files_function(version_major, version_minor): """ def scan_files_2_0(self, iF, current_byte): - if self.__parse_detector: + if self._parse_detector: self.logger(f"Scanning a file of version 2.0 which does not contain a detector object. " f"However, \"parse_detector\" is true.") @@ -90,7 +90,7 @@ def scan_files_2_2(self, iF, current_byte): self._bytes_start[iF].append(current_byte) self._bytes_length[iF].append(bytes_to_read) - elif object_type == 1 and self.__parse_detector: # object is detector info + elif object_type == 1 and self._parse_detector: # object is detector info self.logger.debug("Read detector ...") detector_dict = pickle.loads(self._get_file(iF).read(bytes_to_read)) From ba3b1b2d51db9266480f2e4cbbeed5071967f3a6 Mon Sep 17 00:00:00 2001 From: Sjoerd Bouma Date: Tue, 26 Sep 2023 16:36:32 +0200 Subject: [PATCH 364/418] make blockoffsetfitter faster by setting maxiter=2 by default --- .../modules/RNO_G/channelBlockOffsetFitter.py | 20 ++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/NuRadioReco/modules/RNO_G/channelBlockOffsetFitter.py b/NuRadioReco/modules/RNO_G/channelBlockOffsetFitter.py index e686e3b75..b55247799 100644 --- a/NuRadioReco/modules/RNO_G/channelBlockOffsetFitter.py +++ b/NuRadioReco/modules/RNO_G/channelBlockOffsetFitter.py @@ -13,7 +13,7 @@ from NuRadioReco.framework.base_trace import BaseTrace from NuRadioReco.framework.parameters import channelParameters import numpy as np -import scipy +import scipy.optimize class channelBlockOffsets: @@ -95,7 +95,7 @@ def add_offsets(self, event, station, offsets=1*units.mV, channel_ids=None): channel.get_sampling_rate() ) - def remove_offsets(self, event, station, mode='fit', channel_ids=None): + def remove_offsets(self, event, station, mode='fit', channel_ids=None, maxiter=2): """ Remove block offsets from an event @@ -120,6 +120,11 @@ def remove_offsets(self, event, station, mode='fit', channel_ids=None): channel_ids: list | None List of channel ids to remove offsets from. If None (default), remove offsets from all channels in ``station`` + maxiter: int, default 2 + (Only if mode=='fit') The maximum number of fit iterations. + This can be increased to more accurately remove the block offsets + at the cost of performance. (The default value removes 'most' offsets + to about 1%) """ if channel_ids is None: @@ -138,7 +143,7 @@ def remove_offsets(self, event, station, mode='fit', channel_ids=None): block_offsets = fit_block_offsets( trace, self.block_size, channel.get_sampling_rate(), self._max_frequency, - mode=mode + mode=mode, maxiter=maxiter ) offsets[channel_id] = -block_offsets @@ -148,7 +153,7 @@ def remove_offsets(self, event, station, mode='fit', channel_ids=None): def fit_block_offsets( trace, block_size=128, sampling_rate=3.2*units.GHz, max_frequency=50*units.MHz, mode='fit', return_trace = False, - tol=1e-6,): + maxiter=2, tol=1e-6): """ Fit 'block' offsets for a voltage trace @@ -175,6 +180,11 @@ def fit_block_offsets( if True, return the tuple (offsets, output_trace) where the output_trace is the input trace with fitted block offsets removed + maxiter: int (default: 2) + (Only if mode=='fit') The maximum number of fit iterations. + This can be increased to more accurately remove the block offsets + at the cost of performance. (The default value removes 'most' offsets + to about 1%) Returns ------- @@ -235,7 +245,7 @@ def pedestal_fit(a): chi2 = np.sum(np.abs(fit-spectrum_oob)**2) return chi2 - res = scipy.optimize.minimize(pedestal_fit, a_guess, tol=tol).x + res = scipy.optimize.minimize(pedestal_fit, a_guess, tol=tol, options=dict(maxiter=maxiter)).x block_offsets = np.zeros(len(res) + 1) block_offsets[:-1] = res From 80ef76dfbd4bfc3e9e846968af1cf59781ae44f2 Mon Sep 17 00:00:00 2001 From: Sjoerd Bouma Date: Tue, 26 Sep 2023 17:00:55 +0200 Subject: [PATCH 365/418] deprecate old baseline correction in readRNOGDataMattak --- .../modules/io/RNO_G/readRNOGDataMattak.py | 25 ++++++++++++------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py b/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py index f31c1f80c..5a349f8a8 100644 --- a/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py +++ b/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py @@ -20,8 +20,13 @@ def baseline_correction(wfs, n_bins=128, func=np.median, return_offsets=False): """ - Simple baseline correction function. Determines baseline in discrete chuncks of "n_bins" with + Simple baseline correction function. + + Determines baseline in discrete chuncks of "n_bins" with the function specified (i.e., mean or median). + + .. Warning:: This function has been deprecated, use :mod:`NuRadioReco.modules.RNO_G.channelBlockOffsetFitter` + instead Parameters ---------- @@ -47,7 +52,10 @@ def baseline_correction(wfs, n_bins=128, func=np.median, return_offsets=False): baseline_values: np.array of shape (n_samples // n_bins, n_events, n_channels) (Only if return_offsets==True) The baseline offsets """ - + import warnings + warnings.warn( + 'baseline_correction is deprecated, use NuRadioReco.modules.RNO_G.channelBlockOffsetFitter instead', + DeprecationWarning) # Example: Get baselines in chunks of 128 bins # wfs in (n_events, n_channels, 2048) # np.split -> (16, n_events, n_channels, 128) each waveform split in 16 chuncks @@ -187,7 +195,7 @@ def begin(self, read_calibrated_data=False, select_triggers=None, select_runs=False, - apply_baseline_correction='median', + apply_baseline_correction='approximate', convert_to_voltage=True, selectors=[], run_types=["physics"], @@ -218,16 +226,15 @@ def begin(self, Other Parameters ---------------- - apply_baseline_correction: 'median' | 'approximate' | 'fit' | 'none' + apply_baseline_correction: 'approximate' | 'fit' | 'none' Only applies when non-calibrated data are read. Removes the DC (baseline) block offsets (pedestals). Options are: - * 'median' (Default) - subtract the median of each block - * 'approximate' - apply a bandpass filter before calculating the median of each block + * 'approximate' (default) - estimate block offsets by looking at the low-pass filtered trace * 'fit' - do a full out-of-band fit to determine the block offsets; for more details, see ``NuRadioReco.modules.RNO_G.channelBlockOffsetFitter`` - * 'none' - do not apply a baseline correction + * 'none' - do not apply a baseline correction (faster) convert_to_voltage: bool Only applies when non-calibrated data are read. If true, convert ADC to voltage. @@ -264,7 +271,7 @@ def begin(self, t0 = time.time() self._read_calibrated_data = read_calibrated_data - baseline_correction_valid_options = ['median', 'approximate', 'fit', 'none'] + baseline_correction_valid_options = ['approximate', 'fit', 'none'] if apply_baseline_correction.lower() not in baseline_correction_valid_options: raise ValueError( f"Value for apply_baseline_correction ({apply_baseline_correction}) not recognized. " @@ -644,7 +651,7 @@ def _get_event(self, event_info, waveforms): # convert adc to voltage wf = wf * (self._adc_ref_voltage_range / (2 ** (self._adc_n_bits) - 1)) - if self._apply_baseline_correction == 'median': + if self._apply_baseline_correction == 'median': #TODO: deprecate / remove # correct baseline wf, offsets = baseline_correction(wf, return_offsets=True) channel.set_parameter(NuRadioReco.framework.parameters.channelParameters.block_offsets, offsets) From 291433e3fd71b69ef0e0c6052adddbf8ae19a920 Mon Sep 17 00:00:00 2001 From: Sjoerd Bouma Date: Tue, 26 Sep 2023 17:08:55 +0200 Subject: [PATCH 366/418] remove inaccessible old baseline correction code --- NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py b/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py index 5a349f8a8..783ed512b 100644 --- a/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py +++ b/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py @@ -651,11 +651,6 @@ def _get_event(self, event_info, waveforms): # convert adc to voltage wf = wf * (self._adc_ref_voltage_range / (2 ** (self._adc_n_bits) - 1)) - if self._apply_baseline_correction == 'median': #TODO: deprecate / remove - # correct baseline - wf, offsets = baseline_correction(wf, return_offsets=True) - channel.set_parameter(NuRadioReco.framework.parameters.channelParameters.block_offsets, offsets) - channel.set_trace(wf, sampling_rate * units.GHz) time_offset = get_time_offset(event_info.triggerType) From 600359d28ae4e7d3cdf82ab5d3ee293d6b165eea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= <30903175+fschlueter@users.noreply.github.com> Date: Tue, 26 Sep 2023 19:27:23 +0200 Subject: [PATCH 367/418] Update event.py Copy kwargs dicts before manipulating them --- NuRadioReco/framework/event.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/NuRadioReco/framework/event.py b/NuRadioReco/framework/event.py index a1a211015..c199d0c26 100644 --- a/NuRadioReco/framework/event.py +++ b/NuRadioReco/framework/event.py @@ -8,6 +8,7 @@ import NuRadioReco.utilities.version from six import itervalues import collections +import copy import logging logger = logging.getLogger('Event') @@ -45,7 +46,7 @@ def register_module_event(self, instance, name, kwargs): kwargs: the key word arguments of the run method """ - + kwargs = copy.deepcopy(kwargs) # Not every kwargs argument passed to a run(..) method is serializable. Example is a detector object. # Drop all arguments for which this is the case keys_to_be_dropped = [key for key in kwargs @@ -72,6 +73,8 @@ def register_module_station(self, station_id, instance, name, kwargs): kwargs: the key word arguments of the run method """ + kwargs = copy.deepcopy(kwargs) + if station_id not in self.__modules_station: self.__modules_station[station_id] = [] From e3b640915ff414f2f241871bbd211c2e342d10b1 Mon Sep 17 00:00:00 2001 From: Sjoerd Bouma Date: Fri, 29 Sep 2023 14:52:42 +0200 Subject: [PATCH 368/418] add thread-locking to prevent multiple file_handlers with same id --- NuRadioReco/eventbrowser/dataprovider.py | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/NuRadioReco/eventbrowser/dataprovider.py b/NuRadioReco/eventbrowser/dataprovider.py index 772d422c3..d5fa44614 100644 --- a/NuRadioReco/eventbrowser/dataprovider.py +++ b/NuRadioReco/eventbrowser/dataprovider.py @@ -1,6 +1,12 @@ import NuRadioReco.eventbrowser.dataprovider_root import NuRadioReco.eventbrowser.dataprovider_nur +import threading +import logging +logging.basicConfig() +logger = logging.getLogger('eventbrowser.dataprovider') +logger.setLevel(logging.INFO) +LOCK = threading.Lock() class DataProvider(object): __instance = None @@ -20,4 +26,12 @@ def set_filetype(self, use_root): self.__data_provider = NuRadioReco.eventbrowser.dataprovider_nur.DataProvider() def get_file_handler(self, user_id, filename): - return self.__data_provider.get_file_handler(user_id, filename) + thread = threading.get_ident() + total_threads = threading.active_count() + logger.debug(f"Thread {thread} out of total {total_threads} requesting file_handler for user {user_id}") + LOCK.acquire() + logger.debug(f"Thread {thread} locked, getting file_handler for user {user_id}...") + file_handler = self.__data_provider.get_file_handler(user_id, filename) + LOCK.release() + logger.debug(f"Returning file_handler and releasing lock") + return file_handler From 3af7aacb250fdf2d664f95f964034079d1b19aec Mon Sep 17 00:00:00 2001 From: Sjoerd Bouma Date: Fri, 29 Sep 2023 14:52:58 +0200 Subject: [PATCH 369/418] make sure event ids are always initialised --- NuRadioReco/eventbrowser/dataprovider_root.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/NuRadioReco/eventbrowser/dataprovider_root.py b/NuRadioReco/eventbrowser/dataprovider_root.py index 603696f47..712e8560d 100644 --- a/NuRadioReco/eventbrowser/dataprovider_root.py +++ b/NuRadioReco/eventbrowser/dataprovider_root.py @@ -2,6 +2,11 @@ import os import time import numpy as np +import logging +import threading +logging.basicConfig() +logger = logging.getLogger('eventbrowser') +logger.setLevel(logging.DEBUG) ### we create a wrapper for readRNOGData to mirror the interface of the .nur reader class readRNOG_wrapper(readRNOGData): @@ -40,6 +45,7 @@ def __init__(self, max_user_instances=12): requests for new readers drop older readers. """ + logger.info("Creating new DataProviderRoot instance") self.__max_user_instances = max_user_instances self.__user_instances = {} @@ -47,7 +53,6 @@ def get_file_handler(self, user_id, filename): if filename is None: return if user_id not in self.__user_instances: - # create new reader for the new user reader = readRNOG_wrapper() self.__user_instances[user_id] = dict( reader=reader, filename=None, @@ -56,6 +61,7 @@ def get_file_handler(self, user_id, filename): # user is requesting new file -> close current file and open new one reader = self.__user_instances[user_id]['reader'] reader.begin([os.path.dirname(filename)], overwrite_sampling_rate=3.2) #TODO - remove hardcoded sampling rate + reader.get_event_ids() # self.__user_instances[user_id] = dict( reader=reader, filename=filename, ) @@ -72,5 +78,5 @@ def get_file_handler(self, user_id, filename): users_by_access_time = sorted(users) # drop oldest session self.__user_instances.pop(users_by_access_time[0]) - + return self.__user_instances[user_id]['reader'] From 55d729a6ae636279e2a3f1b76256aa6f591765d4 Mon Sep 17 00:00:00 2001 From: Sjoerd Bouma Date: Fri, 29 Sep 2023 14:53:49 +0200 Subject: [PATCH 370/418] explicitly cast slider positions to ints to avoid mysterious error --- NuRadioReco/eventbrowser/index.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/NuRadioReco/eventbrowser/index.py b/NuRadioReco/eventbrowser/index.py index aa8a9bcd0..ec1b402a4 100644 --- a/NuRadioReco/eventbrowser/index.py +++ b/NuRadioReco/eventbrowser/index.py @@ -271,9 +271,9 @@ def update_slider_marks(filename, juser_id): step_size = int(np.power(10., int(np.log10(n_events)))) marks = {} for i in range(0, n_events, step_size): - marks[i] = str(i) + marks[int(i)] = str(i) if n_events % step_size != 0: - marks[n_events] = str(n_events) + marks[int(n_events)] = str(n_events) return marks From 83e4e6dde549be64b501a6bef707eaa5fd106afc Mon Sep 17 00:00:00 2001 From: Sjoerd Bouma Date: Fri, 29 Sep 2023 14:56:35 +0200 Subject: [PATCH 371/418] change to new RNO-G data reader for example --- .../examples/RNO_data/read_data_example/run_reconstruction.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/NuRadioReco/examples/RNO_data/read_data_example/run_reconstruction.py b/NuRadioReco/examples/RNO_data/read_data_example/run_reconstruction.py index 10e50965d..10fe88283 100644 --- a/NuRadioReco/examples/RNO_data/read_data_example/run_reconstruction.py +++ b/NuRadioReco/examples/RNO_data/read_data_example/run_reconstruction.py @@ -1,6 +1,6 @@ import NuRadioReco import matplotlib.pyplot as plt -from NuRadioReco.modules.io.rno_g.readRNOGData import readRNOGData +from NuRadioReco.modules.io.RNO_G.readRNOGDataMattak import readRNOGData import pandas as pd import numpy as np from NuRadioReco.utilities import units @@ -37,7 +37,7 @@ list_of_root_files = ['pulser_data_21.root'] -readRNOGData = NuRadioReco.modules.io.rno_g.readRNOGData.readRNOGData() +readRNOGData = NuRadioReco.modules.io.RNO_G.readRNOGDataMattak.readRNOGData() readRNOGData.begin(list_of_root_files) for i_event, event in enumerate(readRNOGData.run()): From 2945800bfb36260d46a2d46cb7f6ab100d6f352b Mon Sep 17 00:00:00 2001 From: Sjoerd Bouma Date: Fri, 29 Sep 2023 16:00:41 +0200 Subject: [PATCH 372/418] move serializability check over to base.module --- NuRadioReco/framework/event.py | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/NuRadioReco/framework/event.py b/NuRadioReco/framework/event.py index c199d0c26..0198b7a09 100644 --- a/NuRadioReco/framework/event.py +++ b/NuRadioReco/framework/event.py @@ -8,15 +8,10 @@ import NuRadioReco.utilities.version from six import itervalues import collections -import copy import logging logger = logging.getLogger('Event') -def is_serializable(obj): - return obj.__class__.__module__ == 'builtins' or obj.__class__.__module__ == "numpy" - - class Event: def __init__(self, run_number, event_id): @@ -46,15 +41,6 @@ def register_module_event(self, instance, name, kwargs): kwargs: the key word arguments of the run method """ - kwargs = copy.deepcopy(kwargs) - # Not every kwargs argument passed to a run(..) method is serializable. Example is a detector object. - # Drop all arguments for which this is the case - keys_to_be_dropped = [key for key in kwargs - if not is_serializable(kwargs[key])] - - for key in keys_to_be_dropped: - logger.warn(f"Dropping \"{key}\" of type {type(kwargs[key])} from kwargs of __modules_event") - kwargs.pop(key) self.__modules_event.append([name, instance, kwargs]) @@ -73,20 +59,9 @@ def register_module_station(self, station_id, instance, name, kwargs): kwargs: the key word arguments of the run method """ - kwargs = copy.deepcopy(kwargs) - if station_id not in self.__modules_station: self.__modules_station[station_id] = [] - # Not every kwargs argument passed to a run(..) method is serializable. Example is a detector object. - # Drop all arguments for which this is the case - keys_to_be_dropped = [key for key in kwargs - if not is_serializable(kwargs[key])] - - for key in keys_to_be_dropped: - logger.warn(f"Dropping \"{key}\" of type {type(kwargs[key])} from kwargs of __modules_station") - kwargs.pop(key) - iE = len(self.__modules_event) self.__modules_station[station_id].append([iE, name, instance, kwargs]) From 535c00834304ec877a4a0bde4c134a9b1b71f4e3 Mon Sep 17 00:00:00 2001 From: Sjoerd Bouma Date: Fri, 29 Sep 2023 16:01:48 +0200 Subject: [PATCH 373/418] store all serializable run arguments (positional or keyword) --- NuRadioReco/modules/base/module.py | 70 ++++++++++++++++++------------ 1 file changed, 42 insertions(+), 28 deletions(-) diff --git a/NuRadioReco/modules/base/module.py b/NuRadioReco/modules/base/module.py index 3df0e7af6..83cf070df 100644 --- a/NuRadioReco/modules/base/module.py +++ b/NuRadioReco/modules/base/module.py @@ -3,7 +3,7 @@ import NuRadioReco.framework.event import NuRadioReco.framework.base_station import logging - +import inspect def setup_logger(name="NuRadioReco", level=logging.WARNING): @@ -23,6 +23,20 @@ def register_run(level=None): which module is executed in which order and with what parameters. Also the execution time of each module is tracked. """ + + def is_serializable(obj): + """ + Check that the object consists of builtins or numpy objects only + + If this is not the case, this may lead to errors when attempting to + serialize it. + """ + if isinstance(obj, dict): # check that all objects inside are serializable + return all([is_serializable(value) for value in obj.values()]) + elif isinstance(obj, list): + return all([is_serializable(value) for value in obj]) + + return obj.__class__.__module__ == 'builtins' or obj.__class__.__module__ == "numpy" def run_decorator(run): @@ -40,40 +54,40 @@ def register_run_method(self, *args, **kwargs): evt = None station = None - # find out type of module automatically - if len(args) == 1: - if isinstance(args[0], NuRadioReco.framework.event.Event): - module_level = "event" - evt = args[0] - else: - # this is a module that creats events - module_level = "reader" - elif len(args) >= 2: - if isinstance(args[0], NuRadioReco.framework.event.Event) and isinstance(args[1], NuRadioReco.framework.base_station.BaseStation): - module_level = "station" - evt = args[0] - station = args[1] - elif isinstance(args[0], NuRadioReco.framework.event.Event): - module_level = "event" - evt = args[0] - else: - # this is a module that creates events - module_level = "reader" - raise AttributeError("first argument of run method is not of type NuRadioReco.framework.event.Event") + signature = inspect.signature(run) + parameters = signature.parameters + # convert args to kwargs to facilitate easier bookkeeping + all_kwargs = {key:value for key,value in zip(parameters.keys(), args)} + all_kwargs.update(kwargs) # this silently overwrites positional args with kwargs, but this is probably okay as we still raise an error later + + # include parameters with default values + for key,value in parameters.items(): + if key not in all_kwargs.keys(): + if value.default is not inspect.Parameter.empty: + all_kwargs[key] = value + + for key,value in all_kwargs.items(): + if isinstance(value, NuRadioReco.framework.event.Event): + evt = value + elif isinstance(value, NuRadioReco.framework.base_station.BaseStation): + station = value + + if station is not None: + module_level = "station" + elif evt is not None: + module_level = "event" else: - # this is a module that creats events module_level = "reader" + # we only store serializable objects to avoid errors + store_kwargs = {key:value for key,value in all_kwargs.items() if is_serializable(value)} + start = timer() - - # Currently we are not storing the args with which the module is called. Typically those are the event and/or station - # on which the module is run which should not be stored here. The danger is if other data is passed as args - # kwargs["args"] = args # otherwise we do not store the args if module_level == "event": - evt.register_module_event(self, self.__class__.__name__, kwargs) + evt.register_module_event(self, self.__class__.__name__, store_kwargs) elif module_level == "station": - evt.register_module_station(station.get_id(), self, self.__class__.__name__, kwargs) + evt.register_module_station(station.get_id(), self, self.__class__.__name__, store_kwargs) elif module_level == "reader": # not sure what to do... function returns generator, not sure how to access the event... pass From 3b23407cc1a2d4560f398d43e63157821fdd77aa Mon Sep 17 00:00:00 2001 From: Sjoerd Bouma Date: Fri, 29 Sep 2023 18:36:52 +0200 Subject: [PATCH 374/418] correctly store default values --- NuRadioReco/modules/base/module.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NuRadioReco/modules/base/module.py b/NuRadioReco/modules/base/module.py index 83cf070df..c27a4a5d0 100644 --- a/NuRadioReco/modules/base/module.py +++ b/NuRadioReco/modules/base/module.py @@ -64,7 +64,7 @@ def register_run_method(self, *args, **kwargs): for key,value in parameters.items(): if key not in all_kwargs.keys(): if value.default is not inspect.Parameter.empty: - all_kwargs[key] = value + all_kwargs[key] = value.default for key,value in all_kwargs.items(): if isinstance(value, NuRadioReco.framework.event.Event): From 30726a0ce6e920d7de58c656a8ad0a1286f0aa42 Mon Sep 17 00:00:00 2001 From: Sjoerd Bouma Date: Fri, 29 Sep 2023 19:11:20 +0200 Subject: [PATCH 375/418] increase default number of iterations to 5 --- NuRadioReco/modules/RNO_G/channelBlockOffsetFitter.py | 8 ++++---- NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/NuRadioReco/modules/RNO_G/channelBlockOffsetFitter.py b/NuRadioReco/modules/RNO_G/channelBlockOffsetFitter.py index b55247799..e4711e094 100644 --- a/NuRadioReco/modules/RNO_G/channelBlockOffsetFitter.py +++ b/NuRadioReco/modules/RNO_G/channelBlockOffsetFitter.py @@ -95,7 +95,7 @@ def add_offsets(self, event, station, offsets=1*units.mV, channel_ids=None): channel.get_sampling_rate() ) - def remove_offsets(self, event, station, mode='fit', channel_ids=None, maxiter=2): + def remove_offsets(self, event, station, mode='fit', channel_ids=None, maxiter=5): """ Remove block offsets from an event @@ -120,7 +120,7 @@ def remove_offsets(self, event, station, mode='fit', channel_ids=None, maxiter=2 channel_ids: list | None List of channel ids to remove offsets from. If None (default), remove offsets from all channels in ``station`` - maxiter: int, default 2 + maxiter: int, default 5 (Only if mode=='fit') The maximum number of fit iterations. This can be increased to more accurately remove the block offsets at the cost of performance. (The default value removes 'most' offsets @@ -153,7 +153,7 @@ def remove_offsets(self, event, station, mode='fit', channel_ids=None, maxiter=2 def fit_block_offsets( trace, block_size=128, sampling_rate=3.2*units.GHz, max_frequency=50*units.MHz, mode='fit', return_trace = False, - maxiter=2, tol=1e-6): + maxiter=5, tol=1e-6): """ Fit 'block' offsets for a voltage trace @@ -180,7 +180,7 @@ def fit_block_offsets( if True, return the tuple (offsets, output_trace) where the output_trace is the input trace with fitted block offsets removed - maxiter: int (default: 2) + maxiter: int (default: 5) (Only if mode=='fit') The maximum number of fit iterations. This can be increased to more accurately remove the block offsets at the cost of performance. (The default value removes 'most' offsets diff --git a/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py b/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py index 783ed512b..9b5783e8b 100644 --- a/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py +++ b/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py @@ -17,6 +17,7 @@ from NuRadioReco.utilities import units import mattak.Dataset +blockoffsetfitter = channelBlockOffsets() def baseline_correction(wfs, n_bins=128, func=np.median, return_offsets=False): """ @@ -78,7 +79,6 @@ def baseline_correction(wfs, n_bins=128, func=np.median, return_offsets=False): return wfs - baseline_traces -blockoffsetfitter = channelBlockOffsets() def get_time_offset(trigger_type): """ From 69f6fda60b1638f9766a039ec2557a128c52aa8e Mon Sep 17 00:00:00 2001 From: Sjoerd Bouma Date: Fri, 29 Sep 2023 19:13:22 +0200 Subject: [PATCH 376/418] make blockoffsetfitter a private attribute to reduce clutter in module --- NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py b/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py index 9b5783e8b..7ca5edd89 100644 --- a/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py +++ b/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py @@ -17,7 +17,6 @@ from NuRadioReco.utilities import units import mattak.Dataset -blockoffsetfitter = channelBlockOffsets() def baseline_correction(wfs, n_bins=128, func=np.median, return_offsets=False): """ @@ -169,6 +168,8 @@ def __init__(self, run_table_path=None, log_level=logging.INFO): """ self.logger = logging.getLogger('NuRadioReco.readRNOGData') self.logger.setLevel(log_level) + + self._blockoffsetfitter = channelBlockOffsets() # Initialize run table for run selection self.__run_table = None @@ -233,7 +234,7 @@ def begin(self, * 'approximate' (default) - estimate block offsets by looking at the low-pass filtered trace * 'fit' - do a full out-of-band fit to determine the block offsets; for more details, - see ``NuRadioReco.modules.RNO_G.channelBlockOffsetFitter`` + see :mod:`NuRadioReco.modules.RNO_G.channelBlockOffsetFitter` * 'none' - do not apply a baseline correction (faster) convert_to_voltage: bool @@ -660,7 +661,7 @@ def _get_event(self, event_info, waveforms): evt.set_station(station) if self._apply_baseline_correction in ['fit', 'approximate'] and not self._read_calibrated_data: - blockoffsetfitter.remove_offsets(evt, station, mode=self._apply_baseline_correction) + self._blockoffsetfitter.remove_offsets(evt, station, mode=self._apply_baseline_correction) return evt From 7db677ec62474e92477b920ac8ebb473c59612b8 Mon Sep 17 00:00:00 2001 From: Sjoerd Bouma Date: Tue, 3 Oct 2023 13:31:33 +0200 Subject: [PATCH 377/418] switch to EAFP approach for storing arguments (try to pickle everything) --- NuRadioReco/modules/base/module.py | 33 +++++++++++------------------- 1 file changed, 12 insertions(+), 21 deletions(-) diff --git a/NuRadioReco/modules/base/module.py b/NuRadioReco/modules/base/module.py index c27a4a5d0..181719e37 100644 --- a/NuRadioReco/modules/base/module.py +++ b/NuRadioReco/modules/base/module.py @@ -4,6 +4,7 @@ import NuRadioReco.framework.base_station import logging import inspect +import pickle def setup_logger(name="NuRadioReco", level=logging.WARNING): @@ -24,20 +25,6 @@ def register_run(level=None): module is tracked. """ - def is_serializable(obj): - """ - Check that the object consists of builtins or numpy objects only - - If this is not the case, this may lead to errors when attempting to - serialize it. - """ - if isinstance(obj, dict): # check that all objects inside are serializable - return all([is_serializable(value) for value in obj.values()]) - elif isinstance(obj, list): - return all([is_serializable(value) for value in obj]) - - return obj.__class__.__module__ == 'builtins' or obj.__class__.__module__ == "numpy" - def run_decorator(run): @wraps(run) @@ -66,21 +53,25 @@ def register_run_method(self, *args, **kwargs): if value.default is not inspect.Parameter.empty: all_kwargs[key] = value.default - for key,value in all_kwargs.items(): - if isinstance(value, NuRadioReco.framework.event.Event): + store_kwargs = {} + for idx, (key,value) in enumerate(all_kwargs.items()): + if isinstance(value, NuRadioReco.framework.event.Event) and idx == 0: # event should be the first argument evt = value - elif isinstance(value, NuRadioReco.framework.base_station.BaseStation): + elif isinstance(value, NuRadioReco.framework.base_station.BaseStation) and idx == 1: # station should be second argument station = value - + else: # we try to store other arguments IF they are pickleable + try: + pickle.dumps(value, protocol=4) + store_kwargs[key] = value + except TypeError as e: # object couldn't be pickled - we store the error instead + store_kwargs[key] = e + if station is not None: module_level = "station" elif evt is not None: module_level = "event" else: module_level = "reader" - - # we only store serializable objects to avoid errors - store_kwargs = {key:value for key,value in all_kwargs.items() if is_serializable(value)} start = timer() From 85bf9239a9f2ffa6c5084c3444317ec7fad5c3c3 Mon Sep 17 00:00:00 2001 From: Sjoerd Bouma Date: Tue, 3 Oct 2023 13:31:53 +0200 Subject: [PATCH 378/418] raise warnings for dropped arguments --- NuRadioReco/framework/event.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/NuRadioReco/framework/event.py b/NuRadioReco/framework/event.py index 0198b7a09..bd9f2ab4d 100644 --- a/NuRadioReco/framework/event.py +++ b/NuRadioReco/framework/event.py @@ -443,12 +443,18 @@ def serialize(self, mode): modules_out_event = [] for value in self.__modules_event: # remove module instances (this will just blow up the file size) modules_out_event.append([value[0], None, value[2]]) + invalid_keys = [key for key,val in value[2].items() if isinstance(val, TypeError)] + if len(invalid_keys): + logger.warning(f"The following arguments to module {value[0]} could not be serialized and will not be stored: {invalid_keys}") modules_out_station = {} for key in self.__modules_station: # remove module instances (this will just blow up the file size) modules_out_station[key] = [] for value in self.__modules_station[key]: modules_out_station[key].append([value[0], value[1], None, value[3]]) + invalid_keys = [key for key,val in value[3].items() if isinstance(val, TypeError)] + if len(invalid_keys): + logger.warning(f"The following arguments to module {value[0]} could not be serialized and will not be stored: {invalid_keys}") data = {'_parameters': self._parameters, '__run_number': self.__run_number, From 2af6d443656960f6dc40da11a89228a861b4ba81 Mon Sep 17 00:00:00 2001 From: Sjoerd Bouma Date: Wed, 4 Oct 2023 11:50:24 +0200 Subject: [PATCH 379/418] add property _pre_trigger_time to Trigger class --- NuRadioReco/framework/trigger.py | 34 ++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/NuRadioReco/framework/trigger.py b/NuRadioReco/framework/trigger.py index 1792f0916..ab1b8f156 100644 --- a/NuRadioReco/framework/trigger.py +++ b/NuRadioReco/framework/trigger.py @@ -59,6 +59,7 @@ def __init__(self, name, channels=None, trigger_type='default'): self._trigger_times = None self._trigger_type = trigger_type self._triggered_channels = [] + self._pre_trigger_times = None def has_triggered(self): """ @@ -119,6 +120,39 @@ def get_triggered_channels(self): def set_triggered_channels(self, triggered_channels): self._triggered_channels = triggered_channels + def set_pre_trigger_times(self, pre_trigger_times): + """ + Set the pre-trigger times + + This parameter should only be set if this trigger + determines the readout windows (e.g. by :py:`NuRadioReco.modules.triggerTimeAdjuster`) + + Parameters + ---------- + pre_trigger_times: dict + keys are the channel_ids, and the value is the pre_trigger_time between the + start of the trace and the trigger time. + """ + self._pre_trigger_times = pre_trigger_times + + def get_pre_trigger_times(self): + """ + Return the pre_trigger_time between the start of the trace and the (global) trigger time + + If this trigger has not been used to adjust the readout windows, returns None instead + + Returns + ------- + pre_trigger_times: dict | None + If this trigger has been used to set the readout windows, returns a + dictionary where the keys are the channel ids and the values are the + time between the start of the channel trace and the trigger time. Otherwise, + returns None + + """ + + return self._pre_trigger_times + def serialize(self): return pickle.dumps(self.__dict__, protocol=4) From ee80152df237f62f2a800bc9d30fc9d338cde8a4 Mon Sep 17 00:00:00 2001 From: Sjoerd Bouma Date: Wed, 4 Oct 2023 11:51:35 +0200 Subject: [PATCH 380/418] save pre_trigger_times in Trigger object instead of adjusting trace_start_time --- NuRadioReco/modules/triggerTimeAdjuster.py | 193 +++++++++++++-------- 1 file changed, 116 insertions(+), 77 deletions(-) diff --git a/NuRadioReco/modules/triggerTimeAdjuster.py b/NuRadioReco/modules/triggerTimeAdjuster.py index 002b30eb5..fc2a79a57 100644 --- a/NuRadioReco/modules/triggerTimeAdjuster.py +++ b/NuRadioReco/modules/triggerTimeAdjuster.py @@ -44,83 +44,122 @@ def begin(self, trigger_name=None, pre_trigger_time=55. * units.ns): self.__pre_trigger_time = pre_trigger_time @register_run() - def run(self, event, station, detector): - trigger = None - if self.__trigger_name is not None: - trigger = station.get_trigger(self.__trigger_name) - else: - min_trigger_time = None - for trig in station.get_triggers().values(): - if(trig.has_triggered()): - if min_trigger_time is None or trig.get_trigger_time() < min_trigger_time: - min_trigger_time = trig.get_trigger_time() - trigger = trig - if(min_trigger_time is not None): - logger.info(f"minimum trigger time is {min_trigger_time/units.ns:.2f}ns") - if trigger is None: - logger.info('No trigger found! Channel timings will not be changed.') - return - if trigger.has_triggered(): - trigger_time = trigger.get_trigger_time() - for channel in station.iter_channels(): - trigger_time_channel = trigger_time - channel.get_trace_start_time() + def run(self, event, station, detector, mode='sim_to_data'): + """ + Run the trigger time adjuster. + + This module can be used either to 'cut' the simulated traces into + the appropriate readout windows, or to adjust the trace start times + of simulated / real data to account for the different trigger readout + delays. + + Parameters + ---------- + event: NuRadioReco.framework.event.Event + + station: NuRadioReco.framework.base_station.Station + + detector: NuRadioReco.detector.detector.Detector + + mode: 'sim_to_data' (default) | 'data_to_sim' + If 'sim_to_data', cuts the (arbitrary-length) simulated traces + to the appropriate readout windows. If 'data_to_sim', + looks through all triggers in the station and adjusts the + trace_start_time according to the different readout delays + + """ + if mode == 'sim_to_data': + trigger = None + if self.__trigger_name is not None: + trigger = station.get_trigger(self.__trigger_name) + else: + min_trigger_time = None + for trig in station.get_triggers().values(): + if(trig.has_triggered()): + if min_trigger_time is None or trig.get_trigger_time() < min_trigger_time: + min_trigger_time = trig.get_trigger_time() + trigger = trig + if(min_trigger_time is not None): + logger.info(f"minimum trigger time is {min_trigger_time/units.ns:.2f}ns") + if trigger is None: + logger.info('No trigger found! Channel timings will not be changed.') + return + if trigger.has_triggered(): + trigger_time = trigger.get_trigger_time() + store_pre_trigger_time = {} # we also want to save the used pre_trigger_time + for channel in station.iter_channels(): + trigger_time_channel = trigger_time - channel.get_trace_start_time() - trace = channel.get_trace() - trace_length = len(trace) - number_of_samples = int( - 2 * np.ceil( # this should ensure that 1) the number of samples is even and 2) resampling to the detector sampling rate results in the correct number of samples (note that 2) can only be guaranteed if the detector sampling rate is lower than the current sampling rate) - detector.get_number_of_samples(station.get_id(), channel.get_id()) / 2 - * channel.get_sampling_rate() / detector.get_sampling_frequency(station.get_id(), channel.get_id()) - )) - if number_of_samples > trace.shape[0]: - logger.error("Input has fewer samples than desired output. Channels has only {} samples but {} samples are requested.".format( - trace.shape[0], number_of_samples)) - raise AttributeError - else: - sampling_rate = channel.get_sampling_rate() - trigger_time_sample = int(np.round(trigger_time_channel * sampling_rate)) - # logger.debug(f"channel {channel.get_id()}: trace_start_time = {channel.get_trace_start_time():.1f}ns, trigger time channel {trigger_time_channel/units.ns:.1f}ns, trigger time sample = {trigger_time_sample}") - pre_trigger_time = self.__pre_trigger_time - channel_id = channel.get_id() - trigger_name = trigger.get_name() - while isinstance(pre_trigger_time, dict): - if trigger_name in pre_trigger_time.keys(): # keys are different triggers - pre_trigger_time = pre_trigger_time[trigger_name] - elif channel_id in pre_trigger_time: # keys are channel_ids - pre_trigger_time = pre_trigger_time[channel_id] - else: - logger.error( - 'pre_trigger_time was specified as a dictionary, ' - f'but the neither the trigger_name {trigger_name} ' - f'nor the channel id {channel_id} are present as keys' - ) - raise KeyError - samples_before_trigger = int(pre_trigger_time * sampling_rate) - rel_station_time_samples = 0 - cut_samples_beginning = 0 - if(samples_before_trigger < trigger_time_sample): - cut_samples_beginning = trigger_time_sample - samples_before_trigger - roll_by = 0 - if(cut_samples_beginning + number_of_samples > trace_length): - logger.info("trigger time is sample {} but total trace length is only {} samples (requested trace length is {} with an offest of {} before trigger). To achieve desired configuration, trace will be rolled".format( - trigger_time_sample, trace_length, number_of_samples, samples_before_trigger)) - roll_by = cut_samples_beginning + number_of_samples - trace_length # roll_by is positive - trace = np.roll(trace, -1 * roll_by) - cut_samples_beginning -= roll_by - rel_station_time_samples = cut_samples_beginning + roll_by - elif(samples_before_trigger > trigger_time_sample): - roll_by = -trigger_time_sample + samples_before_trigger - logger.info( - "trigger time is before 'trigger offset window', the trace needs to be rolled by {} samples first".format(roll_by)) - trace = np.roll(trace, roll_by) - trigger_time_sample -= roll_by - rel_station_time_samples = -roll_by + trace = channel.get_trace() + trace_length = len(trace) + number_of_samples = int( + 2 * np.ceil( # this should ensure that 1) the number of samples is even and 2) resampling to the detector sampling rate results in the correct number of samples (note that 2) can only be guaranteed if the detector sampling rate is lower than the current sampling rate) + detector.get_number_of_samples(station.get_id(), channel.get_id()) / 2 + * channel.get_sampling_rate() / detector.get_sampling_frequency(station.get_id(), channel.get_id()) + )) + if number_of_samples > trace.shape[0]: + logger.error("Input has fewer samples than desired output. Channels has only {} samples but {} samples are requested.".format( + trace.shape[0], number_of_samples)) + raise AttributeError + else: + sampling_rate = channel.get_sampling_rate() + trigger_time_sample = int(np.round(trigger_time_channel * sampling_rate)) + # logger.debug(f"channel {channel.get_id()}: trace_start_time = {channel.get_trace_start_time():.1f}ns, trigger time channel {trigger_time_channel/units.ns:.1f}ns, trigger time sample = {trigger_time_sample}") + pre_trigger_time = self.__pre_trigger_time + channel_id = channel.get_id() + trigger_name = trigger.get_name() + while isinstance(pre_trigger_time, dict): + if trigger_name in pre_trigger_time.keys(): # keys are different triggers + pre_trigger_time = pre_trigger_time[trigger_name] + elif channel_id in pre_trigger_time: # keys are channel_ids + pre_trigger_time = pre_trigger_time[channel_id] + else: + logger.error( + 'pre_trigger_time was specified as a dictionary, ' + f'but the neither the trigger_name {trigger_name} ' + f'nor the channel id {channel_id} are present as keys' + ) + raise KeyError + samples_before_trigger = int(pre_trigger_time * sampling_rate) + rel_station_time_samples = 0 + cut_samples_beginning = 0 + if(samples_before_trigger < trigger_time_sample): + cut_samples_beginning = trigger_time_sample - samples_before_trigger + roll_by = 0 + if(cut_samples_beginning + number_of_samples > trace_length): + logger.info("trigger time is sample {} but total trace length is only {} samples (requested trace length is {} with an offest of {} before trigger). To achieve desired configuration, trace will be rolled".format( + trigger_time_sample, trace_length, number_of_samples, samples_before_trigger)) + roll_by = cut_samples_beginning + number_of_samples - trace_length # roll_by is positive + trace = np.roll(trace, -1 * roll_by) + cut_samples_beginning -= roll_by + rel_station_time_samples = cut_samples_beginning + roll_by + elif(samples_before_trigger > trigger_time_sample): + roll_by = -trigger_time_sample + samples_before_trigger + logger.info( + "trigger time is before 'trigger offset window', the trace needs to be rolled by {} samples first".format(roll_by)) + trace = np.roll(trace, roll_by) + trigger_time_sample -= roll_by + rel_station_time_samples = -roll_by - # shift trace to be in the correct location for cutting - # logger.debug(f"cutting trace to {cut_samples_beginning}-{number_of_samples + cut_samples_beginning} samples") - trace = trace[cut_samples_beginning:(number_of_samples + cut_samples_beginning)] - channel.set_trace(trace, channel.get_sampling_rate()) - channel.set_trace_start_time(channel.get_trace_start_time() + rel_station_time_samples / channel.get_sampling_rate()) - # logger.debug(f"setting trace start time to {channel.get_trace_start_time() + rel_station_time_samples / channel.get_sampling_rate():.0f} = {channel.get_trace_start_time():.0f} + {rel_station_time_samples / channel.get_sampling_rate():.0f}") + # shift trace to be in the correct location for cutting + # logger.debug(f"cutting trace to {cut_samples_beginning}-{number_of_samples + cut_samples_beginning} samples") + trace = trace[cut_samples_beginning:(number_of_samples + cut_samples_beginning)] + channel.set_trace(trace, channel.get_sampling_rate()) + channel.set_trace_start_time(trigger_time) + store_pre_trigger_time[channel_id] = pre_trigger_time + # channel.set_trace_start_time(channel.get_trace_start_time() + rel_station_time_samples / channel.get_sampling_rate()) + # logger.debug(f"setting trace start time to {channel.get_trace_start_time() + rel_station_time_samples / channel.get_sampling_rate():.0f} = {channel.get_trace_start_time():.0f} + {rel_station_time_samples / channel.get_sampling_rate():.0f}") + + # store the used pre_trigger_times + trigger.set_pre_trigger_times(store_pre_trigger_time) + + else: + logger.debug('Trigger {} has not triggered. Channel timings will not be changed.'.format(self.__trigger_name)) + elif mode == 'data_to_sim': + for trigger in station.get_triggers().values(): + pre_trigger_time = trigger.get_pre_trigger_times() + if pre_trigger_time is not None: + for channel in station.iter_channels(): + channel.set_trace_start_time(channel.get_trace_start_time()-pre_trigger_time[channel.get_id()]) else: - logger.debug('Trigger {} has not triggered. Channel timings will not be changed.'.format(self.__trigger_name)) + raise ValueError(f"Argument '{mode}' for mode is not valid. Options are 'sim_to_data' or 'data_to_sim'.") From 122368eb3cc4f1e0bb67037682be6e2dda816b25 Mon Sep 17 00:00:00 2001 From: Sjoerd Bouma Date: Wed, 4 Oct 2023 14:06:26 +0200 Subject: [PATCH 381/418] don't store self, include AttributeError --- NuRadioReco/framework/event.py | 4 ++-- NuRadioReco/modules/base/module.py | 5 ++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/NuRadioReco/framework/event.py b/NuRadioReco/framework/event.py index bd9f2ab4d..1d4c06128 100644 --- a/NuRadioReco/framework/event.py +++ b/NuRadioReco/framework/event.py @@ -443,7 +443,7 @@ def serialize(self, mode): modules_out_event = [] for value in self.__modules_event: # remove module instances (this will just blow up the file size) modules_out_event.append([value[0], None, value[2]]) - invalid_keys = [key for key,val in value[2].items() if isinstance(val, TypeError)] + invalid_keys = [key for key,val in value[2].items() if isinstance(val, BaseException)] if len(invalid_keys): logger.warning(f"The following arguments to module {value[0]} could not be serialized and will not be stored: {invalid_keys}") @@ -452,7 +452,7 @@ def serialize(self, mode): modules_out_station[key] = [] for value in self.__modules_station[key]: modules_out_station[key].append([value[0], value[1], None, value[3]]) - invalid_keys = [key for key,val in value[3].items() if isinstance(val, TypeError)] + invalid_keys = [key for key,val in value[3].items() if isinstance(val, BaseException)] if len(invalid_keys): logger.warning(f"The following arguments to module {value[0]} could not be serialized and will not be stored: {invalid_keys}") diff --git a/NuRadioReco/modules/base/module.py b/NuRadioReco/modules/base/module.py index 181719e37..b867f703f 100644 --- a/NuRadioReco/modules/base/module.py +++ b/NuRadioReco/modules/base/module.py @@ -44,7 +44,7 @@ def register_run_method(self, *args, **kwargs): signature = inspect.signature(run) parameters = signature.parameters # convert args to kwargs to facilitate easier bookkeeping - all_kwargs = {key:value for key,value in zip(parameters.keys(), args)} + all_kwargs = {key:value for key,value in zip(parameters.keys(), args) if key is not 'self'} all_kwargs.update(kwargs) # this silently overwrites positional args with kwargs, but this is probably okay as we still raise an error later # include parameters with default values @@ -63,9 +63,8 @@ def register_run_method(self, *args, **kwargs): try: pickle.dumps(value, protocol=4) store_kwargs[key] = value - except TypeError as e: # object couldn't be pickled - we store the error instead + except (TypeError, AttributeError) as e: # object couldn't be pickled - we store the error instead store_kwargs[key] = e - if station is not None: module_level = "station" elif evt is not None: From 7e619aeeefe681d0c6de92ae33e5b12f305d4995 Mon Sep 17 00:00:00 2001 From: Sjoerd Bouma Date: Thu, 5 Oct 2023 22:48:16 +0200 Subject: [PATCH 382/418] actually exclude self this time, always exclude detector as kwarg --- NuRadioReco/modules/base/module.py | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/NuRadioReco/modules/base/module.py b/NuRadioReco/modules/base/module.py index b867f703f..fc55c8657 100644 --- a/NuRadioReco/modules/base/module.py +++ b/NuRadioReco/modules/base/module.py @@ -2,6 +2,7 @@ from timeit import default_timer as timer import NuRadioReco.framework.event import NuRadioReco.framework.base_station +import NuRadioReco.detector.detector_base import logging import inspect import pickle @@ -24,7 +25,7 @@ def register_run(level=None): which module is executed in which order and with what parameters. Also the execution time of each module is tracked. """ - + def run_decorator(run): @wraps(run) @@ -40,11 +41,12 @@ def register_run_method(self, *args, **kwargs): # generator, so not sure how to access the event. evt = None station = None - + signature = inspect.signature(run) parameters = signature.parameters # convert args to kwargs to facilitate easier bookkeeping - all_kwargs = {key:value for key,value in zip(parameters.keys(), args) if key is not 'self'} + keys = [key for key in parameters.keys() if key != 'self'] + all_kwargs = {key:value for key,value in zip(keys, args)} all_kwargs.update(kwargs) # this silently overwrites positional args with kwargs, but this is probably okay as we still raise an error later # include parameters with default values @@ -59,21 +61,23 @@ def register_run_method(self, *args, **kwargs): evt = value elif isinstance(value, NuRadioReco.framework.base_station.BaseStation) and idx == 1: # station should be second argument station = value + elif isinstance(value, NuRadioReco.detector.detector_base.DetectorBase): + pass # we don't try to store detectors else: # we try to store other arguments IF they are pickleable try: pickle.dumps(value, protocol=4) store_kwargs[key] = value - except (TypeError, AttributeError) as e: # object couldn't be pickled - we store the error instead - store_kwargs[key] = e + except (TypeError, AttributeError): # object couldn't be pickled - we store the error instead + store_kwargs[key] = TypeError(f"Argument of type {type(value)} could not be serialized") if station is not None: module_level = "station" elif evt is not None: module_level = "event" else: module_level = "reader" - + start = timer() - + if module_level == "event": evt.register_module_event(self, self.__class__.__name__, store_kwargs) elif module_level == "station": @@ -81,15 +85,15 @@ def register_run_method(self, *args, **kwargs): elif module_level == "reader": # not sure what to do... function returns generator, not sure how to access the event... pass - + res = run(self, *args, **kwargs) - + end = timer() - + if self not in register_run_method.time: # keep track of timing of modules. We use the module instance as key to time different module instances separately. register_run_method.time[self] = 0 register_run_method.time[self] += (end - start) - + return res register_run_method.time = {} From 95a80d1bbb274603e480948bace0e6e6d6d4587a Mon Sep 17 00:00:00 2001 From: Sjoerd Bouma Date: Thu, 19 Oct 2023 17:10:20 +0200 Subject: [PATCH 383/418] add methods get_header, get_detector to wrapper to prevent errors --- NuRadioReco/eventbrowser/dataprovider_root.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/NuRadioReco/eventbrowser/dataprovider_root.py b/NuRadioReco/eventbrowser/dataprovider_root.py index 712e8560d..a14ae7e93 100644 --- a/NuRadioReco/eventbrowser/dataprovider_root.py +++ b/NuRadioReco/eventbrowser/dataprovider_root.py @@ -23,6 +23,14 @@ def get_event(self, event_id): def get_n_events(self): return self._n_events_total + + def get_detector(self): + """Not implemented in mattak reader""" + return None + + def get_header(self): + """Not implemented in mattak reader""" + return None class DataProviderRoot(object): From b1bc9303da649c8cddd020eac06fda8b4aeed05f Mon Sep 17 00:00:00 2001 From: Christian Glaser Date: Mon, 23 Oct 2023 11:28:43 +0000 Subject: [PATCH 384/418] improve plotting --- NuRadioMC/SignalProp/examples/E02ToAir.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/NuRadioMC/SignalProp/examples/E02ToAir.py b/NuRadioMC/SignalProp/examples/E02ToAir.py index a8a54f633..2c509c4df 100644 --- a/NuRadioMC/SignalProp/examples/E02ToAir.py +++ b/NuRadioMC/SignalProp/examples/E02ToAir.py @@ -33,7 +33,7 @@ ax.plot(x1[0], x1[2], 'ko') for i, x in enumerate([x2, x3, x4, x5]): print('finding solutions for ', x) - r = ray.ray_tracing(ice, log_level=logging.DEBUG, use_cpp=False) + r = ray.ray_tracing(ice, log_level=logging.WARNING, use_cpp=False) r.set_start_and_end_point(x1, x) r.find_solutions() if(r.has_solution()): @@ -50,6 +50,10 @@ receive_vectors[i, iS] = receive_vector zenith, azimuth = hp.cartesian_to_spherical(*receive_vector) print(" Receiving Zenith %.3f and Azimuth %.3f " % (zenith / units.deg, azimuth / units.deg)) + + # get focussing factor + focusing = r.get_focusing(0) + print(f" focusing factor = {focusing:.8f}") att = r.get_attenuation(iS, np.array([100, 200]) * units.MHz) print(att) @@ -65,7 +69,7 @@ x2_2d = np.array([X2r[0], X2r[2]]) r_2d = ray.ray_tracing_2D(ice) yy, zz = r_2d.get_path(x1_2d, x2_2d, ray_tracing_C0[i, iS]) - ax.plot(yy, zz, '{}'.format(php.get_color_linestyle(i)), label='{} C0 = {:.4f}'.format(ray_tracing_solution_type[i, iS], ray_tracing_C0[i, iS])) + ax.plot(yy, zz, '{}'.format(php.get_color_linestyle(i)), label='{} C0 = {:.4f}, f = {:.2f}'.format(ray_tracing_solution_type[i, iS], ray_tracing_C0[i, iS], focusing)) ax.plot(x2_2d[0], x2_2d[1], '{}{}-'.format('d', php.get_color(i))) ax.legend() From adb4049b9524aaabbf3efb55cef1912e0d3a9bcf Mon Sep 17 00:00:00 2001 From: Alan Coleman <74733466+colemanalan@users.noreply.github.com> Date: Mon, 23 Oct 2023 11:06:21 -0400 Subject: [PATCH 385/418] 562 include more info about the pa trigger in class (#578) * Include window/stride and maximum amplitudes in the PA trigger class --- NuRadioReco/framework/trigger.py | 14 +++- .../modules/phasedarray/triggerSimulator.py | 84 +++++++++---------- changelog.txt | 1 + 3 files changed, 55 insertions(+), 44 deletions(-) diff --git a/NuRadioReco/framework/trigger.py b/NuRadioReco/framework/trigger.py index 1792f0916..cde481bc6 100644 --- a/NuRadioReco/framework/trigger.py +++ b/NuRadioReco/framework/trigger.py @@ -213,7 +213,10 @@ class SimplePhasedTrigger(Trigger): def __init__(self, name, threshold, channels=None, secondary_channels=None, primary_angles=None, secondary_angles=None, - trigger_delays=None, sec_trigger_delays=None): + trigger_delays=None, sec_trigger_delays=None, + window_size=None, step_size=None, + maximum_amps=None + ): """ initialize trigger class @@ -238,6 +241,12 @@ def __init__(self, name, threshold, channels=None, secondary_channels=None, sec_trigger_delays: dictionary the delays for the secondary channels that have caused a trigger. If there is no trigger or no secondary channels, it's an empty dictionary + window_size: int + the size of the integration window (units of ADC time ticks) + step_size: int + the size of the stride between calculating the phasing (units of ADC time ticks) + maximum_amps: list of floats (length equal to that of `phasing_angles`) + the maximum value of all the integration windows for each of the phased waveforms """ Trigger.__init__(self, name, channels, 'simple_phased') self._primary_channels = channels @@ -247,6 +256,9 @@ def __init__(self, name, threshold, channels=None, secondary_channels=None, self._threshold = threshold self._trigger_delays = trigger_delays self._sec_trigger_delays = sec_trigger_delays + self._window_size = window_size + self._step_side = step_size + self._maximum_amps = maximum_amps class HighLowTrigger(Trigger): diff --git a/NuRadioReco/modules/phasedarray/triggerSimulator.py b/NuRadioReco/modules/phasedarray/triggerSimulator.py index 44ac9cc53..0128d0fe8 100644 --- a/NuRadioReco/modules/phasedarray/triggerSimulator.py +++ b/NuRadioReco/modules/phasedarray/triggerSimulator.py @@ -336,6 +336,8 @@ def phased_trigger(self, station, det, the earliest trigger time with respect to first interaction time. trigger_times: dictionary all time bins that fulfil the trigger condition per beam. The key is the beam number. Time with respect to first interaction time. + maximum_amps: list of floats (length equal to that of `phasing_angles`) + the maximum value of all the integration windows for each of the phased waveforms """ if(triggered_channels is None): @@ -375,30 +377,10 @@ def phased_trigger(self, station, det, raise ValueError("Could not convert upsampling_factor to integer. Exiting.") if(upsampling_factor >= 2): - ''' - # Zero inserting and filtering - upsampled_trace = upsampling_fir(trace, adc_sampling_frequency, - int_factor=upsampling_factor, ntaps=1) - - channelBandPassFilter = NuRadioReco.modules.channelBandPassFilter.channelBandPassFilter() - ff = np.fft.rfftfreq(len(upsampled_trace), 1.0 / adc_sampling_frequency / upsampling_factor) - filt = channelBandPassFilter.get_filter(ff, 0, 0, None, passband=[0, 240 * units.MHz], filter_type="cheby1", order=9, rp=.1) - - upsampled_trace = np.fft.irfft(np.fft.rfft(upsampled_trace) * filt) - ''' - # FFT upsampling new_len = len(trace) * upsampling_factor upsampled_trace = scipy.signal.resample(trace, new_len) - ''' - # Linear interpolation - x = np.arange(len(trace)) - f_trace = interp1d(x, trace, kind='linear', fill_value=(trace[0], trace[-1]), bounds_error=False) - x_new = np.arange(len(trace) * upsampling_factor) / upsampling_factor - upsampled_trace = f_trace(x_new) - ''' - # If upsampled is performed, the final sampling frequency changes trace = upsampled_trace[:] @@ -424,11 +406,15 @@ def phased_trigger(self, station, det, channel_trace_start_time = self.get_channel_trace_start_time(station, triggered_channels) trigger_delays = {} + maximum_amps = np.zeros_like(phased_traces) + for iTrace, phased_trace in enumerate(phased_traces): # Create a sliding window squared_mean, num_frames = self.power_sum(coh_sum=phased_trace, window=window, step=step, adc_output=adc_output) + maximum_amps[iTrace] = np.max(squared_mean) + if True in (squared_mean > threshold): trigger_delays[iTrace] = {} @@ -436,18 +422,19 @@ def phased_trigger(self, station, det, trigger_delays[iTrace][channel_id] = beam_rolls[iTrace][channel_id] * time_step triggered_bins = np.atleast_1d(np.squeeze(np.argwhere(squared_mean > threshold))) - # logger.debug(f"Station has triggered, at bins {triggered_bins}") - # logger.debug(trigger_delays) - # logger.debug(f"trigger_delays {trigger_delays[iTrace][triggered_channels[0]]}") + logger.debug(f"Station has triggered, at bins {triggered_bins}") + logger.debug(trigger_delays) + logger.debug(f"trigger_delays {trigger_delays[iTrace][triggered_channels[0]]}") is_triggered = True trigger_times[iTrace] = trigger_delays[iTrace][triggered_channels[0]] + triggered_bins * step * time_step + channel_trace_start_time - # logger.debug(f"trigger times = {trigger_times[iTrace]}") + logger.debug(f"trigger times = {trigger_times[iTrace]}") if is_triggered: - # logger.debug(trigger_times) + logger.debug("Trigger condition satisfied!") + logger.debug("all trigger times", trigger_times) trigger_time = min([x.min() for x in trigger_times.values()]) - # logger.debug(f"minimum trigger time is {trigger_time:.0f}ns") + logger.debug(f"minimum trigger time is {trigger_time:.0f}ns") - return is_triggered, trigger_delays, trigger_time, trigger_times + return is_triggered, trigger_delays, trigger_time, trigger_times, maximum_amps @register_run() def run(self, evt, station, det, @@ -543,25 +530,36 @@ def run(self, evt, station, det, if(set_not_triggered): is_triggered = False trigger_delays = {} + triggered_beams = [] else: - is_triggered, trigger_delays, trigger_time, trigger_times = self.phased_trigger(station=station, - det=det, - Vrms=Vrms, - threshold=threshold, - triggered_channels=triggered_channels, - phasing_angles=phasing_angles, - ref_index=ref_index, - trigger_adc=trigger_adc, - clock_offset=clock_offset, - adc_output=adc_output, - trigger_filter=trigger_filter, - upsampling_factor=upsampling_factor, - window=window, - step=step) + is_triggered, trigger_delays, trigger_time, trigger_times, maximum_amps = self.phased_trigger( + station=station, + det=det, + Vrms=Vrms, + threshold=threshold, + triggered_channels=triggered_channels, + phasing_angles=phasing_angles, + ref_index=ref_index, + trigger_adc=trigger_adc, + clock_offset=clock_offset, + adc_output=adc_output, + trigger_filter=trigger_filter, + upsampling_factor=upsampling_factor, + window=window, + step=step, + ) # Create a trigger object to be returned to the station - trigger = SimplePhasedTrigger(trigger_name, threshold, channels=triggered_channels, - primary_angles=phasing_angles, trigger_delays=trigger_delays) + trigger = SimplePhasedTrigger( + trigger_name, + threshold, + channels=triggered_channels, + primary_angles=phasing_angles, + trigger_delays=trigger_delays, + window_size=window, + step_size=step, + maximum_amps=maximum_amps, + ) trigger.set_triggered(is_triggered) diff --git a/changelog.txt b/changelog.txt index e37cade64..3e5c19bfd 100644 --- a/changelog.txt +++ b/changelog.txt @@ -4,6 +4,7 @@ please update the categories "new features" and "bugfixes" before a pull request version 2.2.0-dev new features: +- expand values stored in SimplePhasedTrigger - added getting to query ARZ charge-excess profiles - upgrade to proposal v 7.5.0 with new NuRadioProposal interface and improved LPM treatment - add script to generate / download pre-calculated proposal tables for known detector configurations From e0b9f1f745084b1496641e2400f61f69bc45bc33 Mon Sep 17 00:00:00 2001 From: Sjoerd Bouma Date: Wed, 25 Oct 2023 14:13:17 +0200 Subject: [PATCH 386/418] add support for reading multiple files simultaneously --- NuRadioReco/eventbrowser/dataprovider.py | 7 ++++++ NuRadioReco/eventbrowser/dataprovider_root.py | 25 ++++++++++--------- 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/NuRadioReco/eventbrowser/dataprovider.py b/NuRadioReco/eventbrowser/dataprovider.py index d5fa44614..4ec4a6762 100644 --- a/NuRadioReco/eventbrowser/dataprovider.py +++ b/NuRadioReco/eventbrowser/dataprovider.py @@ -2,12 +2,15 @@ import NuRadioReco.eventbrowser.dataprovider_nur import threading import logging +import six +import NuRadioReco.utilities.metaclasses logging.basicConfig() logger = logging.getLogger('eventbrowser.dataprovider') logger.setLevel(logging.INFO) LOCK = threading.Lock() +@six.add_metaclass(NuRadioReco.utilities.metaclasses.Singleton) class DataProvider(object): __instance = None @@ -18,12 +21,16 @@ def __new__(cls): def __init__(self): self.__data_provider = None + self._use_root = None def set_filetype(self, use_root): + if self._use_root == use_root: + return None if use_root: self.__data_provider = NuRadioReco.eventbrowser.dataprovider_root.DataProviderRoot() else: self.__data_provider = NuRadioReco.eventbrowser.dataprovider_nur.DataProvider() + self._use_root = use_root def get_file_handler(self, user_id, filename): thread = threading.get_ident() diff --git a/NuRadioReco/eventbrowser/dataprovider_root.py b/NuRadioReco/eventbrowser/dataprovider_root.py index a14ae7e93..e08dda4dd 100644 --- a/NuRadioReco/eventbrowser/dataprovider_root.py +++ b/NuRadioReco/eventbrowser/dataprovider_root.py @@ -3,36 +3,35 @@ import time import numpy as np import logging -import threading + logging.basicConfig() logger = logging.getLogger('eventbrowser') logger.setLevel(logging.DEBUG) ### we create a wrapper for readRNOGData to mirror the interface of the .nur reader class readRNOG_wrapper(readRNOGData): - + def get_event_ids(self): event_infos = self.get_events_information() return np.array([(i['run'], i['eventNumber']) for i in event_infos.values()]) - + def get_event_i(self, i): return self.get_event_by_index(i) - + def get_event(self, event_id): return super().get_event(*event_id) def get_n_events(self): return self._n_events_total - + def get_detector(self): """Not implemented in mattak reader""" return None - + def get_header(self): """Not implemented in mattak reader""" return None - class DataProviderRoot(object): __instance = None @@ -51,7 +50,7 @@ def __init__(self, max_user_instances=12): Each unique session id gets its own reader, up to a maximum of ``max_user_instances`` concurrent readers. Subsequent requests for new readers drop older readers. - + """ logger.info("Creating new DataProviderRoot instance") self.__max_user_instances = max_user_instances @@ -65,15 +64,17 @@ def get_file_handler(self, user_id, filename): self.__user_instances[user_id] = dict( reader=reader, filename=None, ) + if isinstance(filename, str): + filename = [filename] if filename != self.__user_instances[user_id]['filename']: # user is requesting new file -> close current file and open new one reader = self.__user_instances[user_id]['reader'] - reader.begin([os.path.dirname(filename)], overwrite_sampling_rate=3.2) #TODO - remove hardcoded sampling rate - reader.get_event_ids() # + reader.begin([os.path.dirname(f) for f in filename], overwrite_sampling_rate=3.2) #TODO - remove hardcoded sampling rate + reader.get_event_ids() # self.__user_instances[user_id] = dict( reader=reader, filename=filename, ) - + # update last access time self.__user_instances[user_id]['last_access_time'] = time.time() @@ -86,5 +87,5 @@ def get_file_handler(self, user_id, filename): users_by_access_time = sorted(users) # drop oldest session self.__user_instances.pop(users_by_access_time[0]) - + return self.__user_instances[user_id]['reader'] From a810b93baac25edeaf4cc5e4c0590cee8fc13edc Mon Sep 17 00:00:00 2001 From: Sjoerd Bouma Date: Wed, 25 Oct 2023 19:46:40 +0200 Subject: [PATCH 387/418] correctly label channels --- NuRadioReco/eventbrowser/apps/trace_plots/channel_spectrum.py | 2 +- .../eventbrowser/apps/trace_plots/channel_time_trace.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/NuRadioReco/eventbrowser/apps/trace_plots/channel_spectrum.py b/NuRadioReco/eventbrowser/apps/trace_plots/channel_spectrum.py index 943ef99a6..19e0b24ce 100644 --- a/NuRadioReco/eventbrowser/apps/trace_plots/channel_spectrum.py +++ b/NuRadioReco/eventbrowser/apps/trace_plots/channel_spectrum.py @@ -47,7 +47,7 @@ def update_channel_spectrum(trigger, evt_counter, filename, station_id, juser_id 'color': colors[i % len(colors)], 'line': {'color': colors[i % len(colors)]} }, - name='Channel {}'.format(i) + name='Channel {}'.format(channel.get_id()) ), 1, 1) fig['layout'].update(default_layout) fig['layout']['legend']['uirevision'] = filename diff --git a/NuRadioReco/eventbrowser/apps/trace_plots/channel_time_trace.py b/NuRadioReco/eventbrowser/apps/trace_plots/channel_time_trace.py index f9a156e51..36d1780bf 100644 --- a/NuRadioReco/eventbrowser/apps/trace_plots/channel_time_trace.py +++ b/NuRadioReco/eventbrowser/apps/trace_plots/channel_time_trace.py @@ -52,8 +52,8 @@ def update_time_trace(trigger, evt_counter, filename, station_id, juser_id): 'color': colors[i % len(colors)], 'line': {'color': colors[i % len(colors)]} }, - name='Channel {}'.format(i), - uid='Channel {}'.format(i) + name='Channel {}'.format(channel.get_id()), + uid='Channel {}'.format(channel.get_id()) ), 1, 1) fig['layout'].update(default_layout) fig['layout']['legend']['uirevision'] = filename # only update channel selection on changing files. From cdfcbf02bcf638210a644e17fe04e69e3aadca8f Mon Sep 17 00:00:00 2001 From: Sjoerd Bouma Date: Wed, 25 Oct 2023 19:47:18 +0200 Subject: [PATCH 388/418] added readRNOGData wrapper for eventbrowser --- .../modules/io/RNO_G/readRNOGDataMattak.py | 482 ++++++++++-------- 1 file changed, 264 insertions(+), 218 deletions(-) diff --git a/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py b/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py index f7585aa31..aacbab001 100644 --- a/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py +++ b/NuRadioReco/modules/io/RNO_G/readRNOGDataMattak.py @@ -4,6 +4,7 @@ import time import astropy.time import math +from functools import lru_cache from NuRadioReco.modules.base.module import register_run @@ -22,53 +23,53 @@ def create_random_directory_path(prefix="/tmp/", n=7): """ Produces a path for a temporary directory with a n letter random suffix - + Parameters ---------- - + prefix: str Path prefix, i.e., root directory. (Defaut: /tmp/) - + n: int Number of letters for the random suffix. (Default: 7) - + Returns ------- - + path: str Return path (e.g, /tmp/readRNOGData_XXXXXXX) """ # generating random strings res = ''.join(random.choices(string.ascii_lowercase + string.digits, k=n)) path = os.path.join(prefix, "readRNOGData_" + res) - + return path - + def baseline_correction(wfs, n_bins=128, func=np.median): """ Simple baseline correction function. Determines baseline in discrete chuncks of "n_bins" with the function specified (i.e., mean or median). - + Parameters ---------- - + wfs: np.array(n_events, n_channels, n_samples) Waveforms of several events/channels. - + n_bins: int Number of samples/bins in one "chunck". If None, calculate median/mean over entire trace. (Default: 128) - + func: np.mean or np.median Function to calculate pedestal - + Returns ------- - + wfs_corrected: np.array(n_events, n_channels, n_samples) Baseline/pedestal corrected waveforms """ - + # Example: Get baselines in chunks of 128 bins # wfs in (n_events, n_channels, 2048) # np.split -> (16, n_events, n_channels, 128) each waveform split in 16 chuncks @@ -82,70 +83,70 @@ def baseline_correction(wfs, n_bins=128, func=np.median): baseline_values = func(wfs, axis=-1) # np.repeat -> (2048, n_events, n_channels) concatenate the 16 chuncks to one baseline baseline_traces = np.repeat(baseline_values, 2048, axis=0) - + # np.moveaxis -> (n_events, n_channels, 2048) baseline_traces = np.moveaxis(baseline_traces, 0, -1) - + return wfs - baseline_traces def get_time_offset(trigger_type): - """ - Mapping the offset between trace start time and trigger time (~ signal time). + """ + Mapping the offset between trace start time and trigger time (~ signal time). Temporary use hard-coded values for each trigger type. In the future this - information might be time, station, and channel dependent and should come + information might be time, station, and channel dependent and should come from a database (or is already calibrated in mattak) - + Current values motivated by figures posted in PR https://github.com/nu-radio/NuRadioMC/pull/519 - + Parameters ---------- - + trigger_type: str Trigger type encoded as string from Mattak - + Returns ------- - + time_offset: float - trace_start_time = trigger_time - time_offset - + trace_start_time = trigger_time - time_offset + """ - + time_offsets = { "FORCE": 0, - "LT": 250 * units.ns, + "LT": 250 * units.ns, "RADIANT": 475 * units.ns, "UNKNOWN": 0 # Due to a firmware issue at the beginning of data taking the trigger types were not properly set. } - + # Should have the same time offset ?! if trigger_type.startswith("RADIANT"): trigger_type = "RADIANT" - + if trigger_type in time_offsets: return time_offsets[trigger_type] else: known_trigger_types = ", ".join(time_offsets.keys()) raise KeyError(f"Unknown trigger type: {trigger_type}. Known are: {known_trigger_types}. Abort ....") - - + + def all_files_in_directory(mattak_dir): """ Checks if all Mattak root files are in a directory. Ignoring runinfo.root because (asaik) not all runs have those and information is currently not read by Mattak. There are mattak directories which produce a ReferenceError when reading. They have a "combined.root" which is apparently empty but are missing the daqstatus, pedestal, and header file. - + Parameters ---------- - + mattak_dir: str Path to a mattak directory - + Returns ------- - + all_there: bool True, if all "req_files" are there and waveforms.root or combined.root. Otherwise returns False. """ @@ -153,7 +154,7 @@ def all_files_in_directory(mattak_dir): if not os.path.exists(os.path.join(mattak_dir, "waveforms.root")) and \ not os.path.exists(os.path.join(mattak_dir, "combined.root")): return False - + req_files = ["daqstatus.root", "headers.root", "pedestal.root"] for file in req_files: if not os.path.exists(os.path.join(mattak_dir, file)): @@ -163,46 +164,49 @@ def all_files_in_directory(mattak_dir): class readRNOGData: - - def __init__(self, run_table_path=None, log_level=logging.INFO): + + def __init__(self, run_table_path=None, load_run_table=True, log_level=logging.INFO): """ Parameters ---------- - - run_table_path: str + + run_table_path: str | None Path to a run_table.cvs file. If None, the run table is queried from the DB. (Default: None) - + + load_run_table: bool + If True, try to load the run_table from run_table_path. Otherwise, skip this. + log_level: enum Set verbosity level of logger. If logging.DEBUG, set mattak to verbose (unless specified in mattak_kwargs). - (Default: logging.INFO) + (Default: logging.INFO) """ self.logger = logging.getLogger('NuRadioReco.readRNOGData') self.logger.setLevel(log_level) - + # Initialize run table for run selection self.__run_table = None - - self.__temporary_dirs = [] - if run_table_path is None: - try: - from rnog_data.runtable import RunTable - self.logger.debug("Access RunTable database ...") + self.__temporary_dirs = [] + if load_run_table: + if run_table_path is None: try: - self.__run_table = RunTable().get_table() - except: - self.logger.warn("No connect to RunTable database could be established. " - "Runs can not be filtered.") - except ImportError: - self.logger.warn("Import of run table failed. Runs can not be filtered.! \n" - "You can get the interface from GitHub: git@github.com:RNO-G/rnog-runtable.git") - else: - import pandas - self.__run_table = pandas.read_csv(run_table_path) - - - def begin(self, - dirs_files, + from rnog_data.runtable import RunTable + self.logger.debug("Access RunTable database ...") + try: + self.__run_table = RunTable().get_table() + except: + self.logger.warn("No connect to RunTable database could be established. " + "Runs can not be filtered.") + except ImportError: + self.logger.warn("Import of run table failed. Runs can not be filtered.! \n" + "You can get the interface from GitHub: git@github.com:RNO-G/rnog-runtable.git") + else: + import pandas + self.__run_table = pandas.read_csv(run_table_path) + + + def begin(self, + dirs_files, read_calibrated_data=False, select_triggers=None, select_runs=False, @@ -219,24 +223,24 @@ def begin(self, ---------- dirs_files: str, list(str) - Path to run directories (i.e. ".../stationXX/runXXX/") or path to root files (have to be "combined" mattak files). - + Path to run directories (i.e. ".../stationXX/runXXX/") or path to root files (have to be "combined" mattak files). + read_calibrated_data: bool If True, read calibrated waveforms from Mattak.Dataset. If False, read "raw" ADC traces. (temp. Default: False, this can/should be switched once the calibration in incorp. into Mattak) - + select_triggers: str or list(str) Names of triggers which should be selected. Convinence interface instead of passing a selector - (see "selectors" below). (Default: None) - + (see "selectors" below). (Default: None) + select_runs: bool If True, use information in run_table to select runs (based on run_type, run_time, trigger_rate, ...). - If the run_table is not available no selection is performed (and the programm is not interrupted, + If the run_table is not available no selection is performed (and the programm is not interrupted, only an error message is raised). See parameters to configure run selection. (Default: False) - + Other Parameters ---------------- - + apply_baseline_correction: bool Only applies when non-calibrated data are read. If true, correct for DC offset. (Default: True) @@ -251,45 +255,45 @@ def begin(self, run_types: list Used to select/reject runs from information in the RNO-G RunTable. List of run_types to be used. (Default: ['physics']) - + run_time_range: tuple - Specify a time range to select runs (it is sufficient that runs cover the time range partially). - Each value of the tuple has to be in a format which astropy.time.Time understands. A value can be None + Specify a time range to select runs (it is sufficient that runs cover the time range partially). + Each value of the tuple has to be in a format which astropy.time.Time understands. A value can be None which means that the lower or upper bound is unconstrained. If run_time_range is None no time selection is applied. (Default: None) - + max_trigger_rate: float Used to select/reject runs from information in the RNO-G RunTable. Maximum allowed trigger rate (per run) in Hz. If 0, no cut is applied. (Default: 1 Hz) - + mattak_kwargs: dict Dictionary of arguments for mattak.Dataset.Dataset. (Default: {}) - Example: Select a mattak "backend". Options are "auto", "pyroot", "uproot". If "auto" is selected, + Example: Select a mattak "backend". Options are "auto", "pyroot", "uproot". If "auto" is selected, pyroot is used if available otherwise a "fallback" to uproot is used. (Default: "auto") - + overwrite_sampling_rate: float Set sampling rate of the imported waveforms. This overwrites what is read out from runinfo (i.e., stored in the mattak files). If None, nothing is overwritten and the sampling rate from the mattak file is used. (Default: None) - NOTE: This option might be necessary when old mattak files are read which have this not set. + NOTE: This option might be necessary when old mattak files are read which have this not set. """ - + t0 = time.time() - + self._read_calibrated_data = read_calibrated_data self._apply_baseline_correction = apply_baseline_correction self._convert_to_voltage = convert_to_voltage - + # Temporary solution hard-coded values from Cosmin. Only used when uncalibrated data # is read and convert_to_voltage is True. self._adc_ref_voltage_range = 2.5 * units.volt self._adc_n_bits = 12 - + self._overwrite_sampling_rate = overwrite_sampling_rate - - # Set parameter for run selection + + # Set parameter for run selection self.__max_trigger_rate = max_trigger_rate self.__run_types = run_types - + if run_time_range is not None: convert_time = lambda t: None if t is None else astropy.time.Time(t) self._time_low = convert_time(run_time_range[0]) @@ -297,12 +301,12 @@ def begin(self, else: self._time_low = None self._time_high = None - + if select_runs and self.__run_table is not None: self.logger.info("\n\tSelect runs with type: {}".format(", ".join(run_types)) + f"\n\tSelect runs with max. trigger rate of {max_trigger_rate / units.Hz} Hz" f"\n\tSelect runs which are between {self._time_low} - {self._time_high}") - + self.set_selectors(selectors, select_triggers) # Read data @@ -311,16 +315,16 @@ def begin(self, self.__counter = 0 self.__skipped = 0 self.__invalid = 0 - + self._events_information = None self._datasets = [] self.__n_events_per_dataset = [] - + self.logger.info(f"Parse through / read-in {len(dirs_files)} directory(ies) / file(s).") - + self.__skipped_runs = 0 self.__n_runs = 0 - + if not isinstance(dirs_files, (list, np.ndarray)): dirs_files = [dirs_files] @@ -335,31 +339,31 @@ def begin(self, if not os.path.exists(dir_file): self.logger.error(f"The directory/file {dir_file} does not exist") continue - + if os.path.isdir(dir_file): - + if not all_files_in_directory(dir_file): self.logger.error(f"Incomplete directory: {dir_file}. Skip ...") continue else: - # Providing direct paths to a Mattak combined.root file is not supported by the mattak library yet. - # It only accepts directry paths in which it will look for a file called `combined.root` (or waveforms.root if + # Providing direct paths to a Mattak combined.root file is not supported by the mattak library yet. + # It only accepts directry paths in which it will look for a file called `combined.root` (or waveforms.root if # it is not a combined file). To work around this: Create a tmp directory under `/tmp/`, link the file you want to # read into this directory with the the name `combined.root`, use this path to read the run. - + path = create_random_directory_path() self.logger.debug(f"Create temporary directory: {path}") if os.path.exists(path): raise ValueError(f"Temporary directory {path} already exists.") - + os.mkdir(path) self.__temporary_dirs.append(path) # for housekeeping - + self.logger.debug(f"Create symlink for {dir_file}") os.symlink(dir_file, os.path.join(path, "combined.root")) - + dir_file = path # set path to e.g. /tmp/NuRadioReco_XXXXXXX/combined.root - + try: dataset = mattak.Dataset.Dataset(station=0, run=0, data_dir=dir_file, verbose=verbose, **mattak_kwargs) @@ -367,15 +371,15 @@ def begin(self, self.logger.error(f"The following exeption was raised reading in the run: {dir_file}. Skip that run ...:\n", exc_info=e) continue - # filter runs/datasets based on + # filter runs/datasets based on if select_runs and self.__run_table is not None and not self.__select_run(dataset): self.__skipped_runs += 1 continue - + self.__n_runs += 1 self._datasets.append(dataset) self.__n_events_per_dataset.append(dataset.N()) - + if not len(self._datasets): err = "Found no valid datasets. Stop!" self.logger.error(err) @@ -385,33 +389,33 @@ def begin(self, self._event_idxs_datasets = np.cumsum(self.__n_events_per_dataset) self._n_events_total = np.sum(self.__n_events_per_dataset) self._time_begin = time.time() - t0 - + self.logger.info(f"{self._n_events_total} events in {len(self._datasets)} runs/datasets " f"have been found using the {self._datasets[0].backend} Mattak backend.") - + if not self._n_events_total: err = "No runs have been selected. Abort ..." self.logger.error(err) raise ValueError(err) - - + + def set_selectors(self, selectors, select_triggers=None): """ Parameters ---------- - + selectors: list of lambdas List of lambda(eventInfo) -> bool to pass to mattak.Dataset.iterate to select events. Example: trigger_selector = lambda eventInfo: eventInfo.triggerType == "FORCE" - + select_triggers: str or list(str) - Names of triggers which should be selected. Convinence interface instead of passing a selector. (Default: None) + Names of triggers which should be selected. Convinence interface instead of passing a selector. (Default: None) """ - + # Initialize selectors for event filtering if not isinstance(selectors, (list, np.ndarray)): selectors = [selectors] - + if select_triggers is not None: if isinstance(select_triggers, str): selectors.append(lambda eventInfo: eventInfo.triggerType == select_triggers) @@ -422,57 +426,57 @@ def set_selectors(self, selectors, select_triggers=None): self._selectors = selectors self.logger.info(f"Set {len(self._selectors)} selector(s)") - + def __select_run(self, dataset): - """ Filter/select runs/datasets. - + """ Filter/select runs/datasets. + Parameters ---------- - + dataset: mattak.Dataset.Dataset - + select: bool Return True to select an dataset, return False to reject/skip it. """ - + # get first eventInfo dataset.setEntries(0) event_info = dataset.eventInfo() - + run_id = event_info.run station_id = event_info.station - + run_info = self.__run_table.query(f"station == {station_id:d} & run == {run_id:d}") - + if not len(run_info): self.logger.error(f"Run {run_id:d} (station {station_id:d}) not in run table. Reject...") return False - + # "time_start/end" is stored in the isot format. datetime is much faster than astropy (~85ns vs 55 mus). - # But using datetime would mean to stip decimals because datetime can only handle mu sec precision and can not cope + # But using datetime would mean to stip decimals because datetime can only handle mu sec precision and can not cope # with the additional decimals for ns. if self._time_low is not None: time_end = astropy.time.Time(run_info["time_end"].values[0]) if time_end < self._time_low: self.logger.info(f"Reject station {station_id} run {run_id} because run ended before {self._time_low}") return False - + if self._time_high is not None: time_start = astropy.time.Time(run_info["time_start"].values[0]) if time_start > self._time_high: self.logger.info(f"Reject station {station_id} run {run_id} because run started time after {self._time_high}") return False - + run_type = run_info["run_type"].values[0] if not run_type in self.__run_types: self.logger.info(f"Reject station {station_id} run {run_id} because of run type {run_type}") return False - - trigger_rate = run_info["trigger_rate"].values[0] * units.Hz + + trigger_rate = run_info["trigger_rate"].values[0] * units.Hz if self.__max_trigger_rate and trigger_rate > self.__max_trigger_rate: self.logger.info(f"Reject station {station_id} run {run_id} because trigger rate is to high ({trigger_rate / units.Hz:.2f} Hz)") return False - + return True @@ -480,20 +484,20 @@ def __get_n_events_of_prev_datasets(self, dataset_idx): """ Get accumulated number of events from previous datasets """ dataset_idx_prev = dataset_idx - 1 return int(self._event_idxs_datasets[dataset_idx_prev]) if dataset_idx_prev >= 0 else 0 - - + + def __get_dataset_for_event(self, event_idx): """ Get correct dataset and set entry accordingly to event index - + Parameters ---------- - + event_index: int Same as in read_event(). - + Returns ------- - + dataset: mattak.Dataset.Dataset """ # find correct dataset @@ -502,25 +506,25 @@ def __get_dataset_for_event(self, event_idx): event_idx_in_dataset = event_idx - self.__get_n_events_of_prev_datasets(dataset_idx) dataset.setEntries(event_idx_in_dataset) # increment iterator -> point to new event - + return dataset - - + + def _filter_event(self, evtinfo, event_idx=None): """ Filter an event base on its EventInfo and the configured selectors. Parameters ---------- - + event_info: mattak.Dataset.EventInfo The event info object for one event. - + event_index: int Same as in read_event(). Only use for logger.info(). (Default: None) - + Returns ------- - + skip: bool Returns True to skip/reject event, return False to keep/read event """ @@ -531,35 +535,35 @@ def _filter_event(self, evtinfo, event_idx=None): f"event number {evtinfo.eventNumber}) is skipped.") self.__skipped += 1 return True - + return False - - + + def get_events_information(self, keys=["station", "run", "eventNumber"]): """ Return information of all events from the EventInfo - - This function is useful to make a pre-selection of events before actually reading them in combination with + + This function is useful to make a pre-selection of events before actually reading them in combination with self.read_event(). - + Parameters ---------- - + keys: list(str) List of the information to receive from each event. Have to match the attributes (member variables) of the mattak.Dataset.EventInfo class (examples are "station", "run", "triggerTime", "triggerType", "eventNumber", ...). (Default: ["station", "run", "eventNumber"]) - + Returns ------- - + data: dict - Keys of the dict are the event indecies (as used in self.read_event(event_index)). The values are dictinaries + Keys of the dict are the event indecies (as used in self.read_event(event_index)). The values are dictinaries them self containing the information specified with "keys" parameter. """ - + # Read if dict is None ... do_read = self._events_information is None - + if not do_read: # ... or when it does not have the desired information first_event_info = self._events_information[list(self._events_information.keys())[0]] @@ -567,44 +571,44 @@ def get_events_information(self, keys=["station", "run", "eventNumber"]): for key in keys: if key not in list(first_event_info.keys()): do_read = True - + if do_read: - + self._events_information = {} n_prev = 0 for dataset in self._datasets: dataset.setEntries((0, dataset.N())) - + for idx, evtinfo in enumerate(dataset.eventInfo()): # returns a list - - event_idx = idx + n_prev # event index accross all datasets combined - + + event_idx = idx + n_prev # event index accross all datasets combined + if self._filter_event(evtinfo, event_idx): continue - + self._events_information[event_idx] = {key: getattr(evtinfo, key) for key in keys} - + n_prev += dataset.N() return self._events_information - - + + def _check_for_valid_information_in_event_info(self, event_info): """ Checks if certain information (sampling rate, trigger time) in mattak.Dataset.EventInfo are valid - + Parameters ---------- - + event_info: mattak.Dataset.EventInfo - + Returns ------- - + is_valid: bool Returns True if all information valid, false otherwise """ - + if math.isinf(event_info.triggerTime): self.logger.error(f"Event {event_info.eventNumber} (st {event_info.station}, run {event_info.run}) " "has inf trigger time. Skip event...") @@ -618,25 +622,25 @@ def _check_for_valid_information_in_event_info(self, event_info): f"You can avoid this by setting 'overwrite_sampling_rate' in the begin() method.") self.__invalid += 1 return False - + return True - - + + def _get_event(self, event_info, waveforms): """ Return a NuRadioReco event - + Parameters ---------- - + event_info: mattak.Dataset.EventInfo The event info object for one event. - + waveforms: np.array(n_channel, n_samples) Typically what dataset.wfs() returns (for one event!) Returns ------- - + evt: NuRadioReco.framework.event """ @@ -654,95 +658,95 @@ def _get_event(self, event_info, waveforms): trigger.set_triggered() trigger.set_trigger_time(trigger_time) station.set_trigger(trigger) - + for channel_id, wf in enumerate(waveforms): - channel = NuRadioReco.framework.channel.Channel(channel_id) - if self._read_calibrated_data: + channel = NuRadioReco.framework.channel.Channel(channel_id) + if self._read_calibrated_data: channel.set_trace(wf * units.mV, sampling_rate * units.GHz) else: # wf stores ADC counts - + if self._apply_baseline_correction: # correct baseline wf = baseline_correction(wf) - + if self._convert_to_voltage: # convert adc to voltage wf *= (self._adc_ref_voltage_range / (2 ** (self._adc_n_bits) - 1)) - + channel.set_trace(wf, sampling_rate * units.GHz) - + time_offset = get_time_offset(event_info.triggerType) channel.set_trace_start_time(-time_offset) # relative to event/trigger time - + station.add_channel(channel) - + evt.set_station(station) - - return evt + + return evt @register_run() def run(self): - """ + """ Loop over all events. - + Returns ------- - + evt: generator(NuRadioReco.framework.event) """ event_idx = -1 for dataset in self._datasets: dataset.setEntries((0, dataset.N())) - + # read all event infos of the entier dataset (= run) event_infos = dataset.eventInfo() wfs = None for idx, evtinfo in enumerate(event_infos): # returns a list event_idx += 1 - + self.logger.debug(f"Processing event number {event_idx} out of total {self._n_events_total}") t0 = time.time() - + if self._filter_event(evtinfo, event_idx): continue - + if not self._check_for_valid_information_in_event_info(evtinfo): continue - + # Just read wfs if necessary if wfs is None: wfs = dataset.wfs() - + waveforms_of_event = wfs[idx] - + evt = self._get_event(evtinfo, waveforms_of_event) - + self._time_run += time.time() - t0 self.__counter += 1 - + yield evt def get_event_by_index(self, event_index): - """ Allows to read a specific event identifed by its index - + """ Allows to read a specific event identifed by its index + Parameters ---------- - + event_index: int - The index of a particluar event. The index is the chronological number from 0 to + The index of a particluar event. The index is the chronological number from 0 to number of total events (across all datasets). - + Returns ------- - + evt: NuRadioReco.framework.event """ - + self.logger.debug(f"Processing event number {event_index} out of total {self._n_events_total}") t0 = time.time() @@ -751,22 +755,22 @@ def get_event_by_index(self, event_index): if self._filter_event(event_info, event_index): return None - + # check this before reading the wfs if not self._check_for_valid_information_in_event_info(event_info): return None - + # access data waveforms = dataset.wfs() - + evt = self._get_event(event_info, waveforms) - + self._time_run += time.time() - t0 self.__counter += 1 - + return evt - - + + def get_event(self, run_nr, event_id): """ Allows to read a specific event identifed by run number and event id @@ -778,7 +782,7 @@ def get_event(self, run_nr, event_id): event_id: int Event Id - + Returns ------- @@ -809,11 +813,11 @@ def get_event(self, run_nr, event_id): if self._filter_event(event_info, event_index): return None - + # check this before reading the wfs if not self._check_for_valid_information_in_event_info(event_info): return None - + # access data waveforms = dataset.wfs() @@ -836,9 +840,51 @@ def end(self): else: self.logger.info( f"\n\tRead {self.__counter} events (skipped {self.__skipped} events, {self.__invalid} invalid events)") - + # Clean up links and temporary directories. for d in self.__temporary_dirs: self.logger.debug(f"Remove temporary folder: {d}") os.unlink(os.path.join(d, "combined.root")) os.rmdir(d) + + +### we create a wrapper for readRNOGData to mirror the interface of the .nur reader +class _readRNOGData_eventbrowser(readRNOGData): + """ + Wrapper for readRNOGData for use in the eventbrowser + + This wrapper mirrors the interface of the .nur reader for use in the eventbrowser, + and uses the lru_cache to speed up IO for parallel plots of the same event. + It should probably not be used outside of the eventbrowser. + + """ + def begin(self, *args, **kwargs): + # We reduce the required amount of IO by caching individual events. + # However, we need to clear the cache every time we change the file + # we're reading. This is implemented here. + self.get_event_i.cache_clear() + self.get_event.cache_clear() + return super().begin(*args, **kwargs) + + def get_event_ids(self): + event_infos = self.get_events_information() + return np.array([(i['run'], i['eventNumber']) for i in event_infos.values()]) + + @lru_cache(maxsize=1) + def get_event_i(self, i): + return self.get_event_by_index(i) + + @lru_cache(maxsize=1) + def get_event(self, event_id): + return super().get_event(*event_id) + + def get_n_events(self): + return self._n_events_total + + def get_detector(self): + """Not implemented in mattak reader""" + return None + + def get_header(self): + """Not implemented in mattak reader""" + return None \ No newline at end of file From 86ea3a3697a6b0de1bac8f731cf152a689f5be9f Mon Sep 17 00:00:00 2001 From: Sjoerd Bouma Date: Wed, 25 Oct 2023 19:47:53 +0200 Subject: [PATCH 389/418] merge eventbrowser dataproviders into one --- NuRadioReco/eventbrowser/dataprovider.py | 125 +++++++++++++++--- NuRadioReco/eventbrowser/dataprovider_nur.py | 25 ---- NuRadioReco/eventbrowser/dataprovider_root.py | 91 ------------- NuRadioReco/eventbrowser/index.py | 3 +- 4 files changed, 108 insertions(+), 136 deletions(-) delete mode 100644 NuRadioReco/eventbrowser/dataprovider_nur.py delete mode 100644 NuRadioReco/eventbrowser/dataprovider_root.py diff --git a/NuRadioReco/eventbrowser/dataprovider.py b/NuRadioReco/eventbrowser/dataprovider.py index 4ec4a6762..a3b173d91 100644 --- a/NuRadioReco/eventbrowser/dataprovider.py +++ b/NuRadioReco/eventbrowser/dataprovider.py @@ -1,44 +1,133 @@ -import NuRadioReco.eventbrowser.dataprovider_root -import NuRadioReco.eventbrowser.dataprovider_nur import threading import logging import six import NuRadioReco.utilities.metaclasses +import os +import time +from NuRadioReco.modules.io import NuRadioRecoio + logging.basicConfig() logger = logging.getLogger('eventbrowser.dataprovider') logger.setLevel(logging.INFO) -LOCK = threading.Lock() +try: + from NuRadioReco.modules.io.RNO_G.readRNOGDataMattak import _readRNOGData_eventbrowser +except ImportError as e: + logger.error( + msg=( + "Failed to import NuRadioReco.modules.io.RNO_G.readRNOGDataMattak, `.root` files can not be read." + " If you are only trying to read .nur files this error can be ignored.." + ), exc_info=e + ) + _readRNOGData_eventbrowser = None # if we don't define this we'll raise more errors later @six.add_metaclass(NuRadioReco.utilities.metaclasses.Singleton) class DataProvider(object): - __instance = None + _use_root = None + + def __init__(self, use_root=False, max_user_instances=12): + """" + Interface to .nur or .root file IO for the eventbrowser - def __new__(cls): - if DataProvider.__instance is None: - DataProvider.__instance = object.__new__(cls) - return DataProvider.__instance + Parameters + ---------- + use_root: bool, default False + If True, use the the RNO-G specific root file reader. Otherwise, + use the NuRadioMC + max_user_instances: int, default=12 + Each unique session id gets its own reader, up to a maximum + of ``max_user_instances`` concurrent readers. Subsequent + requests for new readers drop older readers. - def __init__(self): - self.__data_provider = None - self._use_root = None + """ + logger.info("Creating new DataProvider instance") + self.__max_user_instances = max_user_instances + self.__user_instances = {} + self.__lock = threading.Lock() + self.set_filetype(use_root=use_root) def set_filetype(self, use_root): + """ + Set the filetype to read in. + + Parameters + ---------- + use_root: bool + If True, use the :mod:`NuRadioReco.modules.io.RNO_G.readRNOGDataMattak` module + to read in RNO-G ROOT files. Otherwise, use the 'standard' NuRadioMC `.nur` file + reader. + """ if self._use_root == use_root: return None if use_root: - self.__data_provider = NuRadioReco.eventbrowser.dataprovider_root.DataProviderRoot() + if _readRNOGData_eventbrowser is None: + raise ImportError( + "The .root reading interface `NuRadioReco.modules.io.RNO_G.readRNOGDataMattak`" + " is not available, so .root files can not be read. Make sure you have a working installation" + " of mattak (https://github.com/RNO-G/mattak)." + ) + self.__file_handler = _readRNOGData_eventbrowser # we only initialize once, maybe this saves some time? else: - self.__data_provider = NuRadioReco.eventbrowser.dataprovider_nur.DataProvider() + self.__file_handler = NuRadioRecoio.NuRadioRecoio # need to initialize for every file self._use_root = use_root def get_file_handler(self, user_id, filename): + """ + Interface to retrieve the actual IO module + + Thread-locked to avoid competing threads reading the same file. + + Parameters + ---------- + user_id: str + unique user_id to allow multiple users to use the dataprovider at once + filename: str | list + path or paths to files to read in + + """ + # because the dash app is multi-threaded, we use a lock to avoid + # multiple simultaneous requests to read the same file + thread = threading.get_ident() total_threads = threading.active_count() logger.debug(f"Thread {thread} out of total {total_threads} requesting file_handler for user {user_id}") - LOCK.acquire() - logger.debug(f"Thread {thread} locked, getting file_handler for user {user_id}...") - file_handler = self.__data_provider.get_file_handler(user_id, filename) - LOCK.release() + with self.__lock: + logger.debug(f"Thread {thread} locked, getting file_handler for user {user_id}...") + + if filename is None: + return None + if user_id not in self.__user_instances: + reader = self.__file_handler + self.__user_instances[user_id] = dict( + reader=reader, filename=None, + ) + if isinstance(filename, str): + filename = [filename] + if filename != self.__user_instances[user_id]['filename']: + # user is requesting new file -> close current file and open new one + reader = self.__user_instances[user_id]['reader'] + if self._use_root: + reader = self.__file_handler(load_run_table=False) + reader.begin([os.path.dirname(f) for f in filename], overwrite_sampling_rate=3.2) + reader.get_event_ids() + else: + reader = self.__file_handler(filename) # NuRadioRecoio takes filenames as argument to __init__ + self.__user_instances[user_id] = dict( + reader=reader, filename=filename, + ) + + # update last access time + self.__user_instances[user_id]['last_access_time'] = time.time() + + # check if we exceed maximum number of concurrent sessions + if len(self.__user_instances) > self.__max_user_instances: + users = { + self.__user_instances[k]['last_access_time']:k + for k in self.__user_instances.keys() + } + users_by_access_time = sorted(users) + # drop oldest session + self.__user_instances.pop(users_by_access_time[0]) + logger.debug(f"Returning file_handler and releasing lock") - return file_handler + return self.__user_instances[user_id]['reader'] diff --git a/NuRadioReco/eventbrowser/dataprovider_nur.py b/NuRadioReco/eventbrowser/dataprovider_nur.py deleted file mode 100644 index a9fb2ea80..000000000 --- a/NuRadioReco/eventbrowser/dataprovider_nur.py +++ /dev/null @@ -1,25 +0,0 @@ -from __future__ import absolute_import, division, print_function # , unicode_literals -from NuRadioReco.modules.io import NuRadioRecoio - - -class DataProvider(object): - __instance = None - - def __new__(cls): - if DataProvider.__instance is None: - DataProvider.__instance = object.__new__(cls) - return DataProvider.__instance - - def __init__(self): - self.__user_instances = {} - - def get_file_handler(self, user_id, filename): - if filename is None: - return - if user_id not in self.__user_instances: - self.__user_instances[user_id] = NuRadioRecoio.NuRadioRecoio(filename) - if filename != self.__user_instances[user_id].get_filenames()[0]: - # user is requesting new file -> close current file and open new one - self.__user_instances[user_id].close_files() - self.__user_instances[user_id] = NuRadioRecoio.NuRadioRecoio(filename) - return self.__user_instances[user_id] diff --git a/NuRadioReco/eventbrowser/dataprovider_root.py b/NuRadioReco/eventbrowser/dataprovider_root.py deleted file mode 100644 index e08dda4dd..000000000 --- a/NuRadioReco/eventbrowser/dataprovider_root.py +++ /dev/null @@ -1,91 +0,0 @@ -from NuRadioReco.modules.io.RNO_G.readRNOGDataMattak import readRNOGData -import os -import time -import numpy as np -import logging - -logging.basicConfig() -logger = logging.getLogger('eventbrowser') -logger.setLevel(logging.DEBUG) - -### we create a wrapper for readRNOGData to mirror the interface of the .nur reader -class readRNOG_wrapper(readRNOGData): - - def get_event_ids(self): - event_infos = self.get_events_information() - return np.array([(i['run'], i['eventNumber']) for i in event_infos.values()]) - - def get_event_i(self, i): - return self.get_event_by_index(i) - - def get_event(self, event_id): - return super().get_event(*event_id) - - def get_n_events(self): - return self._n_events_total - - def get_detector(self): - """Not implemented in mattak reader""" - return None - - def get_header(self): - """Not implemented in mattak reader""" - return None - -class DataProviderRoot(object): - __instance = None - - def __new__(cls): - if DataProviderRoot.__instance is None: - DataProviderRoot.__instance = object.__new__(cls) - return DataProviderRoot.__instance - - def __init__(self, max_user_instances=12): - """" - Convenience wrapper for the root-based RNO-G data reader - - Parameters - ---------- - max_user_instances: int, default=12 - Each unique session id gets its own reader, up to a maximum - of ``max_user_instances`` concurrent readers. Subsequent - requests for new readers drop older readers. - - """ - logger.info("Creating new DataProviderRoot instance") - self.__max_user_instances = max_user_instances - self.__user_instances = {} - - def get_file_handler(self, user_id, filename): - if filename is None: - return - if user_id not in self.__user_instances: - reader = readRNOG_wrapper() - self.__user_instances[user_id] = dict( - reader=reader, filename=None, - ) - if isinstance(filename, str): - filename = [filename] - if filename != self.__user_instances[user_id]['filename']: - # user is requesting new file -> close current file and open new one - reader = self.__user_instances[user_id]['reader'] - reader.begin([os.path.dirname(f) for f in filename], overwrite_sampling_rate=3.2) #TODO - remove hardcoded sampling rate - reader.get_event_ids() # - self.__user_instances[user_id] = dict( - reader=reader, filename=filename, - ) - - # update last access time - self.__user_instances[user_id]['last_access_time'] = time.time() - - # check if we exceed maximum number of concurrent sessions - if len(self.__user_instances) > self.__max_user_instances: - users = { - self.__user_instances[k]['last_access_time']:k - for k in self.__user_instances.keys() - } - users_by_access_time = sorted(users) - # drop oldest session - self.__user_instances.pop(users_by_access_time[0]) - - return self.__user_instances[user_id]['reader'] diff --git a/NuRadioReco/eventbrowser/index.py b/NuRadioReco/eventbrowser/index.py index ec1b402a4..824ca76fd 100644 --- a/NuRadioReco/eventbrowser/index.py +++ b/NuRadioReco/eventbrowser/index.py @@ -15,7 +15,6 @@ import os import argparse import NuRadioReco.eventbrowser.dataprovider -import NuRadioReco.eventbrowser.dataprovider_root import logging import webbrowser from NuRadioReco.modules.base import module @@ -196,7 +195,7 @@ def get_page_content(selection): Input('event-info-run', 'value')], [State('user_id', 'children')] ) -def set_event_number(next_evt_click_timestamp, prev_evt_click_timestamp, event_id, j_plot_click_info, filename, +def set_event_number(next_evt_click_timestamp, prev_evt_click_timestamp, event_id, j_plot_click_info, filename, i_event, run_number, juser_id): context = dash.callback_context if filename is None: From 79cf646ba343222a0d135a8fd4ab966542eb25bd Mon Sep 17 00:00:00 2001 From: Sjoerd Bouma Date: Fri, 27 Oct 2023 00:53:00 +0200 Subject: [PATCH 390/418] identify file reader by file endings --- NuRadioReco/eventbrowser/dataprovider.py | 59 ++++++++++++++---------- 1 file changed, 34 insertions(+), 25 deletions(-) diff --git a/NuRadioReco/eventbrowser/dataprovider.py b/NuRadioReco/eventbrowser/dataprovider.py index a3b173d91..e640a5ee1 100644 --- a/NuRadioReco/eventbrowser/dataprovider.py +++ b/NuRadioReco/eventbrowser/dataprovider.py @@ -23,18 +23,25 @@ @six.add_metaclass(NuRadioReco.utilities.metaclasses.Singleton) class DataProvider(object): - _use_root = None + __lock = threading.Lock() - def __init__(self, use_root=False, max_user_instances=12): + def __init__(self, filetype='auto', max_user_instances=6): """" Interface to .nur or .root file IO for the eventbrowser Parameters ---------- - use_root: bool, default False - If True, use the the RNO-G specific root file reader. Otherwise, - use the NuRadioMC - max_user_instances: int, default=12 + filetype: 'auto' | 'nur' | 'root' + Which IO module to use: + + * 'nur': The standard `NuRadioRecoio` module for reading `.nur` files + * 'root': Read RNO-G root files with the + :mod:`NuRadioReco.modules.io.RNO_G.readRNOGDataMattak` module (requires + `mattak` to be installed from https://github.com/RNO-G/mattak) + * 'auto' (default): determine the appropriate file reader based on the + file endings + + max_user_instances: int (default: 6) Each unique session id gets its own reader, up to a maximum of ``max_user_instances`` concurrent readers. Subsequent requests for new readers drop older readers. @@ -43,11 +50,12 @@ def __init__(self, use_root=False, max_user_instances=12): logger.info("Creating new DataProvider instance") self.__max_user_instances = max_user_instances self.__user_instances = {} - self.__lock = threading.Lock() - self.set_filetype(use_root=use_root) + self.__filetype = filetype def set_filetype(self, use_root): """ + DEPRECATED - we use the file endings to determine file type now + Set the filetype to read in. Parameters @@ -57,19 +65,10 @@ def set_filetype(self, use_root): to read in RNO-G ROOT files. Otherwise, use the 'standard' NuRadioMC `.nur` file reader. """ - if self._use_root == use_root: - return None if use_root: - if _readRNOGData_eventbrowser is None: - raise ImportError( - "The .root reading interface `NuRadioReco.modules.io.RNO_G.readRNOGDataMattak`" - " is not available, so .root files can not be read. Make sure you have a working installation" - " of mattak (https://github.com/RNO-G/mattak)." - ) - self.__file_handler = _readRNOGData_eventbrowser # we only initialize once, maybe this saves some time? + self.__filetype = 'root' else: - self.__file_handler = NuRadioRecoio.NuRadioRecoio # need to initialize for every file - self._use_root = use_root + self.__filetype = 'nur' def get_file_handler(self, user_id, filename): """ @@ -97,21 +96,31 @@ def get_file_handler(self, user_id, filename): if filename is None: return None if user_id not in self.__user_instances: - reader = self.__file_handler self.__user_instances[user_id] = dict( - reader=reader, filename=None, + reader=None, filename=None, ) if isinstance(filename, str): filename = [filename] + + # determine which reader to use + use_root = self.__filetype == 'root' + if (self.__filetype == 'auto') and any([f.endswith('.root') for f in filename]): + use_root = True + if filename != self.__user_instances[user_id]['filename']: # user is requesting new file -> close current file and open new one - reader = self.__user_instances[user_id]['reader'] - if self._use_root: - reader = self.__file_handler(load_run_table=False) + if use_root: + if _readRNOGData_eventbrowser is None: + raise ImportError( + "The .root reading interface `NuRadioReco.modules.io.RNO_G.readRNOGDataMattak`" + " is not available, so .root files can not be read. Make sure you have a working installation" + " of mattak (https://github.com/RNO-G/mattak)." + ) + reader = _readRNOGData_eventbrowser(load_run_table=False) reader.begin([os.path.dirname(f) for f in filename], overwrite_sampling_rate=3.2) reader.get_event_ids() else: - reader = self.__file_handler(filename) # NuRadioRecoio takes filenames as argument to __init__ + reader = NuRadioRecoio.NuRadioRecoio(filename) # NuRadioRecoio takes filenames as argument to __init__ self.__user_instances[user_id] = dict( reader=reader, filename=filename, ) From 15ab040a349d77fb557faedf42158203eb86c34f Mon Sep 17 00:00:00 2001 From: lpyras Date: Wed, 30 Aug 2023 15:54:57 +0200 Subject: [PATCH 391/418] improve docstrings and name all coreas stations observer --- NuRadioReco/modules/io/coreas/coreas.py | 37 +++++++++++++------ .../modules/io/coreas/readCoREASShower.py | 7 ++-- .../modules/io/coreas/readCoREASStation.py | 7 ++-- 3 files changed, 31 insertions(+), 20 deletions(-) diff --git a/NuRadioReco/modules/io/coreas/coreas.py b/NuRadioReco/modules/io/coreas/coreas.py index 8898f6ee0..ea2e18510 100644 --- a/NuRadioReco/modules/io/coreas/coreas.py +++ b/NuRadioReco/modules/io/coreas/coreas.py @@ -1,20 +1,16 @@ import numpy as np import matplotlib.pyplot as plt - from radiotools import helper as hp from radiotools import coordinatesystems - from NuRadioReco.utilities import units import NuRadioReco.framework.sim_station import NuRadioReco.framework.base_trace import NuRadioReco.framework.electric_field import NuRadioReco.framework.radio_shower import radiotools.coordinatesystems - from NuRadioReco.framework.parameters import stationParameters as stnp from NuRadioReco.framework.parameters import electricFieldParameters as efp from NuRadioReco.framework.parameters import showerParameters as shp - import logging logger = logging.getLogger('coreas') @@ -70,7 +66,7 @@ def calculate_simulation_weights(positions, zenith, azimuth, site='summit', debu ax1.set_ylabel(r'Position in $\vec{v} \times \vec{v} \times \vec{B}$ - direction [m]') weights = np.zeros_like(positions[:, 0]) - for p in range(0, weights.shape[0]): # loop over all 240 station positions + for p in range(0, weights.shape[0]): # loop over all observer positions vertices_shower_2d = vor.vertices[vor.regions[vor.point_region[p]]] # x_vertice_ground = x_trafo_from_shower[0] * x_vertice_shower + y_trafo_from_shower[0] * y_vertice_shower + z_trafo_from_shower[0] * z_vertice_shower @@ -87,7 +83,7 @@ def calculate_simulation_weights(positions, zenith, azimuth, site='summit', debu vertices_shower_3d = np.array(vertices_shower_3d) vertices_ground = cstrafo.transform_from_vxB_vxvxB(station_position=vertices_shower_3d) - n_arms = 8 # mask last stations of each arm + n_arms = 8 # mask last observer position of each arm length_shower = np.sqrt(shower[:, 0] ** 2 + shower[:, 1] ** 2) ind = np.argpartition(length_shower, -n_arms)[-n_arms:] @@ -99,7 +95,7 @@ def calculate_simulation_weights(positions, zenith, azimuth, site='summit', debu ax2.plot(vertices_ground[:, 0], vertices_ground[:, 1], c='grey', zorder=1) ax2.scatter(vertices_ground[:, 0], vertices_ground[:, 1], c='tab:orange', zorder=2) if debug: - ax2.scatter(positions[:, 0], positions[:, 1], c='tab:blue', s=10, label='Position of stations') + ax2.scatter(positions[:, 0], positions[:, 1], c='tab:blue', s=10, label='Position of observer') ax2.scatter(vertices_ground[:, 0], vertices_ground[:, 1], c='tab:orange', label='Vertices of cell') ax2.set_aspect('equal') ax2.set_title('On ground, total area {:.2f} $km^2$'.format(sum(weights) / units.km ** 2)) @@ -117,7 +113,7 @@ def calculate_simulation_weights(positions, zenith, azimuth, site='summit', debu ax4.hist(weights) ax4.set_title('Weight distribution') ax4.set_xlabel(r'Weights (here area) $[m^2]$') - ax4.set_ylabel(r'Number of stations') + ax4.set_ylabel(r'Number of observer') ax5.scatter(length_shower ** 2, weights) ax5.set_xlabel(r'$Length^2 [m^2]$') @@ -127,9 +123,9 @@ def calculate_simulation_weights(positions, zenith, azimuth, site='summit', debu return weights -def make_sim_station(station_id, corsika, observer, channel_ids, weight=None): +def make_sim_station(station_id, corsika, observer, channel_ids, weight=None) """ - creates an NuRadioReco sim station from the observer object of the coreas hdf5 file + creates an NuRadioReco sim station from the (interpolated) observer object of the coreas hdf5 file Parameters ---------- @@ -145,10 +141,11 @@ def make_sim_station(station_id, corsika, observer, channel_ids, weight=None): Returns ------- sim_station: sim station - ARIANNA simulated station object + simulated station object """ - # loop over all coreas stations, rotate to ARIANNA CS and save to simulation branch + zenith, azimuth, magnetic_field_vector = get_angles(corsika) + if(observer is None): data = np.zeros((512, 4)) data[:, 0] = np.arange(0, 512) * units.ns / units.second @@ -201,6 +198,22 @@ def make_sim_station(station_id, corsika, observer, channel_ids, weight=None): def make_sim_shower(corsika, observer=None, detector=None, station_id=None): + """ + creates an NuRadioReco sim shower from the coreas hdf5 file + + Parameters + ---------- + corsika : hdf5 file object + the open hdf5 file object of the corsika hdf5 file + observer : hdf5 observer object + detector : detector object + station_id : station id of the station relativ to which the shower core is given + + Returns + ------- + sim_shower: sim shower + simulated shower object + """ sim_shower = NuRadioReco.framework.radio_shower.RadioShower() zenith, azimuth, magnetic_field_vector = get_angles(corsika) diff --git a/NuRadioReco/modules/io/coreas/readCoREASShower.py b/NuRadioReco/modules/io/coreas/readCoREASShower.py index c0bd0dd1b..a0c8fd486 100644 --- a/NuRadioReco/modules/io/coreas/readCoREASShower.py +++ b/NuRadioReco/modules/io/coreas/readCoREASShower.py @@ -4,13 +4,11 @@ from NuRadioReco.modules.io.coreas import coreas from NuRadioReco.utilities import units from radiotools import coordinatesystems - import h5py import numpy as np import time import re import os - import logging logger = logging.getLogger('readCoREASShower') @@ -57,8 +55,9 @@ def begin(self, input_files, det=None, logger_level=logging.NOTSET, set_ascendin def run(self): """ - Reads in a CoREAS file and returns an event containing all simulated stations - + Reads in a CoREAS file and returns one event containing all simulated observer positions as stations. + A detector description is not needed to run this module. If a genericDetector is passed to the begin method, + the stations are added to it and the run method returns both the event and the detector. """ while self.__current_input_file < len(self.__input_files): t = time.time() diff --git a/NuRadioReco/modules/io/coreas/readCoREASStation.py b/NuRadioReco/modules/io/coreas/readCoREASStation.py index f47f4313e..45b6d9843 100644 --- a/NuRadioReco/modules/io/coreas/readCoREASStation.py +++ b/NuRadioReco/modules/io/coreas/readCoREASStation.py @@ -5,7 +5,6 @@ import NuRadioReco.framework.station from NuRadioReco.modules.io.coreas import coreas from NuRadioReco.utilities import units - import logging logger = logging.getLogger('readCoREASStation') @@ -34,13 +33,13 @@ def begin(self, input_files, station_id, debug=False): @register_run() def run(self, detector): """ - Reads in all observers in the CoREAS files and returns a new simulated - event for each. + Reads in all observers in the CoREAS files and returns a new simulated event for each observer with + respect to a given detector with a single station. Parameters ---------- detector: Detector object - Detector description of the detector that shall be simulated + Detector description of the detector that shall be simulated containing one station """ for input_file in self.__input_files: From 4a20ccf560d41f6cf50976d395a3627191e1d365 Mon Sep 17 00:00:00 2001 From: Christoph Date: Fri, 27 Oct 2023 09:37:02 -0500 Subject: [PATCH 392/418] Adds RNO-G detector description based on 2023 survey campaign --- .../detector/RNO_G/RNO_season_2023.json | 3371 +++++++++++++++++ 1 file changed, 3371 insertions(+) create mode 100644 NuRadioReco/detector/RNO_G/RNO_season_2023.json diff --git a/NuRadioReco/detector/RNO_G/RNO_season_2023.json b/NuRadioReco/detector/RNO_G/RNO_season_2023.json new file mode 100644 index 000000000..b1be43208 --- /dev/null +++ b/NuRadioReco/detector/RNO_G/RNO_season_2023.json @@ -0,0 +1,3371 @@ +{ + "channels": { + "0": { + "station_id": 11, + "channel_id": 0, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -96.215, + "amp_type": "iglu", + "cab_time_delay": 716.2603798064285, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-11T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "1": { + "station_id": 11, + "channel_id": 1, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -95.174, + "amp_type": "iglu", + "cab_time_delay": 711.7615958304959, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-11T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "2": { + "station_id": 11, + "channel_id": 2, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -94.183, + "amp_type": "iglu", + "cab_time_delay": 706.495904921158, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-11T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "3": { + "station_id": 11, + "channel_id": 3, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -93.155, + "amp_type": "iglu", + "cab_time_delay": 702.195731800799, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-11T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "4": { + "station_id": 11, + "channel_id": 4, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -91.218, + "amp_type": "iglu", + "cab_time_delay": 690.6185223242599, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-11T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_quadslot_v3_air_rescaled_to_n1.74" + }, + "5": { + "station_id": 11, + "channel_id": 5, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -79.121, + "amp_type": "iglu", + "cab_time_delay": 583.0629875035971, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-11T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "6": { + "station_id": 11, + "channel_id": 6, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -59.131, + "amp_type": "iglu", + "cab_time_delay": 484.257805977493, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-11T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "7": { + "station_id": 11, + "channel_id": 7, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -39.357, + "amp_type": "iglu", + "cab_time_delay": 387.1159239346471, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-11T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "8": { + "station_id": 11, + "channel_id": 8, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -92.177, + "amp_type": "iglu", + "cab_time_delay": 695.0077691915028, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-11T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_quadslot_v3_air_rescaled_to_n1.74" + }, + "9": { + "station_id": 11, + "channel_id": 9, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 18.018524515656964, + "ant_position_y": -30.46999302062511, + "ant_position_z": -82.95, + "amp_type": "iglu", + "cab_time_delay": 704.8660580862335, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-11T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "10": { + "station_id": 11, + "channel_id": 10, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 18.018524515656964, + "ant_position_y": -30.46999302062511, + "ant_position_z": -81.94, + "amp_type": "iglu", + "cab_time_delay": 700.3063612901005, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-11T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "11": { + "station_id": 11, + "channel_id": 11, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 18.018524515656964, + "ant_position_y": -30.46999302062511, + "ant_position_z": -80.94, + "amp_type": "iglu", + "cab_time_delay": 695.125480287199, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-11T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_quadslot_v3_air_rescaled_to_n1.74" + }, + "12": { + "station_id": 11, + "channel_id": 21, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 34.96881000487633, + "ant_position_y": -0.19141220844210238, + "ant_position_z": -94.66, + "amp_type": "iglu", + "cab_time_delay": 695.0278958661603, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-11T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_quadslot_v3_air_rescaled_to_n1.74" + }, + "13": { + "station_id": 11, + "channel_id": 22, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 34.96881000487633, + "ant_position_y": -0.19141220844210238, + "ant_position_z": -95.66, + "amp_type": "iglu", + "cab_time_delay": 700.4737404863125, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-11T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "14": { + "station_id": 11, + "channel_id": 23, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 34.96881000487633, + "ant_position_y": -0.19141220844210238, + "ant_position_z": -96.67, + "amp_type": "iglu", + "cab_time_delay": 704.7261333365847, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-11T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "15": { + "station_id": 11, + "channel_id": 20, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 120.0, + "ant_position_x": 21.186104256390763, + "ant_position_y": -17.507627395985082, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 49.32699419041931, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-11T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "16": { + "station_id": 11, + "channel_id": 19, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 18.861426350457805, + "ant_position_y": -17.407802956481987, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 45.43439538521371, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-11T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "17": { + "station_id": 11, + "channel_id": 18, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 180.0, + "ant_orientation_theta": 120.0, + "ant_position_x": 15.811921687833092, + "ant_position_y": -17.356092695615303, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 52.51563909722448, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-11T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "18": { + "station_id": 11, + "channel_id": 12, + "ant_rotation_phi": 243.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 333.0, + "ant_orientation_theta": 120.0, + "ant_position_x": 25.245374429777485, + "ant_position_y": -9.271898202581497, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 49.556691492869795, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-11T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "19": { + "station_id": 11, + "channel_id": 13, + "ant_rotation_phi": 243.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 24.478617781898492, + "ant_position_y": -6.758508805503766, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 45.883012205651234, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-11T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "20": { + "station_id": 11, + "channel_id": 14, + "ant_rotation_phi": 243.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 153.0, + "ant_orientation_theta": 120.0, + "ant_position_x": 23.709240577868513, + "ant_position_y": -4.359449327425068, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 49.20101294697667, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-11T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "21": { + "station_id": 11, + "channel_id": 15, + "ant_rotation_phi": 351.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 81.0, + "ant_orientation_theta": 120.0, + "ant_position_x": 13.659226614984846, + "ant_position_y": -4.116966752974577, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 52.57621291824783, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-11T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "22": { + "station_id": 11, + "channel_id": 16, + "ant_rotation_phi": 351.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 12.579191943719934, + "ant_position_y": -6.338409142274372, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 45.398781691972694, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-11T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "23": { + "station_id": 11, + "channel_id": 17, + "ant_rotation_phi": 351.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 261.0, + "ant_orientation_theta": 120.0, + "ant_position_x": 11.212162270289355, + "ant_position_y": -9.197601282929554, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 52.51394131174265, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-11T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "24": { + "station_id": 12, + "channel_id": 9, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": -17.169786577567038, + "ant_position_y": 30.105416502163507, + "ant_position_z": -93.472, + "amp_type": "iglu", + "cab_time_delay": 704.8326985978704, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-21T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "25": { + "station_id": 12, + "channel_id": 10, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": -17.169786577567038, + "ant_position_y": 30.105416502163507, + "ant_position_z": -92.507, + "amp_type": "iglu", + "cab_time_delay": 700.5853011208408, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-21T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "26": { + "station_id": 12, + "channel_id": 11, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": -17.169786577567038, + "ant_position_y": 30.105416502163507, + "ant_position_z": -91.491, + "amp_type": "iglu", + "cab_time_delay": 695.0992381351823, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-21T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_quadslot_v3_air_rescaled_to_n1.74" + }, + "27": { + "station_id": 12, + "channel_id": 21, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 17.54306172678298, + "ant_position_y": 30.752842104373485, + "ant_position_z": -92.799, + "amp_type": "iglu", + "cab_time_delay": 694.4016530026131, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-17T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_quadslot_v3_air_rescaled_to_n1.74" + }, + "28": { + "station_id": 12, + "channel_id": 22, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 17.54306172678298, + "ant_position_y": 30.752842104373485, + "ant_position_z": -93.764, + "amp_type": "iglu", + "cab_time_delay": 699.8409090956202, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-17T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "29": { + "station_id": 12, + "channel_id": 23, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 17.54306172678298, + "ant_position_y": 30.752842104373485, + "ant_position_z": -94.755, + "amp_type": "iglu", + "cab_time_delay": 704.1016818511831, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-17T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "30": { + "station_id": 12, + "channel_id": 0, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -94.209, + "amp_type": "iglu", + "cab_time_delay": 717.8528684487527, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-16T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "31": { + "station_id": 12, + "channel_id": 1, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -93.243, + "amp_type": "iglu", + "cab_time_delay": 711.768, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-16T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "32": { + "station_id": 12, + "channel_id": 2, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -92.24, + "amp_type": "iglu", + "cab_time_delay": 707.7227809582946, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-16T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "33": { + "station_id": 12, + "channel_id": 3, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -91.262, + "amp_type": "iglu", + "cab_time_delay": 703.6051877256091, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-16T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "34": { + "station_id": 12, + "channel_id": 4, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -89.319, + "amp_type": "iglu", + "cab_time_delay": 691.703621620457, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-16T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_quadslot_v3_air_rescaled_to_n1.74" + }, + "35": { + "station_id": 12, + "channel_id": 5, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -77.279, + "amp_type": "iglu", + "cab_time_delay": 583.1145481356763, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-16T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "36": { + "station_id": 12, + "channel_id": 6, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -57.252, + "amp_type": "iglu", + "cab_time_delay": 484.39813876384204, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-16T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "37": { + "station_id": 12, + "channel_id": 7, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -37.262, + "amp_type": "iglu", + "cab_time_delay": 387.28183644102774, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-16T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "38": { + "station_id": 12, + "channel_id": 8, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -90.297, + "amp_type": "iglu", + "cab_time_delay": 696.568527555139, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-16T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_quadslot_v3_air_rescaled_to_n1.74" + }, + "39": { + "station_id": 12, + "channel_id": 17, + "ant_rotation_phi": 330.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 240.0, + "ant_orientation_theta": 120.0, + "ant_position_x": -7.25335276193141, + "ant_position_y": 21.34712319053824, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 45.91827499385921, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-17T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "40": { + "station_id": 12, + "channel_id": 16, + "ant_rotation_phi": 330.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": -6.003013655671339, + "ant_position_y": 23.847734045334846, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 45.83638105867064, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-17T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "41": { + "station_id": 12, + "channel_id": 15, + "ant_rotation_phi": 330.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 60.0, + "ant_orientation_theta": 120.0, + "ant_position_x": -4.360019878962476, + "ant_position_y": 26.51315499704583, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 45.730803410479524, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-17T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "42": { + "station_id": 12, + "channel_id": 14, + "ant_rotation_phi": 210.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 120.0, + "ant_orientation_theta": 120.0, + "ant_position_x": 4.522656115828795, + "ant_position_y": 25.910670151475188, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 46.01978301616729, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-21T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "43": { + "station_id": 12, + "channel_id": 13, + "ant_rotation_phi": 210.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 5.838854205594316, + "ant_position_y": 24.5431206774806, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 45.742412236972015, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-21T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "44": { + "station_id": 12, + "channel_id": 12, + "ant_rotation_phi": 210.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 300.0, + "ant_orientation_theta": 120.0, + "ant_position_x": 7.03900825822484, + "ant_position_y": 21.618757784814306, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 45.839198595315175, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-21T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "45": { + "station_id": 12, + "channel_id": 18, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 180.0, + "ant_orientation_theta": 120.0, + "ant_position_x": -3.172374694597238, + "ant_position_y": 13.365198347965134, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 45.59430891887436, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-16T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "46": { + "station_id": 12, + "channel_id": 19, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": -0.09184631579910274, + "ant_position_y": 13.105892618229063, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 45.846178367177174, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-16T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "47": { + "station_id": 12, + "channel_id": 20, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 120.0, + "ant_position_x": 2.89471342104207, + "ant_position_y": 12.980386719307944, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 45.89728312662527, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-16T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "48": { + "station_id": 13, + "channel_id": 0, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -96.266, + "amp_type": "iglu", + "cab_time_delay": 716.5569003542323, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-30T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "49": { + "station_id": 13, + "channel_id": 1, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -95.25, + "amp_type": "iglu", + "cab_time_delay": 711.893994185995, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-30T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "50": { + "station_id": 13, + "channel_id": 2, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -94.259, + "amp_type": "iglu", + "cab_time_delay": 706.675717791364, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-30T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "51": { + "station_id": 13, + "channel_id": 3, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -93.218, + "amp_type": "iglu", + "cab_time_delay": 702.2727756955887, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-30T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "52": { + "station_id": 13, + "channel_id": 4, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -91.211, + "amp_type": "iglu", + "cab_time_delay": 690.6134090862433, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-30T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_quadslot_v3_air_rescaled_to_n1.74" + }, + "53": { + "station_id": 13, + "channel_id": 5, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -79.175, + "amp_type": "iglu", + "cab_time_delay": 583.6510751776831, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-30T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "54": { + "station_id": 13, + "channel_id": 6, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -59.182, + "amp_type": "iglu", + "cab_time_delay": 484.71366908125884, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-30T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "55": { + "station_id": 13, + "channel_id": 7, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -39.243, + "amp_type": "iglu", + "cab_time_delay": 387.4357117300662, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-30T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "56": { + "station_id": 13, + "channel_id": 8, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -92.215, + "amp_type": "iglu", + "cab_time_delay": 695.082404371683, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-30T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_quadslot_v3_air_rescaled_to_n1.74" + }, + "57": { + "station_id": 13, + "channel_id": 9, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": -17.51197811169982, + "ant_position_y": 29.742022928890492, + "ant_position_z": -94.818, + "amp_type": "iglu", + "cab_time_delay": 705.8226166224723, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "58": { + "station_id": 13, + "channel_id": 10, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": -17.51197811169982, + "ant_position_y": 29.742022928890492, + "ant_position_z": -93.802, + "amp_type": "iglu", + "cab_time_delay": 701.4365946711572, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "59": { + "station_id": 13, + "channel_id": 11, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": -17.51197811169982, + "ant_position_y": 29.742022928890492, + "ant_position_z": -92.812, + "amp_type": "iglu", + "cab_time_delay": 696.2095237776895, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_quadslot_v3_air_rescaled_to_n1.74" + }, + "60": { + "station_id": 13, + "channel_id": 21, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 16.95447838550831, + "ant_position_y": 30.12568265560958, + "ant_position_z": -93.091, + "amp_type": "iglu", + "cab_time_delay": 694.966307648661, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-07-04T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_quadslot_v3_air_rescaled_to_n1.74" + }, + "61": { + "station_id": 13, + "channel_id": 22, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 16.95447838550831, + "ant_position_y": 30.12568265560958, + "ant_position_z": -94.082, + "amp_type": "iglu", + "cab_time_delay": 700.4557991679768, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-07-04T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "62": { + "station_id": 13, + "channel_id": 23, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 16.95447838550831, + "ant_position_y": 30.12568265560958, + "ant_position_z": -95.098, + "amp_type": "iglu", + "cab_time_delay": 704.7490940670381, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-07-04T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "63": { + "station_id": 13, + "channel_id": 17, + "ant_rotation_phi": 330.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 240.0, + "ant_orientation_theta": 120.0, + "ant_position_x": -7.659842837283577, + "ant_position_y": 21.248748214991338, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 45.4816564960653, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-07-04T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "64": { + "station_id": 13, + "channel_id": 16, + "ant_rotation_phi": 330.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": -6.394915495773603, + "ant_position_y": 23.544812894404913, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 45.917833705247084, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-07-04T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "65": { + "station_id": 13, + "channel_id": 15, + "ant_rotation_phi": 330.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 60.0, + "ant_orientation_theta": 120.0, + "ant_position_x": -4.7293936275261785, + "ant_position_y": 25.843182149080803, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 45.38950686394398, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-07-04T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "66": { + "station_id": 13, + "channel_id": 14, + "ant_rotation_phi": 210.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 120.0, + "ant_orientation_theta": 120.0, + "ant_position_x": 4.387081260395007, + "ant_position_y": 25.783898894905633, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 45.977255276242445, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "67": { + "station_id": 13, + "channel_id": 13, + "ant_rotation_phi": 210.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 5.591569317517724, + "ant_position_y": 23.363173077020747, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 45.85528602130243, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "68": { + "station_id": 13, + "channel_id": 12, + "ant_rotation_phi": 210.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 300.0, + "ant_orientation_theta": 120.0, + "ant_position_x": 6.975139683861471, + "ant_position_y": 21.094408011153973, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 46.01961725310455, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "69": { + "station_id": 13, + "channel_id": 20, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 120.0, + "ant_position_x": 2.4579457368663498, + "ant_position_y": 13.335390086505413, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 45.764002862920535, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-30T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "70": { + "station_id": 13, + "channel_id": 19, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": -0.08945918504923611, + "ant_position_y": 13.066877906649552, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 45.97540552376522, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-30T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "71": { + "station_id": 13, + "channel_id": 18, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 180.0, + "ant_orientation_theta": 120.0, + "ant_position_x": -2.8286647134991654, + "ant_position_y": 13.04946226926404, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 45.75640441890302, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-30T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "72": { + "station_id": 21, + "channel_id": 0, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -95.37, + "amp_type": "iglu", + "cab_time_delay": 716.2340516693513, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-04T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "73": { + "station_id": 21, + "channel_id": 1, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -94.37, + "amp_type": "iglu", + "cab_time_delay": 711.6738111253712, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-04T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "74": { + "station_id": 21, + "channel_id": 2, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -93.36, + "amp_type": "iglu", + "cab_time_delay": 706.3043868097873, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-04T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "75": { + "station_id": 21, + "channel_id": 3, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -92.36, + "amp_type": "iglu", + "cab_time_delay": 702.1201325816487, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-04T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "76": { + "station_id": 21, + "channel_id": 4, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -90.39, + "amp_type": "iglu", + "cab_time_delay": 689.9220583040554, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-04T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_quadslot_v3_air_rescaled_to_n1.74" + }, + "77": { + "station_id": 21, + "channel_id": 5, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -78.42, + "amp_type": "iglu", + "cab_time_delay": 583.6085635800221, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-04T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "78": { + "station_id": 21, + "channel_id": 6, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -57.98, + "amp_type": "iglu", + "cab_time_delay": 484.73964774406437, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-04T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "79": { + "station_id": 21, + "channel_id": 7, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -38.33, + "amp_type": "iglu", + "cab_time_delay": 387.6103598042084, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-04T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "80": { + "station_id": 21, + "channel_id": 8, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -91.37, + "amp_type": "iglu", + "cab_time_delay": 695.0287325115062, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-04T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_quadslot_v3_air_rescaled_to_n1.74" + }, + "81": { + "station_id": 21, + "channel_id": 9, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": -17.237822409178648, + "ant_position_y": 29.436009810348025, + "ant_position_z": -94.7, + "amp_type": "iglu", + "cab_time_delay": 706.0498570594092, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-04T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "82": { + "station_id": 21, + "channel_id": 10, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": -17.237822409178648, + "ant_position_y": 29.436009810348025, + "ant_position_z": -93.71, + "amp_type": "iglu", + "cab_time_delay": 701.7155539494165, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-04T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "83": { + "station_id": 21, + "channel_id": 11, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": -17.237822409178648, + "ant_position_y": 29.436009810348025, + "ant_position_z": -92.7, + "amp_type": "iglu", + "cab_time_delay": 696.5371961764442, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-04T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_quadslot_v3_air_rescaled_to_n1.74" + }, + "84": { + "station_id": 21, + "channel_id": 21, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": -34.1288896622176, + "ant_position_y": -1.2407598474927681, + "ant_position_z": -93.37, + "amp_type": "iglu", + "cab_time_delay": 695.8319798499194, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-04T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_quadslot_v3_air_rescaled_to_n1.74" + }, + "85": { + "station_id": 21, + "channel_id": 22, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": -34.1288896622176, + "ant_position_y": -1.2407598474927681, + "ant_position_z": -94.34, + "amp_type": "iglu", + "cab_time_delay": 701.0882803491144, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-04T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "86": { + "station_id": 21, + "channel_id": 23, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": -34.1288896622176, + "ant_position_y": -1.2407598474927681, + "ant_position_z": -95.37, + "amp_type": "iglu", + "cab_time_delay": 705.241651007666, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-04T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "87": { + "station_id": 21, + "channel_id": 15, + "ant_rotation_phi": 254.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 164.0, + "ant_orientation_theta": 120.0, + "ant_position_x": -20.913616334864287, + "ant_position_y": 16.537611216532184, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 49.254956245215354, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-04T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "88": { + "station_id": 21, + "channel_id": 16, + "ant_rotation_phi": 254.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": -18.326662967684683, + "ant_position_y": 16.91462123190064, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 45.82958226071196, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-04T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "89": { + "station_id": 21, + "channel_id": 17, + "ant_rotation_phi": 254.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 344.0, + "ant_orientation_theta": 120.0, + "ant_position_x": -15.404148418065631, + "ant_position_y": 17.46318633982372, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 48.96724049428868, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-04T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "90": { + "station_id": 21, + "channel_id": 14, + "ant_rotation_phi": 65.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 155.0, + "ant_orientation_theta": 120.0, + "ant_position_x": -25.02971666518448, + "ant_position_y": 7.293175091846081, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 49.42704773531392, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-04T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "91": { + "station_id": 21, + "channel_id": 13, + "ant_rotation_phi": 65.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": -23.892386133465607, + "ant_position_y": 4.978986751043749, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 45.43375896297529, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-04T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "92": { + "station_id": 21, + "channel_id": 12, + "ant_rotation_phi": 65.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 335.0, + "ant_orientation_theta": 120.0, + "ant_position_x": -22.479689741668324, + "ant_position_y": 2.80783833285102, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 49.36961127763919, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-04T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "93": { + "station_id": 21, + "channel_id": 20, + "ant_rotation_phi": 118.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 208.0, + "ant_orientation_theta": 120.0, + "ant_position_x": -11.266588048738129, + "ant_position_y": 2.9011467712219314, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 48.99288182695537, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-04T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "94": { + "station_id": 21, + "channel_id": 19, + "ant_rotation_phi": 118.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": -10.00827839620348, + "ant_position_y": 5.2833313663230115, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 45.75937993162733, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-04T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "95": { + "station_id": 21, + "channel_id": 18, + "ant_rotation_phi": 118.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 28.0, + "ant_orientation_theta": 120.0, + "ant_position_x": -8.513397338379718, + "ant_position_y": 7.724537269470318, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 49.48968661430838, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-04T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "96": { + "station_id": 22, + "channel_id": 9, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": -17.199498709672298, + "ant_position_y": 29.357402778427513, + "ant_position_z": -96.8, + "amp_type": "iglu", + "cab_time_delay": 706.0498570594092, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "97": { + "station_id": 22, + "channel_id": 10, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": -17.199498709672298, + "ant_position_y": 29.357402778427513, + "ant_position_z": -95.8, + "amp_type": "iglu", + "cab_time_delay": 701.7155539494165, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "98": { + "station_id": 22, + "channel_id": 11, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": -17.199498709672298, + "ant_position_y": 29.357402778427513, + "ant_position_z": -94.8, + "amp_type": "iglu", + "cab_time_delay": 696.5371961764442, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_quadslot_v3_air_rescaled_to_n1.74" + }, + "99": { + "station_id": 22, + "channel_id": 21, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 16.39538465744613, + "ant_position_y": 29.513529144740687, + "ant_position_z": -94.61, + "amp_type": "iglu", + "cab_time_delay": 695.0887166749822, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_quadslot_v3_air_rescaled_to_n1.74" + }, + "100": { + "station_id": 22, + "channel_id": 22, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 16.39538465744613, + "ant_position_y": 29.513529144740687, + "ant_position_z": -95.61, + "amp_type": "iglu", + "cab_time_delay": 700.5097259660157, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "101": { + "station_id": 22, + "channel_id": 23, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 16.39538465744613, + "ant_position_y": 29.513529144740687, + "ant_position_z": -96.62, + "amp_type": "iglu", + "cab_time_delay": 704.7852281608289, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "102": { + "station_id": 22, + "channel_id": 0, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -95.67, + "amp_type": "iglu", + "cab_time_delay": 716.5273297729007, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "103": { + "station_id": 22, + "channel_id": 1, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -94.66, + "amp_type": "iglu", + "cab_time_delay": 711.9338529670598, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "104": { + "station_id": 22, + "channel_id": 2, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -93.66, + "amp_type": "iglu", + "cab_time_delay": 706.6720443161013, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "105": { + "station_id": 22, + "channel_id": 3, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -92.66, + "amp_type": "iglu", + "cab_time_delay": 702.2200344958492, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "106": { + "station_id": 22, + "channel_id": 4, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -90.72, + "amp_type": "iglu", + "cab_time_delay": 690.5959592568203, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_quadslot_v3_air_rescaled_to_n1.74" + }, + "107": { + "station_id": 22, + "channel_id": 5, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -78.7, + "amp_type": "iglu", + "cab_time_delay": 583.316058590185, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "108": { + "station_id": 22, + "channel_id": 6, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -58.62, + "amp_type": "iglu", + "cab_time_delay": 484.8636828671781, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "109": { + "station_id": 22, + "channel_id": 7, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -38.53, + "amp_type": "iglu", + "cab_time_delay": 387.5505598225923, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "110": { + "station_id": 22, + "channel_id": 8, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -91.67, + "amp_type": "iglu", + "cab_time_delay": 695.1562845004979, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_quadslot_v3_air_rescaled_to_n1.74" + }, + "111": { + "station_id": 22, + "channel_id": 17, + "ant_rotation_phi": 330.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 240.0, + "ant_orientation_theta": 120.0, + "ant_position_x": -8.6049483702011, + "ant_position_y": 21.47786411167135, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 52.71319900390884, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "112": { + "station_id": 22, + "channel_id": 16, + "ant_rotation_phi": 330.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": -7.5612403179679575, + "ant_position_y": 23.893840401733087, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 45.602214424020616, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "113": { + "station_id": 22, + "channel_id": 15, + "ant_rotation_phi": 330.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 60.0, + "ant_orientation_theta": 120.0, + "ant_position_x": -6.378764994213384, + "ant_position_y": 26.059809190085844, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 52.983380707350655, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "114": { + "station_id": 22, + "channel_id": 13, + "ant_rotation_phi": 213.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 7.223712045816455, + "ant_position_y": 23.24066900706316, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 45.989096119098235, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "115": { + "station_id": 22, + "channel_id": 20, + "ant_rotation_phi": 81.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 351.0, + "ant_orientation_theta": 120.0, + "ant_position_x": 2.5453667925172567, + "ant_position_y": 11.108734895638918, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 49.510627155343215, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "116": { + "station_id": 22, + "channel_id": 19, + "ant_rotation_phi": 81.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": -0.033351822535991005, + "ant_position_y": 11.348087174853845, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 45.777650776480506, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "117": { + "station_id": 22, + "channel_id": 14, + "ant_rotation_phi": 213.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 123.0, + "ant_orientation_theta": 120.0, + "ant_position_x": 5.363380066230661, + "ant_position_y": 25.697792916809476, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 49.527426912487186, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "118": { + "station_id": 22, + "channel_id": 12, + "ant_rotation_phi": 213.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 303.0, + "ant_orientation_theta": 120.0, + "ant_position_x": 8.118574044456068, + "ant_position_y": 20.662247745052127, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 49.07793698494233, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "119": { + "station_id": 22, + "channel_id": 18, + "ant_rotation_phi": 81.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 171.0, + "ant_orientation_theta": 120.0, + "ant_position_x": -2.5448638218912265, + "ant_position_y": 11.377546831037535, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 52.95363112541108, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "120": { + "station_id": 23, + "channel_id": 0, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -94.717, + "amp_type": "iglu", + "cab_time_delay": 717.0534637454359, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-23T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "121": { + "station_id": 23, + "channel_id": 1, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -93.751, + "amp_type": "iglu", + "cab_time_delay": 712.4004767769894, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-23T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "122": { + "station_id": 23, + "channel_id": 2, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -92.735, + "amp_type": "iglu", + "cab_time_delay": 707.1524946995909, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-23T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "123": { + "station_id": 23, + "channel_id": 3, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -91.745, + "amp_type": "iglu", + "cab_time_delay": 702.8617993250889, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-23T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "124": { + "station_id": 23, + "channel_id": 4, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -89.764, + "amp_type": "iglu", + "cab_time_delay": 690.9500500747815, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-23T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_quadslot_v3_air_rescaled_to_n1.74" + }, + "125": { + "station_id": 23, + "channel_id": 5, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -77.699, + "amp_type": "iglu", + "cab_time_delay": 582.3601331742286, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-23T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "126": { + "station_id": 23, + "channel_id": 7, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -57.709, + "amp_type": "iglu", + "cab_time_delay": 483.6670431088573, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-23T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "127": { + "station_id": 23, + "channel_id": 6, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -37.719, + "amp_type": "iglu", + "cab_time_delay": 386.37548644736046, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-23T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "128": { + "station_id": 23, + "channel_id": 8, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -90.729, + "amp_type": "iglu", + "cab_time_delay": 695.8484064369925, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-23T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_quadslot_v3_air_rescaled_to_n1.74" + }, + "129": { + "station_id": 23, + "channel_id": 9, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": -34.54191609133999, + "ant_position_y": -0.1224676067567998, + "ant_position_z": -94.945, + "amp_type": "iglu", + "cab_time_delay": 705.2304586807497, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-24T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "130": { + "station_id": 23, + "channel_id": 10, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": -34.54191609133999, + "ant_position_y": -0.1224676067567998, + "ant_position_z": -93.942, + "amp_type": "iglu", + "cab_time_delay": 701.1086074022868, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-24T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "131": { + "station_id": 23, + "channel_id": 11, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": -34.54191609133999, + "ant_position_y": -0.1224676067567998, + "ant_position_z": -92.951, + "amp_type": "iglu", + "cab_time_delay": 695.7224638947405, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-24T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_quadslot_v3_air_rescaled_to_n1.74" + }, + "132": { + "station_id": 23, + "channel_id": 21, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": -17.11733208278625, + "ant_position_y": 29.755711625947697, + "ant_position_z": -93.764, + "amp_type": "iglu", + "cab_time_delay": 696.6159498314443, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-26T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_quadslot_v3_air_rescaled_to_n1.74" + }, + "133": { + "station_id": 23, + "channel_id": 22, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": -17.11733208278625, + "ant_position_y": 29.755711625947697, + "ant_position_z": -94.767, + "amp_type": "iglu", + "cab_time_delay": 701.7183093306504, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-26T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "134": { + "station_id": 23, + "channel_id": 23, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": -17.11733208278625, + "ant_position_y": 29.755711625947697, + "ant_position_z": -95.783, + "amp_type": "iglu", + "cab_time_delay": 706.0542491285506, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-26T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "135": { + "station_id": 23, + "channel_id": 14, + "ant_rotation_phi": 270.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 180.0, + "ant_orientation_theta": 120.0, + "ant_position_x": -19.211573683413533, + "ant_position_y": 17.319975661629087, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 45.54795118967973, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-24T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "136": { + "station_id": 23, + "channel_id": 13, + "ant_rotation_phi": 270.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": -16.664335137387823, + "ant_position_y": 17.16331723660869, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 45.7577340623503, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-24T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "137": { + "station_id": 23, + "channel_id": 20, + "ant_rotation_phi": 150.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 60.0, + "ant_orientation_theta": 120.0, + "ant_position_x": -8.850478318870572, + "ant_position_y": 9.054268302787932, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 45.9267504993418, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-23T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "138": { + "station_id": 23, + "channel_id": 19, + "ant_rotation_phi": 150.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": -10.17433696300425, + "ant_position_y": 6.733546452867358, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 45.3209139461091, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-23T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "139": { + "station_id": 23, + "channel_id": 18, + "ant_rotation_phi": 150.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 240.0, + "ant_orientation_theta": 120.0, + "ant_position_x": -11.704241496685498, + "ant_position_y": 4.103020992519305, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 45.77034957757189, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-23T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "140": { + "station_id": 23, + "channel_id": 17, + "ant_rotation_phi": 30.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 300.0, + "ant_orientation_theta": 120.0, + "ant_position_x": -21.051474002000376, + "ant_position_y": 4.618674469174039, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 45.39048669843476, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-26T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "141": { + "station_id": 23, + "channel_id": 16, + "ant_rotation_phi": 30.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": -22.374936914001708, + "ant_position_y": 6.947502613768393, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 45.40997699209948, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-26T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "142": { + "station_id": 23, + "channel_id": 15, + "ant_rotation_phi": 30.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 120.0, + "ant_orientation_theta": 120.0, + "ant_position_x": -23.792431708424672, + "ant_position_y": 9.490450425534164, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 45.83094862959857, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-26T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "143": { + "station_id": 24, + "channel_id": 9, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": -17.6294982705393, + "ant_position_y": 30.01858899282888, + "ant_position_z": -97.511, + "amp_type": "iglu", + "cab_time_delay": 705.32011112294, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-07-06T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "144": { + "station_id": 24, + "channel_id": 10, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": -17.6294982705393, + "ant_position_y": 30.01858899282888, + "ant_position_z": -96.495, + "amp_type": "iglu", + "cab_time_delay": 701.118919397236, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-07-06T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "145": { + "station_id": 24, + "channel_id": 11, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": -17.6294982705393, + "ant_position_y": 30.01858899282888, + "ant_position_z": -95.504, + "amp_type": "iglu", + "cab_time_delay": 695.8325149249811, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-07-06T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_quadslot_v3_air_rescaled_to_n1.74" + }, + "146": { + "station_id": 24, + "channel_id": 0, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -97.638, + "amp_type": "iglu", + "cab_time_delay": 716.7233780139192, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-07-05T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "147": { + "station_id": 24, + "channel_id": 1, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -96.622, + "amp_type": "iglu", + "cab_time_delay": 712.1044846158909, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-07-05T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "148": { + "station_id": 24, + "channel_id": 2, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -95.631, + "amp_type": "iglu", + "cab_time_delay": 706.8892411537641, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-07-05T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "149": { + "station_id": 24, + "channel_id": 3, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -94.615, + "amp_type": "iglu", + "cab_time_delay": 702.4226072909622, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-07-05T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "150": { + "station_id": 24, + "channel_id": 4, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -92.659, + "amp_type": "iglu", + "cab_time_delay": 690.761838353226, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-07-05T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_quadslot_v3_air_rescaled_to_n1.74" + }, + "151": { + "station_id": 24, + "channel_id": 5, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -80.594, + "amp_type": "iglu", + "cab_time_delay": 583.7560433649974, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-07-05T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "152": { + "station_id": 24, + "channel_id": 6, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -60.604, + "amp_type": "iglu", + "cab_time_delay": 484.7189595813629, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-07-05T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "153": { + "station_id": 24, + "channel_id": 7, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -40.64, + "amp_type": "iglu", + "cab_time_delay": 387.69316314434445, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-07-05T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "154": { + "station_id": 24, + "channel_id": 8, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": 0.0, + "ant_position_z": -93.65, + "amp_type": "iglu", + "cab_time_delay": 695.2098026860888, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-07-05T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_quadslot_v3_air_rescaled_to_n1.74" + }, + "155": { + "station_id": 24, + "channel_id": 21, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 17.01617867674605, + "ant_position_y": 30.089051222671515, + "ant_position_z": -78.372, + "amp_type": "iglu", + "cab_time_delay": 696.0136180352841, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-07-12T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_quadslot_v3_air_rescaled_to_n1.74" + }, + "156": { + "station_id": 24, + "channel_id": 22, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 17.01617867674605, + "ant_position_y": 30.089051222671515, + "ant_position_z": -79.375, + "amp_type": "iglu", + "cab_time_delay": 701.1819591709564, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-07-12T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "157": { + "station_id": 24, + "channel_id": 23, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 17.01617867674605, + "ant_position_y": 30.089051222671515, + "ant_position_z": -80.391, + "amp_type": "iglu", + "cab_time_delay": 705.6007352061425, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-07-12T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "RNOG_vpol_4inch_center_n1.73" + }, + "158": { + "station_id": 24, + "channel_id": 15, + "ant_rotation_phi": 330.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 60.0, + "ant_orientation_theta": 120.0, + "ant_position_x": -5.171399705444173, + "ant_position_y": 25.841320159085626, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 45.75439206401613, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-07-12T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "159": { + "station_id": 24, + "channel_id": 16, + "ant_rotation_phi": 330.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": -6.320901644269725, + "ant_position_y": 23.59709970223321, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 45.458824371215705, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-07-12T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "160": { + "station_id": 24, + "channel_id": 17, + "ant_rotation_phi": 330.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 240.0, + "ant_orientation_theta": 120.0, + "ant_position_x": -7.721578483910434, + "ant_position_y": 21.042051775049913, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 45.767816340568835, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-07-12T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "161": { + "station_id": 24, + "channel_id": 18, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 180.0, + "ant_orientation_theta": 120.0, + "ant_position_x": -3.1296279810530905, + "ant_position_y": 13.016645591927954, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 45.72635561302779, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-07-05T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "162": { + "station_id": 24, + "channel_id": 19, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": -0.49897710181994626, + "ant_position_y": 12.8886429463073, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 46.20942421716986, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-07-05T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "163": { + "station_id": 24, + "channel_id": 20, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 120.0, + "ant_position_x": 2.4626351626473024, + "ant_position_y": 12.830654934149607, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 45.8043779968151, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-07-05T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "164": { + "station_id": 24, + "channel_id": 12, + "ant_rotation_phi": 210.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 300.0, + "ant_orientation_theta": 120.0, + "ant_position_x": 7.210917268336061, + "ant_position_y": 21.083718102880994, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 45.364441874451146, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-07-06T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "165": { + "station_id": 24, + "channel_id": 13, + "ant_rotation_phi": 210.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 5.667346182745405, + "ant_position_y": 23.556566756125903, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 45.824131294404665, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-07-06T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "166": { + "station_id": 24, + "channel_id": 14, + "ant_rotation_phi": 210.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 120.0, + "ant_orientation_theta": 120.0, + "ant_position_x": 4.16767475236702, + "ant_position_y": 25.935868936541738, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 45.61878753278558, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-07-06T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + } + }, + "stations": { + "11": { + "station_id": 11, + "pos_easting": -1572.8161736544128, + "pos_northing": 729.3722386485937, + "pos_altitude": -3.783231150073059, + "pos_site": "summit", + "commission_time": "{TinyDate}:2021-07-11T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00" + }, + "12": { + "station_id": 12, + "pos_easting": -1352.364325059356, + "pos_northing": 1911.1738485252934, + "pos_altitude": -4.03610097553792, + "pos_site": "summit", + "commission_time": "{TinyDate}:2022-06-21T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00" + }, + "13": { + "station_id": 13, + "pos_easting": -1147.4927545674973, + "pos_northing": 3124.0456946337963, + "pos_altitude": -4.50342952129995, + "pos_site": "summit", + "commission_time": "{TinyDate}:2022-07-04T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00" + }, + "21": { + "station_id": 21, + "pos_easting": -308.1768397289919, + "pos_northing": 495.8958356648789, + "pos_altitude": -3.001389475218261, + "pos_site": "summit", + "commission_time": "{TinyDate}:2021-07-04T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00" + }, + "22": { + "station_id": 22, + "pos_easting": -138.03400922620767, + "pos_northing": 1708.005557160627, + "pos_altitude": -2.463255858468301, + "pos_site": "summit", + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00" + }, + "23": { + "station_id": 23, + "pos_easting": 82.4071346964168, + "pos_northing": 2949.9982332582017, + "pos_altitude": -2.837141509331976, + "pos_site": "summit", + "commission_time": "{TinyDate}:2022-06-26T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00" + }, + "24": { + "station_id": 24, + "pos_easting": 269.08737268271943, + "pos_northing": 4133.055983521074, + "pos_altitude": -3.6948952982193837, + "pos_site": "summit", + "commission_time": "{TinyDate}:2022-07-12T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00" + } + }, + "devices": { + "1": { + "ant_comment": "Helper String B Cal Vpol", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_position_x": 18.018524515656964, + "ant_position_y": -30.46999302062511, + "ant_position_z": -79.92, + "commission_time": "{TinyDate}:2021-07-11T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "device_id": 1, + "station_id": 11 + }, + "0": { + "ant_comment": "Helper String C Cal Vpol", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_position_x": 34.96881000487633, + "ant_position_y": -0.19141220844210238, + "ant_position_z": -93.68, + "commission_time": "{TinyDate}:2021-07-11T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "device_id": 0, + "station_id": 11 + }, + "2": { + "ant_comment": "Surface Cal Pulser", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_position_x": 18.107832415371604, + "ant_position_y": -1.3719442312160481, + "ant_position_z": -0.5, + "commission_time": "{TinyDate}:2021-07-11T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "device_id": 2, + "station_id": 11 + }, + "4": { + "ant_comment": "Helper String B Cal Vpol", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_position_x": -17.169786577567038, + "ant_position_y": 30.105416502163507, + "ant_position_z": -90.5, + "commission_time": "{TinyDate}:2022-06-21T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "device_id": 1, + "station_id": 12 + }, + "3": { + "ant_comment": "Helper String C Cal Vpol", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_position_x": 17.54306172678298, + "ant_position_y": 30.752842104373485, + "ant_position_z": -91.821, + "commission_time": "{TinyDate}:2022-06-17T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "device_id": 0, + "station_id": 12 + }, + "5": { + "ant_comment": "Surface Cal Pulser", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_position_x": -0.3753118916176845, + "ant_position_y": 29.75475708622207, + "ant_position_z": -0.5, + "commission_time": "{TinyDate}:2022-06-21T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "device_id": 2, + "station_id": 12 + }, + "7": { + "ant_comment": "Helper String B Cal Vpol", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_position_x": -17.51197811169982, + "ant_position_y": 29.742022928890492, + "ant_position_z": -91.834, + "commission_time": "{TinyDate}:2022-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "device_id": 1, + "station_id": 13 + }, + "6": { + "ant_comment": "Helper String C Cal Vpol", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_position_x": 16.95447838550831, + "ant_position_y": 30.12568265560958, + "ant_position_z": -92.1, + "commission_time": "{TinyDate}:2022-07-04T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "device_id": 0, + "station_id": 13 + }, + "8": { + "ant_comment": "Surface Cal Pulser", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_position_x": -0.5740155279763712, + "ant_position_y": 35.923120880881925, + "ant_position_z": -0.5, + "commission_time": "{TinyDate}:2022-07-04T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "device_id": 2, + "station_id": 13 + }, + "10": { + "ant_comment": "Helper String B Cal Vpol", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_position_x": -17.237822409178648, + "ant_position_y": 29.436009810348025, + "ant_position_z": -91.72, + "commission_time": "{TinyDate}:2021-07-04T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "device_id": 1, + "station_id": 21 + }, + "9": { + "ant_comment": "Helper String C Cal Vpol", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_position_x": -34.1288896622176, + "ant_position_y": -1.2407598474927681, + "ant_position_z": -92.37, + "commission_time": "{TinyDate}:2021-07-04T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "device_id": 0, + "station_id": 21 + }, + "11": { + "ant_comment": "Surface Cal Pulser", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_position_x": -51.74498926313953, + "ant_position_y": 29.063846909018764, + "ant_position_z": -0.5, + "commission_time": "{TinyDate}:2021-07-04T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "device_id": 2, + "station_id": 21 + }, + "13": { + "ant_comment": "Helper String B Cal Vpol", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_position_x": -17.199498709672298, + "ant_position_y": 29.357402778427513, + "ant_position_z": -93.8, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "device_id": 1, + "station_id": 22 + }, + "12": { + "ant_comment": "Helper String C Cal Vpol", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_position_x": 16.39538465744613, + "ant_position_y": 29.513529144740687, + "ant_position_z": -93.62, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "device_id": 0, + "station_id": 22 + }, + "14": { + "ant_comment": "Surface Cal Pulser", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_position_x": -51.74498926313953, + "ant_position_y": 29.063846909018764, + "ant_position_z": -0.5, + "commission_time": "{TinyDate}:2021-07-01T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "device_id": 2, + "station_id": 22 + }, + "16": { + "ant_comment": "Helper String B Cal Vpol", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_position_x": -34.54191609133999, + "ant_position_y": -0.1224676067567998, + "ant_position_z": -91.961, + "commission_time": "{TinyDate}:2022-06-24T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "device_id": 1, + "station_id": 23 + }, + "15": { + "ant_comment": "Helper String C Cal Vpol", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_position_x": -17.11733208278625, + "ant_position_y": 29.755711625947697, + "ant_position_z": -92.774, + "commission_time": "{TinyDate}:2022-06-26T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "device_id": 0, + "station_id": 23 + }, + "17": { + "ant_comment": "Surface Cal Pulser", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_position_x": -28.515812899579103, + "ant_position_y": 19.496516800697464, + "ant_position_z": -0.5, + "commission_time": "{TinyDate}:2022-06-26T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "device_id": 2, + "station_id": 23 + }, + "19": { + "ant_comment": "Helper String B Cal Vpol", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_position_x": -17.6294982705393, + "ant_position_y": 30.01858899282888, + "ant_position_z": -94.513, + "commission_time": "{TinyDate}:2022-07-06T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "device_id": 1, + "station_id": 24 + }, + "18": { + "ant_comment": "Helper String C Cal Vpol", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_position_x": 17.01617867674605, + "ant_position_y": 30.089051222671515, + "ant_position_z": -77.368, + "commission_time": "{TinyDate}:2022-07-12T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "device_id": 0, + "station_id": 24 + }, + "20": { + "ant_comment": "Surface Cal Pulser", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_position_x": -0.9999079284443724, + "ant_position_y": 36.36050283253098, + "ant_position_z": -0.5, + "commission_time": "{TinyDate}:2022-07-12T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "device_id": 2, + "station_id": 24 + } + } +} From 4c55a17466406180491dcc51c058b1a7ea9a6977 Mon Sep 17 00:00:00 2001 From: lpyras Date: Wed, 1 Nov 2023 11:04:49 +0100 Subject: [PATCH 393/418] add array with upward LPDAs --- NuRadioReco/detector/RNO_G/RNO_cr_array.json | 341 +++++++++++++++++++ NuRadioReco/modules/io/coreas/coreas.py | 2 +- 2 files changed, 342 insertions(+), 1 deletion(-) create mode 100644 NuRadioReco/detector/RNO_G/RNO_cr_array.json diff --git a/NuRadioReco/detector/RNO_G/RNO_cr_array.json b/NuRadioReco/detector/RNO_G/RNO_cr_array.json new file mode 100644 index 000000000..631ee1a52 --- /dev/null +++ b/NuRadioReco/detector/RNO_G/RNO_cr_array.json @@ -0,0 +1,341 @@ +{ + "channels": { + "0": { + "amp_type": "rno_surface", + "ant_comment": "upward LPDA north from DAQ", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 0.0, + "ant_position_y": -11, + "ant_position_z": -2.0, + "ant_rotation_phi": 90.0, + "ant_rotation_theta": 90.0, + "ant_type": "createLPDA_100MHz_InfFirn", + "cab_time_delay": 19.8, + "commission_time": "{TinyDate}:2017-10-01T00:00:00", + "decommission_time": "{TinyDate}:2020-11-01T00:00:00", + "channel_id": 0, + "station_id": 11 + }, + + "1": { + "amp_type": "rno_surface", + "ant_comment": "upward LPDA south-east from DAQ", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": -9.526, + "ant_position_y": 5.5, + "ant_position_z": -2.0, + "ant_rotation_phi": 330.0, + "ant_rotation_theta": 90.0, + "ant_type": "createLPDA_100MHz_InfFirn", + "cab_time_delay": 19.8, + "commission_time": "{TinyDate}:2017-10-01T00:00:00", + "decommission_time": "{TinyDate}:2020-11-01T00:00:00", + "channel_id": 1, + "station_id": 11 + }, + + + "2": { + "amp_type": "rno_surface", + "ant_comment": "upward LPDA south-west from DAQ", + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 0.0, + "ant_position_x": 9.526, + "ant_position_y": 5.5, + "ant_position_z": -2.0, + "ant_rotation_phi": 210.0, + "ant_rotation_theta": 90.0, + "ant_type": "createLPDA_100MHz_InfFirn", + "cab_time_delay": 19.8, + "commission_time": "{TinyDate}:2017-10-01T00:00:00", + "decommission_time": "{TinyDate}:2020-11-01T00:00:00", + "channel_id": 2, + "station_id": 11 + } + }, + "stations": { + "01": { + "pos_easting": -1401.32, + "pos_northing": 1154.08, + "pos_altitude": 3200, + "pos_site": "summit", + "station_id": 11, + "station_type": "Nanoq", + "reference_station": 11 + }, + "02": { + "pos_easting": -1197.62, + "pos_northing": 2366.47, + "pos_site": "summit", + "station_id": 12, + "station_type": "Terianniaq", + "reference_station": 11 + }, + "03": { + "pos_easting": -993.895, + "pos_northing": 3578.9, + "pos_site": "summit", + "station_id": 13, + "station_type": "Ukaleq", + "reference_station": 11 + }, + "04": { + "pos_easting": -790.163, + "pos_northing": 4791.36, + "pos_site": "summit", + "station_id": 14, + "station_type": "Tuttu", + "reference_station": 11 + }, + "05": { + "pos_easting": -586.42, + "pos_northing": 6003.86, + "pos_site": "summit", + "station_id": 15, + "station_type": "Umimmak", + "reference_station": 11 + }, + "06": { + "pos_easting": -382.664, + "pos_northing": 7216.39, + "pos_site": "summit", + "station_id": 16, + "station_type": "Aarluk", + "reference_station": 11 + }, + "07": { + "pos_easting": -178.897, + "pos_northing": 8428.95, + "pos_site": "summit", + "station_id": 17, + "station_type": "Ussuk", + "reference_station": 11 + }, + "08": { + "pos_easting": -188.953, + "pos_northing": 950.358, + "pos_site": "summit", + "station_id": 21, + "station_type": "Amaroq", + "reference_station": 11 + }, + "09": { + "pos_easting": 14.789, + "pos_northing": 2162.74, + "pos_site": "summit", + "station_id": 22, + "station_type": "Avinngaq", + "reference_station": 11 + }, + "10": { + "pos_easting": 218.543, + "pos_northing": 3375.16, + "pos_site": "summit", + "station_id": 23, + "station_type": "Ukaliatsiaq", + "reference_station": 11 + }, + "11": { + "pos_easting": 422.309, + "pos_northing": 4587.61, + "pos_site": "summit", + "station_id": 24, + "station_type": "Qappik", + "reference_station": 11 + }, + "12": { + "pos_easting": 626.087, + "pos_northing": 5800.09, + "pos_site": "summit", + "station_id": 25, + "station_type": "Aataaq", + "reference_station": 11 + }, + "13": { + "pos_easting": 829.877, + "pos_northing": 7012.61, + "pos_site": "summit", + "station_id": 26, + "station_type": "Aaveq", + "reference_station": 11 + }, + "14": { + "pos_easting": 1033.68, + "pos_northing": 8225.16, + "pos_site": "summit", + "station_id": 27, + "station_type": "Eqalussuaq", + "reference_station": 11 + }, + "15": { + "pos_easting": 1430.97, + "pos_northing": 3171.38, + "pos_site": "summit", + "station_id": 33, + "station_type": "Ippernaq", + "reference_station": 11 + }, + "16": { + "pos_easting": 1634.77, + "pos_northing": 4383.82, + "pos_site": "summit", + "station_id": 34, + "station_type": "Isunngaq", + "reference_station": 11 + }, + "17": { + "pos_easting": 1838.58, + "pos_northing": 5596.29, + "pos_site": "summit", + "station_id": 35, + "station_type": "Natseq", + "reference_station": 11 + }, + "18": { + "pos_easting": 2042.41, + "pos_northing": 6808.79, + "pos_site": "summit", + "station_id": 36, + "station_type": "Niisa", + "reference_station": 11 + }, + "19": { + "pos_easting": 2246.24, + "pos_northing": 8021.33, + "pos_site": "summit", + "station_id": 37, + "station_type": "Uppik", + "reference_station": 11 + }, + "20": { + "pos_easting": 2847.22, + "pos_northing": 4179.99, + "pos_site": "summit", + "station_id": 44, + "station_type": "Nattoralik", + "reference_station": 11 + }, + "21": { + "pos_easting": 3051.07, + "pos_northing": 5392.45, + "pos_site": "summit", + "station_id": 45, + "station_type": "Qilanngaq", + "reference_station": 11 + }, + "22": { + "pos_easting": 3254.92, + "pos_northing": 6604.95, + "pos_site": "summit", + "station_id": 46, + "station_type": "Aqisseq", + "reference_station": 11 + }, + "23": { + "pos_easting": 3458.79, + "pos_northing": 7817.48, + "pos_site": "summit", + "station_id": 47, + "station_type": "Natsersuaq", + "reference_station": 11 + }, + "24": { + "pos_easting": 4059.66, + "pos_northing": 3976.14, + "pos_site": "summit", + "station_id": 54, + "station_type": "Qipoqqaq", + "reference_station": 11 + }, + "25": { + "pos_easting": 4263.54, + "pos_northing": 5188.58, + "pos_site": "summit", + "station_id": 55, + "station_type": "Arfiviit", + "reference_station": 11 + }, + "26": { + "pos_easting": 4467.43, + "pos_northing": 6401.07, + "pos_site": "summit", + "station_id": 56, + "station_type": "Alleq", + "reference_station": 11 + }, + "27": { + "pos_easting": 4671.33, + "pos_northing": 7613.58, + "pos_site": "summit", + "station_id": 57, + "station_type": "Qarsaaq", + "reference_station": 11 + }, + "28": { + "pos_easting": 5272.08, + "pos_northing": 3772.24, + "pos_site": "summit", + "station_id": 64, + "station_type": "Tikaagullik", + "reference_station": 11 + }, + "29": { + "pos_easting": 5476, + "pos_northing": 4984.68, + "pos_site": "summit", + "station_id": 65, + "station_type": "Kapisillik", + "reference_station": 11 + }, + "30": { + "pos_easting": 5679.92, + "pos_northing": 6197.15, + "pos_site": "summit", + "station_id": 66, + "station_type": "Eqaluk", + "reference_station": 11 + }, + "31": { + "pos_easting": 5883.86, + "pos_northing": 7409.66, + "pos_site": "summit", + "station_id": 67, + "station_type": "Qeeraq", + "reference_station": 11 + }, + "32": { + "pos_easting": 6484.5, + "pos_northing": 3568.32, + "pos_site": "summit", + "station_id": 74, + "station_type": "Qaleralik", + "reference_station": 11 + }, + "33": { + "pos_easting": 6688.44, + "pos_northing": 4780.74, + "pos_site": "summit", + "station_id": 75, + "station_type": "Uugaq", + "reference_station": 11 + }, + "34": { + "pos_easting": 6892.4, + "pos_northing": 5993.2, + "pos_site": "summit", + "station_id": 76, + "station_type": "Amiqok", + "reference_station": 11 + }, + "35": { + "pos_easting": 7096.38, + "pos_northing": 7205.69, + "pos_site": "summit", + "station_id": 77, + "station_type": "Nerleq", + "reference_station": 11 + } + } + } \ No newline at end of file diff --git a/NuRadioReco/modules/io/coreas/coreas.py b/NuRadioReco/modules/io/coreas/coreas.py index ea2e18510..38bee3a2e 100644 --- a/NuRadioReco/modules/io/coreas/coreas.py +++ b/NuRadioReco/modules/io/coreas/coreas.py @@ -123,7 +123,7 @@ def calculate_simulation_weights(positions, zenith, azimuth, site='summit', debu return weights -def make_sim_station(station_id, corsika, observer, channel_ids, weight=None) +def make_sim_station(station_id, corsika, observer, channel_ids, weight=None): """ creates an NuRadioReco sim station from the (interpolated) observer object of the coreas hdf5 file From 5f15c4188fa6e1b5ea4421b1688cfb1b94e5c978 Mon Sep 17 00:00:00 2001 From: lpyras Date: Wed, 1 Nov 2023 11:53:40 +0100 Subject: [PATCH 394/418] refactor units for theta --- NuRadioMC/utilities/muon_flux.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/NuRadioMC/utilities/muon_flux.py b/NuRadioMC/utilities/muon_flux.py index e3ba81c90..b47b481c4 100644 --- a/NuRadioMC/utilities/muon_flux.py +++ b/NuRadioMC/utilities/muon_flux.py @@ -51,7 +51,7 @@ def get_mu_flux(self, theta, altitude=3200, interaction_model='SIBYLL23C', prima altitude *= self.mc_m mceq = MCEqRun(interaction_model=interaction_model, primary_model=primary_model, - theta_deg=theta * self.mc_rad) + theta_deg=theta/units.deg) h_grid = np.linspace(50 * 1e3 * 1e2, 0, 500) X_grid = mceq.density_model.h2X(h_grid) @@ -157,7 +157,7 @@ def get_int_angle_mu_flux_buffered(self, energy, theta_min, theta_max, altitude= return self.__buffer[params] - def get_e_grid(self, theta_deg=50, interaction_model='SIBYLL23C', primary_model=(crf.GlobalSplineFitBeta, None)): + def get_e_grid(self, theta=50*units.deg, interaction_model='SIBYLL23C', primary_model=(crf.GlobalSplineFitBeta, None)): """ Returns the energy grid for a given interaction model and primary model. Usually this is the same for all zenith angles. @@ -175,6 +175,6 @@ def get_e_grid(self, theta_deg=50, interaction_model='SIBYLL23C', primary_model= energies: array of floats energy grid in eV """ - mceq = MCEqRun(interaction_model=interaction_model, primary_model=primary_model, theta_deg=theta_deg) + mceq = MCEqRun(interaction_model=interaction_model, primary_model=primary_model, theta_deg=theta/units.deg) e_grid = mceq.e_grid / self.mc_eV return e_grid \ No newline at end of file From 3776d09cb481c31aeaad231c986c3b687bc639e1 Mon Sep 17 00:00:00 2001 From: Brian Clark Date: Fri, 3 Nov 2023 10:26:07 -0400 Subject: [PATCH 395/418] Update analog_components.py Fix typo RNO-G phased array response loader. S21deg -> S11deg. --- NuRadioReco/detector/RNO_G/analog_components.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NuRadioReco/detector/RNO_G/analog_components.py b/NuRadioReco/detector/RNO_G/analog_components.py index 7be975e48..771f7637f 100644 --- a/NuRadioReco/detector/RNO_G/analog_components.py +++ b/NuRadioReco/detector/RNO_G/analog_components.py @@ -58,7 +58,7 @@ def iglu_correction_func(temp, freqs): correction_function = iglu_correction_func elif amp_type == 'phased_array': ph = os.path.join(path, 'HardwareResponses/ULP-216+_Plus25DegC.s2p') - ff, S11gain, S21deg, S21gain, S21deg, S12gain, S12deg, S22gain, S22deg = np.loadtxt(ph, comments=['#', '!'], unpack=True) + ff, S11gain, S11deg, S21gain, S21deg, S12gain, S12deg, S22gain, S22deg = np.loadtxt(ph, comments=['#', '!'], unpack=True) ff *= units.MHz amp_gain_discrete = hp.dB_to_linear(S21gain) amp_phase_discrete = S21deg * units.deg From a407250fdce3746dd089639ec49b8c14b3edc4a3 Mon Sep 17 00:00:00 2001 From: Sjoerd Bouma Date: Mon, 13 Nov 2023 15:59:26 +0100 Subject: [PATCH 396/418] update changelog --- changelog.txt | 49 ++++++++++++++++++++++++++----------------------- 1 file changed, 26 insertions(+), 23 deletions(-) diff --git a/changelog.txt b/changelog.txt index 9a44a4779..7c2b35083 100644 --- a/changelog.txt +++ b/changelog.txt @@ -4,7 +4,7 @@ please update the categories "new features" and "bugfixes" before a pull request version 2.2.0-dev new features: -- expand values stored in SimplePhasedTrigger +- expand values stored in SimplePhasedTrigger - added getting to query ARZ charge-excess profiles - upgrade to proposal v 7.5.0 with new NuRadioProposal interface and improved LPM treatment - add script to generate / download pre-calculated proposal tables for known detector configurations @@ -14,6 +14,9 @@ new features: - added ability to generate high-low-triggered noise on a narrow band but return full-band waveforms - phased array noise generation utility class: calculate trigger time and cut trace accordingly - use Philox noise generator in noise adder module (this changes the default random sequence) +- triggerTimeAdjuster now works more reliably and supports different readout windows per channel. +The readout time adjustment now is stored in the trigger object and needs to be accounted for in analysis +by running the triggerTimeAdjuster, analogously to the channelAddCableDelay module. bugfixes: - fixed/improved C++ raytracer not finding solutions for some near-horizontal or near-shadowzone vertices @@ -41,13 +44,13 @@ is not found in the current station version 2.1.6 bugfixes: -- the n_interaction parameter was accidentally overridden. n_interaction counts the number of interactions of taus and +- the n_interaction parameter was accidentally overridden. n_interaction counts the number of interactions of taus and muons generated in the corresponding CC interactions. The bug resulted in the following behaviour: The n_interaction value of the primary neutrino interaction was overridden with the n_interaction value of the last shower of the previous event group. If the previous event group was a CC interaction, the n_interaction value of the primary interaction was set to a value larger than 1. If that happened, and if the primary -shower did not trigger the detector, this shower is not added to the output hdf5 file. This has consquences for analyzing hdf5 files for -secondary interactions. With this bug, the initial interaction needs to be idenfified with np.abs(flavor) == 14 or 16. -This bug does not effect any effective volume calculation. +shower did not trigger the detector, this shower is not added to the output hdf5 file. This has consquences for analyzing hdf5 files for +secondary interactions. With this bug, the initial interaction needs to be idenfified with np.abs(flavor) == 14 or 16. +This bug does not effect any effective volume calculation. new features: - add hvsp1, update idl1 model for emitter simulation (from KU lab measurements) and remove hvsp2(no longer in use for experiment) @@ -57,7 +60,7 @@ version 2.1.5 bugfixes: - the phased array trigger module did not calculate the trigger time. - The trigger time was always set to the trace start time. This got fixed in this version. + The trigger time was always set to the trace start time. This got fixed in this version. version 2.1.4 @@ -70,7 +73,7 @@ bugfixes: version 2.1.2 bugfixes: -- Fixes that the generic detector crashes for certain detector files. +- Fixes that the generic detector crashes for certain detector files. version 2.1.1 new features: @@ -87,7 +90,7 @@ new features: - add a basic uproot data reader for RNO-G data - add option to simulate emitters - added helper function for cosmic ray flux models -- speed improvements of ARZ model through use of numba +- speed improvements of ARZ model through use of numba bugfixes: - correct volume extension depending on zenith angle range when running with @@ -106,26 +109,26 @@ bugfixes: version 2.0.0 - NuRadioReco is merged into the NuRadioMC repository. No new features were added and everything works (e.g. the imports) -as before but the NuRadioReco code is now part of the NuRadioMC github repository to simplify code development where NuRadioMC -changes depend on changes in NuRadioReco. +as before but the NuRadioReco code is now part of the NuRadioMC github repository to simplify code development where NuRadioMC +changes depend on changes in NuRadioReco. version 1.2.0 new features: -- major change in internal looping. Now, the radio signal from each shower is calculated and signal arrival times +- major change in internal looping. Now, the radio signal from each shower is calculated and signal arrival times (from different shower, ray racing solutions and receiver positions) that cluster together are simualted as one event - merge hdf5 utility has multithreading option (and was refactored -> function names changed) - distance cut can sum up all sourounding shower energies to properly account for possible interference - noise temperature can be specified per station and channel - trigger thresholds can be specified per channel -- bandwidth can be specified per station and channel +- bandwidth can be specified per station and channel - specifying the detector simulation became easier (check out the updated examples) - memory consumption was optimized to stay <4GB per core - random realization of showers are saved so that triggered events can be resimulated using the same random realization - added option for noiseless channels in a "with noise" simulation - add option to generate events on the fly and pass them directly to the simulation part (no need to save input hdf5 files anymore) - added uncertainties to CTW cross sections -- +- bugfixes: - Fixed issue with merge hdf5 utility so that "event_group_ids" are properly unique @@ -133,7 +136,7 @@ bugfixes: -version 1.1.2 - +version 1.1.2 - new features: - Veff utility can now handle extended bins - New tutorial and example for the webinar @@ -150,10 +153,10 @@ bugfixes: version 1.1.1 - 2020/03/23 new features -- New version for the ARZ model available (ARZ2020) -- a list with event ids can be passed to the main simulation class. All events not in this list will not be simulated. - This is useful for a quick resimulation of certain events. -- Alvarez???? Askaryan models now place the trace into the center of the trace (instead of 50ns into the trace) +- New version for the ARZ model available (ARZ2020) +- a list with event ids can be passed to the main simulation class. All events not in this list will not be simulated. + This is useful for a quick resimulation of certain events. +- Alvarez???? Askaryan models now place the trace into the center of the trace (instead of 50ns into the trace) - New data set array 'vertex_times' contains the time elapsed from the first interaction to the current interaction - new utility to split output hdf5 files into smaller chucks (to be able to resimulate events on a cluster) - Greenland added to proposal config @@ -161,11 +164,11 @@ new features - improved Earth model (PREM), path from interaction vertex through Earth is calculated (before interaction was assumed to happen at the surface) - detector description is saved to nur output files -- new handling of random numbers. Each module has its own random generator instance. Global seed can be controlled via +- new handling of random numbers. Each module has its own random generator instance. Global seed can be controlled via config file setting. bugfixes: -- ARZxxxx and Alvarez2009 Askaryan modules now use the same (random) shower per event. +- ARZxxxx and Alvarez2009 Askaryan modules now use the same (random) shower per event. - fixes zenith distribution of event generator back to cos(zenith) - ray tracing precision was increased to 1e-9 - saveguard against too many ray tracing solutions added @@ -189,9 +192,9 @@ bugfixes: - fixed that Veff utility script didn't calculate effective volumes for individual triggers - fixed that the multiple_triggers key was not created for multiple stations - Angular distribution now accounts for projected area - - - - + - + + version 1.0.0 - 2019/08/30 - first python 3 release From a6bf9f2883555cbbe22708146870634245b933cb Mon Sep 17 00:00:00 2001 From: Sjoerd Bouma Date: Tue, 14 Nov 2023 14:05:01 +0100 Subject: [PATCH 397/418] fix some modules assuming the first channel has id 0 --- .../modules/beamFormingDirectionFitter.py | 4 +- .../modules/correlationDirectionFitter.py | 2 +- NuRadioReco/modules/sphericalWaveFitter.py | 40 +++++++++---------- .../voltageToAnalyticEfieldConverter.py | 9 +++-- .../modules/voltageToEfieldConverter.py | 10 ++--- .../voltageToEfieldConverterPerChannel.py | 4 +- 6 files changed, 35 insertions(+), 34 deletions(-) diff --git a/NuRadioReco/modules/beamFormingDirectionFitter.py b/NuRadioReco/modules/beamFormingDirectionFitter.py index 5cc431d0a..126596baa 100644 --- a/NuRadioReco/modules/beamFormingDirectionFitter.py +++ b/NuRadioReco/modules/beamFormingDirectionFitter.py @@ -38,7 +38,7 @@ def get_array_of_channels(station, det, zenith, azimuth, polarization): time_shifts = np.zeros(8) t_geos = np.zeros(8) - sampling_rate = station.get_channel(0).get_sampling_rate() + sampling_rate = next(station.iter_channels()).get_sampling_rate() station_id = station.get_id() site = det.get_site(station_id) for iCh, channel in enumerate(station.get_electric_fields()): @@ -185,7 +185,7 @@ def ll_regular_station(angles, evt, station, det, polarization, sampling_rate, p positions = [] for chan in channels: positions.append(det.get_relative_position(station_id, chan)) - sampling_rate = station.get_channel(0).get_sampling_rate() + sampling_rate = station.get_channel(channels[0]).get_sampling_rate() ll = opt.brute( ll_regular_station, diff --git a/NuRadioReco/modules/correlationDirectionFitter.py b/NuRadioReco/modules/correlationDirectionFitter.py index 5c6ca4d34..9cb2d8134 100644 --- a/NuRadioReco/modules/correlationDirectionFitter.py +++ b/NuRadioReco/modules/correlationDirectionFitter.py @@ -142,7 +142,7 @@ def ll_regular_station_fft(angles, corr_02_fft, corr_13_fft, sampling_rate, posi station_id = station.get_id() positions_pairs = [[det.get_relative_position(station_id, channel_pairs[0][0]), det.get_relative_position(station_id, channel_pairs[0][1])], [det.get_relative_position(station_id, channel_pairs[1][0]), det.get_relative_position(station_id, channel_pairs[1][1])]] - sampling_rate = station.get_channel(0).get_sampling_rate() # assume that channels have the same sampling rate + sampling_rate = station.get_channel(channel_pairs[0][0]).get_sampling_rate() # assume that channels have the same sampling rate trace_start_time_pairs = [[station.get_channel(channel_pairs[0][0]).get_trace_start_time(), station.get_channel(channel_pairs[0][1]).get_trace_start_time()], [station.get_channel(channel_pairs[1][0]).get_trace_start_time(), station.get_channel(channel_pairs[1][1]).get_trace_start_time()]] # determine automatically if one channel has an inverted waveform with respect to the other diff --git a/NuRadioReco/modules/sphericalWaveFitter.py b/NuRadioReco/modules/sphericalWaveFitter.py index ce9b8b943..a08c2821d 100644 --- a/NuRadioReco/modules/sphericalWaveFitter.py +++ b/NuRadioReco/modules/sphericalWaveFitter.py @@ -13,25 +13,25 @@ class sphericalWaveFitter: " Fits position x,y, z of a source using spherical fit to channels " - + def __init__(self): pass - - + + def begin(self, channel_ids = [0, 3, 9, 10]): self.__channel_ids = channel_ids pass def run(self, evt, station, det, start_pulser_position, n_index = None, debug = True): - + print("channels used for this reconstruction:", self.__channel_ids) - + def get_distance(x, y): return np.sqrt((x[0] - y[0])**2+ (x[1] - y[1])**2 + (x[2] - y[2])**2) - - + + def get_time_delay_spherical_wave(position, ch_pair, n=n_index): T0 = get_distance(position, det.get_relative_position(station_id, ch_pair[0]))/(constants.c/n_index)*units.s T1 = get_distance(position , det.get_relative_position(station_id, ch_pair[1]))/(constants.c/n_index)*units.s @@ -45,11 +45,11 @@ def get_time_delay_spherical_wave(position, ch_pair, n=n_index): for j in range(i + 1, len(self.__channel_ids)): relative_positions = det.get_relative_position(station_id, self.__channel_ids[i]) - det.get_relative_position(station_id, self.__channel_ids[j]) self.__relative_positions.append(relative_positions) - + self.__channel_pairs.append([self.__channel_ids[i], self.__channel_ids[j]]) - - - self.__sampling_rate = station.get_channel(0).get_sampling_rate() + + + self.__sampling_rate = station.get_channel(self.__channel_ids[0]).get_sampling_rate() if debug: fig, ax = plt.subplots( len(self.__channel_pairs), 2) @@ -73,16 +73,16 @@ def likelihood(pulser_position, x = None, y = None, debug_corr = False): ax.set_ylim((0, max(self.__correlation[ich]))) ax.axvline(pos, label = 'reconstruction', lw = 1, color = 'orange') ax.axvline(self._pos_starting[ich], label = 'starting pos', lw = 1, color = 'green') - ax.set_title("channel pair {}".format( ch_pair), fontsize = 5) + ax.set_title("channel pair {}".format( ch_pair), fontsize = 5) ax.legend(fontsize = 5) - + if debug_corr: fig.tight_layout() fig.savefig("debug.pdf") return -1*corr - - + + trace = np.copy(station.get_channel(self.__channel_pairs[0][0]).get_trace()) self.__correlation = np.zeros((len(self.__channel_pairs), len(np.abs(scipy.signal.correlate(trace, trace))) )) @@ -90,7 +90,7 @@ def likelihood(pulser_position, x = None, y = None, debug_corr = False): for ich, ch_pair in enumerate(self.__channel_pairs): trace1 = np.copy(station.get_channel(self.__channel_pairs[ich][0]).get_trace()) trace2 = np.copy(station.get_channel(self.__channel_pairs[ich][1]).get_trace()) - + t_max1 = station.get_channel(self.__channel_pairs[ich][0]).get_times()[np.argmax(np.abs(trace1))] t_max2 = station.get_channel(self.__channel_pairs[ich][1]).get_times()[np.argmax(np.abs(trace2))] corr_range = 50 * units.ns @@ -101,7 +101,7 @@ def likelihood(pulser_position, x = None, y = None, debug_corr = False): else: trace2[np.abs(station.get_channel(self.__channel_pairs[ich][1]).get_times() - t_max2) > corr_range] = 0 self.__correlation[ich] = np.abs(scipy.signal.correlate(trace1, trace2)) - + #### set positions for starting position #### @@ -124,7 +124,7 @@ def likelihood(pulser_position, x = None, y = None, debug_corr = False): print("reconstructed position: {}".format([ll[0], ll[1], ll[2]])) if debug: - + method = 'Nelder-Mead' x = np.arange(x_start -3, x_start +3, dx) y = np.arange(y_start - 3, y_start +3, dy) @@ -137,7 +137,7 @@ def likelihood(pulser_position, x = None, y = None, debug_corr = False): c = opt.minimize(likelihood, x0 = (start_pulser_position[2]), args = (x_i, y_i, False), method = method) zz[ix, iy] = c.fun zz_values[ix, iy] = c.x[0] - + fig = plt.figure(figsize = (10, 5)) ax1 = fig.add_subplot(121) pax1 = ax1.pcolor(xx, yy, zz.T) @@ -170,4 +170,4 @@ def likelihood(pulser_position, x = None, y = None, debug_corr = False): def end(self): pass - + diff --git a/NuRadioReco/modules/voltageToAnalyticEfieldConverter.py b/NuRadioReco/modules/voltageToAnalyticEfieldConverter.py index d517b8d22..33bd3cff5 100644 --- a/NuRadioReco/modules/voltageToAnalyticEfieldConverter.py +++ b/NuRadioReco/modules/voltageToAnalyticEfieldConverter.py @@ -314,10 +314,10 @@ def run(self, evt, station, det, debug=False, debug_plotpath=None, efield_antenna_factor, V, V_timedomain = get_array_of_channels(station, use_channels, det, zenith, azimuth, self.antenna_provider, time_domain=True) - sampling_rate = station.get_channel(0).get_sampling_rate() + sampling_rate = station.get_channel(use_channels[0]).get_sampling_rate() n_samples_time = V_timedomain.shape[1] - noise_RMS = det.get_noise_RMS(station.get_id(), 0) + noise_RMS = det.get_noise_RMS(station.get_id(), use_channels[0]) def obj_xcorr(params): if(len(params) == 3): @@ -482,9 +482,10 @@ def obj_amplitude_second_order(params, slope, phase, pos, compare='hilbert', deb ax[iCh][1].axvline(imin, linestyle='--', alpha=.8) ax[iCh][1].axvline(imax, linestyle='--', alpha=.8) if(debug_obj and self.i_slope_fit_iterations % 50 == 0): - sim_channel = station.get_sim_station().get_channel(0)[0] + sim_station = station.get_sim_station() + sim_channel = next(sim_station.iter_channels()) ax[4][0].plot(sim_channel.get_frequencies() / units.MHz, np.abs(pulse.get_analytic_pulse_freq(ampTheta, slope, phase, len(sim_channel.get_times()), sim_channel.get_sampling_rate(), bandpass=bandpass, quadratic_term=second_order)), '--', color='orange') - ax[4][0].plot(sim_channel.get_frequencies() / units.MHz, np.abs(station.get_sim_station().get_channel(0)[0].get_frequency_spectrum()[1]), color='blue') + ax[4][0].plot(sim_channel.get_frequencies() / units.MHz, np.abs(sim_channel.get_frequency_spectrum()[1]), color='blue') ax[4][1].plot(sim_channel.get_frequencies() / units.MHz, np.abs(pulse.get_analytic_pulse_freq(ampPhi, slope, phase, len(sim_channel.get_times()), sim_channel.get_sampling_rate(), bandpass=bandpass, quadratic_term=second_order)), '--', color='orange') ax[4][1].plot(sim_channel.get_frequencies() / units.MHz, np.abs(sim_channel.get_frequency_spectrum()[2]), color='blue') ax[4][0].set_xlim([20, 500]) diff --git a/NuRadioReco/modules/voltageToEfieldConverter.py b/NuRadioReco/modules/voltageToEfieldConverter.py index df6144a48..5c2f5fb08 100644 --- a/NuRadioReco/modules/voltageToEfieldConverter.py +++ b/NuRadioReco/modules/voltageToEfieldConverter.py @@ -47,7 +47,7 @@ def get_array_of_channels(station, use_channels, det, zenith, azimuth, tmax = time_shifts.max() logger.debug("adding relative station time = {:.0f}ns".format((t_cables.min() + t_geos.max()) / units.ns)) logger.debug("delta t is {:.2f}".format(delta_t / units.ns)) - trace_length = station.get_channel(0).get_times()[-1] - station.get_channel(0).get_times()[0] + trace_length = station.get_channel(use_channels[0]).get_times()[-1] - station.get_channel(use_channels[0]).get_times()[0] debug_cut = 0 if(debug_cut): fig, ax = plt.subplots(len(use_channels), 1) @@ -110,11 +110,11 @@ def stacked_lstsq(L, b, rcond=1e-10): class voltageToEfieldConverter: """ - This module reconstructs the electric field by solving the system of equation that related the incident electric field via the antenna response functions to the measured voltages + This module reconstructs the electric field by solving the system of equation that related the incident electric field via the antenna response functions to the measured voltages (see Eq. 4 of the NuRadioReco paper https://link.springer.com/article/10.1140/epjc/s10052-019-6971-5). The module assumed that the electric field is identical at the antennas/channels that are used for the reconstruction. Furthermore, at least two antennas with - orthogonal polarization response are needed to reconstruct the 3dim electric field. - Alternatively, the polarization of the resulting efield could be forced to a single polarization component. In that case, a single antenna is sufficient. + orthogonal polarization response are needed to reconstruct the 3dim electric field. + Alternatively, the polarization of the resulting efield could be forced to a single polarization component. In that case, a single antenna is sufficient. """ def __init__(self): @@ -183,7 +183,7 @@ def run(self, evt, station, det, use_channels=None, use_MC_direction=False, forc efield3_f[1]]) electric_field = NuRadioReco.framework.electric_field.ElectricField(use_channels, [0, 0, 0]) - electric_field.set_frequency_spectrum(efield3_f, station.get_channel(0).get_sampling_rate()) + electric_field.set_frequency_spectrum(efield3_f, station.get_channel(use_channels[0]).get_sampling_rate()) electric_field.set_parameter(efp.zenith, zenith) electric_field.set_parameter(efp.azimuth, azimuth) # figure out the timing of the E-field diff --git a/NuRadioReco/modules/voltageToEfieldConverterPerChannel.py b/NuRadioReco/modules/voltageToEfieldConverterPerChannel.py index bdc79caf8..f55f5f875 100644 --- a/NuRadioReco/modules/voltageToEfieldConverterPerChannel.py +++ b/NuRadioReco/modules/voltageToEfieldConverterPerChannel.py @@ -53,12 +53,12 @@ def run(self, evt, station, det, pol=0): zenith = station[stnp.zenith] azimuth = station[stnp.azimuth] - frequencies = station.get_channel(0).get_frequencies() # assuming that all channels have the same sampling rate and length use_channels = det.get_channel_ids(station.get_id()) + frequencies = station.get_channel(use_channels[0]).get_frequencies() # assuming that all channels have the same sampling rate and length efield_antenna_factor = trace_utilities.get_efield_antenna_factor(station, frequencies, use_channels, det, zenith, azimuth, self.antenna_provider) - sampling_rate = station.get_channel(0).get_sampling_rate() + sampling_rate = station.get_channel(use_channels[0]).get_sampling_rate() for iCh, channel in enumerate(station.iter_channels()): efield = ef.ElectricField([iCh]) From ba29dd278299aff2c811ccc593790454617ff51c Mon Sep 17 00:00:00 2001 From: Sjoerd Bouma Date: Thu, 16 Nov 2023 16:05:09 +0100 Subject: [PATCH 398/418] recycle user_id=None --- NuRadioReco/eventbrowser/dataprovider.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/NuRadioReco/eventbrowser/dataprovider.py b/NuRadioReco/eventbrowser/dataprovider.py index e640a5ee1..9027c3b9f 100644 --- a/NuRadioReco/eventbrowser/dataprovider.py +++ b/NuRadioReco/eventbrowser/dataprovider.py @@ -96,9 +96,15 @@ def get_file_handler(self, user_id, filename): if filename is None: return None if user_id not in self.__user_instances: - self.__user_instances[user_id] = dict( - reader=None, filename=None, - ) + # Occasionally, this gets called before the user_id is initialized (user_id=None). + # We can save a bit of memory by re-using this instance for the first initialized user. + if None in self.__user_instances: + self.__user_instances[user_id] = self.__user_instances[None] + self.__user_instances.pop(None) + else: + self.__user_instances[user_id] = dict( + reader=None, filename=None, + ) if isinstance(filename, str): filename = [filename] From 57b7a7b248e710813f7c24e1683bf25baa120958 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schl=C3=BCter?= <30903175+fschlueter@users.noreply.github.com> Date: Mon, 20 Nov 2023 18:56:03 +0100 Subject: [PATCH 399/418] Update dataprovider.py refactor few lines --- NuRadioReco/eventbrowser/dataprovider.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/NuRadioReco/eventbrowser/dataprovider.py b/NuRadioReco/eventbrowser/dataprovider.py index 9027c3b9f..a96dd800d 100644 --- a/NuRadioReco/eventbrowser/dataprovider.py +++ b/NuRadioReco/eventbrowser/dataprovider.py @@ -95,16 +95,16 @@ def get_file_handler(self, user_id, filename): if filename is None: return None + if user_id not in self.__user_instances: # Occasionally, this gets called before the user_id is initialized (user_id=None). # We can save a bit of memory by re-using this instance for the first initialized user. if None in self.__user_instances: - self.__user_instances[user_id] = self.__user_instances[None] - self.__user_instances.pop(None) + self.__user_instances[user_id] = self.__user_instances.pop(None) else: self.__user_instances[user_id] = dict( - reader=None, filename=None, - ) + reader=None, filename=None) + if isinstance(filename, str): filename = [filename] From 31236bd9aa619e3f94f81ab7805dbd38e5ca6162 Mon Sep 17 00:00:00 2001 From: Sjoerd Bouma Date: Tue, 21 Nov 2023 10:48:30 +0100 Subject: [PATCH 400/418] fix dropping of oldest user --- NuRadioReco/eventbrowser/dataprovider.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/NuRadioReco/eventbrowser/dataprovider.py b/NuRadioReco/eventbrowser/dataprovider.py index a96dd800d..bd07dcc35 100644 --- a/NuRadioReco/eventbrowser/dataprovider.py +++ b/NuRadioReco/eventbrowser/dataprovider.py @@ -95,7 +95,7 @@ def get_file_handler(self, user_id, filename): if filename is None: return None - + if user_id not in self.__user_instances: # Occasionally, this gets called before the user_id is initialized (user_id=None). # We can save a bit of memory by re-using this instance for the first initialized user. @@ -104,7 +104,7 @@ def get_file_handler(self, user_id, filename): else: self.__user_instances[user_id] = dict( reader=None, filename=None) - + if isinstance(filename, str): filename = [filename] @@ -140,9 +140,9 @@ def get_file_handler(self, user_id, filename): self.__user_instances[k]['last_access_time']:k for k in self.__user_instances.keys() } - users_by_access_time = sorted(users) + oldest_user = users[min(users)] # drop oldest session - self.__user_instances.pop(users_by_access_time[0]) + self.__user_instances.pop(oldest_user) logger.debug(f"Returning file_handler and releasing lock") return self.__user_instances[user_id]['reader'] From 5d0507fd93076dce93d8cb4372642db90872352f Mon Sep 17 00:00:00 2001 From: Christian Glaser Date: Fri, 24 Nov 2023 14:08:12 +0000 Subject: [PATCH 401/418] add warning that tranmission coefficient is not calculated for ice/air ray tracing --- NuRadioMC/SignalProp/analyticraytracing.py | 1 + 1 file changed, 1 insertion(+) diff --git a/NuRadioMC/SignalProp/analyticraytracing.py b/NuRadioMC/SignalProp/analyticraytracing.py index 436d6fcd6..41f5cd9eb 100644 --- a/NuRadioMC/SignalProp/analyticraytracing.py +++ b/NuRadioMC/SignalProp/analyticraytracing.py @@ -685,6 +685,7 @@ def get_attenuation_along_path(self, x1, x2, C_0, frequency, max_detector_freq, z_turn = 0 y_turn = self.get_y(self.get_gamma(z_turn), C_0, self.get_C_1(x1, C_0)) x2 = [y_turn, z_turn] + self.__logger.warning(f"transmission coefficient of propagation from ice into air, or air into ice is not taken into account in attenuation calculation!") if self.use_cpp: mask = frequency > 0 From cbf0feb34f6bc7ec549a3e7ba49a9c8f5346762a Mon Sep 17 00:00:00 2001 From: Christian Glaser Date: Mon, 27 Nov 2023 13:38:55 +0000 Subject: [PATCH 402/418] add calculation of transmission coefficients --- NuRadioMC/SignalProp/analyticraytracing.py | 44 +++++++++++++------ NuRadioMC/SignalProp/examples/E02ToAir.py | 51 +++++++++++++--------- 2 files changed, 62 insertions(+), 33 deletions(-) diff --git a/NuRadioMC/SignalProp/analyticraytracing.py b/NuRadioMC/SignalProp/analyticraytracing.py index 41f5cd9eb..c86621a07 100644 --- a/NuRadioMC/SignalProp/analyticraytracing.py +++ b/NuRadioMC/SignalProp/analyticraytracing.py @@ -2309,19 +2309,37 @@ def apply_propagation_effects(self, efield, i_solution): for zenith_reflection in zenith_reflections: # loop through all possible reflections if (zenith_reflection is None): # skip all ray segments where not reflection at surface happens continue - r_theta = NuRadioReco.utilities.geometryUtilities.get_fresnel_r_p( - zenith_reflection, n_2=1., n_1=self._medium.get_index_of_refraction([self._X2[0], self._X2[1], -1 * units.cm])) - r_phi = NuRadioReco.utilities.geometryUtilities.get_fresnel_r_s( - zenith_reflection, n_2=1., n_1=self._medium.get_index_of_refraction([self._X2[0], self._X2[1], -1 * units.cm])) - efield[efp.reflection_coefficient_theta] = r_theta - efield[efp.reflection_coefficient_phi] = r_phi - - spec[1] *= r_theta - spec[2] *= r_phi - self.__logger.debug( - "ray hits the surface at an angle {:.2f}deg -> reflection coefficient is r_theta = {:.2f}, r_phi = {:.2f}".format( - zenith_reflection / units.deg, - r_theta, r_phi)) + if(self._x2[1] > 0): # we need to treat the case of air to ice/ice to air propagation sepatately: + # air/ice propagation + if(not self._swap): # ice to air case + t_theta = NuRadioReco.utilities.geometryUtilities.get_fresnel_t_p( + zenith_reflection, n_2=1., n_1=self._medium.get_index_of_refraction([self._X2[0], self._X2[1], -1 * units.cm])) + t_phi = NuRadioReco.utilities.geometryUtilities.get_fresnel_t_s( + zenith_reflection, n_2=1., n_1=self._medium.get_index_of_refraction([self._X2[0], self._X2[1], -1 * units.cm])) + self.__logger.warning(f"propagating from ice to air: transmission coefficient is {t_theta:.2f}, {t_phi:.2f}") + else: # air to ice + t_theta = NuRadioReco.utilities.geometryUtilities.get_fresnel_t_p( + zenith_reflection, n_1=1., n_2=self._medium.get_index_of_refraction([self._X2[0], self._X2[1], -1 * units.cm])) + t_phi = NuRadioReco.utilities.geometryUtilities.get_fresnel_t_s( + zenith_reflection, n_1=1., n_2=self._medium.get_index_of_refraction([self._X2[0], self._X2[1], -1 * units.cm])) + self.__logger.warning(f"propagating from air to ice: transmission coefficient is {t_theta:.2f}, {t_phi:.2f}") + spec[1] *= t_theta + spec[2] *= t_phi + else: + #in-ice propagation + r_theta = NuRadioReco.utilities.geometryUtilities.get_fresnel_r_p( + zenith_reflection, n_2=1., n_1=self._medium.get_index_of_refraction([self._X2[0], self._X2[1], -1 * units.cm])) + r_phi = NuRadioReco.utilities.geometryUtilities.get_fresnel_r_s( + zenith_reflection, n_2=1., n_1=self._medium.get_index_of_refraction([self._X2[0], self._X2[1], -1 * units.cm])) + efield[efp.reflection_coefficient_theta] = r_theta + efield[efp.reflection_coefficient_phi] = r_phi + + spec[1] *= r_theta + spec[2] *= r_phi + self.__logger.warning( + "ray hits the surface at an angle {:.2f}deg -> reflection coefficient is r_theta = {:.2f}, r_phi = {:.2f}".format( + zenith_reflection / units.deg, + r_theta, r_phi)) i_reflections = self.get_results()[i_solution]['reflection'] if (i_reflections > 0): # take into account possible bottom reflections # each reflection lowers the amplitude by the reflection coefficient and introduces a phase shift diff --git a/NuRadioMC/SignalProp/examples/E02ToAir.py b/NuRadioMC/SignalProp/examples/E02ToAir.py index 2c509c4df..1ef30857f 100644 --- a/NuRadioMC/SignalProp/examples/E02ToAir.py +++ b/NuRadioMC/SignalProp/examples/E02ToAir.py @@ -4,6 +4,7 @@ from NuRadioMC.SignalProp import analyticraytracing as ray from NuRadioReco.utilities import units from NuRadioMC.utilities import medium +import NuRadioReco.framework.electric_field import logging from radiotools import helper as hp from radiotools import plthelpers as php @@ -12,11 +13,15 @@ # ray.cpp_available=False x1 = np.array([0, 0., -149.]) * units.m + x2 = np.array([200, 0., 100]) * units.m x3 = np.array([500, 0., 100]) * units.m x4 = np.array([1000, 0., 100]) * units.m x5 = np.array([10000, 0., 100]) * units.m -N = 4 + +x_starts = [x1, x1, x1, x1, x5] +x_stops = [x2, x3, x4, x5, x1] +N = 5 receive_vectors = np.zeros((N, 2, 3)) * np.nan ray_tracing_C0 = np.zeros((N, 2)) * np.nan @@ -27,14 +32,12 @@ ice = medium.southpole_simple() -lss = ['-', '--', ':'] -colors = ['b', 'g', 'r'] fig, ax = plt.subplots(1, 1) -ax.plot(x1[0], x1[2], 'ko') -for i, x in enumerate([x2, x3, x4, x5]): - print('finding solutions for ', x) +for i, (x_start, x_stop) in enumerate(zip(x_starts, x_stops)): + ax.plot(x_start[0], x_start[2], 'ko') + print(f'finding solutions for {x_start} to {x_stop}') r = ray.ray_tracing(ice, log_level=logging.WARNING, use_cpp=False) - r.set_start_and_end_point(x1, x) + r.set_start_and_end_point(x_start, x_stop) r.find_solutions() if(r.has_solution()): for iS in range(r.get_number_of_solutions()): @@ -57,20 +60,28 @@ att = r.get_attenuation(iS, np.array([100, 200]) * units.MHz) print(att) + + + efield=NuRadioReco.framework.electric_field.ElectricField([0]) + efield.set_trace(np.ones((3,200)), 1) + efield2 = r.apply_propagation_effects(efield, 0) + + + xx, zz = r.get_ray_path(iS) - # to readout the actual trace, we have to flatten to 2D - dX = x - x1 - dPhi = -np.arctan2(dX[1], dX[0]) - c, s = np.cos(dPhi), np.sin(dPhi) - R = np.array(((c, -s, 0), (s, c, 0), (0, 0, 1))) - X1r = x1 - X2r = np.dot(R, x - x1) + x1 - x1_2d = np.array([X1r[0], X1r[2]]) - x2_2d = np.array([X2r[0], X2r[2]]) - r_2d = ray.ray_tracing_2D(ice) - yy, zz = r_2d.get_path(x1_2d, x2_2d, ray_tracing_C0[i, iS]) - ax.plot(yy, zz, '{}'.format(php.get_color_linestyle(i)), label='{} C0 = {:.4f}, f = {:.2f}'.format(ray_tracing_solution_type[i, iS], ray_tracing_C0[i, iS], focusing)) - ax.plot(x2_2d[0], x2_2d[1], '{}{}-'.format('d', php.get_color(i))) + # # to readout the actual trace, we have to flatten to 2D + # dX = x - x_start + # dPhi = -np.arctan2(dX[1], dX[0]) + # c, s = np.cos(dPhi), np.sin(dPhi) + # R = np.array(((c, -s, 0), (s, c, 0), (0, 0, 1))) + # X1r = x_start + # X2r = np.dot(R, x - x_start) + x_start + # x1_2d = np.array([X1r[0], X1r[2]]) + # x2_2d = np.array([X2r[0], X2r[2]]) + # r_2d = ray.ray_tracing_2D(ice) + # yy, zz = r_2d.get_path(x1_2d, x2_2d, ray_tracing_C0[i, iS]) + ax.plot(xx, zz, '{}'.format(php.get_color_linestyle(i)), label='{} C0 = {:.4f}, f = {:.2f}'.format(ray_tracing_solution_type[i, iS], ray_tracing_C0[i, iS], focusing)) + ax.plot(x_stop[0], x_stop[2], '{}{}-'.format('d', php.get_color(i))) ax.legend() ax.set_xlabel("y [m]") From 420cd2ec2bcb937b5824befdbac953ce081d460f Mon Sep 17 00:00:00 2001 From: Christian Glaser Date: Mon, 27 Nov 2023 13:51:16 +0000 Subject: [PATCH 403/418] improve logging --- NuRadioMC/SignalProp/analyticraytracing.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/NuRadioMC/SignalProp/analyticraytracing.py b/NuRadioMC/SignalProp/analyticraytracing.py index c86621a07..ba14c62fa 100644 --- a/NuRadioMC/SignalProp/analyticraytracing.py +++ b/NuRadioMC/SignalProp/analyticraytracing.py @@ -685,7 +685,6 @@ def get_attenuation_along_path(self, x1, x2, C_0, frequency, max_detector_freq, z_turn = 0 y_turn = self.get_y(self.get_gamma(z_turn), C_0, self.get_C_1(x1, C_0)) x2 = [y_turn, z_turn] - self.__logger.warning(f"transmission coefficient of propagation from ice into air, or air into ice is not taken into account in attenuation calculation!") if self.use_cpp: mask = frequency > 0 @@ -2311,18 +2310,19 @@ def apply_propagation_effects(self, efield, i_solution): continue if(self._x2[1] > 0): # we need to treat the case of air to ice/ice to air propagation sepatately: # air/ice propagation + self.__logger.warning(f"calculation of transmission coefficients and focussing factor for air/ice propagation is experimental and needs further validation") if(not self._swap): # ice to air case t_theta = NuRadioReco.utilities.geometryUtilities.get_fresnel_t_p( zenith_reflection, n_2=1., n_1=self._medium.get_index_of_refraction([self._X2[0], self._X2[1], -1 * units.cm])) t_phi = NuRadioReco.utilities.geometryUtilities.get_fresnel_t_s( zenith_reflection, n_2=1., n_1=self._medium.get_index_of_refraction([self._X2[0], self._X2[1], -1 * units.cm])) - self.__logger.warning(f"propagating from ice to air: transmission coefficient is {t_theta:.2f}, {t_phi:.2f}") + self.__logger.info(f"propagating from ice to air: transmission coefficient is {t_theta:.2f}, {t_phi:.2f}") else: # air to ice t_theta = NuRadioReco.utilities.geometryUtilities.get_fresnel_t_p( zenith_reflection, n_1=1., n_2=self._medium.get_index_of_refraction([self._X2[0], self._X2[1], -1 * units.cm])) t_phi = NuRadioReco.utilities.geometryUtilities.get_fresnel_t_s( zenith_reflection, n_1=1., n_2=self._medium.get_index_of_refraction([self._X2[0], self._X2[1], -1 * units.cm])) - self.__logger.warning(f"propagating from air to ice: transmission coefficient is {t_theta:.2f}, {t_phi:.2f}") + self.__logger.info(f"propagating from air to ice: transmission coefficient is {t_theta:.2f}, {t_phi:.2f}") spec[1] *= t_theta spec[2] *= t_phi else: @@ -2336,7 +2336,7 @@ def apply_propagation_effects(self, efield, i_solution): spec[1] *= r_theta spec[2] *= r_phi - self.__logger.warning( + self.__logger.info( "ray hits the surface at an angle {:.2f}deg -> reflection coefficient is r_theta = {:.2f}, r_phi = {:.2f}".format( zenith_reflection / units.deg, r_theta, r_phi)) From 4d6a9f83da69b10459cc89a85e6bca972147636f Mon Sep 17 00:00:00 2001 From: Sjoerd Bouma Date: Wed, 29 Nov 2023 16:43:31 +0100 Subject: [PATCH 404/418] fix issue where missing time traces were stored as array(None), leading to errors when reading in --- NuRadioReco/framework/base_trace.py | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/NuRadioReco/framework/base_trace.py b/NuRadioReco/framework/base_trace.py index c79c86c29..ee3e5443f 100644 --- a/NuRadioReco/framework/base_trace.py +++ b/NuRadioReco/framework/base_trace.py @@ -114,7 +114,7 @@ def get_times(self): err = f"time array does not have the same length as the trace. n_samples = {length:d}, sampling rate = {self._sampling_rate:.5g}" logger.error(err) raise ValueError(err) - except: + except (ValueError, AttributeError): times = np.array([]) return times @@ -186,19 +186,23 @@ def resample(self, sampling_rate): if resampling_factor.numerator != 1: # resample and use axis -1 since trace might be either shape (N) for analytic trace or shape (3,N) for E-field resampled_trace = scipy.signal.resample(resampled_trace, resampling_factor.numerator * self.get_number_of_samples(), axis=-1) - + if resampling_factor.denominator != 1: # resample and use axis -1 since trace might be either shape (N) for analytic trace or shape (3,N) for E-field resampled_trace = scipy.signal.resample(resampled_trace, np.shape(resampled_trace)[-1] // resampling_factor.denominator, axis=-1) if resampled_trace.shape[-1] % 2 != 0: resampled_trace = resampled_trace.T[:-1].T - + self.set_trace(resampled_trace, sampling_rate) def serialize(self): + time_trace = self.get_trace() + # if there is no trace, the above will return np.array(None). + if not time_trace.shape: + return None data = {'sampling_rate': self.get_sampling_rate(), - 'time_trace': self.get_trace(), + 'time_trace': time_trace, 'trace_start_time': self.get_trace_start_time()} return pickle.dumps(data, protocol=4) @@ -218,13 +222,13 @@ def __add__(self, x): # Some sanity checks if not isinstance(x, BaseTrace): raise TypeError('+ operator is only defined for 2 BaseTrace objects') - + if self.get_trace() is None or x.get_trace() is None: raise ValueError('One of the trace objects has no trace set') - + if self.get_trace().ndim != x.get_trace().ndim: raise ValueError('Traces have different dimensions') - + if self.get_sampling_rate() != x.get_sampling_rate(): # Upsample trace with lower sampling rate # Create new baseTrace object for the resampling so we don't change the originals @@ -256,12 +260,12 @@ def __add__(self, x): first_trace = trace_2 second_trace = trace_1 trace_start = x.get_trace_start_time() - + # Calculate the difference in the trace start time between the traces and the number of # samples that time difference corresponds to time_offset = np.abs(x.get_trace_start_time() - self.get_trace_start_time()) i_start = int(round(time_offset * sampling_rate)) - + # We have to distinguish 2 cases: Trace is 1D (channel) or 2D(E-field) # and treat them differently if trace_1.ndim == 1: @@ -282,13 +286,13 @@ def __add__(self, x): early_trace[:, :first_trace.shape[1]] = first_trace late_trace = np.zeros((second_trace.shape[0], trace_length)) late_trace[:, :second_trace.shape[1]] = second_trace - + # Correct for different trace start times by using fourier shift theorem to # shift the later trace backwards. late_trace_object = BaseTrace() late_trace_object.set_trace(late_trace, sampling_rate) late_trace_object.apply_time_shift(time_offset, True) - + # Create new BaseTrace object holding the summed traces new_trace = BaseTrace() new_trace.set_trace(early_trace + late_trace_object.get_trace(), sampling_rate) From 0d8d0288e2f8a51d74f62c821125ca1bdbcc9dcc Mon Sep 17 00:00:00 2001 From: Sjoerd Bouma Date: Wed, 29 Nov 2023 16:47:33 +0100 Subject: [PATCH 405/418] update changelog --- changelog.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/changelog.txt b/changelog.txt index 4101747c8..bc242b7bc 100644 --- a/changelog.txt +++ b/changelog.txt @@ -4,7 +4,7 @@ please update the categories "new features" and "bugfixes" before a pull request version 2.2.0-dev new features: -- expand values stored in SimplePhasedTrigger +- expand values stored in SimplePhasedTrigger - added getting to query ARZ charge-excess profiles - upgrade to proposal v 7.5.0 with new NuRadioProposal interface and improved LPM treatment - add script to generate / download pre-calculated proposal tables for known detector configurations @@ -19,6 +19,7 @@ bugfixes: - fixed/improved C++ raytracer not finding solutions for some near-horizontal or near-shadowzone vertices - fixed wrong number in Feldman-Cousins upper limit - in antennapattern.py, fixed line 1398; was masking frequencies >= 0 instead of frequencies > 0, causing NaN errors +- Fixed issue where saving empty traces (channels or Efields) created unreadable .nur files version 2.1.8 From bea87725491deb8e26cba360dbd6f71071a546c4 Mon Sep 17 00:00:00 2001 From: Christian Glaser Date: Thu, 30 Nov 2023 12:23:22 +0000 Subject: [PATCH 406/418] fix code to allow for more vertical propagation direction for air/ice case. --- NuRadioMC/SignalProp/analyticraytracing.py | 76 ++++++++++++---------- NuRadioMC/SignalProp/examples/E02ToAir.py | 15 ++++- 2 files changed, 53 insertions(+), 38 deletions(-) diff --git a/NuRadioMC/SignalProp/analyticraytracing.py b/NuRadioMC/SignalProp/analyticraytracing.py index ba14c62fa..4788d6b26 100644 --- a/NuRadioMC/SignalProp/analyticraytracing.py +++ b/NuRadioMC/SignalProp/analyticraytracing.py @@ -1139,12 +1139,32 @@ def get_delta_y(self, C_0, x1, x2, C0range=None, reflection=0, reflection_case=2 # between the turning point and the target point + 10 x the distance between the z position of the turning points # and the target position. This results in a objective function that has the solutions as the only minima and # is smooth in C_0 + diff = ((z_turn - x2[1]) ** 2 + (y_turn - x2[0]) ** 2) ** 0.5 + 10 * np.abs(z_turn - x2[1]) self.__logger.debug( - "turning points (zturn = {:.0f} is deeper than x2 positon z2 = {:.0f}, setting distance to target position to {:.1f}".format(z_turn, x2[1], -diff)) + "turning points (zturn = {:.4g} is deeper than x2 positon z2 = {:.0f}, setting distance to target position to {:.1f}".format(z_turn, x2[1], -diff)) return -diff # return -np.inf self.__logger.debug('turning points is z = {:.1f}, y = {:.1f}'.format(z_turn, y_turn)) + + if(x2[1] > 0): # first treat the ice to air case + # Do nothing if ray is refracted. If ray is reflected, don't mirror but do straight line upwards + if(z_turn == 0): + zenith_reflection = self.get_reflection_angle(x1, x2, C_0, reflection, reflection_case) + if(zenith_reflection == None): + diff = x2[1] + self.__logger.debug(f"not refracting into air") + return diff + n_1 = self.medium.get_index_of_refraction([y_turn, 0, z_turn]) + zenith_air = NuRadioReco.utilities.geometryUtilities.get_fresnel_angle(zenith_reflection, n_1=n_1, n_2=1) + if(zenith_air is None): + diff = x2[1] + self.__logger.debug(f"not refracting into air") + return diff + z = (x2[0] - y_turn) / np.tan(zenith_air) + diff = x2[1] - z + self.__logger.debug(f"touching surface at {zenith_reflection/units.deg:.1f}deg -> {zenith_air/units.deg:.1f}deg -> x2 = {x2} diff {diff:.2f}") + return diff if(y_turn > x2[0]): # we always propagate from left to right # direct ray y2_fit = self.get_y(self.get_gamma(x2[1]), C_0, C_1) # calculate y position at get_path position @@ -1158,35 +1178,19 @@ def get_delta_y(self, C_0, x1, x2, C0range=None, reflection=0, reflection_case=2 'we have a direct ray, y({:.1f}) = {:.1f} -> {:.1f} away from {:.1f}, turning point = y={:.1f}, z={:.2f}, x0 = {:.1f} {:.1f}'.format(x2[1], y2_fit, diff, x2[0], y_turn, z_turn, x1[0], x1[1])) return diff else: + # now it's a bit more complicated. we need to transform the coordinates to + # be on the mirrored part of the function + z_mirrored = x2[1] + gamma = self.get_gamma(z_mirrored) + self.__logger.debug("get_y( {}, {}, {})".format(gamma, C_0, C_1)) + y2_raw = self.get_y(gamma, C_0, C_1) + y2_fit = 2 * y_turn - y2_raw + diff = (x2[0] - y2_fit) - if(x2[1] > 0): # first treat the ice to air case - # Do nothing if ray is refracted. If ray is reflected, don't mirror but do straight line upwards - if(z_turn == 0): - zenith_reflection = self.get_reflection_angle(x1, x2, C_0, reflection, reflection_case) - n_1 = self.medium.get_index_of_refraction([y_turn, 0, z_turn]) - zenith_air = NuRadioReco.utilities.geometryUtilities.get_fresnel_angle(zenith_reflection, n_1=n_1, n_2=1) - if(zenith_air is None): - diff = x2[0] - self.__logger.debug(f"not refracting into air") - return diff - z = (x2[0] - y_turn) / np.tan(zenith_air) - diff = x2[1] - z - self.__logger.debug(f"touching surface at {zenith_reflection/units.deg:.1f}deg -> {zenith_air/units.deg:.1f}deg -> x2 = {x2} diff {diff:.2f}") - return diff - else: - # now it's a bit more complicated. we need to transform the coordinates to - # be on the mirrored part of the function - z_mirrored = x2[1] - gamma = self.get_gamma(z_mirrored) - self.__logger.debug("get_y( {}, {}, {})".format(gamma, C_0, C_1)) - y2_raw = self.get_y(gamma, C_0, C_1) - y2_fit = 2 * y_turn - y2_raw - diff = (x2[0] - y2_fit) - - self.__logger.debug('we have a reflected/refracted ray, y({:.1f}) = {:.1f} ({:.1f}) -> {:.1f} away from {:.1f} (gamma = {:.5g})'.format( - z_mirrored, y2_fit, y2_raw, diff, x2[0], gamma)) - - return -1 * diff + self.__logger.debug('we have a reflected/refracted ray, y({:.1f}) = {:.1f} ({:.1f}) -> {:.1f} away from {:.1f} (gamma = {:.5g})'.format( + z_mirrored, y2_fit, y2_raw, diff, x2[0], gamma)) + + return -1 * diff def determine_solution_type(self, x1, x2, C_0): """ returns the type of the solution @@ -1264,19 +1268,21 @@ def find_solutions(self, x1, x2, plot=False, reflection=0, reflection_case=1): if(x2[1] > 0): # special case of ice to air ray tracing. There is always one unique solution between C_0 = inf and C_0 that # skims the surface. Therefore, we can find the solution using an efficient root finding algorithm. - logC0_start = 1 # infinity is bad, 1 is steep enough + logC0_start = 100 # infinity is bad, 100 is steep enough C_0_stop = self.get_C_0_from_angle(np.arcsin(1/self.medium.get_index_of_refraction([0, x1[0], x1[1]])), x1[1]).x[0] logC0_stop = np.log(C_0_stop - 1/self.medium.n_ice) - self.__logger.debug( - "Looking for ice-air solutions between C0 ({}, {}) with delta_y ({}, {})".format( - logC0_start, logC0_stop, *[self.obj_delta_y(logC0, x1, x2, reflection, reflection_case) for logC0 in [logC0_start, logC0_stop]] - )) + delta_ys = [self.obj_delta_y(logC0, x1, x2, reflection, reflection_case) for logC0 in [logC0_start, logC0_stop]] + self.__logger.debug("Looking for ice-air solutions between log(C0) ({}, {}) with delta_y ({}, {})".format(logC0_start, logC0_stop, *delta_ys)) + if(np.sign(delta_ys[0]) == np.sign(delta_ys[1])): + self.__logger.warning(f"can't find a solution for ice/air propagation. The trajectory might be too vertical! This is currently not"\ + " supported because of numerical instabilities.") + return results result = optimize.brentq(self.obj_delta_y, logC0_start, logC0_stop, args=(x1, x2, reflection, reflection_case)) C_0 = self.get_C0_from_log(result) C0s.append(C_0) solution_type = self.determine_solution_type(x1, x2, C_0) - self.__logger.info("found {} solution C0 = {:.2f}".format(solution_types[solution_type], C_0)) + self.__logger.info("found {} solution C0 = {:.2f} (internal logC = {:.2f})".format(solution_types[solution_type], C_0, result)) results.append({'type': solution_type, 'C0': C_0, 'C1': self.get_C_1(x1, C_0), diff --git a/NuRadioMC/SignalProp/examples/E02ToAir.py b/NuRadioMC/SignalProp/examples/E02ToAir.py index 1ef30857f..44237d1bf 100644 --- a/NuRadioMC/SignalProp/examples/E02ToAir.py +++ b/NuRadioMC/SignalProp/examples/E02ToAir.py @@ -14,8 +14,8 @@ x1 = np.array([0, 0., -149.]) * units.m -x2 = np.array([200, 0., 100]) * units.m -x3 = np.array([500, 0., 100]) * units.m +x2 = np.array([0, 0., 100]) * units.m +x3 = np.array([200, 0., 100]) * units.m x4 = np.array([1000, 0., 100]) * units.m x5 = np.array([10000, 0., 100]) * units.m @@ -32,6 +32,15 @@ ice = medium.southpole_simple() +if 0: # for debug purpuses, plot the objective function + fig2, ax2 = plt.subplots(1, 1) + for i, (x_start, x_stop) in enumerate(zip(x_starts, x_stops)): + r2d = ray.ray_tracing_2D(ice, log_level=logging.WARNING) + logC0s = np.linspace(-0.9, 10, 10) + oo = [r2d.obj_delta_y(t, x_start[np.array([0,2])], x_stop[np.array([0,2])]) for t in logC0s] + ax2.plot(logC0s, oo, "-o") + plt.show() + fig, ax = plt.subplots(1, 1) for i, (x_start, x_stop) in enumerate(zip(x_starts, x_stops)): ax.plot(x_start[0], x_start[2], 'ko') @@ -59,7 +68,7 @@ print(f" focusing factor = {focusing:.8f}") att = r.get_attenuation(iS, np.array([100, 200]) * units.MHz) - print(att) + print(f" attenuation: {att}") efield=NuRadioReco.framework.electric_field.ElectricField([0]) From 799d78985715af4690eb5dd84082cb271c49bfc6 Mon Sep 17 00:00:00 2001 From: Sjoerd Bouma Date: Sat, 2 Dec 2023 10:58:31 +0100 Subject: [PATCH 407/418] correct for n in focussing factor only until ice/air boundary to avoid double-counting with fresnel coefficients --- NuRadioMC/SignalProp/analyticraytracing.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/NuRadioMC/SignalProp/analyticraytracing.py b/NuRadioMC/SignalProp/analyticraytracing.py index 4788d6b26..4215be25f 100644 --- a/NuRadioMC/SignalProp/analyticraytracing.py +++ b/NuRadioMC/SignalProp/analyticraytracing.py @@ -2245,12 +2245,17 @@ def get_focusing(self, iS, dz=-1. * units.cm, limit=2.): focusing = limit # now also correct for differences in refractive index between emitter and receiver position + # for ice-to-air transmission, the fresnel coefficients account for this at the boundary already, + # so in that case we only take the difference up to the ice-air boundary + z_max = -0.01 * units.m + z1 = np.min([self._X1[-1], z_max]) + z2 = np.min([self._X2[-1], z_max]) if self._swap: - n1 = self._medium.get_index_of_refraction(self._X2) # emitter - n2 = self._medium.get_index_of_refraction(self._X1) # receiver + n1 = self._medium.get_index_of_refraction([0, 0, z2]) # emitter + n2 = self._medium.get_index_of_refraction([0, 0, z1]) # receiver else: - n1 = self._medium.get_index_of_refraction(self._X1) # emitter - n2 = self._medium.get_index_of_refraction(self._X2) # receiver + n1 = self._medium.get_index_of_refraction([0, 0, z1]) # emitter + n2 = self._medium.get_index_of_refraction([0, 0, z2]) # receiver return focusing * (n1 / n2) ** 0.5 def get_ray_path(self, iS): From 9d7ed56aa45082e01b724874d503df89f66ce397 Mon Sep 17 00:00:00 2001 From: Christian Glaser Date: Tue, 5 Dec 2023 16:13:41 +0000 Subject: [PATCH 408/418] improve documentation --- documentation/source/NuRadioMC/pages/HDF5_structure.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/source/NuRadioMC/pages/HDF5_structure.rst b/documentation/source/NuRadioMC/pages/HDF5_structure.rst index aaa4ee51f..c4734237c 100644 --- a/documentation/source/NuRadioMC/pages/HDF5_structure.rst +++ b/documentation/source/NuRadioMC/pages/HDF5_structure.rst @@ -142,7 +142,7 @@ station triggered, with which amplitude, etc. The same approach works for ``show ``maximum_amplitudes_envelope`` | (``m_events``, ``n_channels``) | Maximum amplitude of the hilbert envelope for each event and channel ``multiple_triggers`` | (``m_showers``, ``n_triggers``) | A boolean array that specifies if a shower contributed to an event that fulfills a certain trigger. The index of the trigger can be translated to the trigger name via the attribute ``trigger_names``. ``multiple_triggers_per_event`` | (``m_events``, ``n_triggers``) | A boolean array that specifies if each event fulfilled a certain trigger. The index of the trigger can be translated to the trigger name via the attribute ``trigger_names``. - ``polarization`` | (``m_showers``, ``n_channels``, ``n_ray_tracing_solutions``, ``3``) | 3D (Cartesian) coordinates of the polarization vector + ``polarization`` | (``m_showers``, ``n_channels``, ``n_ray_tracing_solutions``, ``3``) | 3D coordinates of the polarization vector at the antenna in cartesian coordinates. (The receive vector was used to rotate from spherical/on-sky coordinates to cartesian coordinates). ``ray_tracing_C0`` | (``m_showers``, ``n_channels``, ``n_ray_tracing_solutions``) | One of two parameters specifying the **analytic** ray tracing solution. Can be used to retrieve the solutions without having to re-run the ray tracer. ``ray_tracing_C1`` | (``m_showers``, ``n_channels``, ``n_ray_tracing_solutions``) | One of two parameters specifying the **analytic** ray tracing solution. Can be used to retrieve the solutions without having to re-run the ray tracer. ``ray_tracing_reflection`` | (``m_showers``, ``n_channels``, ``n_ray_tracing_solutions``) | From f2f5af01bce6ed8507fdf1aab51febd048c18c97 Mon Sep 17 00:00:00 2001 From: Christian Glaser Date: Tue, 5 Dec 2023 16:17:49 +0000 Subject: [PATCH 409/418] more details --- documentation/source/NuRadioMC/pages/HDF5_structure.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/source/NuRadioMC/pages/HDF5_structure.rst b/documentation/source/NuRadioMC/pages/HDF5_structure.rst index c4734237c..6fc136da3 100644 --- a/documentation/source/NuRadioMC/pages/HDF5_structure.rst +++ b/documentation/source/NuRadioMC/pages/HDF5_structure.rst @@ -142,7 +142,7 @@ station triggered, with which amplitude, etc. The same approach works for ``show ``maximum_amplitudes_envelope`` | (``m_events``, ``n_channels``) | Maximum amplitude of the hilbert envelope for each event and channel ``multiple_triggers`` | (``m_showers``, ``n_triggers``) | A boolean array that specifies if a shower contributed to an event that fulfills a certain trigger. The index of the trigger can be translated to the trigger name via the attribute ``trigger_names``. ``multiple_triggers_per_event`` | (``m_events``, ``n_triggers``) | A boolean array that specifies if each event fulfilled a certain trigger. The index of the trigger can be translated to the trigger name via the attribute ``trigger_names``. - ``polarization`` | (``m_showers``, ``n_channels``, ``n_ray_tracing_solutions``, ``3``) | 3D coordinates of the polarization vector at the antenna in cartesian coordinates. (The receive vector was used to rotate from spherical/on-sky coordinates to cartesian coordinates). + ``polarization`` | (``m_showers``, ``n_channels``, ``n_ray_tracing_solutions``, ``3``) | 3D coordinates of the polarization vector at the antenna in cartesian coordinates. (The receive vector was used to rotate from spherical/on-sky coordinates to cartesian coordinates). The polarization vector does not include any propagation effects that could change the polarization, such as different reflectivities at the surface for the p and s polarization component. ``ray_tracing_C0`` | (``m_showers``, ``n_channels``, ``n_ray_tracing_solutions``) | One of two parameters specifying the **analytic** ray tracing solution. Can be used to retrieve the solutions without having to re-run the ray tracer. ``ray_tracing_C1`` | (``m_showers``, ``n_channels``, ``n_ray_tracing_solutions``) | One of two parameters specifying the **analytic** ray tracing solution. Can be used to retrieve the solutions without having to re-run the ray tracer. ``ray_tracing_reflection`` | (``m_showers``, ``n_channels``, ``n_ray_tracing_solutions``) | From 6c6ebd0fa7efab431b638aaec2abdda4ceb0fea1 Mon Sep 17 00:00:00 2001 From: Christoph Date: Wed, 6 Dec 2023 13:44:31 -0600 Subject: [PATCH 410/418] Add missing LPDA and fix LPDA rotation --- .../detector/RNO_G/RNO_season_2023.json | 132 ++++++++++-------- 1 file changed, 75 insertions(+), 57 deletions(-) diff --git a/NuRadioReco/detector/RNO_G/RNO_season_2023.json b/NuRadioReco/detector/RNO_G/RNO_season_2023.json index b1be43208..801612dcd 100644 --- a/NuRadioReco/detector/RNO_G/RNO_season_2023.json +++ b/NuRadioReco/detector/RNO_G/RNO_season_2023.json @@ -327,9 +327,9 @@ "18": { "station_id": 11, "channel_id": 12, - "ant_rotation_phi": 243.0, + "ant_rotation_phi": 220.0, "ant_rotation_theta": 90.0, - "ant_orientation_phi": 333.0, + "ant_orientation_phi": 310.0, "ant_orientation_theta": 120.0, "ant_position_x": 25.245374429777485, "ant_position_y": -9.271898202581497, @@ -345,7 +345,7 @@ "19": { "station_id": 11, "channel_id": 13, - "ant_rotation_phi": 243.0, + "ant_rotation_phi": 220.0, "ant_rotation_theta": 90.0, "ant_orientation_phi": 0.0, "ant_orientation_theta": 0.0, @@ -363,9 +363,9 @@ "20": { "station_id": 11, "channel_id": 14, - "ant_rotation_phi": 243.0, + "ant_rotation_phi": 220.0, "ant_rotation_theta": 90.0, - "ant_orientation_phi": 153.0, + "ant_orientation_phi": 130.0, "ant_orientation_theta": 120.0, "ant_position_x": 23.709240577868513, "ant_position_y": -4.359449327425068, @@ -381,9 +381,9 @@ "21": { "station_id": 11, "channel_id": 15, - "ant_rotation_phi": 351.0, + "ant_rotation_phi": 328.0, "ant_rotation_theta": 90.0, - "ant_orientation_phi": 81.0, + "ant_orientation_phi": 58.0, "ant_orientation_theta": 120.0, "ant_position_x": 13.659226614984846, "ant_position_y": -4.116966752974577, @@ -399,7 +399,7 @@ "22": { "station_id": 11, "channel_id": 16, - "ant_rotation_phi": 351.0, + "ant_rotation_phi": 328.0, "ant_rotation_theta": 90.0, "ant_orientation_phi": 0.0, "ant_orientation_theta": 0.0, @@ -417,9 +417,9 @@ "23": { "station_id": 11, "channel_id": 17, - "ant_rotation_phi": 351.0, + "ant_rotation_phi": 328.0, "ant_rotation_theta": 90.0, - "ant_orientation_phi": 261.0, + "ant_orientation_phi": 238.0, "ant_orientation_theta": 120.0, "ant_position_x": 11.212162270289355, "ant_position_y": -9.197601282929554, @@ -1569,9 +1569,9 @@ "87": { "station_id": 21, "channel_id": 15, - "ant_rotation_phi": 254.0, + "ant_rotation_phi": 277.0, "ant_rotation_theta": 90.0, - "ant_orientation_phi": 164.0, + "ant_orientation_phi": 187.0, "ant_orientation_theta": 120.0, "ant_position_x": -20.913616334864287, "ant_position_y": 16.537611216532184, @@ -1587,7 +1587,7 @@ "88": { "station_id": 21, "channel_id": 16, - "ant_rotation_phi": 254.0, + "ant_rotation_phi": 277.0, "ant_rotation_theta": 90.0, "ant_orientation_phi": 0.0, "ant_orientation_theta": 0.0, @@ -1605,9 +1605,9 @@ "89": { "station_id": 21, "channel_id": 17, - "ant_rotation_phi": 254.0, + "ant_rotation_phi": 277.0, "ant_rotation_theta": 90.0, - "ant_orientation_phi": 344.0, + "ant_orientation_phi": 7.0, "ant_orientation_theta": 120.0, "ant_position_x": -15.404148418065631, "ant_position_y": 17.46318633982372, @@ -1623,9 +1623,9 @@ "90": { "station_id": 21, "channel_id": 14, - "ant_rotation_phi": 65.0, + "ant_rotation_phi": 42.0, "ant_rotation_theta": 90.0, - "ant_orientation_phi": 155.0, + "ant_orientation_phi": 132.0, "ant_orientation_theta": 120.0, "ant_position_x": -25.02971666518448, "ant_position_y": 7.293175091846081, @@ -1641,7 +1641,7 @@ "91": { "station_id": 21, "channel_id": 13, - "ant_rotation_phi": 65.0, + "ant_rotation_phi": 42.0, "ant_rotation_theta": 90.0, "ant_orientation_phi": 0.0, "ant_orientation_theta": 0.0, @@ -1659,9 +1659,9 @@ "92": { "station_id": 21, "channel_id": 12, - "ant_rotation_phi": 65.0, + "ant_rotation_phi": 42.0, "ant_rotation_theta": 90.0, - "ant_orientation_phi": 335.0, + "ant_orientation_phi": 312.0, "ant_orientation_theta": 120.0, "ant_position_x": -22.479689741668324, "ant_position_y": 2.80783833285102, @@ -1677,9 +1677,9 @@ "93": { "station_id": 21, "channel_id": 20, - "ant_rotation_phi": 118.0, + "ant_rotation_phi": 141.0, "ant_rotation_theta": 90.0, - "ant_orientation_phi": 208.0, + "ant_orientation_phi": 231.0, "ant_orientation_theta": 120.0, "ant_position_x": -11.266588048738129, "ant_position_y": 2.9011467712219314, @@ -1695,7 +1695,7 @@ "94": { "station_id": 21, "channel_id": 19, - "ant_rotation_phi": 118.0, + "ant_rotation_phi": 141.0, "ant_rotation_theta": 90.0, "ant_orientation_phi": 0.0, "ant_orientation_theta": 0.0, @@ -1713,9 +1713,9 @@ "95": { "station_id": 21, "channel_id": 18, - "ant_rotation_phi": 118.0, + "ant_rotation_phi": 141.0, "ant_rotation_theta": 90.0, - "ant_orientation_phi": 28.0, + "ant_orientation_phi": 51.0, "ant_orientation_theta": 120.0, "ant_position_x": -8.513397338379718, "ant_position_y": 7.724537269470318, @@ -2270,7 +2270,7 @@ }, "126": { "station_id": 23, - "channel_id": 7, + "channel_id": 6, "ant_rotation_phi": 90.0, "ant_rotation_theta": 90.0, "ant_orientation_phi": 0.0, @@ -2288,7 +2288,7 @@ }, "127": { "station_id": 23, - "channel_id": 6, + "channel_id": 7, "ant_rotation_phi": 90.0, "ant_rotation_theta": 90.0, "ant_orientation_phi": 0.0, @@ -2467,6 +2467,24 @@ "ant_type": "createLPDA_100MHz_InfFirn_n1.4" }, "137": { + "station_id": 23, + "channel_id": 12, + "ant_rotation_phi": 270.0, + "ant_rotation_theta": 90.0, + "ant_orientation_phi": 0.0, + "ant_orientation_theta": 120.0, + "ant_position_x": -13.716551579004388, + "ant_position_y": 17.24043830214714, + "ant_position_z": -0.5, + "amp_type": "rno_surface", + "cab_time_delay": 45.78713480723031, + "adc_n_samples": 2048, + "adc_sampling_frequency": 3.2, + "commission_time": "{TinyDate}:2022-06-24T00:00:00", + "decommission_time": "{TinyDate}:2035-11-01T00:00:00", + "ant_type": "createLPDA_100MHz_InfFirn_n1.4" + }, + "138": { "station_id": 23, "channel_id": 20, "ant_rotation_phi": 150.0, @@ -2484,7 +2502,7 @@ "decommission_time": "{TinyDate}:2035-11-01T00:00:00", "ant_type": "createLPDA_100MHz_InfFirn_n1.4" }, - "138": { + "139": { "station_id": 23, "channel_id": 19, "ant_rotation_phi": 150.0, @@ -2502,7 +2520,7 @@ "decommission_time": "{TinyDate}:2035-11-01T00:00:00", "ant_type": "createLPDA_100MHz_InfFirn_n1.4" }, - "139": { + "140": { "station_id": 23, "channel_id": 18, "ant_rotation_phi": 150.0, @@ -2520,7 +2538,7 @@ "decommission_time": "{TinyDate}:2035-11-01T00:00:00", "ant_type": "createLPDA_100MHz_InfFirn_n1.4" }, - "140": { + "141": { "station_id": 23, "channel_id": 17, "ant_rotation_phi": 30.0, @@ -2538,7 +2556,7 @@ "decommission_time": "{TinyDate}:2035-11-01T00:00:00", "ant_type": "createLPDA_100MHz_InfFirn_n1.4" }, - "141": { + "142": { "station_id": 23, "channel_id": 16, "ant_rotation_phi": 30.0, @@ -2556,7 +2574,7 @@ "decommission_time": "{TinyDate}:2035-11-01T00:00:00", "ant_type": "createLPDA_100MHz_InfFirn_n1.4" }, - "142": { + "143": { "station_id": 23, "channel_id": 15, "ant_rotation_phi": 30.0, @@ -2574,7 +2592,7 @@ "decommission_time": "{TinyDate}:2035-11-01T00:00:00", "ant_type": "createLPDA_100MHz_InfFirn_n1.4" }, - "143": { + "144": { "station_id": 24, "channel_id": 9, "ant_rotation_phi": 90.0, @@ -2592,7 +2610,7 @@ "decommission_time": "{TinyDate}:2035-11-01T00:00:00", "ant_type": "RNOG_vpol_4inch_center_n1.73" }, - "144": { + "145": { "station_id": 24, "channel_id": 10, "ant_rotation_phi": 90.0, @@ -2610,7 +2628,7 @@ "decommission_time": "{TinyDate}:2035-11-01T00:00:00", "ant_type": "RNOG_vpol_4inch_center_n1.73" }, - "145": { + "146": { "station_id": 24, "channel_id": 11, "ant_rotation_phi": 90.0, @@ -2628,7 +2646,7 @@ "decommission_time": "{TinyDate}:2035-11-01T00:00:00", "ant_type": "RNOG_quadslot_v3_air_rescaled_to_n1.74" }, - "146": { + "147": { "station_id": 24, "channel_id": 0, "ant_rotation_phi": 90.0, @@ -2646,7 +2664,7 @@ "decommission_time": "{TinyDate}:2035-11-01T00:00:00", "ant_type": "RNOG_vpol_4inch_center_n1.73" }, - "147": { + "148": { "station_id": 24, "channel_id": 1, "ant_rotation_phi": 90.0, @@ -2664,7 +2682,7 @@ "decommission_time": "{TinyDate}:2035-11-01T00:00:00", "ant_type": "RNOG_vpol_4inch_center_n1.73" }, - "148": { + "149": { "station_id": 24, "channel_id": 2, "ant_rotation_phi": 90.0, @@ -2682,7 +2700,7 @@ "decommission_time": "{TinyDate}:2035-11-01T00:00:00", "ant_type": "RNOG_vpol_4inch_center_n1.73" }, - "149": { + "150": { "station_id": 24, "channel_id": 3, "ant_rotation_phi": 90.0, @@ -2700,7 +2718,7 @@ "decommission_time": "{TinyDate}:2035-11-01T00:00:00", "ant_type": "RNOG_vpol_4inch_center_n1.73" }, - "150": { + "151": { "station_id": 24, "channel_id": 4, "ant_rotation_phi": 90.0, @@ -2718,7 +2736,7 @@ "decommission_time": "{TinyDate}:2035-11-01T00:00:00", "ant_type": "RNOG_quadslot_v3_air_rescaled_to_n1.74" }, - "151": { + "152": { "station_id": 24, "channel_id": 5, "ant_rotation_phi": 90.0, @@ -2736,7 +2754,7 @@ "decommission_time": "{TinyDate}:2035-11-01T00:00:00", "ant_type": "RNOG_vpol_4inch_center_n1.73" }, - "152": { + "153": { "station_id": 24, "channel_id": 6, "ant_rotation_phi": 90.0, @@ -2754,7 +2772,7 @@ "decommission_time": "{TinyDate}:2035-11-01T00:00:00", "ant_type": "RNOG_vpol_4inch_center_n1.73" }, - "153": { + "154": { "station_id": 24, "channel_id": 7, "ant_rotation_phi": 90.0, @@ -2772,7 +2790,7 @@ "decommission_time": "{TinyDate}:2035-11-01T00:00:00", "ant_type": "RNOG_vpol_4inch_center_n1.73" }, - "154": { + "155": { "station_id": 24, "channel_id": 8, "ant_rotation_phi": 90.0, @@ -2790,7 +2808,7 @@ "decommission_time": "{TinyDate}:2035-11-01T00:00:00", "ant_type": "RNOG_quadslot_v3_air_rescaled_to_n1.74" }, - "155": { + "156": { "station_id": 24, "channel_id": 21, "ant_rotation_phi": 90.0, @@ -2808,7 +2826,7 @@ "decommission_time": "{TinyDate}:2035-11-01T00:00:00", "ant_type": "RNOG_quadslot_v3_air_rescaled_to_n1.74" }, - "156": { + "157": { "station_id": 24, "channel_id": 22, "ant_rotation_phi": 90.0, @@ -2826,7 +2844,7 @@ "decommission_time": "{TinyDate}:2035-11-01T00:00:00", "ant_type": "RNOG_vpol_4inch_center_n1.73" }, - "157": { + "158": { "station_id": 24, "channel_id": 23, "ant_rotation_phi": 90.0, @@ -2844,7 +2862,7 @@ "decommission_time": "{TinyDate}:2035-11-01T00:00:00", "ant_type": "RNOG_vpol_4inch_center_n1.73" }, - "158": { + "159": { "station_id": 24, "channel_id": 15, "ant_rotation_phi": 330.0, @@ -2862,7 +2880,7 @@ "decommission_time": "{TinyDate}:2035-11-01T00:00:00", "ant_type": "createLPDA_100MHz_InfFirn_n1.4" }, - "159": { + "160": { "station_id": 24, "channel_id": 16, "ant_rotation_phi": 330.0, @@ -2880,7 +2898,7 @@ "decommission_time": "{TinyDate}:2035-11-01T00:00:00", "ant_type": "createLPDA_100MHz_InfFirn_n1.4" }, - "160": { + "161": { "station_id": 24, "channel_id": 17, "ant_rotation_phi": 330.0, @@ -2898,7 +2916,7 @@ "decommission_time": "{TinyDate}:2035-11-01T00:00:00", "ant_type": "createLPDA_100MHz_InfFirn_n1.4" }, - "161": { + "162": { "station_id": 24, "channel_id": 18, "ant_rotation_phi": 90.0, @@ -2916,7 +2934,7 @@ "decommission_time": "{TinyDate}:2035-11-01T00:00:00", "ant_type": "createLPDA_100MHz_InfFirn_n1.4" }, - "162": { + "163": { "station_id": 24, "channel_id": 19, "ant_rotation_phi": 90.0, @@ -2934,7 +2952,7 @@ "decommission_time": "{TinyDate}:2035-11-01T00:00:00", "ant_type": "createLPDA_100MHz_InfFirn_n1.4" }, - "163": { + "164": { "station_id": 24, "channel_id": 20, "ant_rotation_phi": 90.0, @@ -2952,7 +2970,7 @@ "decommission_time": "{TinyDate}:2035-11-01T00:00:00", "ant_type": "createLPDA_100MHz_InfFirn_n1.4" }, - "164": { + "165": { "station_id": 24, "channel_id": 12, "ant_rotation_phi": 210.0, @@ -2970,7 +2988,7 @@ "decommission_time": "{TinyDate}:2035-11-01T00:00:00", "ant_type": "createLPDA_100MHz_InfFirn_n1.4" }, - "165": { + "166": { "station_id": 24, "channel_id": 13, "ant_rotation_phi": 210.0, @@ -2988,7 +3006,7 @@ "decommission_time": "{TinyDate}:2035-11-01T00:00:00", "ant_type": "createLPDA_100MHz_InfFirn_n1.4" }, - "166": { + "167": { "station_id": 24, "channel_id": 14, "ant_rotation_phi": 210.0, @@ -3368,4 +3386,4 @@ "station_id": 24 } } -} +} \ No newline at end of file From 36cb5f7f90e2a4e9869a7208bbaf57c27a80e17c Mon Sep 17 00:00:00 2001 From: Christian Glaser Date: Thu, 7 Dec 2023 09:41:33 +0000 Subject: [PATCH 411/418] add more details --- documentation/source/NuRadioMC/pages/HDF5_structure.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/source/NuRadioMC/pages/HDF5_structure.rst b/documentation/source/NuRadioMC/pages/HDF5_structure.rst index 6fc136da3..20abb7a84 100644 --- a/documentation/source/NuRadioMC/pages/HDF5_structure.rst +++ b/documentation/source/NuRadioMC/pages/HDF5_structure.rst @@ -142,7 +142,7 @@ station triggered, with which amplitude, etc. The same approach works for ``show ``maximum_amplitudes_envelope`` | (``m_events``, ``n_channels``) | Maximum amplitude of the hilbert envelope for each event and channel ``multiple_triggers`` | (``m_showers``, ``n_triggers``) | A boolean array that specifies if a shower contributed to an event that fulfills a certain trigger. The index of the trigger can be translated to the trigger name via the attribute ``trigger_names``. ``multiple_triggers_per_event`` | (``m_events``, ``n_triggers``) | A boolean array that specifies if each event fulfilled a certain trigger. The index of the trigger can be translated to the trigger name via the attribute ``trigger_names``. - ``polarization`` | (``m_showers``, ``n_channels``, ``n_ray_tracing_solutions``, ``3``) | 3D coordinates of the polarization vector at the antenna in cartesian coordinates. (The receive vector was used to rotate from spherical/on-sky coordinates to cartesian coordinates). The polarization vector does not include any propagation effects that could change the polarization, such as different reflectivities at the surface for the p and s polarization component. + ``polarization`` | (``m_showers``, ``n_channels``, ``n_ray_tracing_solutions``, ``3``) | 3D coordinates of the polarization vector at the antenna in cartesian coordinates. (The receive vector (which is opposite to the propagation direction) was used to rotate from spherical/on-sky coordinates to cartesian coordinates). The polarization vector does not include any propagation effects that could change the polarization, such as different reflectivities at the surface for the p and s polarization component. ``ray_tracing_C0`` | (``m_showers``, ``n_channels``, ``n_ray_tracing_solutions``) | One of two parameters specifying the **analytic** ray tracing solution. Can be used to retrieve the solutions without having to re-run the ray tracer. ``ray_tracing_C1`` | (``m_showers``, ``n_channels``, ``n_ray_tracing_solutions``) | One of two parameters specifying the **analytic** ray tracing solution. Can be used to retrieve the solutions without having to re-run the ray tracer. ``ray_tracing_reflection`` | (``m_showers``, ``n_channels``, ``n_ray_tracing_solutions``) | From 1928b2706e0ec5515bce331a9f843751b44cef63 Mon Sep 17 00:00:00 2001 From: Christian Glaser Date: Thu, 7 Dec 2023 14:05:54 +0000 Subject: [PATCH 412/418] add new feature to changelog --- changelog.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/changelog.txt b/changelog.txt index bc242b7bc..5fe8b7c56 100644 --- a/changelog.txt +++ b/changelog.txt @@ -14,6 +14,7 @@ new features: - added ability to generate high-low-triggered noise on a narrow band but return full-band waveforms - phased array noise generation utility class: calculate trigger time and cut trace accordingly - use Philox noise generator in noise adder module (this changes the default random sequence) +- allow raytracing from air to ice and vice versa. Only supported by the Python implementation. (Note that the calculation of the focussing factor was not thoroughly tested.) bugfixes: - fixed/improved C++ raytracer not finding solutions for some near-horizontal or near-shadowzone vertices From c809cfe645c9462aed46e48993537e7fabc1c529 Mon Sep 17 00:00:00 2001 From: Christoph Date: Thu, 7 Dec 2023 10:15:59 -0600 Subject: [PATCH 413/418] Switch channels 6 and 7 on station 23 --- NuRadioReco/detector/RNO_G/RNO_season_2023.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/NuRadioReco/detector/RNO_G/RNO_season_2023.json b/NuRadioReco/detector/RNO_G/RNO_season_2023.json index 801612dcd..52da48e43 100644 --- a/NuRadioReco/detector/RNO_G/RNO_season_2023.json +++ b/NuRadioReco/detector/RNO_G/RNO_season_2023.json @@ -2270,7 +2270,7 @@ }, "126": { "station_id": 23, - "channel_id": 6, + "channel_id": 7, "ant_rotation_phi": 90.0, "ant_rotation_theta": 90.0, "ant_orientation_phi": 0.0, @@ -2288,7 +2288,7 @@ }, "127": { "station_id": 23, - "channel_id": 7, + "channel_id": 6, "ant_rotation_phi": 90.0, "ant_rotation_theta": 90.0, "ant_orientation_phi": 0.0, @@ -3386,4 +3386,4 @@ "station_id": 24 } } -} \ No newline at end of file +} From 8bf56a0f2a8ae02daa4417b8858742105640f785 Mon Sep 17 00:00:00 2001 From: Sjoerd Bouma Date: Sun, 17 Dec 2023 20:07:55 +0100 Subject: [PATCH 414/418] added warning if multiple triggers specify pre_trigger_times --- NuRadioReco/modules/triggerTimeAdjuster.py | 26 +++++++++++++++++----- 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/NuRadioReco/modules/triggerTimeAdjuster.py b/NuRadioReco/modules/triggerTimeAdjuster.py index fc2a79a57..29edb6a2c 100644 --- a/NuRadioReco/modules/triggerTimeAdjuster.py +++ b/NuRadioReco/modules/triggerTimeAdjuster.py @@ -26,8 +26,8 @@ def begin(self, trigger_name=None, pre_trigger_time=55. * units.ns): ---------- trigger_name: string or None name of the trigger that should be used. - If trigger_name is None, the trigger with the smalles trigger_time will be used. - If a name is give, corresponding trigger module must be run beforehand. + If trigger_name is None, the trigger with the smallest trigger_time will be used. + If a name is given, corresponding trigger module must be run beforehand. If the trigger does not exist or did not trigger, this module will do nothing pre_trigger_time: float or dict Amount of time that should be stored in the channel trace before the trigger. @@ -64,8 +64,11 @@ def run(self, event, station, detector, mode='sim_to_data'): mode: 'sim_to_data' (default) | 'data_to_sim' If 'sim_to_data', cuts the (arbitrary-length) simulated traces to the appropriate readout windows. If 'data_to_sim', - looks through all triggers in the station and adjusts the + looks through all triggers in the station and adjusts the trace_start_time according to the different readout delays + + If the ``trigger_name`` was specified in the ``begin`` function, + only this trigger is considered. """ if mode == 'sim_to_data': @@ -116,7 +119,7 @@ def run(self, event, station, detector, mode='sim_to_data'): else: logger.error( 'pre_trigger_time was specified as a dictionary, ' - f'but the neither the trigger_name {trigger_name} ' + f'but neither the trigger_name {trigger_name} ' f'nor the channel id {channel_id} are present as keys' ) raise KeyError @@ -156,8 +159,19 @@ def run(self, event, station, detector, mode='sim_to_data'): else: logger.debug('Trigger {} has not triggered. Channel timings will not be changed.'.format(self.__trigger_name)) elif mode == 'data_to_sim': - for trigger in station.get_triggers().values(): - pre_trigger_time = trigger.get_pre_trigger_times() + if self.__trigger_name is not None: + triggers = [station.get_trigger(self.__trigger_name)] + else: + triggers = station.get_triggers().values() + + pre_trigger_times = [trigger.get_pre_trigger_times() for trigger in triggers] + if np.sum([dt is not None for dt in pre_trigger_times]) > 1: + logger.warning( + 'More than one trigger claims to have adjusted the pre_trigger_times. ' + 'Normally, only one trigger should set pre_trigger_times. ' + ) + + for pre_trigger_time in pre_trigger_times: if pre_trigger_time is not None: for channel in station.iter_channels(): channel.set_trace_start_time(channel.get_trace_start_time()-pre_trigger_time[channel.get_id()]) From 5e12b3ed8c12f5ffef98ccc5f224bbd13cfc7a50 Mon Sep 17 00:00:00 2001 From: Sjoerd Bouma Date: Sun, 17 Dec 2023 22:52:03 +0100 Subject: [PATCH 415/418] raise warning if triggerTimeAdjuster is called before resampling to detector sampling rate --- NuRadioReco/modules/triggerTimeAdjuster.py | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/NuRadioReco/modules/triggerTimeAdjuster.py b/NuRadioReco/modules/triggerTimeAdjuster.py index 29edb6a2c..a8e10c655 100644 --- a/NuRadioReco/modules/triggerTimeAdjuster.py +++ b/NuRadioReco/modules/triggerTimeAdjuster.py @@ -42,6 +42,7 @@ def begin(self, trigger_name=None, pre_trigger_time=55. * units.ns): """ self.__trigger_name = trigger_name self.__pre_trigger_time = pre_trigger_time + self.__sampling_rate_warning_issued = False @register_run() def run(self, event, station, detector, mode='sim_to_data'): @@ -95,10 +96,11 @@ def run(self, event, station, detector, mode='sim_to_data'): trace = channel.get_trace() trace_length = len(trace) + detector_sampling_rate = detector.get_sampling_frequency(station.get_id(), channel.get_id()) number_of_samples = int( 2 * np.ceil( # this should ensure that 1) the number of samples is even and 2) resampling to the detector sampling rate results in the correct number of samples (note that 2) can only be guaranteed if the detector sampling rate is lower than the current sampling rate) - detector.get_number_of_samples(station.get_id(), channel.get_id()) / 2 - * channel.get_sampling_rate() / detector.get_sampling_frequency(station.get_id(), channel.get_id()) + detector.get_number_of_samples(station.get_id(), channel.get_id()) / 2 + * channel.get_sampling_rate() / detector_sampling_rate )) if number_of_samples > trace.shape[0]: logger.error("Input has fewer samples than desired output. Channels has only {} samples but {} samples are requested.".format( @@ -106,6 +108,7 @@ def run(self, event, station, detector, mode='sim_to_data'): raise AttributeError else: sampling_rate = channel.get_sampling_rate() + self.__check_sampling_rates(detector_sampling_rate, sampling_rate) trigger_time_sample = int(np.round(trigger_time_channel * sampling_rate)) # logger.debug(f"channel {channel.get_id()}: trace_start_time = {channel.get_trace_start_time():.1f}ns, trigger time channel {trigger_time_channel/units.ns:.1f}ns, trigger time sample = {trigger_time_sample}") pre_trigger_time = self.__pre_trigger_time @@ -177,3 +180,14 @@ def run(self, event, station, detector, mode='sim_to_data'): channel.set_trace_start_time(channel.get_trace_start_time()-pre_trigger_time[channel.get_id()]) else: raise ValueError(f"Argument '{mode}' for mode is not valid. Options are 'sim_to_data' or 'data_to_sim'.") + + def __check_sampling_rates(self, detector_sampling_rate, channel_sampling_rate): + if not self.__sampling_rate_warning_issued: # we only issue this warning once + if not np.isclose(detector_sampling_rate, channel_sampling_rate): + logger.warning( + 'triggerTimeAdjuster was called, but the channel sampling rate ' + f'({channel_sampling_rate/units.GHz:3.f} GHz) is not equal to ' + f'the target detector sampling rate ({detector_sampling_rate/units.GHz:.3f} GHz). ' + 'Traces may not have the correct trace length after resampling.' + ) + self.__sampling_rate_warning_issued = True From c09394945cd6d57f5518dcdc37c32b74e34800b4 Mon Sep 17 00:00:00 2001 From: Sjoerd Bouma Date: Sun, 17 Dec 2023 22:52:51 +0100 Subject: [PATCH 416/418] enable triggerTimeAdjuster logger inheritance from NuRadioReco logger --- NuRadioReco/modules/triggerTimeAdjuster.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NuRadioReco/modules/triggerTimeAdjuster.py b/NuRadioReco/modules/triggerTimeAdjuster.py index a8e10c655..6560e6395 100644 --- a/NuRadioReco/modules/triggerTimeAdjuster.py +++ b/NuRadioReco/modules/triggerTimeAdjuster.py @@ -3,7 +3,7 @@ import logging from NuRadioReco.utilities import units -logger = logging.getLogger('triggerTimeAdjuster') +logger = logging.getLogger('NuRadioReco.triggerTimeAdjuster') class triggerTimeAdjuster: From 5e8e136a64c66a10ce7710ff159a407716521779 Mon Sep 17 00:00:00 2001 From: Sjoerd Bouma Date: Mon, 18 Dec 2023 07:41:26 +0100 Subject: [PATCH 417/418] fix typo in f-string --- NuRadioReco/modules/triggerTimeAdjuster.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NuRadioReco/modules/triggerTimeAdjuster.py b/NuRadioReco/modules/triggerTimeAdjuster.py index 6560e6395..57cb52399 100644 --- a/NuRadioReco/modules/triggerTimeAdjuster.py +++ b/NuRadioReco/modules/triggerTimeAdjuster.py @@ -186,7 +186,7 @@ def __check_sampling_rates(self, detector_sampling_rate, channel_sampling_rate): if not np.isclose(detector_sampling_rate, channel_sampling_rate): logger.warning( 'triggerTimeAdjuster was called, but the channel sampling rate ' - f'({channel_sampling_rate/units.GHz:3.f} GHz) is not equal to ' + f'({channel_sampling_rate/units.GHz:.3f} GHz) is not equal to ' f'the target detector sampling rate ({detector_sampling_rate/units.GHz:.3f} GHz). ' 'Traces may not have the correct trace length after resampling.' ) From a87f413411f0b35a42b00b746d19d434bb4b9787 Mon Sep 17 00:00:00 2001 From: Sjoerd Bouma Date: Fri, 22 Dec 2023 10:32:53 +0100 Subject: [PATCH 418/418] update version number for release 2.2.0 --- changelog.txt | 2 +- pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/changelog.txt b/changelog.txt index 578b65d31..92f29fa23 100644 --- a/changelog.txt +++ b/changelog.txt @@ -2,7 +2,7 @@ Changelog - to keep track of all relevant changes please update the categories "new features" and "bugfixes" before a pull request merge! -version 2.2.0-dev +version 2.2.0 new features: - expand values stored in SimplePhasedTrigger - added getting to query ARZ charge-excess profiles diff --git a/pyproject.toml b/pyproject.toml index b525276d5..b70d3feca 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api" [tool.poetry] name = "NuRadioMC" -version = "2.2.0-dev" +version = "2.2.0" authors = ["Christian Glaser et al."] homepage = "https://github.com/nu-radio/NuRadioMC" documentation = "https://nu-radio.github.io/NuRadioMC/main.html"