Commit 97e65ce1 authored by Alessio Berti's avatar Alessio Berti
Browse files

Merge branch 'dev-dipierro-adapting-to-pyIRF' into 'master'

Add general run-wise MC info

See merge request !12
parents 5c184a38 0af1b2e9
Pipeline #89394 failed with stage
in 18 minutes and 26 seconds
...@@ -85,8 +85,12 @@ Monitoring data are saved in `run['data'].monitoring_data` and can also accessed ...@@ -85,8 +85,12 @@ Monitoring data are saved in `run['data'].monitoring_data` and can also accessed
Dead pixel and pedestal information are read by `magic-cta-pipe` `MAGIC_Badpixels.py` class. Dead pixel and pedestal information are read by `magic-cta-pipe` `MAGIC_Badpixels.py` class.
##### MC Header data
Some general information about the simulated data, useful for IRF calculation, are read from the root files and stored in data.mcheader container.
#### Changelog #### Changelog
- v0.1: Initial version - v0.1: Initial version
- v0.2.0: Unification of data and MC reading - v0.2.0: Unification of data and MC reading
- v0.2.1: Monitoring data (Dead pixel and pedestal information) - v0.2.1: Monitoring data (Dead pixel and pedestal information)
\ No newline at end of file - v0.2.2: Added MC Header info
\ No newline at end of file
...@@ -148,7 +148,7 @@ class MAGICEventSource(EventSource): ...@@ -148,7 +148,7 @@ class MAGICEventSource(EventSource):
for file_path in file_list: for file_path in file_list:
try: try:
import uproot import uproot3 as uproot
try: try:
with uproot.open(file_path) as input_data: with uproot.open(file_path) as input_data:
...@@ -289,7 +289,7 @@ class MAGICEventSource(EventSource): ...@@ -289,7 +289,7 @@ class MAGICEventSource(EventSource):
# Setting the new active run (class MarsRun object) # Setting the new active run (class MarsRun object)
self.current_run = self._set_active_run(run_number) self.current_run = self._set_active_run(run_number)
# Set monitoring data: # Set monitoring data:
if not self.is_mc: if not self.is_mc:
...@@ -333,6 +333,19 @@ class MAGICEventSource(EventSource): ...@@ -333,6 +333,19 @@ class MAGICEventSource(EventSource):
data.mon.tels_with_data = {1, 2} data.mon.tels_with_data = {1, 2}
data.mon.tel[tel_i + 1] = monitoring_camera data.mon.tel[tel_i + 1] = monitoring_camera
else:
assert self.current_run['data'].mcheader_data['M1'] == self.current_run['data'].mcheader_data['M2'], "Simulation configurations are different for M1 and M2 !!!"
data.mcheader.num_showers = self.current_run['data'].mcheader_data['M1']['sim_nevents']
data.mcheader.energy_range_min = (self.current_run['data'].mcheader_data['M1']['sim_emin']).to(u.TeV) # GeV->TeV
data.mcheader.energy_range_max = (self.current_run['data'].mcheader_data['M1']['sim_emax']).to(u.TeV) # GeV->TeV
data.mcheader.spectral_index = self.current_run['data'].mcheader_data['M1']['sim_eslope']
data.mcheader.max_scatter_range = (self.current_run['data'].mcheader_data['M1']['sim_max_impact']).to(u.m) # cm->m
data.mcheader.max_viewcone_radius = (self.current_run['data'].mcheader_data['M1']['sim_conesemiangle']).to(u.deg)# deg->deg
if data.mcheader.max_viewcone_radius != 0.:
data.mcheader.diffuse = True
else:
data.mcheader.diffuse = False
# Loop over the events # Loop over the events
for event_i in range(self.current_run['data'].n_stereo_events): for event_i in range(self.current_run['data'].n_stereo_events):
...@@ -475,7 +488,7 @@ class MAGICEventSource(EventSource): ...@@ -475,7 +488,7 @@ class MAGICEventSource(EventSource):
tel_i + 1)]['PedestalMJD'], scale='utc', format='mjd') tel_i + 1)]['PedestalMJD'], scale='utc', format='mjd')
pedestal_info.sample_time = Time( pedestal_info.sample_time = Time(
time_tmp, format='unix', scale='utc', precision=9) time_tmp, format='unix', scale='utc', precision=9)
pedestal_info.n_events = 500 # hardcoded number of pedestal events averaged over pedestal_info.n_events = 500 # hardcoded number of pedestal events averaged over
pedestal_info.charge_mean = [] pedestal_info.charge_mean = []
pedestal_info.charge_mean.append( pedestal_info.charge_mean.append(
monitoring_data['M{:d}'.format(tel_i + 1)]['PedestalFundamental']['Mean']) monitoring_data['M{:d}'.format(tel_i + 1)]['PedestalFundamental']['Mean'])
...@@ -504,6 +517,16 @@ class MAGICEventSource(EventSource): ...@@ -504,6 +517,16 @@ class MAGICEventSource(EventSource):
data.mon.tels_with_data = tels_with_data data.mon.tels_with_data = tels_with_data
data.mon.tel[tel_i + 1] = monitoring_camera data.mon.tel[tel_i + 1] = monitoring_camera
#fdp (mono version not fully tested)
else:
data.mcheader.num_showers = self.current_run['data'].mcheader_data[telescope]['sim_nevents'] # total, including reuse
data.mcheader.energy_range_min = (self.current_run['data'].mcheader_data[telescope]['sim_emin']).to(u.TeV) # GeV->TeV
data.mcheader.energy_range_max = (self.current_run['data'].mcheader_data[telescope]['sim_emax']).to(u.TeV) # GeV->TeV
data.mcheader.spectral_index = self.current_run['data'].mcheader_data[telescope]['sim_eslope']
data.mcheader.max_scatter_range = (self.current_run['data'].mcheader_data[telescope]['sim_max_impact']).to(u.m) # cm->m
data.mcheader.max_viewcone_radius = (self.current_run['data'].mcheader_data[telescope]['sim_conesemiangle']).to(u.deg) # deg->deg
if telescope == 'M1': if telescope == 'M1':
n_events = self.current_run['data'].n_mono_events_m1 n_events = self.current_run['data'].n_mono_events_m1
else: else:
...@@ -636,7 +659,7 @@ class MAGICEventSource(EventSource): ...@@ -636,7 +659,7 @@ class MAGICEventSource(EventSource):
tel_i + 1)]['PedestalMJD'], scale='utc', format='mjd') tel_i + 1)]['PedestalMJD'], scale='utc', format='mjd')
pedestal_info.sample_time = Time( pedestal_info.sample_time = Time(
time_tmp, format='unix', scale='utc', precision=9) time_tmp, format='unix', scale='utc', precision=9)
pedestal_info.n_events = 500 # hardcoded number of pedestal events averaged over pedestal_info.n_events = 500 # hardcoded number of pedestal events averaged over
pedestal_info.charge_mean = [] pedestal_info.charge_mean = []
pedestal_info.charge_mean.append( pedestal_info.charge_mean.append(
monitoring_data['M{:d}'.format(tel_i + 1)]['PedestalFundamental']['Mean']) monitoring_data['M{:d}'.format(tel_i + 1)]['PedestalFundamental']['Mean'])
...@@ -807,6 +830,12 @@ class MarsRun: ...@@ -807,6 +830,12 @@ class MarsRun:
self.monitoring_data['M1'] = m1_data[1] self.monitoring_data['M1'] = m1_data[1]
self.monitoring_data['M2'] = m2_data[1] self.monitoring_data['M2'] = m2_data[1]
# Getting the run-wise MC header data
if self.is_mc:
self.mcheader_data = dict()
self.mcheader_data['M1'] = m1_data[2]
self.mcheader_data['M2'] = m2_data[2]
# Detecting pedestal events # Detecting pedestal events
self.pedestal_ids = self._find_pedestal_events() self.pedestal_ids = self._find_pedestal_events()
# Detecting stereo events # Detecting stereo events
...@@ -863,7 +892,7 @@ class MarsRun: ...@@ -863,7 +892,7 @@ class MarsRun:
""" """
try: try:
import uproot import uproot3 as uproot
except ImportError: except ImportError:
msg = "The `uproot` python module is required to access the MAGIC data" msg = "The `uproot` python module is required to access the MAGIC data"
raise ImportError(msg) raise ImportError(msg)
...@@ -897,6 +926,9 @@ class MarsRun: ...@@ -897,6 +926,9 @@ class MarsRun:
monitoring_data['PedestalFromExtractorRndm']['Mean'] = [] monitoring_data['PedestalFromExtractorRndm']['Mean'] = []
monitoring_data['PedestalFromExtractorRndm']['Rms'] = [] monitoring_data['PedestalFromExtractorRndm']['Rms'] = []
#MC Header information, dictionary always created, but filled only in case of MC run
mcheader_data = dict()
event_data['file_edges'] = [0] event_data['file_edges'] = [0]
degrees_per_hour = 15.0 degrees_per_hour = 15.0
...@@ -959,7 +991,18 @@ class MarsRun: ...@@ -959,7 +991,18 @@ class MarsRun:
'MMcEvt.fPartId', 'MMcEvt.fPartId',
'MMcEvt.fZFirstInteraction', 'MMcEvt.fZFirstInteraction',
'MMcEvt.fCoreX', 'MMcEvt.fCoreX',
'MMcEvt.fCoreY', 'MMcEvt.fCoreY'
]
mcheader_list = [
#'MMcRunHeader.fNumSimulatedShowers',
'MMcRunHeader.fNumEvents',
'MMcCorsikaRunHeader.fELowLim', #GeV
'MMcCorsikaRunHeader.fEUppLim', #GeV
'MMcCorsikaRunHeader.fSlopeSpec',
'MMcRunHeader.fImpactMax', #cm
#'MMcCorsikaRunHeader.fViewconeAngles',
'MMcRunHeader.fRandomPointingConeSemiAngle' # deg
] ]
# Metadata, currently not strictly required # Metadata, currently not strictly required
...@@ -988,6 +1031,15 @@ class MarsRun: ...@@ -988,6 +1031,15 @@ class MarsRun:
mars_meta['is_simulation'] = is_mc mars_meta['is_simulation'] = is_mc
if is_mc:
mc_header_info = input_file['RunHeaders'].arrays(mcheader_list)
mcheader_data['sim_nevents']=int(mc_header_info[b'MMcRunHeader.fNumEvents'][0]) #std: 5000
mcheader_data['sim_emin']=mc_header_info[b'MMcCorsikaRunHeader.fELowLim'][0]*u.GeV
mcheader_data['sim_emax']=mc_header_info[b'MMcCorsikaRunHeader.fEUppLim'][0]*u.GeV
mcheader_data['sim_eslope']=mc_header_info[b'MMcCorsikaRunHeader.fSlopeSpec'][0] #std: -1.6
mcheader_data['sim_max_impact']=mc_header_info[b'MMcRunHeader.fImpactMax'][0]*u.cm
mcheader_data['sim_conesemiangle']=mc_header_info[b'MMcRunHeader.fRandomPointingConeSemiAngle'][0]*u.deg #std: 2.5 deg, also corsika viewcone is defined by "half of the cone angle".
# Reading event timing information: # Reading event timing information:
if not is_mc: if not is_mc:
event_times = input_file['Events'].arrays(time_array_list) event_times = input_file['Events'].arrays(time_array_list)
...@@ -1223,8 +1275,9 @@ class MarsRun: ...@@ -1223,8 +1275,9 @@ class MarsRun:
monitoring_data['PedestalFromExtractor'][quantity]) monitoring_data['PedestalFromExtractor'][quantity])
monitoring_data['PedestalFromExtractorRndm'][quantity] = np.array( monitoring_data['PedestalFromExtractorRndm'][quantity] = np.array(
monitoring_data['PedestalFromExtractorRndm'][quantity]) monitoring_data['PedestalFromExtractorRndm'][quantity])
return event_data, monitoring_data return event_data, monitoring_data, mcheader_data
def _find_pedestal_events(self): def _find_pedestal_events(self):
""" """
......
...@@ -10,20 +10,20 @@ with open(path.join(this_directory, 'README.md'), encoding='utf-8') as f: ...@@ -10,20 +10,20 @@ with open(path.join(this_directory, 'README.md'), encoding='utf-8') as f:
setup( setup(
name='ctapipe_io_magic', name='ctapipe_io_magic',
packages=find_packages(), packages=find_packages(),
version='0.2.1', version='0.2.2',
description='ctapipe plugin for reading of the calibrated MAGIC files', description='ctapipe plugin for reading of the calibrated MAGIC files',
long_description=long_description, long_description=long_description,
long_description_content_type='text/markdown', long_description_content_type='text/markdown',
install_requires=[ install_requires=[
'ctapipe', 'ctapipe',
'astropy', 'astropy',
'uproot', 'uproot3',
'numpy', 'numpy',
'scipy' 'scipy'
], ],
tests_require=['pytest'], tests_require=['pytest'],
setup_requires=['pytest_runner'], setup_requires=['pytest_runner'],
author='Ievgen Vovk', author='Ievgen Vovk et al.',
author_email='Ievgen.Vovk@mpp.mpg.de', author_email='Ievgen.Vovk@mpp.mpg.de',
license='MIT', license='MIT',
) )
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment