Exemplo n.º 1
0
def process_mc(simtelfile, dl2_file, mc_type):
    """
    Process the MC simulated and reconstructed to extract the relevant
    parameters to compute the sensitivity

    Paramenters
    ---------
    simtel: simtelarray file
    dl2_file: `pandas.DataFrame` dl2 parameters
    mc_type: 'string' type of particle

    Returns
    ---------
    gammaness: `numpy.ndarray`
    angdist2:  `numpy.ndarray` angular distance squared
    e_reco:    `numpy.ndarray` reconstructed energies
    n_reco:    `int` number of reconstructed events
    mc_par:    `dict` with simulated parameters

    """
    source = SimTelFile(simtelfile)
    sim_par = read_sim_par(source)
    events = pd.read_hdf(dl2_file)

    e_reco = 10**events.mc_energy.to_numpy() * u.GeV
    gammaness = events.gammaness

    #Get source position in radians

    focal_length = source.telescope_descriptions[1]['camera_settings']['focal_length'] * u.m


    # If the particle is a gamma ray, it returns the squared angular distance
    # from the reconstructed gamma-ray position and the simulated incoming position
    if mc_type=='gamma':
        events = events[events.mc_type==0]
        alt2 = events.mc_alt
        az2 = np.arctan(np.tan(events.mc_az))

    # If the particle is not a gamma-ray (diffuse protons/electrons), it returns
    # the squared angular distance of the reconstructed position w.r.t. the
    # center of the camera
    else:
        events = events[events.mc_type!=0]
        alt2 = events.mc_alt_tel
        az2 = np.arctan(np.tan(events.mc_az_tel))

    src_pos_reco = reco_source_position_sky(events.x.values * u.m,
                                            events.y.values * u.m,
                                            events.disp_dx_rec.values * u.m,
                                            events.disp_dy_rec.values * u.m,
                                            focal_length,
                                            events.mc_alt_tel.values * u.rad,
                                            events.mc_az_tel.values * u.rad)

    alt1 = src_pos_reco.alt.rad
    az1 = np.arctan(np.tan(src_pos_reco.az.rad))

    angdist2 = (angular_separation(az1, alt1, az2, alt2).to_numpy() * u.rad)**2
    return gammaness, angdist2.to(u.deg**2), e_reco, sim_par
Exemplo n.º 2
0
    def __init__(self, config=None, tool=None, **kwargs):
        super().__init__(config=config, tool=tool, **kwargs)
        self.metadata['is_simulation'] = True
        self.file_ = SimTelFile(self.input_url)

        self._subarray_info = self.prepare_subarray_info(
            self.file_.telescope_descriptions, self.file_.header)
Exemplo n.º 3
0
def process_mc(simtelfile, dl2_file):
    """
    Process the MC simulated and reconstructed to extract the relevant
    parameters to compute the sensitivity

    Paramenters
    ---------
    simtel: simtelarray file
    dl2_file: `pandas.DataFrame` dl2 parameters

    Returns
    ---------
    gammaness: `numpy.ndarray` 
    theta2:    `numpy.ndarray` 
    e_reco:    `numpy.ndarray` reconstructed energies
    n_reco:    `int` number of reconstructed events
    mc_par:    `dict` with simulated parameters

    """
    source = SimTelFile(simtelfile)
    sim_par = read_sim_par(source)
    events = pd.read_hdf(dl2_file)

    e_reco = 10**events.mc_energy * u.GeV
    # n_reco = e_reco.shape[0]
    gammaness = events.gammaness
    theta2 = (events.src_x - events.src_x_rec)**2 + \
        (events.src_y - events.src_y_rec)**2 * u.deg**2

    return gammaness, theta2, e_reco, sim_par
Exemplo n.º 4
0
def get_spectral_w_pars(filename):
    """
    Return parameters required to calculate spectral weighting of an event

    Parameters
    ----------
    filename: string, simtelarray file

    Returns
    -------
    array of parameters
    """

    particle = utils.guess_type(filename)

    source = SimTelFile(filename)

    emin, emax = source.mc_run_headers[0]['E_range'] * 1e3  #GeV
    spectral_index = source.mc_run_headers[0]['spectral_index']
    num_showers = source.mc_run_headers[0]['num_showers']
    num_use = source.mc_run_headers[0]['num_use']
    Simulated_Events = num_showers * num_use
    Max_impact = source.mc_run_headers[0]['core_range'][1] * 1e2  #cm
    Area_sim = np.pi * math.pow(Max_impact, 2)
    cone = source.mc_run_headers[0]['viewcone'][1]

    cone = cone * np.pi / 180
    if (cone == 0):
        Omega = 1
    else:
        Omega = 2 * np.pi * (1 - np.cos(cone))

    if particle == 'proton':
        K_w = 9.6e-11  # GeV^-1 cm^-2 s^-1
        index_w = -2.7
        E0 = 1000.  # GeV
    if particle == 'gamma':
        K_w = 2.83e-11  # GeV^-1 cm^-2 s^-1
        index_w = -2.62
        E0 = 1000.  # GeV

    K = Simulated_Events * (1 + spectral_index) / (emax**(1 + spectral_index) -
                                                   emin**(1 + spectral_index))
    Int_e1_e2 = K * E0**spectral_index
    N_ = Int_e1_e2 * (emax**(index_w + 1) -
                      emin**(index_w + 1)) / (E0**index_w) / (index_w + 1)
    R = K_w * Area_sim * Omega * (emax**(index_w + 1) - emin**(index_w + 1)
                                  ) / (E0**index_w) / (index_w + 1)

    return E0, spectral_index, index_w, R, N_
