Source code for NuRadioReco.modules.ARA.hardwareResponseIncorporator

from NuRadioReco.detector.ARA import analog_components
from NuRadioReco.modules.base.module import register_run
from NuRadioReco.modules.channelAddCableDelay import add_cable_delay

import numpy as np
import time
import logging

logger = logging.getLogger("NuRadioReco.ARA.hardwareResponseIncorporator")


[docs] class hardwareResponseIncorporator: """ Incorporates the gain and phase induced by the ARA hardware. """ def __init__(self): self.__debug = False self.__time_delays = {} self.__t = 0 self.begin()
[docs] def begin(self, debug=False): self.__debug = debug
[docs] def get_filter(self, frequencies, station_id=None, channel_id=None, det=None, sim_to_data=False): """ Helper function to return the filter that the module applies. Loads entire system response from interpolating data of ARA_Electronics_TotalGain_TwoFilters.txt. Parameters ---------- frequencies: array of floats the frequency array for which the filter should be returned station_id: int (default None) the station id channel_id: int (default None) the channel id det: detector instance (default None) the detector sim_to_data: bool (default False) If False, deconvolve the hardware response. If True, convolve with the hardware response Returns ------- array of complex floats the complex filter amplitudes """ system_response = analog_components.get_system_response(frequencies) system_complex_response = system_response['gain'] * system_response['phase'] if sim_to_data: return system_complex_response else: filt = np.zeros_like(system_complex_response) mask = np.abs(system_complex_response) > 0 filt[mask] = 1. / system_complex_response[mask] return filt
[docs] @register_run() def run(self, evt, station, det, sim_to_data=False): """ Switch sim_to_data to go from simulation to data or otherwise. """ t = time.time() channels = station.iter_channels() for channel in channels: frequencies = channel.get_frequencies() trace_fft = channel.get_frequency_spectrum() filt = self.get_filter(frequencies, station.get_id(), channel.get_id(), det, sim_to_data=sim_to_data) trace_after_system_fft = trace_fft * filt if sim_to_data: # zero first bins to avoid DC offset trace_after_system_fft[0] = 0 channel.set_frequency_spectrum(trace_after_system_fft, channel.get_sampling_rate()) if not sim_to_data: # Subtraces the cable delay. For `sim_to_data=True`, the cable delay is added # in the efieldToVoltageConverter or with the channelCableDelayAdder # (if efieldToVoltageConverterPerEfield was used). add_cable_delay(station, det, sim_to_data=False, logger=self.logger) self.__t += time.time() - t
[docs] def end(self): from datetime import timedelta dt = timedelta(seconds=self.__t) logger.info("total time used by this module is {}".format(dt)) return dt