-
Thomas Jürges authoredThomas Jürges authored
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
holography_observation.py 7.13 KiB
import re
import os
import astropy.time as astrotime
from datetime import datetime
from .holography_measurementset import HolographyMeasurementSet
class HolographyObservation():
def __init__(self, path, sas_id, ms_for_a_given_beamlet_number, start_mjd_in_seconds,
end_mjd_in_seconds, sub_band, frequency, source_name):
"""
:param path:
:type path: str
:param sas_id:
:type sas_id: int
:param ms_for_a_given_beamlet_number:
:type ms_for_a_given_beamlet_number: dict[int, HolographyMeasurementSet]
:param start_mjd_in_seconds:
:type start_mjd_in_seconds: float
:param end_mjd_in_seconds:
:type end_mjd_in_seconds: float
:param sub_band:
:type sub_band: int
:param frequency:
:type frequency: float
:param source_name:
:type source_name: str
"""
self.path = path
self.sas_id = sas_id
self.ms_for_a_given_beamlet_number = ms_for_a_given_beamlet_number
self.start_datetime = HolographyObservation.__mjd_to_datetime(start_mjd_in_seconds)
self.end_datetime = HolographyObservation.__mjd_to_datetime(end_mjd_in_seconds)
self.start_mjd = start_mjd_in_seconds
self.end_mjd = end_mjd_in_seconds
self.sub_band = sub_band
self.frequency = frequency
self.source_name = source_name
@staticmethod
def __mjd_to_datetime(mjd_time_seconds):
"""
Convert the modified julian date in seconds in a datetime object
:param mjd_time_seconds: modified julian data in seconds
:return: the date time of the given julian date
:rtype: datetime
"""
hour_in_seconds = 60 * 60
day_in_seconds = hour_in_seconds * 24
return astrotime.Time(mjd_time_seconds / day_in_seconds, format='mjd',
scale='utc').to_datetime()
@staticmethod
def __compute_time_range_from_ms_list(ms_list):
observation_start, observation_end = ms_list[0].get_start_end_observation()
for ms in ms_list:
ms_start_time, ms_end_time = ms.get_start_end_observation()
if observation_start > ms_start_time:
observation_start = ms_start_time
if observation_end < ms_end_time:
observation_end = ms_end_time
return observation_start, observation_end
@staticmethod
def extract_unique_source_names_from_ms_list(ms_list):
"""
Returns a set of unique source names given a list of measurement sets
:param ms_list: a list of measurement set where to extract the reference frequencies
:type ms_list: list[HolographyMeasurementSet]
:return: a set of frequencies
:rtype: set[str]
"""
return {ms.get_source_name() for ms in ms_list}
@staticmethod
def extract_unique_subband_from_ms_list(ms_list):
"""
Returns a set of unique rcu modes given a list of measurement sets
:param ms_list: a list of measurement set where to extract the reference frequencies
:type ms_list: list[HolographyMeasurementSet]
:return: a set of rcu modes
:rtype: set[int]
"""
return {ms.get_subband() for ms in ms_list}
@staticmethod
def list_observations_in_path(path):
"""
List all the observations in the given path and return a list of HolographyObservation
:param path: path to the directory where the holography observation is stored\
:type path: str
:return: a list of HolographyObservation
:rtype: list[HolographyObservation]
"""
ms_dir_name_pattern = 'L(?P<sas_id>\d{6})'
ms_dirs_path_pattern = '^' + os.path.join(path, ms_dir_name_pattern, 'uv$')
observations_list = []
for root, dirnames, filenames in os.walk(path):
match = re.match(ms_dirs_path_pattern, root)
if match:
sas_id = match.group('sas_id')
ms_indexed_per_beamlet_number = HolographyObservation. \
create_ms_dict_from_ms_name_list_and_path(dirnames, root)
start_mjd_in_seconds, end_mjd_in_seconds = HolographyObservation.\
__compute_time_range_from_ms_list(
ms_indexed_per_beamlet_number.values())
unique_frequencies = HolographyObservation. \
extract_unique_reference_frequencies_from_ms_list(
ms_indexed_per_beamlet_number.values())
if len(unique_frequencies) > 1:
raise ValueError(
'Multiple reference frequencies per observation are not supported')
else:
frequency = unique_frequencies.pop()
unique_source_names = HolographyObservation.\
extract_unique_source_names_from_ms_list(ms_indexed_per_beamlet_number.values())
if len(unique_source_names) > 1:
raise ValueError(
'Multiple source target per observation are not supported'
)
else:
source_name = unique_source_names.pop()
unique_subband = HolographyObservation.\
extract_unique_subband_from_ms_list(ms_indexed_per_beamlet_number.values())
if len(unique_subband) > 1:
raise ValueError(
'Multiple subband per observation are not supported'
)
else:
sub_band = unique_subband.pop()
observations_list.append(
HolographyObservation(path, sas_id, ms_indexed_per_beamlet_number,
start_mjd_in_seconds, end_mjd_in_seconds, sub_band,
frequency,
source_name))
return observations_list
@staticmethod
def extract_unique_reference_frequencies_from_ms_list(ms_list):
"""
Returns a set of reference frequencies given a list of measurement setss
:param ms_list: a list of measurement set where to extract the reference frequencies
:type ms_list: list[HolographyMeasurementSet]
:return: returns a set of frequencies
:rtype: set[float]
"""
return {ms.get_frequency() for ms in ms_list}
@staticmethod
def create_ms_dict_from_ms_name_list_and_path(list_of_ms_names, path):
"""
Creates a dict measurement sets indexed by beamlet id
:param list_of_ms_names: a list of the ms to process
:param path: a path were the ms are stored
:return: a dict containing the map of the ms indexed by their beamlet number
ex. { 0 : ms_beam0 ....}
:rtype: dict[int, HolographyMeasurementSet]
"""
filtered_list_of_ms_names = HolographyMeasurementSet.filter_valid_ms_names(list_of_ms_names)
ms_list = [HolographyMeasurementSet(ms_name, path) for ms_name in filtered_list_of_ms_names]
beamlet_ms_map = {ms.beamlet:ms for ms in ms_list} #
return beamlet_ms_map