Exemplo n.º 5
0
    def __init__(self,
                 input_url,
                 config=None,
                 parent=None,
                 gain_selector=None,
                 **kwargs):
        """
        EventSource for simtelarray files using the pyeventio library.

        Parameters
        ----------
        config : traitlets.loader.Config
            Configuration specified by config file or cmdline arguments.
            Used to set traitlet values.
            Set to None if no configuration to pass.
        tool : ctapipe.core.Tool
            Tool executable that is calling this component.
            Passes the correct logger to the component.
            Set to None if no Tool to pass.
        gain_selector : ctapipe.calib.camera.gainselection.GainSelector
            The GainSelector to use. If None, then ThresholdGainSelector will be used.
        kwargs
        """
        super().__init__(input_url=input_url,
                         config=config,
                         parent=parent,
                         **kwargs)
        self._camera_cache = {}

        self.file_ = SimTelFile(
            self.input_url.expanduser(),
            allowed_telescopes=self.allowed_tels,
            skip_calibration=self.skip_calibration_events,
            zcat=not self.back_seekable,
        )
        if self.back_seekable and self.is_stream:
            raise IOError(
                "back seekable was required but not possible for inputfile")

        self._subarray_info = self.prepare_subarray_info(
            self.file_.telescope_descriptions, self.file_.header)
        self._mc_header = self._parse_mc_header()
        self.start_pos = self.file_.tell()

        # Waveforms from simtelarray have both gain channels
        # Gain selection is performed by this EventSource to produce R1 waveforms
        if gain_selector is None:
            gain_selector = ThresholdGainSelector(parent=self)

        self.gain_selector = gain_selector
Exemplo n.º 6
0
    def __init__(self, config=None, parent=None, **kwargs):
        super().__init__(config=config, parent=parent, **kwargs)
        self.metadata['is_simulation'] = True

        # traitlets creates an empty set as default,
        # which ctapipe treats as no restriction on the telescopes
        # but eventio treats an emty set as "no telescopes allowed"
        # so we explicitly pass None in that case
        self.file_ = SimTelFile(self.input_url,
                                allowed_telescopes=self.allowed_tels
                                if self.allowed_tels else None,
                                skip_calibration=self.skip_calibration_events)

        self._subarray_info = self.prepare_subarray_info(
            self.file_.telescope_descriptions, self.file_.header)
        self.start_pos = self.file_.tell()
Exemplo n.º 7
0
    def __init__(self, config=None, parent=None, gain_selector=None, **kwargs):
        """
        EventSource for simtelarray files using the pyeventio library.

        Parameters
        ----------
        config : traitlets.loader.Config
            Configuration specified by config file or cmdline arguments.
            Used to set traitlet values.
            Set to None if no configuration to pass.
        tool : ctapipe.core.Tool
            Tool executable that is calling this component.
            Passes the correct logger to the component.
            Set to None if no Tool to pass.
        gain_selector : ctapipe.calib.camera.gainselection.GainSelector
            The GainSelector to use. If None, then ThresholdGainSelector will be used.
        kwargs
        """
        super().__init__(config=config, parent=parent, **kwargs)
        self.metadata['is_simulation'] = True
        self._camera_cache = {}

        # traitlets creates an empty set as default,
        # which ctapipe treats as no restriction on the telescopes
        # but eventio treats an emty set as "no telescopes allowed"
        # so we explicitly pass None in that case
        self.file_ = SimTelFile(
            Path(self.input_url).expanduser(),
            allowed_telescopes=set(self.allowed_tels)
            if self.allowed_tels else None,
            skip_calibration=self.skip_calibration_events,
            zcat=not self.back_seekable,
        )
        if self.back_seekable and self.is_stream:
            raise IOError(
                'back seekable was required but not possible for inputfile')

        self._subarray_info = self.prepare_subarray_info(
            self.file_.telescope_descriptions, self.file_.header)
        self.start_pos = self.file_.tell()

        # Waveforms from simtelarray have both gain channels
        # Gain selection is performed by this EventSource to produce R1 waveforms
        if gain_selector is None:
            gain_selector = ThresholdGainSelector(parent=self)
        self.gain_selector = gain_selector
