Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change station time #520

Merged
merged 7 commits into from
Apr 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 59 additions & 23 deletions NuRadioReco/framework/base_station.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,22 +75,57 @@ 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):
if time is None:
self._station_time = None
return
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.

Parameters
----------

time: astropy.time.Time or datetime.datetime or float
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):
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.Time):
self._station_time = time
elif time is None:
self._station_time = None
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
self._station_time = astropy.time.Time(time, format=format)

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
"""
if self._station_time is None:
return None

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
Expand Down Expand Up @@ -235,16 +270,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,
Expand All @@ -254,15 +286,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']:
Expand All @@ -273,8 +306,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']
Expand All @@ -285,4 +320,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']
31 changes: 19 additions & 12 deletions NuRadioReco/modules/io/NuRadioRecoio.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
8 changes: 5 additions & 3 deletions NuRadioReco/modules/io/eventWriter.py
Original file line number Diff line number Diff line change
Expand Up @@ -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['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

Expand Down