Exemplo n.º 8
0
    def __init__(self, config=None, parent=None, **kwargs):
        super().__init__(config=config, parent=parent, **kwargs)
        self.metadata['is_simulation'] = True
        self._camera_cache = {}

        # traitlets creates an empty set as default,
        # which ctapipe treats as no restriction on the telescopes
        # but eventio treats an emty set as "no telescopes allowed"
        # so we explicitly pass None in that case
        self.file_ = SimTelFile(
            self.input_url,
            allowed_telescopes=set(self.allowed_tels) if self.allowed_tels else None,
            skip_calibration=self.skip_calibration_events,
            zcat=not self.back_seekable,
        )
        if self.back_seekable and self.is_stream:
            raise IOError('back seekable was required but not possible for inputfile')

        self._subarray_info = self.prepare_subarray_info(
            self.file_.telescope_descriptions,
            self.file_.header
        )
        self.start_pos = self.file_.tell()
Exemplo n.º 9
0
import time
from pprint import pprint
from eventio.simtel.simtelfile import SimTelFile
from argparse import ArgumentParser

parser = ArgumentParser()
parser.add_argument('inputfile')
parser.add_argument('-p', '--print', action='store_true')

args = parser.parse_args()

start_time = time.time()

with SimTelFile(args.inputfile) as f:
    for i, event in enumerate(f):
        print('Event count: {: 04d}, E = {:8.3f} Tev, #Telescopes={: 3d}'.format(
            i, event['mc_shower']['energy'], len(event['telescope_events'])
        ))
        if args.print:
            pprint(event)

print('  Duration:', time.time() - start_time)
Exemplo n.º 10
0
def simtel_event_source(url,
                        camera=None,
                        max_events=None,
                        allowed_tels=None,
                        requested_event=None,
                        use_event_id=False,
                        event_id=None,
                        disable_bar=False):
    """A generator that streams data from an EventIO/HESSIO MC data file
    (e.g. a standard CTA data file.)

    Parameters
    ----------
    url : str
        path to file to open
    max_events : int, optional
        maximum number of events to read
    allowed_tels : list[int]
        select only a subset of telescope, if None, all are read. This can
        be used for example emulate the final CTA data format, where there
        would be 1 telescope per file (whereas in current monte-carlo,
        they are all interleaved into one file)
    requested_event : int
        Seek to a paricular event index
    use_event_id : bool
        If True ,'requested_event' now seeks for a particular event id instead
        of index
    disable_bar : Unused, for compatibility with other readers
    """

    if event_id is not None:
        raise ValueError('Event id feature not implemented yet! \n'
                         'Use event_id=None')
    if not SimTelEventSource.is_compatible(url):
        raise ValueError(url, 'is not a valid simtel file')
    data = DataContainer()
    data.meta['origin'] = "hessio"

    # some hessio_event_source specific parameters
    data.meta['input'] = url
    # data.meta['max_events'] = max_events

    with SimTelFile(url) as file:
        telescope_descriptions = file.telescope_descriptions
        subarray_info = SimTelEventSource.prepare_subarray_info(
            telescope_descriptions, file.header)
        counter = 0
        for array_event in tqdm(file, disable=disable_bar):
            # Seek to requested event
            if requested_event is not None:
                current = counter
                if use_event_id:
                    current = event_id
                if not current == requested_event:
                    counter += 1
                    continue
            run_id = file.header['run']
            event_id = array_event['event_id']
            tels_with_data = set(array_event['telescope_events'].keys())
            data.inst.subarray = subarray_info
            data.r0.run_id = run_id
            data.r0.event_id = event_id
            data.r0.tels_with_data = tels_with_data
            data.r1.run_id = run_id
            data.r1.event_id = event_id
            data.r1.tels_with_data = tels_with_data
            data.dl0.run_id = run_id
            data.dl0.event_id = event_id
            data.dl0.tels_with_data = tels_with_data
            # handle telescope filtering by taking the intersection of
            # tels_with_data and allowed_tels
            if allowed_tels is not None:
                selected = data.r0.tels_with_data & allowed_tels
                if len(selected) == 0:
                    continue  # skip event
                data.r0.tels_with_data = selected
                data.r1.tels_with_data = selected
                data.dl0.tels_with_data = selected
            trigger_information = array_event['trigger_information']
            mc_event = array_event['mc_event']
            mc_shower = array_event['mc_shower']

            data.trig.tels_with_trigger = \
                trigger_information['triggered_telescopes']
            time_s, time_ns = trigger_information['gps_time']
            data.trig.gps_time = Time(time_s * u.s,
                                      time_ns * u.ns,
                                      format='unix',
                                      scale='utc')
            data.mc.energy = mc_shower['energy'] * u.TeV
            data.mc.alt = Angle(mc_shower['altitude'], u.rad)
            data.mc.az = Angle(mc_shower['azimuth'], u.rad)
            data.mc.core_x = mc_event['xcore'] * u.m
            data.mc.core_y = mc_event['ycore'] * u.m
            first_int = mc_shower['h_first_int'] * u.m
            data.mc.h_first_int = first_int
            data.mc.x_max = mc_shower['xmax'] * u.g / (u.cm**2)
            data.mc.shower_primary_id = mc_shower['primary_id']

            # mc run header data
            data.mcheader.run_array_direction = Angle(
                file.header['direction'] * u.rad)
            mc_run_head = file.mc_run_headers[-1]
            data.mcheader.corsika_version = mc_run_head['shower_prog_vers']
            data.mcheader.simtel_version = mc_run_head['detector_prog_vers']
            data.mcheader.energy_range_min = mc_run_head['E_range'][0] * u.TeV
            data.mcheader.energy_range_max = mc_run_head['E_range'][1] * u.TeV
            data.mcheader.prod_site_B_total = mc_run_head['B_total'] * u.uT
            data.mcheader.prod_site_B_declination = Angle(
                mc_run_head['B_declination'] * u.rad)
            data.mcheader.prod_site_B_inclination = Angle(
                mc_run_head['B_inclination'] * u.rad)
            data.mcheader.prod_site_alt = mc_run_head['obsheight'] * u.m
            data.mcheader.spectral_index = mc_run_head['spectral_index']

            # this should be done in a nicer way to not re-allocate the
            # data each time (right now it's just deleted and garbage
            # collected)
            data.r0.tel.clear()
            data.r1.tel.clear()
            data.dl0.tel.clear()
            data.dl1.tel.clear()
            data.mc.tel.clear()  # clear the previous telescopes

            telescope_events = array_event['telescope_events']
            tracking_positions = array_event['tracking_positions']
            for tel_id, telescope_event in telescope_events.items():
                telescope_description = telescope_descriptions[tel_id]
                camera_monitorings = array_event['camera_monitorings'][tel_id]
                pedestal = camera_monitorings['pedestal']
                laser_calib = array_event['laser_calibrations'][tel_id]
                data.mc.tel[tel_id].dc_to_pe = laser_calib['calib']
                data.mc.tel[tel_id].pedestal = pedestal
                adc_samples = telescope_event.get('adc_samples')
                n_pixel = adc_samples.shape[-2]
                if adc_samples is None:
                    adc_samples = telescope_event['adc_sums'][:, :, np.newaxis]
                data.r0.tel[tel_id].adc_samples = adc_samples
                data.r0.tel[tel_id].num_samples = adc_samples.shape[-1]
                # We should not calculate stuff in an event source
                # if this is not needed, we calculate it for nothing
                data.r0.tel[tel_id].adc_sums = adc_samples.sum(axis=-1)
                baseline = pedestal / adc_samples.shape[1]
                data.r0.tel[tel_id].digicam_baseline = np.squeeze(baseline)
                data.r0.tel[tel_id].camera_event_number = event_id

                pixel_settings = telescope_description['pixel_settings']
                data.mc.tel[tel_id].reference_pulse_shape = pixel_settings[
                    'refshape'].astype('float64')
                data.mc.tel[tel_id].meta['refstep'] = float(
                    pixel_settings['ref_step'])
                data.mc.tel[tel_id].time_slice = float(
                    pixel_settings['time_slice'])

                data.mc.tel[tel_id].photo_electron_image = array_event.get(
                    'photoelectrons', {}).get(tel_id)
                if data.mc.tel[tel_id].photo_electron_image is None:
                    data.mc.tel[tel_id].photo_electron_image = np.zeros(
                        (n_pixel, ), dtype='i2')

                tracking_position = tracking_positions[tel_id]
                data.mc.tel[tel_id].azimuth_raw = tracking_position[
                    'azimuth_raw']
                data.mc.tel[tel_id].altitude_raw = tracking_position[
                    'altitude_raw']
                data.mc.tel[tel_id].azimuth_cor = tracking_position.get(
                    'azimuth_cor', 0)
                data.mc.tel[tel_id].altitude_cor = tracking_position.get(
                    'altitude_cor', 0)
            yield data
            counter += 1
            if max_events and counter >= max_events:
                return