コード例 #1
0
ファイル: convert_raw_data.py プロジェクト: kbruegge/jayct
def main(input_file, output_file, limit):
    '''
    The INPUT_FILE argument specifies the path to a simtel file. This script reads the
    camera definitions from there and puts them into a json file
    specified by OUTPUT_FILE argument.
    '''

    event_source = EventSourceFactory.produce(
        input_url=input_file,
        max_events=limit if limit > 1 else None,
    )

    calibrator = CameraCalibrator(eventsource=event_source, )
    data = []
    for id, event in tqdm(enumerate(event_source)):
        if len(valid_triggerd_cameras(event)) < 2:
            continue
        calibrator.calibrate(event)
        c = {}
        # import IPython; IPython.embed()

        c['array'] = fill_array_dict(valid_triggerd_telescope_ids(event))
        c['event_id'] = id
        c['images'] = fill_images_dict(event)
        c['mc'] = fill_mc_dict(event)

        data.append(c)

    with gzip.open(output_file, 'wt') as of:
        json.dump(data, of, indent=2)
コード例 #2
0
ファイル: display_dl1.py プロジェクト: Pluto9th/ctapipe
class DisplayDL1Calib(Tool):
    name = "ctapipe-display-dl1"
    description = __doc__

    telescope = Int(None,
                    allow_none=True,
                    help='Telescope to view. Set to None to display all '
                    'telescopes.').tag(config=True)

    extractor_product = tool_utils.enum_trait(ImageExtractor,
                                              default='NeighborPeakWindowSum')

    aliases = Dict(
        dict(max_events='EventSource.max_events',
             extractor='DisplayDL1Calib.extractor_product',
             T='DisplayDL1Calib.telescope',
             O='ImagePlotter.output_path'))
    flags = Dict(
        dict(D=({
            'ImagePlotter': {
                'display': True
            }
        }, "Display the photoelectron images on-screen as they "
                "are produced.")))
    classes = List([EventSource, CameraDL1Calibrator, ImagePlotter] +
                   tool_utils.classes_with_traits(ImageExtractor))

    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.eventsource = None
        self.calibrator = None
        self.plotter = None

    def setup(self):
        self.eventsource = EventSource.from_url(
            get_dataset_path("gamma_test_large.simtel.gz"),
            parent=self,
        )

        self.calibrator = CameraCalibrator(parent=self)

        self.plotter = ImagePlotter(parent=self)

    def start(self):
        for event in self.eventsource:
            self.calibrator.calibrate(event)

            tel_list = event.r0.tels_with_data

            if self.telescope:
                if self.telescope not in tel_list:
                    continue
                tel_list = [self.telescope]
            for telid in tel_list:
                self.plotter.plot(event, telid)

    def finish(self):
        self.plotter.finish()
コード例 #3
0
ファイル: 3Dground.py プロジェクト: thomasgas/CREED
def load_calibrate(filename):
    # LOAD AND CALIBRATE

    # pwd = "/home/thomas/Programs/astro/CTAPIPE_DAN/"
    # filename = 'gamma_20deg_0deg_run100___cta-prod3-lapalma3-2147m-LaPalma_cone10.simtel.gz'
    # filename = 'gamma_20deg_0deg_run100___cta-prod3_desert-2150m-Paranal-merged.simtel.gz'
    # filename = 'gamma_20deg_0deg_run118___cta-prod3_desert-2150m-Paranal-merged_cone10.simtel.gz'
    # filename = 'gamma_20deg_180deg_run11___cta-prod3_desert-2150m-Paranal-merged_cone10.simtel.gz'

    # layout = np.loadtxt(pwd+'CTA.prod3Sb.3HB9-FG.lis', usecols=0, dtype=int)
    if "Paranal" in filename:
        layout = [4, 5, 6, 11]
        print("PARANAL WITH {0}".format(layout))
    elif "palma" in filename:
        layout = [5, 6, 7, 8]
        print("LAPALMA WITH {0}".format(layout))

    print("Layout telescopes IDs:".format(layout))

    # layout = [279, 280, 281, 282, 283, 284, 286, 287, 289, 297, 298, 299,
    #           300, 301, 302, 303, 304, 305, 306, 307, 308, 315, 316, 317,
    #           318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329,
    #           330, 331, 332, 333, 334, 335, 336, 337, 338, 345, 346, 347,
    #           348, 349, 350, 375, 376, 377, 378, 379, 380, 393, 400, 402,
    #           403, 404, 405, 406, 408, 410, 411, 412, 413, 414, 415, 416,
    #           417]

    layout = set(layout)

    source = event_source(filename)
    source.max_events = 50
    source.allowed_tels = layout
    events = [copy.deepcopy(event) for event in source]

    cal = CameraCalibrator(None,
                           None,
                           r1_product='HESSIOR1Calibrator',
                           extractor_product='NeighbourPeakIntegrator')
    for event in events:
        cal.calibrate(event)

    # Find "big" event (piece of code from T.V. notebook ...thanks :D )
    events_amplitude = []
    for event in events:
        event_amplitude = 0
        for tel_id in event.r0.tels_with_data:
            if event.dl1.tel[tel_id].image is not None:
                event_amplitude += event.dl1.tel[tel_id].image[0].sum()
        events_amplitude.append(event_amplitude)
    events_amplitude = np.array(events_amplitude)

    mm = events_amplitude.argmax()
    print("event: {0}".format(mm))
    event = events[mm]

    return event
コード例 #4
0
def main(simtel_file, output_pdf, num_events):

    event_source = EventSourceFactory.produce(
        input_url=simtel_file,
        max_events=num_events,
    )

    calibrator = CameraCalibrator(eventsource=event_source, )
    with PdfPages(output_pdf) as pdf:
        for event in tqdm(event_source, total=num_events):
            if event.mc.energy > 10 * u.TeV:
                calibrator.calibrate(event)
                reco = HillasReconstructor()
                plt.figure(figsize=(20, 20))
                plt.suptitle(
                    f'EVENT {event.r0.event_id} \n Energy: {event.mc.energy} \n Type: {event.mc.shower_primary_id}'
                )
                try:
                    result = plot_event(event, reco, pdf)
                except TooFewTelescopesException:
                    pdf.savefig()  # saves the current figure into a pdf page
                    plt.close()
                    continue
                pdf.savefig()  # saves the current figure into a pdf page
                plt.close()

                d = calculate_distance_theta(result.alt, result.az,
                                             event.mc.alt, event.mc.az)
                plt.figure(figsize=(18, 18))
                plot_array_birdsview(event, result, reco)
                plt.suptitle(
                    f'EVENT {event.r0.event_id} \n Energy: {event.mc.energy} \n Type: {event.mc.shower_primary_id} \n  \
                Alt: {event.mc.alt.to(u.deg)},   Az: {event.mc.az.to(u.deg)} \n \
                Predicted Alt: {result.alt.to(u.deg)},  Predicted Az: {result.az.to(u.deg)} \n \
                Distance {d}')
                plt.legend()
                pdf.savefig()  # saves the current figure into a pdf page
                plt.close()

                plt.figure(figsize=(18, 18))
                plot_array_sideview(event, result, reco)
                plt.suptitle(
                    f'EVENT {event.r0.event_id} \n Energy: {event.mc.energy} \n Type: {event.mc.shower_primary_id} \n  \
                Alt: {event.mc.alt.to(u.deg)},   Az: {event.mc.az.to(u.deg)} \n \
                Predicted Alt: {result.alt.to(u.deg)},   Predicted Az: {result.az.to(u.deg)} \n \
                Distance: {d}')
                plt.legend()
                pdf.savefig()  # saves the current figure into a pdf page
                plt.close()
コード例 #5
0
def test_basic_muon_reco(example_event):
    """
    Really simplistic test: just run the analyze_muon_event code, to make
    sure it doesn't crash. The input event is so far not a muon, so no output
    is generated.

    Parameters
    ----------
    test_event - a sample event (fixture)

    """

    calib = CameraCalibrator()
    calib.calibrate(example_event)

    muon_params = muon.analyze_muon_event(example_event)
    assert muon_params is not None
コード例 #6
0
def process_file(input_file, reco_algorithm, n_events=-1, silent=False):
    event_source = EventSourceFactory.produce(
        input_url=input_file,
        max_events=n_events if n_events > 1 else None,
        product='HESSIOEventSource',
    )
    calibrator = CameraCalibrator(eventsource=event_source, )

    telescope_event_information = []
    array_event_information = []
    for event in tqdm(event_source, disable=silent):
        if number_of_valid_triggerd_cameras(event) < 2:
            continue

        calibrator.calibrate(event)
        try:
            image_features, reconstruction, _, _ = process_event(
                event, reco_algorithm=reco_algorithm)
            event_features = event_information(event, image_features,
                                               reconstruction)
            array_event_information.append(event_features)
            telescope_event_information.append(image_features)
        except TooFewTelescopesException:
            continue

    if (len(telescope_event_information) == 0):
        return None, None, None

    telescope_events = pd.concat(telescope_event_information)
    telescope_events.set_index(['run_id', 'array_event_id', 'telescope_id'],
                               drop=True,
                               verify_integrity=True,
                               inplace=True)

    array_events = pd.DataFrame(array_event_information)
    array_events.set_index(['run_id', 'array_event_id'],
                           drop=True,
                           verify_integrity=True,
                           inplace=True)

    run_information = read_simtel_mc_information(input_file)
    df_runs = pd.DataFrame([run_information])
    df_runs.set_index('run_id', drop=True, verify_integrity=True, inplace=True)

    return df_runs, array_events, telescope_events
コード例 #7
0
class DisplayDL1Calib(Tool):
    name = "DisplayDL1Calib"
    description = "Calibrate dl0 data to dl1, and plot the photoelectron " \
                  "images."

    telescope = Int(None,
                    allow_none=True,
                    help='Telescope to view. Set to None to display all '
                    'telescopes.').tag(config=True)

    aliases = Dict(
        dict(f='EventFileReaderFactory.input_path',
             r='EventFileReaderFactory.reader',
             max_events='EventFileReaderFactory.max_events',
             extractor='ChargeExtractorFactory.extractor',
             window_width='ChargeExtractorFactory.window_width',
             t0='ChargeExtractorFactory.t0',
             window_shift='ChargeExtractorFactory.window_shift',
             sig_amp_cut_HG='ChargeExtractorFactory.sig_amp_cut_HG',
             sig_amp_cut_LG='ChargeExtractorFactory.sig_amp_cut_LG',
             lwt='ChargeExtractorFactory.lwt',
             clip_amplitude='CameraDL1Calibrator.clip_amplitude',
             T='DisplayDL1Calib.telescope',
             O='ImagePlotter.output_path'))
    flags = Dict(
        dict(D=({
            'ImagePlotter': {
                'display': True
            }
        }, "Display the photoelectron images on-screen as they "
                "are produced.")))
    classes = List([
        EventFileReaderFactory, ChargeExtractorFactory, CameraDL1Calibrator,
        ImagePlotter
    ])

    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.reader = None
        self.calibrator = None
        self.plotter = None

    def setup(self):
        self.log_format = "%(levelname)s: %(message)s [%(name)s.%(funcName)s]"
        kwargs = dict(config=self.config, tool=self)

        reader_factory = EventFileReaderFactory(**kwargs)
        reader_class = reader_factory.get_class()
        self.reader = reader_class(**kwargs)

        self.calibrator = CameraCalibrator(origin=self.reader.origin, **kwargs)

        self.plotter = ImagePlotter(**kwargs)

    def start(self):
        source = self.reader.read()
        for event in source:
            self.calibrator.calibrate(event)

            tel_list = event.r0.tels_with_data

            if self.telescope:
                if self.telescope not in tel_list:
                    continue
                tel_list = [self.telescope]
            for telid in tel_list:
                self.plotter.plot(event, telid)

    def finish(self):
        self.plotter.finish()
コード例 #8
0
ファイル: display_dl1.py プロジェクト: dipierr/ctapipe
class DisplayDL1Calib(Tool):
    name = "ctapipe-display-dl1"
    description = __doc__

    telescope = Int(
        None,
        allow_none=True,
        help='Telescope to view. Set to None to display all '
             'telescopes.'
    ).tag(config=True)

    extractor_product = tool_utils.enum_trait(
        ImageExtractor,
        default='NeighborPeakWindowSum'
    )

    aliases = Dict(
        dict(
            max_events='EventSource.max_events',
            extractor='DisplayDL1Calib.extractor_product',
            T='DisplayDL1Calib.telescope',
            O='ImagePlotter.output_path'
        )
    )
    flags = Dict(
        dict(
            D=(
                {
                    'ImagePlotter': {
                        'display': True
                    }
                },
                "Display the photoelectron images on-screen as they "
                "are produced."
            )
        )
    )
    classes = List(
        [
            EventSource,
            CameraDL1Calibrator,
            ImagePlotter
        ] + tool_utils.classes_with_traits(ImageExtractor)
    )

    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.eventsource = None
        self.calibrator = None
        self.plotter = None

    def setup(self):
        self.eventsource = EventSource.from_url(
            get_dataset_path("gamma_test_large.simtel.gz"),
            parent=self,
        )

        self.calibrator = CameraCalibrator(
            eventsource=self.eventsource,
            parent=self,
        )

        self.plotter = ImagePlotter(parent=self)

    def start(self):
        for event in self.eventsource:
            self.calibrator.calibrate(event)

            tel_list = event.r0.tels_with_data

            if self.telescope:
                if self.telescope not in tel_list:
                    continue
                tel_list = [self.telescope]
            for telid in tel_list:
                self.plotter.plot(event, telid)

    def finish(self):
        self.plotter.finish()
コード例 #9
0
class SimpleEventWriter(Tool):
    name = 'ctapipe-simple-event-writer'
    description = Unicode(__doc__)

    infile = Unicode(help='input file to read', default='').tag(config=True)
    outfile = Unicode(help='output file name',
                      default_value='output.h5').tag(config=True)
    progress = Bool(help='display progress bar',
                    default_value=True).tag(config=True)

    aliases = Dict({
        'infile': 'EventSourceFactory.input_url',
        'outfile': 'SimpleEventWriter.outfile',
        'max-events': 'EventSourceFactory.max_events',
        'progress': 'SimpleEventWriter.progress'
    })
    classes = List([EventSourceFactory, CameraCalibrator, CutFlow])

    def setup(self):
        self.log.info('Configure EventSourceFactory...')

        self.event_source = EventSourceFactory.produce(
            config=self.config, tool=self, product='HESSIOEventSource')
        self.event_source.allowed_tels = self.config['Analysis'][
            'allowed_tels']

        self.calibrator = CameraCalibrator(config=self.config,
                                           tool=self,
                                           eventsource=self.event_source)

        self.writer = HDF5TableWriter(filename=self.outfile,
                                      group_name='image_infos',
                                      overwrite=True)

        # Define Pre-selection for images
        preselcuts = self.config['Preselect']
        self.image_cutflow = CutFlow('Image preselection')
        self.image_cutflow.set_cuts(
            dict(no_sel=None,
                 n_pixel=lambda s: np.count_nonzero(s) < preselcuts['n_pixel'][
                     'min'],
                 image_amplitude=lambda q: q < preselcuts['image_amplitude'][
                     'min']))

        # Define Pre-selection for events
        self.event_cutflow = CutFlow('Event preselection')
        self.event_cutflow.set_cuts(dict(no_sel=None))

    def start(self):
        self.log.info('Loop on events...')

        for event in tqdm(self.event_source,
                          desc='EventWriter',
                          total=self.event_source.max_events,
                          disable=~self.progress):

            self.event_cutflow.count('no_sel')
            self.calibrator.calibrate(event)

            for tel_id in event.dl0.tels_with_data:
                self.image_cutflow.count('no_sel')

                camera = event.inst.subarray.tel[tel_id].camera
                dl1_tel = event.dl1.tel[tel_id]

                # Image cleaning
                image = dl1_tel.image[
                    0]  # Waiting for automatic gain selection
                mask = tailcuts_clean(camera,
                                      image,
                                      picture_thresh=10,
                                      boundary_thresh=5)
                cleaned = image.copy()
                cleaned[~mask] = 0

                # Preselection cuts
                if self.image_cutflow.cut('n_pixel', cleaned):
                    continue
                if self.image_cutflow.cut('image_amplitude', np.sum(cleaned)):
                    continue

                # Image parametrisation
                params = hillas_parameters(camera, cleaned)

                # Save Ids, MC infos and Hillas informations
                self.writer.write(camera.cam_id, [event.r0, event.mc, params])

    def finish(self):
        self.log.info('End of job.')

        self.image_cutflow()
        self.event_cutflow()
        self.writer.close()
コード例 #10
0
class CTAFileLoader(object):
    """
    Loads CTA Files and handles them for saving events in different format
    """

    # particle ID: 0 for gamma, 1 for proton

    def __init__(self,
                 telescopes,
                 file_name_mask,
                 load_option,
                 calibrate=False,
                 use_cut_value=-1,
                 pedestals_only=False):
        """

        :param particleID: ID of particle to save, deprecated
        :param telescopes: set of telescopes to save events for
        :param start_at_runnum: runnum to start at
        :param end_at_runnum: runnum to stop at (file is included)
        :param load_file_name_start: name of file to load after runnum
        :param load_file_name_end: name of file to load after runnum
        :param use_cut_value: use cut and remove all events lower, -1 for no cut
        """
        self.pedestals_only = pedestals_only
        self.calibrate = calibrate
        self.eventList = []
        self.load_option = load_option
        CameraCalibrator()
        # CameraCalibrator()
        if calibrate:
            config = traitlets.config.Config()
            self.calibrator = CameraCalibrator(config=config)
            # r1_product="HESSIOR1Calibrator",extractor_product="NeighbourPeakIntegrator",

        self.telescopes = telescopes

        #
        #  Mask run number with @
        #
        self.runnumset = set()

        p = file_name_mask.split(sep="/")
        path = ""
        for k in range(len(p) - 1):
            path += p[k] + "/"
        filename_mask = p[-1]
        p = None

        self.masked_file_name = filename_mask
        self.path = path

        fl = glob.glob(path + filename_mask.replace('@', '*'))
        mask = r"\w+_M\d{1}.*_(\d+).*_Y_.+.*"

        for fp in fl:
            s2 = fp.split(sep="/")[-1]
            self.runnumset.add(re.findall(mask, s2)[0])

        self.file_name_mask = filename_mask
        self.cut_value = use_cut_value
        self.use_cut = False if self.cut_value == -1 else True

        if load_option == LoadOption.cal_at_once:
            self.loadFilesWithMask()

    def loadFileWithID(self, fid):
        filename = self.loadFileName_start + str(fid) + self.loadFileName_end
        #if self.particleID == 1:
        #    filename = "Protons/proton_20deg_174.681deg_run" + str(
        #        fid) + "___cta-prod4-lapalma-2158m--baseline_with-MAGIC.simtel.gz"

        #elif self.particleID == 0:
        #    filename = "Gamma/gamma_20deg_174.681deg_run" + str(
        #        fid) + "___cta-prod4-lapalma-2158m--baseline_with-MAGIC_cone1.5.simtel.gz"

        #    print("Invalid particle ID given, please set 0 for gamma, 1 for proton file to load")
        self.loadFile(self.filepath + filename)

    def loadFileWithID_string(self, fidstr):
        filename = self.loadFileName_start + fidstr + self.loadFileName_end
        #if self.particleID == 1:
        #    filename = "Protons/proton_20deg_174.681deg_run" + str(
        #        fid) + "___cta-prod4-lapalma-2158m--baseline_with-MAGIC.simtel.gz"

        #elif self.particleID == 0:
        #    filename = "Gamma/gamma_20deg_174.681deg_run" + str(
        #        fid) + "___cta-prod4-lapalma-2158m--baseline_with-MAGIC_cone1.5.simtel.gz"

        #    print("Invalid particle ID given, please set 0 for gamma, 1 for proton file to load")
        self.loadFile(self.filepath + filename)

    def loadNextFile(self):

        maxFilesToTest = 100
        currentFileToTest = 0

        # If all files were loaded at once
        if self.load_option == LoadOption.cal_at_once:
            if self.eventList <= 0:
                print("Eventlist empty - all events used")
                return False

            return True

        if len(self.runnumset) > 0:
            # runnumset
            namecopy = copy.deepcopy(self.file_name_mask)
            fnmask = self.path + namecopy.replace("@", self.runnumset.pop())
            print("QAI: ", fnmask)
            #try:
            if self.loadFile(fnmask):
                return True
            #finally:
            #    print("Error loading files, ending...")
        print("Loaded all files.")
        return False
        print("Could not find next file.")

    def loadFilesWithMask(self):
        # Use masks? path = "/remote/ceph/group/magic/MAGIC-LST/MARS/CrabNebula/CalibratedWithPointings/2018_03_09/*05070968*00[1-2]*root"

        mask = self.filepath + self.loadFileName_start + "*" + self.loadFileName_end
        # Might need to change this line to work?
        event_factory = MAGICEventSource(input_url=path)
        event_factory.allowed_tels = self.telescopes  #{1, 2}
        event_generator = event_factory._generator()
        # event = next(event_generator)

        for s_event in event_generator:
            # Use event only if M1 and M2 are triggered

            #if 1 in s_event.r0.tels_with_data and 1 in self.telescopes and 2 in s_event.r0.tels_with_data:
            if self.telescopes <= s_event.r0.tels_with_data:
                self.calibrator.calibrate(s_event)
                # print("Oder num: {:d}, event id: {:.0f}, triggered telescopes: {}".format(stereo_event.count, stereo_event.r0.event_id, stereo_event.r0.tels_with_data))
                a = copy.deepcopy(s_event)
                self.eventList.append(a)
        #event_factory.pyhessio.close_file()
        print("New File loaded, file {:d} contains {:d} events".format(
            14, len(self.eventList)))

    def loadFile(self, path):
        # Use masks? path = "/remote/ceph/group/magic/MAGIC-LST/MARS/CrabNebula/CalibratedWithPointings/2018_03_09/*05070968*00[1-2]*root"

        # might need to change this line to work?
        #try:
        if True:
            if self.load_option == LoadOption.raw_sim or self.load_option == LoadOption.raw_data:
                event_factory = event_source(input_url=path)
                event_factory.allowed_tels = self.telescopes  #{1, 2}
                event_generator = event_factory._generator()
                if self.pedestals_only:
                    print(
                        "Warning: Pedestals only available for real data, not for simulation data."
                    )

            elif self.load_option == LoadOption.cal_sim or self.load_option == LoadOption.cal_data:
                #event_factory.allowed_tels = self.telescopes #{1, 2}
                if self.pedestals_only:
                    event_factory = MAGICEventSource(input_url=path)
                    pedestal_event_generator1 = event_factory._pedestal_event_generator(
                        telescope='M1')
                    pedestal_event_generator2 = event_factory._pedestal_event_generator(
                        telescope='M2')
                else:
                    event_factory = MAGICEventSource(input_url=path)
                    event_generator = event_factory._generator()

        else:  #except Exception as e:
            print("Error 194: File does not exist: " + path + " or ")
            print("Error: %s" % str(e))
            return False
        # event = next(event_generator)
        if self.pedestals_only:
            ped_available = True
            while ped_available:
                try:
                    p1 = next(pedestal_event_generator1, None)
                    p2 = next(pedestal_event_generator2, None)
                except:
                    print("Errror:")
                    p1 = None
                    p2 = None

                if p1 is None or p2 is None:
                    ped_available = False
                else:
                    a1 = copy.deepcopy(p1)
                    a2 = copy.deepcopy(p2)
                    self.eventList.append({1: a1, 2: a2})
        else:
            for s_event in event_generator:
                # Use event only if M1 and M2 are triggered
                #if 1 in s_event.r0.tels_with_data and 1 in self.telescopes and 2 in s_event.r0.tels_with_data:
                if self.telescopes <= s_event.r0.tels_with_data:
                    if self.calibrate:
                        self.calibrator(s_event)
                    # print("Oder num: {:d}, event id: {:.0f}, triggered telescopes: {}".format(stereo_event.count, stereo_event.r0.event_id, stereo_event.r0.tels_with_data))
                    a = copy.deepcopy(s_event)
                    if not self.use_cut or apply_cut(a, self.cut_value,
                                                     self.load_option):
                        self.eventList.append(a)
                        #print("Accepted. ",len(self.eventList))

        #event_factory.pyhessio.close_file()
        print("New File loaded, file {:d} contains {:d} events".format(
            14, len(self.eventList)))
        return True

    def checkEventList(self):
        """
        Checks whether eventList is empty and loads new file if it is
        Returns False if it is empty and all files were loaded
        Return True if it is not empty
        """
        if len(self.eventList) < 1:
            print("Not enough")
            if self.loadNextFile():
                if not self.checkEventList():
                    return False
            else:
                return False
        #print("Loaded")
        return True

    def getNextEvent(self):
        """
        Returns next event and removes it from eventList
        Automatically loads next file if eventList is empty
        """
        if self.checkEventList():
            return self.eventList.pop(0)
        else:
            return None
コード例 #11
0
"""
The most basic pipeline, using no special features of the framework other 
than a for-loop. This is useful for debugging and profiling of speed.
"""

import sys

import numpy as np

from ctapipe.calib import CameraCalibrator
from ctapipe.io.hessio import hessio_event_source

if __name__ == '__main__':

    filename = sys.argv[1]

    source = hessio_event_source(filename, max_events=None)

    cal = CameraCalibrator(None, None)

    for data in source:

        print("EVENT: {}, ENERGY: {:.2f}, TELS:{}".format(
            data.r0.event_id, data.mc.energy, len(data.dl0.tels_with_data)))

        cal.calibrate(data)

        # now the calibrated images are in data.dl1.tel[x].image
コード例 #12
0
class SingleTelEventDisplay(Tool):
    name = "ctapipe-display-single-tel"
    description = Unicode(__doc__)

    infile = Unicode(help="input file to read", default='').tag(config=True)
    tel = Int(help='Telescope ID to display', default=0).tag(config=True)
    channel = Integer(help="channel number to display", min=0, max=1).tag(
        config=True)
    write = Bool(help="Write out images to PNG files", default=False).tag(
        config=True)
    clean = Bool(help="Apply image cleaning", default=False).tag(config=True)
    hillas = Bool(help="Apply and display Hillas parametrization",
                  default=False).tag(config=True)
    samples = Bool(help="Show each sample", default=False).tag(config=True)
    display = Bool(help="Display results in interactive window",
                   default_value=True).tag(config=True)
    delay = Float(help='delay between events in s', default_value=0.01,
                  min=0.001).tag(config=True)
    progress = Bool(help='display progress bar', default_value=True).tag(
        config=True)

    aliases = Dict({'infile': 'EventFileReaderFactory.input_path',
                    'tel': 'SingleTelEventDisplay.tel',
                    'max-events': 'EventFileReaderFactory.max_events',
                    'channel': 'SingleTelEventDisplay.channel',
                    'write': 'SingleTelEventDisplay.write',
                    'clean': 'SingleTelEventDisplay.clean',
                    'hillas': 'SingleTelEventDisplay.hillas',
                    'samples': 'SingleTelEventDisplay.samples',
                    'display': 'SingleTelEventDisplay.display',
                    'delay': 'SingleTelEventDisplay.delay',
                    'progress': 'SingleTelEventDisplay.progress'
                    })

    classes = List([EventFileReaderFactory, CameraCalibrator])

    def setup(self):

        reader_factory = EventFileReaderFactory(None, self)
        reader_class = reader_factory.get_class()
        self.reader = reader_class(None, self)

        self.calibrator = CameraCalibrator(config=None, tool=self,
                                           origin=self.reader.origin)
        self.source = self.reader.read(allowed_tels=[self.tel, ])

        self.log.info('SELECTING EVENTS FROM TELESCOPE {}'.format(self.tel))

    def start(self):

        disp = None

        for event in tqdm(self.source,
                          desc='Tel{}'.format(self.tel),
                          total=self.reader.max_events,
                          disable=~self.progress):

            self.log.debug(event.trig)
            self.log.debug("Energy: {}".format(event.mc.energy))

            self.calibrator.calibrate(event)

            if disp is None:
                x, y = event.inst.pixel_pos[self.tel]
                focal_len = event.inst.optical_foclen[self.tel]
                geom = CameraGeometry.guess(x, y, focal_len)
                self.log.info(geom)
                disp = CameraDisplay(geom)
                # disp.enable_pixel_picker()
                disp.add_colorbar()
                if self.display:
                    plt.show(block=False)

            # display the event
            disp.axes.set_title('CT{:03d} ({}), event {:06d}'.format(
                self.tel, geom.cam_id, event.r0.event_id)
            )

            if self.samples:
                # display time-varying event
                data = event.dl0.tel[self.tel].pe_samples[self.channel]
                for ii in range(data.shape[1]):
                    disp.image = data[:, ii]
                    disp.set_limits_percent(70)
                    plt.suptitle("Sample {:03d}".format(ii))
                    if self.display:
                        plt.pause(self.delay)
                    if self.write:
                        plt.savefig('CT{:03d}_EV{:10d}_S{:02d}.png'
                                    .format(self.tel, event.r0.event_id, ii))
            else:
                # display integrated event:
                im = event.dl1.tel[self.tel].image[self.channel]

                if self.clean:
                    mask = tailcuts_clean(geom, im, picture_thresh=10,
                                          boundary_thresh=7)
                    im[~mask] = 0.0

                disp.image = im

                if self.hillas:
                    try:
                        ellipses = disp.axes.findobj(Ellipse)
                        if len(ellipses) > 0:
                            ellipses[0].remove()

                        params = hillas_parameters(pix_x=geom.pix_x,
                                                   pix_y=geom.pix_y, image=im)
                        disp.overlay_moments(params, color='pink', lw=3,
                                             with_label=False)
                    except HillasParameterizationError:
                        pass

                if self.display:
                    plt.pause(self.delay)
                if self.write:
                    plt.savefig('CT{:03d}_EV{:010d}.png'
                                .format(self.tel, event.r0.event_id))

        self.log.info("FINISHED READING DATA FILE")

        if disp is None:
            self.log.warning('No events for tel {} were found in {}. Try a '
                             'different EventIO file or another telescope'
                             .format(self.tel, self.infile),
                             )

        pass
コード例 #13
0
ファイル: event_preparer.py プロジェクト: vuillaut/protopipe
class EventPreparer:
    """
    Class which loop on events and returns results stored in container

    The Class has several purposes. First of all, it prepares the images of the event
    that will be further use for reconstruction by applying calibration, cleaning and
    selection. Then, it reconstructs the geometry of the event and then returns
    image (e.g. Hillas parameters)and event information (e.g. reults od the
    reconstruction).

    Parameters
    ----------
    config: dict
        Configuration with analysis parameters
    mode: str
        Mode of the reconstruction, e.g. tail or wave
    event_cutflow: ctapipe.utils.CutFlow
        Statistic of events processed
    image_cutflow: ctapipe.utils.CutFlow
        Statistic of images processed

    Returns: dict
        Dictionnary of results
    """
    def __init__(self, config, mode, event_cutflow=None, image_cutflow=None):
        # Cleaning for reconstruction
        self.cleaner_reco = ImageCleaner(  # for reconstruction
            config=config["ImageCleaning"]["biggest"],
            mode=mode)

        # Cleaning for energy/score estimation
        # Add possibility to force energy/score cleaning with tailcut analysis
        force_mode = mode
        try:
            if config["General"]["force_tailcut_for_extended_cleaning"] is True:
                force_mode = config["General"]["force_mode"]
                print("> Activate force-mode for cleaning!!!!")
        except:
            pass  # force_mode = mode

        self.cleaner_extended = ImageCleaner(  # for energy/score estimation
            config=config["ImageCleaning"]["extended"],
            mode=force_mode)

        # Image book keeping
        self.image_cutflow = image_cutflow or CutFlow("ImageCutFlow")

        # Add quality cuts on images
        charge_bounds = config["ImageSelection"]["charge"]
        npix_bounds = config["ImageSelection"]["pixel"]
        ellipticity_bounds = config["ImageSelection"]["ellipticity"]
        nominal_distance_bounds = config["ImageSelection"]["nominal_distance"]

        self.camera_radius = {
            "LSTCam": 1.126,
            "NectarCam": 1.126,
        }  # Average between max(xpix) and max(ypix), in meter

        self.image_cutflow.set_cuts(
            OrderedDict([
                ("noCuts", None),
                ("min pixel", lambda s: np.count_nonzero(s) < npix_bounds[0]),
                ("min charge", lambda x: x < charge_bounds[0]),
                # ("poor moments", lambda m: m.width <= 0 or m.length <= 0 or np.isnan(m.width) or np.isnan(m.length)),  # TBC, maybe we loose events without nan conditions
                ("poor moments", lambda m: m.width <= 0 or m.length <= 0),
                (
                    "bad ellipticity",
                    lambda m: (m.width / m.length) < ellipticity_bounds[0] or
                    (m.width / m.length) > ellipticity_bounds[-1],
                ),
                # ("close to the edge", lambda m, cam_id: m.r.value > (nominal_distance_bounds[-1] * 1.12949101073069946))  # in meter
                (
                    "close to the edge",
                    lambda m, cam_id: m.r.value >
                    (nominal_distance_bounds[-1] * self.camera_radius[cam_id]),
                ),  # in meter
            ]))

        # Reconstruction
        self.shower_reco = HillasReconstructor()

        # Event book keeping
        self.event_cutflow = event_cutflow or CutFlow("EventCutFlow")

        # Add cuts on events
        min_ntel = config["Reconstruction"]["min_tel"]
        self.event_cutflow.set_cuts(
            OrderedDict([
                ("noCuts", None),
                ("min2Tels trig", lambda x: x < min_ntel),
                ("min2Tels reco", lambda x: x < min_ntel),
                ("direction nan", lambda x: x.is_valid == False),
            ]))

    def prepare_event(self, source, return_stub=False):

        # configuration for the camera calibrator
        # modifies the integration window to be more like in MARS
        # JLK, only for LST!!!!
        # Option for integration correction is done above
        cfg = Config()
        cfg["ChargeExtractorFactory"]["window_width"] = 5
        cfg["ChargeExtractorFactory"]["window_shift"] = 2
        self.calib = CameraCalibrator(
            config=cfg,
            extractor_product="LocalPeakIntegrator",
            eventsource=source,
            tool=None,
        )

        for event in source:

            self.event_cutflow.count("noCuts")

            if self.event_cutflow.cut("min2Tels trig",
                                      len(event.dl0.tels_with_data)):
                if return_stub:
                    yield stub(event)
                else:
                    continue

            # calibrate the event
            self.calib.calibrate(event)

            # telescope loop
            tot_signal = 0
            max_signals = {}
            n_pixel_dict = {}
            hillas_dict_reco = {}  # for geometry
            hillas_dict = {}  # for discrimination
            n_tels = {
                "tot": len(event.dl0.tels_with_data),
                "LST": 0,
                "MST": 0,
                "SST": 0,
            }
            n_cluster_dict = {}
            impact_dict_reco = {}  # impact distance measured in tilt system

            point_azimuth_dict = {}
            point_altitude_dict = {}

            # To compute impact parameter in tilt system
            run_array_direction = event.mcheader.run_array_direction
            az, alt = run_array_direction[0], run_array_direction[1]

            ground_frame = GroundFrame()

            for tel_id in event.dl0.tels_with_data:
                self.image_cutflow.count("noCuts")

                camera = event.inst.subarray.tel[tel_id].camera

                # count the current telescope according to its size
                tel_type = event.inst.subarray.tel[tel_id].optics.tel_type
                # JLK, N telescopes before cut selection are not really interesting for
                # discrimination, too much fluctuations
                # n_tels[tel_type] += 1

                # the camera image as a 1D array and stuff needed for calibration
                # Choose gain according to pywicta's procedure
                image_1d = simtel_event_to_images(event=event,
                                                  tel_id=tel_id,
                                                  ctapipe_format=True)
                pmt_signal = image_1d.input_image  # calibrated image

                # clean the image
                try:
                    with warnings.catch_warnings():
                        # Image with biggest cluster (reco cleaning)
                        image_biggest = self.cleaner_reco.clean_image(
                            pmt_signal, camera)
                        image_biggest2d = geometry_converter.image_1d_to_2d(
                            image_biggest, camera.cam_id)
                        image_biggest2d = filter_pixels_clusters(
                            image_biggest2d)
                        image_biggest = geometry_converter.image_2d_to_1d(
                            image_biggest2d, camera.cam_id)

                        # Image for score/energy estimation (with clusters)
                        image_extended = self.cleaner_extended.clean_image(
                            pmt_signal, camera)
                except FileNotFoundError as e:  # JLK, WHAT?
                    print(e)
                    continue

                # Apply some selection
                if self.image_cutflow.cut("min pixel", image_biggest):
                    continue

                if self.image_cutflow.cut("min charge", np.sum(image_biggest)):
                    continue

                # For cluster counts
                image_2d = geometry_converter.image_1d_to_2d(
                    image_extended, camera.cam_id)
                n_cluster_dict[
                    tel_id] = pixel_clusters.number_of_pixels_clusters(
                        array=image_2d, threshold=0)

                # could this go into `hillas_parameters` ...?
                max_signals[tel_id] = np.max(image_extended)

                # do the hillas reconstruction of the images
                # QUESTION should this change in numpy behaviour be done here
                # or within `hillas_parameters` itself?
                # JLK: make selection on biggest cluster
                with np.errstate(invalid="raise", divide="raise"):
                    try:

                        moments_reco = hillas_parameters(
                            camera,
                            image_biggest)  # for geometry (eg direction)
                        moments = hillas_parameters(
                            camera, image_extended
                        )  # for discrimination and energy reconstruction

                        # if width and/or length are zero (e.g. when there is only only one
                        # pixel or when all  pixel are exactly in one row), the
                        # parametrisation won't be very useful: skip
                        if self.image_cutflow.cut("poor moments",
                                                  moments_reco):
                            # print('poor moments')
                            continue

                        if self.image_cutflow.cut("close to the edge",
                                                  moments_reco, camera.cam_id):
                            # print('close to the edge')
                            continue

                        if self.image_cutflow.cut("bad ellipticity",
                                                  moments_reco):
                            # print('bad ellipticity: w={}, l={}'.format(moments_reco.width, moments_reco.length))
                            continue

                    except (FloatingPointError,
                            hillas.HillasParameterizationError):
                        continue

                point_azimuth_dict[
                    tel_id] = event.mc.tel[tel_id].azimuth_raw * u.rad
                point_altitude_dict[
                    tel_id] = event.mc.tel[tel_id].altitude_raw * u.rad

                n_tels[tel_type] += 1
                hillas_dict[tel_id] = moments
                hillas_dict_reco[tel_id] = moments_reco
                n_pixel_dict[tel_id] = len(np.where(image_extended > 0)[0])
                tot_signal += moments.intensity

            n_tels["reco"] = len(hillas_dict_reco)
            n_tels["discri"] = len(hillas_dict)
            if self.event_cutflow.cut("min2Tels reco", n_tels["reco"]):
                if return_stub:
                    yield stub(event)
                else:
                    continue

            try:
                with warnings.catch_warnings():
                    warnings.simplefilter("ignore")

                    # Reconstruction results
                    reco_result = self.shower_reco.predict(
                        hillas_dict_reco,
                        event.inst,
                        point_altitude_dict,
                        point_azimuth_dict,
                    )

                    # shower_sys = TiltedGroundFrame(pointing_direction=HorizonFrame(
                    #     az=reco_result.az,
                    #     alt=reco_result.alt
                    # ))

                    # Impact parameter for energy estimation (/ tel)
                    subarray = event.inst.subarray
                    for tel_id in hillas_dict.keys():

                        pos = subarray.positions[tel_id]

                        tel_ground = SkyCoord(pos[0],
                                              pos[1],
                                              pos[2],
                                              frame=ground_frame)
                        # tel_tilt = tel_ground.transform_to(shower_sys)

                        core_ground = SkyCoord(
                            reco_result.core_x,
                            reco_result.core_y,
                            0 * u.m,
                            frame=ground_frame,
                        )
                        # core_tilt = core_ground.transform_to(shower_sys)

                        # Should be better handled (tilted frame)
                        impact_dict_reco[tel_id] = np.sqrt(
                            (core_ground.x - tel_ground.x)**2 +
                            (core_ground.y - tel_ground.y)**2)

            except Exception as e:
                print("exception in reconstruction:", e)
                raise
                if return_stub:
                    yield stub(event)
                else:
                    continue

            if self.event_cutflow.cut("direction nan", reco_result):
                if return_stub:
                    yield stub(event)
                else:
                    continue

            yield PreparedEvent(
                event=event,
                n_pixel_dict=n_pixel_dict,
                hillas_dict=hillas_dict,
                hillas_dict_reco=hillas_dict_reco,
                n_tels=n_tels,
                tot_signal=tot_signal,
                max_signals=max_signals,
                n_cluster_dict=n_cluster_dict,
                reco_result=reco_result,
                impact_dict=impact_dict_reco,
            )
コード例 #14
0
class ImageSumDisplayerTool(Tool):
    description = Unicode(__doc__)
    name = "ctapipe-image-sum-display"

    infile = Unicode(help='input simtelarray file',
                     default="/Users/kosack/Data/CTA/Prod3/gamma.simtel.gz"
                     ).tag(config=True)
    telgroup = Integer(help='telescope group number', default=1).tag(
        config=True)

    max_events = Integer(help='stop after this many events if non-zero',
                         default_value=0, min=0).tag(config=True)

    output_suffix=Unicode(help='suffix (file extension) of output '
                               'filenames to write images '
                               'to (no writing is done if blank). '
                               'Images will be named [EVENTID][suffix]' ,
                          default_value="").tag(config=True)

    aliases = Dict({'infile': 'ImageSumDisplayerTool.infile',
                    'telgroup': 'ImageSumDisplayerTool.telgroup',
                    'max-events': 'ImageSumDisplayerTool.max_events',
                    'output-suffix': 'ImageSumDisplayerTool.output_suffix'})
    classes = List([CameraCalibrator,])

    def setup(self):
        # load up the telescope types table (need to first open a file, a bit of
        # a hack until a proper insturment module exists) and select only the
        # telescopes with the same camera type
        data = next(hessio_event_source(self.infile, max_events=1))
        camtypes = get_camera_types(data.inst)
        print_camera_types(data.inst, printer=self.log.info)
        group = camtypes.groups[self.telgroup]
        self._selected_tels = group['tel_id'].data
        self._base_tel = self._selected_tels[0]
        self.log.info("Telescope group %d: %s with %s camera", self.telgroup,
                      group[0]['tel_type'], group[0]['cam_type'])
        self.log.info("SELECTED TELESCOPES:{}".format(self._selected_tels))
        self.calibrator = CameraCalibrator(self.config, self)

    def start(self):
        geom = None
        imsum = None
        disp = None

        for data in hessio_event_source(self.infile,
                                        allowed_tels=self._selected_tels,
                                        max_events=self.max_events):

            self.calibrator.calibrate(data)

            if geom is None:
                x, y = data.inst.pixel_pos[self._base_tel]
                flen = data.inst.optical_foclen[self._base_tel]
                geom = CameraGeometry.guess(x, y, flen)
                imsum = np.zeros(shape=x.shape, dtype=np.float)
                disp = CameraDisplay(geom, title=geom.cam_id)
                disp.add_colorbar()
                disp.cmap = 'viridis'

            if len(data.dl0.tels_with_data) <= 2:
                continue

            imsum[:] = 0
            for telid in data.dl0.tels_with_data:
                imsum += data.dl1.tel[telid].image[0]

            self.log.info("event={} ntels={} energy={}" \
                          .format(data.r0.event_id,
                                  len(data.dl0.tels_with_data),
                                  data.mc.energy))
            disp.image = imsum
            plt.pause(0.1)

            if self.output_suffix is not "":
                filename = "{:020d}{}".format(data.r0.event_id,
                                              self.output_suffix)
                self.log.info("saving: '{}'".format(filename))
                plt.savefig(filename)
コード例 #15
0
ファイル: LoadCTAFile.py プロジェクト: SKellerML/MAGICML
class CTAFileLoader(object):
    """
    Loads CTA Files and handles them for saving events in different format
    """

    # particle ID: 0 for gamma, 1 for proton

    def __init__(
            self,
            telescopes,
            start_at_runnum=0,
            end_at_runnum=0,
            load_file_name_start="Protons/proton_20deg_174.681deg_run",
            load_file_name_end="___cta-prod4-lapalma-2158m--baseline_with-MAGIC.simtel.gz",
            filepath=data_path):
        """

        :param particleID: ID of particle to save, deprecated
        :param telescopes: set of telescopes to save events for
        :param start_at_runnum: runnum to start at
        :param end_at_runnum: runnum to stop at (file is included)
        :param load_file_name_start: name of file to load after runnum
        :param load_file_name_end: name of file to load after runnum
        :param
        """

        self.eventList = []

        # CameraCalibrator()
        config = traitlets.config.Config()
        self.calibrator = CameraCalibrator(
            r1_product="HESSIOR1Calibrator",
            extractor_product="NeighbourPeakIntegrator",
            config=config)
        self.telescopes = telescopes

        self.currentFileID = start_at_runnum

        self.start_at_runnum = start_at_runnum
        self.end_at_runnum = end_at_runnum if end_at_runnum >= start_at_runnum else start_at_runnum
        self.loadFileName_start = load_file_name_start
        self.loadFileName_end = load_file_name_end
        self.filepath = filepath

    def loadFileWithID(self, fid):
        filename = self.loadFileName_start + str(fid) + self.loadFileName_end
        #if self.particleID == 1:
        #    filename = "Protons/proton_20deg_174.681deg_run" + str(
        #        fid) + "___cta-prod4-lapalma-2158m--baseline_with-MAGIC.simtel.gz"

        #elif self.particleID == 0:
        #    filename = "Gamma/gamma_20deg_174.681deg_run" + str(
        #        fid) + "___cta-prod4-lapalma-2158m--baseline_with-MAGIC_cone1.5.simtel.gz"

        #    print("Invalid particle ID given, please set 0 for gamma, 1 for proton file to load")
        self.loadFile(self.filepath + filename)

    def loadFileWithID_string(self, fidstr):
        filename = self.loadFileName_start + fidstr + self.loadFileName_end
        #if self.particleID == 1:
        #    filename = "Protons/proton_20deg_174.681deg_run" + str(
        #        fid) + "___cta-prod4-lapalma-2158m--baseline_with-MAGIC.simtel.gz"

        #elif self.particleID == 0:
        #    filename = "Gamma/gamma_20deg_174.681deg_run" + str(
        #        fid) + "___cta-prod4-lapalma-2158m--baseline_with-MAGIC_cone1.5.simtel.gz"

        #    print("Invalid particle ID given, please set 0 for gamma, 1 for proton file to load")
        self.loadFile(self.filepath + filename)

    def loadNextFile(self):

        maxFilesToTest = 100
        currentFileToTest = 0

        while currentFileToTest < maxFilesToTest:
            if self.currentFileID > self.end_at_runnum:
                print("Loaded all files.")
                return False

            filename = self.loadFileName_start + str(
                self.currentFileID) + self.loadFileName_end
            #if self.particleID == 1:
            #    filename = "Protons/proton_20deg_174.681deg_run" + str(
            #        self.currentFileID) + "___cta-prod4-lapalma-2158m--baseline_with-MAGIC.simtel.gz"

            #elif self.particleID == 0:
            #    filename = "Gamma/gamma_20deg_174.681deg_run" + str(
            #        self.currentFileID) + "___cta-prod4-lapalma-2158m--baseline_with-MAGIC_cone1.5.simtel.gz"
            #else:
            #    print("Invalid particle ID given, please set 0 for gamma, 1 for proton file to load")
            #    return

            # Check whether the file exists or not

            my_file = Path(self.filepath + filename)
            print(my_file)
            if not my_file.is_file():
                print("File does not exist: " + filename)
                self.currentFileID += 1
            else:
                self.loadFile(self.filepath + filename)
                self.currentFileID += 1
                return True

            currentFileToTest += 1

        print("Could not find next file.")

    def loadFile(self, path):
        event_factory = EventSourceFactory.produce(input_url=path)
        event_factory.allowed_tels = self.telescopes  #{1, 2}
        event_generator = event_factory._generator()
        # event = next(event_generator)

        for s_event in event_generator:
            # Use event only if M1 and M2 are triggered

            #if 1 in s_event.r0.tels_with_data and 1 in self.telescopes and 2 in s_event.r0.tels_with_data:
            if self.telescopes <= s_event.r0.tels_with_data:
                self.calibrator.calibrate(s_event)
                # print("Oder num: {:d}, event id: {:.0f}, triggered telescopes: {}".format(stereo_event.count, stereo_event.r0.event_id, stereo_event.r0.tels_with_data))
                a = copy.deepcopy(s_event)
                self.eventList.append(a)
        event_factory.pyhessio.close_file()
        print("New File loaded, file {:d} contains {:d} events".format(
            self.currentFileID, len(self.eventList)))

    def checkEventList(self):
        """
        Checks whether eventList is empty and loads new file if it is
        Returns False if it is empty and all files were loaded
        Return True if it is not empty
        """
        if len(self.eventList) < 1:
            if self.loadNextFile():
                if not self.checkEventList():
                    return False
            else:
                return False

        return True

    def getNextEvent(self):
        """
        Returns next event and removes it from eventList
        Automatically loads next file if eventList is empty
        """
        self.checkEventList()
        return self.eventList.pop(0)
def extract_images(simtel_file_path,
                   tel_id_filter_list=None,
                   event_id_filter_list=None,
                   output_directory=None,
                   crop=True):

    # EXTRACT IMAGES ##########################################################

    # hessio_event_source returns a Python generator that streams data from an
    # EventIO/HESSIO MC data file (e.g. a standard CTA data file).
    # This generator contains ctapipe.core.Container instances ("event").
    # 
    # Parameters:
    # - max_events: maximum number of events to read
    # - allowed_tels: select only a subset of telescope, if None, all are read.
    source = hessio_event_source(simtel_file_path, allowed_tels=tel_id_filter_list)

    # ITERATE OVER EVENTS #####################################################

    calib = CameraCalibrator(None, None)

    for event in source:

        calib.calibrate(event)  # calibrate the event

        event_id = int(event.dl0.event_id)

        if (event_id_filter_list is None) or (event_id in event_id_filter_list):

            #print("event", event_id)

            # ITERATE OVER IMAGES #############################################

            for tel_id in event.trig.tels_with_trigger:

                tel_id = int(tel_id)

                if tel_id in tel_id_filter_list:

                    #print("telescope", tel_id)

                    # CHECK THE IMAGE GEOMETRY (ASTRI ONLY) ###################

                    # TODO

                    #print("checking geometry")

                    x, y = event.inst.pixel_pos[tel_id]
                    foclen = event.inst.optical_foclen[tel_id]
                    geom = CameraGeometry.guess(x, y, foclen)

                    if (geom.pix_type != "rectangular") or (geom.cam_id not in ("ASTRICam", "ASTRI")):
                        raise ValueError("Telescope {}: error (the input image is not a valide ASTRI telescope image) -> {} ({})".format(tel_id, geom.pix_type, geom.cam_id))

                    # GET IMAGES ##############################################

                    pe_image = event.mc.tel[tel_id].photo_electron_image   # 1D np array

                    #uncalibrated_image = event.dl0.tel[tel_id].adc_sums  # ctapipe 0.3.0
                    uncalibrated_image = event.r0.tel[tel_id].adc_sums    # ctapipe 0.4.0
                    pedestal = event.mc.tel[tel_id].pedestal
                    gain = event.mc.tel[tel_id].dc_to_pe
                    pixel_pos = event.inst.pixel_pos[tel_id]

                    calibrated_image = event.dl1.tel[tel_id].image

                    calibrated_image[1, calibrated_image[0,:] <= ASTRI_CAM_CHANNEL_THRESHOLD] = 0
                    calibrated_image[0, calibrated_image[0,:] >  ASTRI_CAM_CHANNEL_THRESHOLD] = 0
                    calibrated_image = calibrated_image.sum(axis=0)

                    #print(pe_image.shape)
                    #print(calibrated_image.shape)
                    #print(uncalibrated_image.shape)
                    #print(pedestal.shape)
                    #print(gain.shape)
                    #print(pixel_pos.shape)
                    #print(pixel_pos[0])
                    #print(pixel_pos[1])

                    # CONVERTING GEOMETRY (1D TO 2D) ##########################

                    pe_image_2d = geometry_converter.astri_to_2d_array(pe_image, crop=crop)
                    calibrated_image_2d = geometry_converter.astri_to_2d_array(calibrated_image, crop=crop)
                    uncalibrated_image_2d = geometry_converter.astri_to_3d_array(uncalibrated_image, crop=crop)
                    pedestal_2d = geometry_converter.astri_to_3d_array(pedestal, crop=crop)
                    gains_2d = geometry_converter.astri_to_3d_array(gain, crop=crop)
                    pixel_pos_2d = geometry_converter.astri_to_3d_array(pixel_pos, crop=crop)

                    #print(pe_image_2d.shape)
                    #print(calibrated_image_2d.shape)
                    #print(uncalibrated_image_2d.shape)
                    #print(pedestal_2d.shape)
                    #print(gains_2d.shape)
                    #print(pixel_pos_2d.shape)
                    #sys.exit(0)

                    # GET PIXEL MASK ##########################################

                    pixel_mask = geometry_converter.astri_pixel_mask(crop)  # 1 for pixels with actual data, 0 for virtual (blank) pixels

                    # MAKE METADATA ###########################################

                    metadata = {}

                    metadata['version'] = 1    # Version of the datapipe fits format

                    if crop:
                        metadata['cam_id'] = "ASTRI_CROPPED"
                    else:
                        metadata['cam_id'] = "ASTRI"

                    metadata['tel_id'] = tel_id
                    metadata['event_id'] = event_id
                    metadata['simtel'] = simtel_file_path

                    metadata['tel_trig'] = len(event.trig.tels_with_trigger)

                    metadata['energy'] =  quantity_to_tuple(event.mc.energy, 'TeV')
                    metadata['mc_az'] = quantity_to_tuple(event.mc.az, 'rad')
                    metadata['mc_alt'] = quantity_to_tuple(event.mc.alt, 'rad')
                    metadata['mc_corex'] = quantity_to_tuple(event.mc.core_x, 'm')
                    metadata['mc_corey'] = quantity_to_tuple(event.mc.core_y, 'm')
                    metadata['mc_hfi'] = quantity_to_tuple(event.mc.h_first_int, 'm')

                    metadata['count'] = int(event.count)
                    
                    metadata['run_id'] = int(event.dl0.run_id)
                    metadata['tel_data'] = len(event.dl0.tels_with_data)

                    metadata['foclen'] = quantity_to_tuple(event.inst.optical_foclen[tel_id], 'm')
                    metadata['tel_posx'] = quantity_to_tuple(event.inst.tel_pos[tel_id][0], 'm')
                    metadata['tel_posy'] = quantity_to_tuple(event.inst.tel_pos[tel_id][1], 'm')
                    metadata['tel_posz'] = quantity_to_tuple(event.inst.tel_pos[tel_id][2], 'm')

                    # TODO: Astropy fails to store the following data in FITS files
                    #metadata['uid'] = os.getuid()
                    #metadata['datetime'] = str(datetime.datetime.now())
                    #metadata['version'] = VERSION
                    #metadata['argv'] = " ".join(sys.argv).encode('ascii', errors='ignore').decode('ascii')
                    #metadata['python'] = " ".join(sys.version.splitlines()).encode('ascii', errors='ignore').decode('ascii')
                    #metadata['system'] = " ".join(os.uname())

                    # SAVE THE IMAGE ##########################################

                    output_file_path_template = "{}_TEL{:03d}_EV{:05d}.fits"

                    if output_directory is not None:
                        simtel_basename = os.path.basename(simtel_file_path)
                        prefix = os.path.join(output_directory, simtel_basename)
                    else:
                        prefix = simtel_file_path

                    output_file_path = output_file_path_template.format(prefix,
                                                                        tel_id,
                                                                        event_id)

                    print("saving", output_file_path)

                    images.save_benchmark_images(img = calibrated_image_2d,
                                                 pe_img = pe_image_2d,
                                                 adc_sums_img = uncalibrated_image_2d,
                                                 pedestal_img = pedestal_2d,
                                                 gains_img = gains_2d,
                                                 pixel_pos = pixel_pos_2d,
                                                 pixel_mask = pixel_mask,
                                                 metadata = metadata,
                                                 output_file_path = output_file_path)
コード例 #17
0
class MuonDisplayerTool(Tool):
    name = 'ctapipe-display-muons'
    description = t.Unicode(__doc__)

    infile = t.Unicode(
        help='input file name',
        default=get_dataset('gamma_test_large.simtel.gz')
    ).tag(config=True)

    outfile = t.Unicode(help='output file name',
                        default=None).tag(config=True)

    display = t.Bool(
        help='display the camera events', default=False
    ).tag(config=True)

    classes = t.List([CameraCalibrator,])

    aliases = t.Dict({'infile': 'MuonDisplayerTool.infile',
                      'outfile': 'MuonDisplayerTool.outfile',
                      'display' : 'MuonDisplayerTool.display'
                      })


    def setup(self):
        self.calib = CameraCalibrator(config=self.config, tool=self)

    def start(self):

        output_parameters = {'MuonEff': [],
                             'ImpactP': [],
                             'RingWidth': []}

        numev = 0
        num_muons_found = 0

        for event in hessio_event_source(self.infile):
            self.log.info("Event Number: %d, found %d muons", numev, num_muons_found)

            self.calib.calibrate(event)
            muon_evt = analyze_muon_event(event)

            numev += 1

            if not muon_evt['MuonIntensityParams']:  # No telescopes contained a good muon
                continue
            else:
                if self.display:
                    plot_muon_event(event, muon_evt)

                for tid in muon_evt['TelIds']:
                    idx = muon_evt['TelIds'].index(tid)
                    if not muon_evt['MuonIntensityParams'][idx]:
                        continue

                    self.log.info("** Muon params: %s", muon_evt[idx])

                    output_parameters['MuonEff'].append(
                        muon_evt['MuonIntensityParams'][idx].optical_efficiency_muon
                    )
                    output_parameters['ImpactP'].append(
                        muon_evt['MuonIntensityParams'][idx].impact_parameter.value
                    )
                    output_parameters['RingWidth'].append(
                        muon_evt['MuonIntensityParams'][idx].ring_width.value
                    )

                    print_muon(muon_evt, printer=self.log.info)
                    num_muons_found += 1



        t = Table(output_parameters)
        t['ImpactP'].unit = 'm'
        t['RingWidth'].unit = 'deg'
        if self.outfile:
            t.write(self.outfile)
コード例 #18
0
class SingleTelEventDisplay(Tool):
    name = "ctapipe-display-televents"
    description = Unicode(__doc__)

    infile = Unicode(help="input file to read", default='').tag(config=True)
    tel = Int(help='Telescope ID to display', default=0).tag(config=True)
    channel = Integer(
        help="channel number to display", min=0, max=1
    ).tag(config=True)
    write = Bool(
        help="Write out images to PNG files", default=False
    ).tag(config=True)
    clean = Bool(help="Apply image cleaning", default=False).tag(config=True)
    hillas = Bool(
        help="Apply and display Hillas parametrization", default=False
    ).tag(config=True)
    samples = Bool(help="Show each sample", default=False).tag(config=True)
    display = Bool(
        help="Display results in interactive window", default_value=True
    ).tag(config=True)
    delay = Float(
        help='delay between events in s', default_value=0.01, min=0.001
    ).tag(config=True)
    progress = Bool(
        help='display progress bar', default_value=True
    ).tag(config=True)

    aliases = Dict({
        'infile': 'SingleTelEventDisplay.infile',
        'tel': 'SingleTelEventDisplay.tel',
        'max-events': 'EventSource.max_events',
        'channel': 'SingleTelEventDisplay.channel',
        'write': 'SingleTelEventDisplay.write',
        'clean': 'SingleTelEventDisplay.clean',
        'hillas': 'SingleTelEventDisplay.hillas',
        'samples': 'SingleTelEventDisplay.samples',
        'display': 'SingleTelEventDisplay.display',
        'delay': 'SingleTelEventDisplay.delay',
        'progress': 'SingleTelEventDisplay.progress'
    })

    classes = List([EventSource, CameraCalibrator])

    def __init__(self, **kwargs):
        super().__init__(**kwargs)

    def setup(self):
        print('TOLLES INFILE', self.infile)
        self.event_source = EventSource.from_url(self.infile, parent=self)
        self.event_source.allowed_tels = {self.tel, }

        self.calibrator = CameraCalibrator(
            parent=self, eventsource=self.event_source
        )

        self.log.info(f'SELECTING EVENTS FROM TELESCOPE {self.tel}')

    def start(self):

        disp = None

        for event in tqdm(
                self.event_source,
                desc=f'Tel{self.tel}',
                total=self.event_source.max_events,
                disable=~self.progress
        ):

            self.log.debug(event.trig)
            self.log.debug(f"Energy: {event.mc.energy}")

            self.calibrator.calibrate(event)

            if disp is None:
                geom = event.inst.subarray.tel[self.tel].camera
                self.log.info(geom)
                disp = CameraDisplay(geom)
                # disp.enable_pixel_picker()
                disp.add_colorbar()
                if self.display:
                    plt.show(block=False)

            # display the event
            disp.axes.set_title(
                'CT{:03d} ({}), event {:06d}'.format(
                    self.tel, geom.cam_id, event.r0.event_id
                )
            )

            if self.samples:
                # display time-varying event
                data = event.dl0.tel[self.tel].waveform[self.channel]
                for ii in range(data.shape[1]):
                    disp.image = data[:, ii]
                    disp.set_limits_percent(70)
                    plt.suptitle(f"Sample {ii:03d}")
                    if self.display:
                        plt.pause(self.delay)
                    if self.write:
                        plt.savefig(
                            f'CT{self.tel:03d}_EV{event.r0.event_id:10d}'
                            f'_S{ii:02d}.png'
                        )
            else:
                # display integrated event:
                im = event.dl1.tel[self.tel].image[self.channel]

                if self.clean:
                    mask = tailcuts_clean(
                        geom, im, picture_thresh=10, boundary_thresh=7
                    )
                    im[~mask] = 0.0

                disp.image = im

                if self.hillas:
                    try:
                        ellipses = disp.axes.findobj(Ellipse)
                        if len(ellipses) > 0:
                            ellipses[0].remove()

                        params = hillas_parameters(geom, image=im)
                        disp.overlay_moments(
                            params, color='pink', lw=3, with_label=False
                        )
                    except HillasParameterizationError:
                        pass

                if self.display:
                    plt.pause(self.delay)
                if self.write:
                    plt.savefig(
                        f'CT{self.tel:03d}_EV{event.r0.event_id:010d}.png'
                    )

        self.log.info("FINISHED READING DATA FILE")

        if disp is None:
            self.log.warning(
                'No events for tel {} were found in {}. Try a '
                'different EventIO file or another telescope'
                    .format(self.tel, self.infile),
            )
コード例 #19
0
ファイル: read_data.py プロジェクト: labsaha/image-extractor
            # print(event.dl0)
            # print(event.dl1)
            # print(event.dl2)
            # print(event.mcheader)
            # print(event.trig)
            # trace = event.r0.tel[tel_id].adc_samples[0]

            # peds, pedvars =
            # pedestals.calc_pedestals_from_traces(trace,start,end)

            # print("PEDS:",peds)
            # print("VARS:",pedvars)

            # event_id = event.r0.event_id

            cal.calibrate(event)

            # energy reconstruction input
            # X = {}

            # hillas_params_dict = {}
            # tel_phi_dict = {}
            # tel_theta_dict = {}

            for tel_id in event.r0.tels_with_data:

                # print(event.dl1.tel[tel_id].peakpos)

                # trace = np.array(event.r0.tel[tel_id].adc_samples)
                # apply trace integration
                # trace_integrated = integ.extract_charge(trace)[0][0]
コード例 #20
0
    def process_data(self, data_file, max_events=None):
        """Main method to read a simtel.gz data file, process the event data,
        and write it to a formatted HDF5 data file.
        """
        logger.info("Preparing HDF5 file structure...")

        f = tables.open_file(self.output_path, mode="a", title="Output File")

        self.write_metadata(f, data_file)

        selected_tels, num_tel = self.select_telescopes(data_file)

        event = next(hessio_event_source(data_file))

        # create and fill array information table
        if not f.__contains__('/Array_Info'):
            arr_table = f.create_table(f.root, 'Array_Info', row_types.Array,
                                       ("Table of array data"))

            arr_row = arr_table.row

            for tel_type in selected_tels:
                for tel_id in selected_tels[tel_type]:
                    arr_row["tel_id"] = tel_id
                    arr_row["tel_x"] = event.inst.subarray.positions[
                        tel_id].value[0]
                    arr_row["tel_y"] = event.inst.subarray.positions[
                        tel_id].value[1]
                    arr_row["tel_z"] = event.inst.subarray.positions[
                        tel_id].value[2]
                    arr_row["tel_type"] = tel_type
                    arr_row[
                        "run_array_direction"] = event.mcheader.run_array_direction
                    arr_row.append()

        # create and fill telescope information table
        if not f.__contains__('/Telescope_Info'):
            tel_table = f.create_table(f.root, 'Telescope_Info', row_types.Tel,
                                       ("Table of telescope data"))

            descr = tel_table.description._v_colobjects
            descr2 = descr.copy()

            max_npix = self.TEL_NUM_PIXELS[max(self.TEL_NUM_PIXELS,
                                               key=self.TEL_NUM_PIXELS.get)]
            descr2["pixel_pos"] = tables.Float32Col(shape=(2, max_npix))

            tel_table2 = f.create_table(f.root, 'temp', descr2,
                                        "Table of telescope data")
            tel_table.attrs._f_copy(tel_table2)
            tel_table.remove()
            tel_table2.move(f.root, 'Telescope_Info')

            tel_row = tel_table2.row

            # add units to table attributes
            random_tel_type = random.choice(list(selected_tels.keys()))
            random_tel_id = random.choice(selected_tels[random_tel_type])
            tel_table2.attrs.tel_pos_units = str(
                event.inst.subarray.positions[random_tel_id].unit)

            for tel_type in selected_tels:
                random_tel_id = random.choice(selected_tels[tel_type])
                tel_row["tel_type"] = tel_type
                tel_row["num_pixels"] = len(
                    event.inst.subarray.tel[random_tel_id].camera.pix_id)
                posx = np.hstack([
                    event.inst.subarray.tel[random_tel_id].camera.pix_x.value,
                    np.zeros(max_npix - len(
                        event.inst.subarray.tel[random_tel_id].camera.pix_x))
                ])
                posy = np.hstack([
                    event.inst.subarray.tel[random_tel_id].camera.pix_y.value,
                    np.zeros(max_npix - len(
                        event.inst.subarray.tel[random_tel_id].camera.pix_y))
                ])
                tel_row["pixel_pos"] = [posx, posy]
                tel_row.append()

        #create event table
        if not f.__contains__('/Event_Info'):
            table = f.create_table(f.root, 'Event_Info', row_types.Event,
                                   "Table of Event metadata")

            descr = table.description._v_colobjects
            descr2 = descr.copy()

            if self.storage_mode == 'tel_type':
                for tel_type in selected_tels:
                    descr2[tel_type + '_indices'] = tables.Int32Col(
                        shape=(len(selected_tels[tel_type])))
            elif self.storage_mode == 'tel_id':
                descr2["indices"] = tables.Int32Col(shape=(num_tel))

            table2 = f.create_table(f.root, 'temp', descr2, "Table of Events")
            table.attrs._f_copy(table2)
            table.remove()
            table2.move(f.root, 'Event_Info')

            #add units to table attributes
            table2.attrs.core_pos_units = str(event.mc.core_x.unit)
            table2.attrs.h_first_int_units = str(event.mc.h_first_int.unit)
            table2.attrs.mc_energy_units = str(event.mc.energy.unit)
            table2.attrs.alt_az_units = str(event.mc.alt.unit)

        #create image tables
        for tel_type in selected_tels:
            if self.img_mode == '2D':
                img_width = self.IMAGE_SHAPES[tel_type][
                    0] * self.img_scale_factors[tel_type]
                img_length = self.IMAGE_SHAPES[tel_type][
                    1] * self.img_scale_factors[tel_type]

                if self.img_dim_order == 'channels_first':
                    array_shape = (self.img_channels, img_width, img_length)
                elif self.img_dim_order == 'channels_last':
                    array_shape = (img_width, img_length, self.img_channels)

                np_type = np.dtype(np.dtype(self.img_dtypes[tel_type]),
                                   array_shape)
                columns_dict = {
                    "image": tables.Col.from_dtype(np_type),
                    "event_index": tables.Int32Col()
                }

            elif self.img_mode == '1D':
                array_shape = (self.TEL_NUM_PIXELS[tel_type], )
                np_type = np.dtype(
                    (np.dtype(self.img_dtypes[tel_type]), array_shape))

                columns_dict = {
                    "image_charge": tables.Col.from_dtype(np_type),
                    "event_index": tables.Int32Col()
                }
                if self.include_timing:
                    columns_dict["image_peak_times"] = tables.Col.from_dtype(
                        np_type)

            description = type('description', (tables.IsDescription, ),
                               columns_dict)

            if self.storage_mode == 'tel_type':
                if not f.__contains__('/' + tel_type):
                    table = f.create_table(
                        f.root, tel_type, description,
                        "Table of {} images".format(tel_type))

                    #append blank image at index 0
                    image_row = table.row

                    if self.img_mode == '2D':
                        image_row['image'] = self.trace_converter.convert(
                            None, None, tel_type)

                    elif self.img_mode == '1D':
                        shape = (image.TEL_NUM_PIXELS[tel_type], )
                        image_row['image_charge'] = np.zeros(
                            shape, dtype=self.img_dtypes[tel_type])
                        image_row['event_index'] = -1
                        if self.include_timing:
                            image_row['image_peak_times'] = np.zeros(
                                shape, dtype=self.img_dtypes[tel_type])

                    image_row.append()
                    table.flush()

            elif self.storage_mode == 'tel_id':
                for tel_id in selected_tels[tel_type]:
                    if not f.__contains__('T' + str(tel_id)):
                        table = f.create_table(
                            f.root, 'T' + str(tel_id), description,
                            "Table of T{} images".format(str(tel_id)))

                        #append blank image at index 0
                        image_row = table.row

                        if self.img_mode == '2D':
                            image_row['image'] = self.trace_converter.convert(
                                None, None, tel_type)

                        elif self.img_mode == '1D':
                            shape = (image.TEL_NUM_PIXELS[tel_type], )
                            image_row['image_charge'] = np.zeros(
                                shape, dtype=self.img_dtypes[tel_type])
                            image_row['event_index'] = -1
                            if self.include_timing:
                                image_row['image_peak_times'] = np.zeros(
                                    shape, dtype=self.img_dtypes[tel_type])

                        image_row.append()
                        table.flush()

        # specify calibration and other processing options
        cal = CameraCalibrator(None, None)

        logger.info("Processing events...")

        event_count = 0
        passing_count = 0

        source = hessio_event_source(
            data_file,
            allowed_tels=[j for i in selected_tels for j in selected_tels[i]],
            max_events=max_events)

        for event in source:
            event_count += 1

            if self.cuts_dict:
                if self.ED_cuts_dict is not None:
                    logger.warning(
                        'Warning: Both ED_cuts_dict and cuts dictionary found. Using cuts dictionary instead.'
                    )

                if test_cuts(event, cuts_dict):
                    passing_count += 1
                else:
                    continue
            else:
                if self.ED_cuts_dict is not None:
                    if (event.r0.run_id,
                            event.r0.event_id) in self.ED_cuts_dict:
                        bin_number, reconstructed_energy = self.ED_cuts_dict[(
                            event.r0.run_id, event.r0.event_id)]
                        passing_count += 1
                    else:
                        continue

            cal.calibrate(event)

            table = f.root.Event_Info
            table.flush()
            event_row = table.row
            event_index = table.nrows

            if self.storage_mode == 'tel_type':
                tel_index_vectors = {
                    tel_type: []
                    for tel_type in selected_tels
                }
            elif self.storage_mode == 'tel_id':
                all_tel_index_vector = []

            for tel_type in selected_tels.keys():
                for tel_id in sorted(selected_tels[tel_type]):
                    if self.storage_mode == 'tel_type':
                        index_vector = tel_index_vectors[tel_type]
                    elif self.storage_mode == 'tel_id':
                        index_vector = all_tel_index_vector

                    if tel_id in event.r0.tels_with_data:
                        pixel_vector = event.dl1.tel[tel_id].image[0]
                        logger.debug(
                            'Storing image from tel_type {} ({} pixels)'.
                            format(tel_type, len(pixel_vector)))
                        if self.include_timing:
                            peaks_vector = event.dl1.tel[tel_id].peakpos[0]
                        else:
                            peaks_vector = None

                        if self.storage_mode == 'tel_type':
                            table = eval('f.root.{}'.format(tel_type))
                        elif self.storage_mode == 'tel_id':
                            table = eval('f.root.T{}'.format(tel_id))
                        next_index = table.nrows
                        image_row = table.row

                        if self.img_mode == '2D':
                            image_row['image'] = self.trace_converter.convert(
                                pixel_vector, peaks_vector, tel_type)

                        elif self.img_mode == '1D':
                            image_row['image_charge'] = pixel_vector
                            if self.include_timing:
                                image_row['image_peak_times'] = peaks_vector

                        image_row["event_index"] = event_index

                        image_row.append()
                        index_vector.append(next_index)
                        table.flush()
                    else:
                        index_vector.append(0)

            if self.storage_mode == 'tel_type':
                for tel_type in tel_index_vectors:
                    event_row[tel_type +
                              '_indices'] = tel_index_vectors[tel_type]
            elif self.storage_mode == 'tel_id':
                event_row['indices'] = all_tel_index_vector

            event_row['event_number'] = event.r0.event_id
            event_row['run_number'] = event.r0.run_id
            event_row['particle_id'] = event.mc.shower_primary_id
            event_row['core_x'] = event.mc.core_x.value
            event_row['core_y'] = event.mc.core_y.value
            event_row['h_first_int'] = event.mc.h_first_int.value
            event_row['mc_energy'] = event.mc.energy.value
            event_row['alt'] = event.mc.alt.value
            event_row['az'] = event.mc.az.value

            event_row.append()
            table.flush()

        f.root.Event_Info.flush()
        total_num_events = f.root.Event_Info.nrows

        f.close()

        logger.info("{} events read in file".format(event_count))
        logger.info("{} total events in output file.".format(total_num_events))
        if self.cuts_dict or self.ED_cuts_dict:
            logger.info(
                "{} events passed cuts/written to file".format(passing_count))
        logger.info("Done!")
コード例 #21
0
class SimpleEventWriter(Tool):
    name = 'ctapipe-simple-event-writer'
    description = Unicode(__doc__)

    infile = Unicode(help='input file to read', default='').tag(config=True)
    outfile = Unicode(help='output file name', default_value='output.h5').tag(config=True)
    progress = Bool(help='display progress bar', default_value=True).tag(config=True)

    aliases = Dict({
        'infile': 'EventSourceFactory.input_url',
        'outfile': 'SimpleEventWriter.outfile',
        'max-events': 'EventSourceFactory.max_events',
        'progress': 'SimpleEventWriter.progress'
    })
    classes = List([EventSourceFactory, CameraCalibrator, CutFlow])

    def setup(self):
        self.log.info('Configure EventSourceFactory...')

        self.event_source = EventSourceFactory.produce(
            config=self.config, tool=self, product='SimTelEventSource'
        )
        self.event_source.allowed_tels = self.config['Analysis']['allowed_tels']

        self.calibrator = CameraCalibrator(
            config=self.config, tool=self, eventsource=self.event_source
        )

        self.writer = HDF5TableWriter(
            filename=self.outfile, group_name='image_infos', overwrite=True
        )

        # Define Pre-selection for images
        preselcuts = self.config['Preselect']
        self.image_cutflow = CutFlow('Image preselection')
        self.image_cutflow.set_cuts(dict(
            no_sel=None,
            n_pixel=lambda s: np.count_nonzero(s) < preselcuts['n_pixel']['min'],
            image_amplitude=lambda q: q < preselcuts['image_amplitude']['min']
        ))

        # Define Pre-selection for events
        self.event_cutflow = CutFlow('Event preselection')
        self.event_cutflow.set_cuts(dict(
            no_sel=None
        ))

    def start(self):
        self.log.info('Loop on events...')

        for event in tqdm(
                self.event_source,
                desc='EventWriter',
                total=self.event_source.max_events,
                disable=~self.progress):

            self.event_cutflow.count('no_sel')
            self.calibrator.calibrate(event)

            for tel_id in event.dl0.tels_with_data:
                self.image_cutflow.count('no_sel')

                camera = event.inst.subarray.tel[tel_id].camera
                dl1_tel = event.dl1.tel[tel_id]

                # Image cleaning
                image = dl1_tel.image[0]  # Waiting for automatic gain selection
                mask = tailcuts_clean(camera, image, picture_thresh=10, boundary_thresh=5)
                cleaned = image.copy()
                cleaned[~mask] = 0

                # Preselection cuts
                if self.image_cutflow.cut('n_pixel', cleaned):
                    continue
                if self.image_cutflow.cut('image_amplitude', np.sum(cleaned)):
                    continue

                # Image parametrisation
                params = hillas_parameters(camera, cleaned)

                # Save Ids, MC infos and Hillas informations
                self.writer.write(camera.cam_id, [event.r0, event.mc, params])

    def finish(self):
        self.log.info('End of job.')

        self.image_cutflow()
        self.event_cutflow()
        self.writer.close()
コード例 #22
0
def extract_images(simtel_file_path,
                   tel_id_filter_list=None,
                   event_id_filter_list=None,
                   output_directory=None,
                   crop=True):

    # EXTRACT IMAGES ##########################################################

    # hessio_event_source returns a Python generator that streams data from an
    # EventIO/HESSIO MC data file (e.g. a standard CTA data file).
    # This generator contains ctapipe.core.Container instances ("event").
    #
    # Parameters:
    # - max_events: maximum number of events to read
    # - allowed_tels: select only a subset of telescope, if None, all are read.
    source = hessio_event_source(simtel_file_path,
                                 allowed_tels=tel_id_filter_list)

    # ITERATE OVER EVENTS #####################################################

    calib = CameraCalibrator(None, None)

    for event in source:

        calib.calibrate(event)  # calibrate the event

        event_id = int(event.dl0.event_id)

        if (event_id_filter_list is None) or (event_id
                                              in event_id_filter_list):

            #print("event", event_id)

            # ITERATE OVER IMAGES #############################################

            for tel_id in event.trig.tels_with_trigger:

                tel_id = int(tel_id)

                if tel_id in tel_id_filter_list:

                    #print("telescope", tel_id)

                    # CHECK THE IMAGE GEOMETRY (ASTRI ONLY) ###################

                    # TODO

                    #print("checking geometry")

                    x, y = event.inst.subarray.tel[
                        tel_id].camera.pix_x, event.inst.subarray.tel[
                            tel_id].camera.pix_y
                    foclen = event.inst.subarray.tel[
                        tel_id].optics.equivalent_focal_length
                    geom = CameraGeometry.guess(x, y, foclen)

                    if (geom.pix_type != "rectangular") or (geom.cam_id
                                                            not in ("ASTRICam",
                                                                    "ASTRI")):
                        raise ValueError(
                            "Telescope {}: error (the input image is not a valide ASTRI telescope image) -> {} ({})"
                            .format(tel_id, geom.pix_type, geom.cam_id))

                    # GET IMAGES ##############################################

                    pe_image = event.mc.tel[
                        tel_id].photo_electron_image  # 1D np array

                    #uncalibrated_image = event.dl0.tel[tel_id].adc_sums  # ctapipe 0.3.0
                    uncalibrated_image = event.r0.tel[
                        tel_id].adc_sums  # ctapipe 0.4.0
                    pedestal = event.mc.tel[tel_id].pedestal
                    gain = event.mc.tel[tel_id].dc_to_pe
                    pixel_pos = (event.inst.subarray.tel[tel_id].camera.pix_x,
                                 event.inst.subarray.tel[tel_id].camera.pix_y)

                    calibrated_image = event.dl1.tel[tel_id].image

                    calibrated_image[1, calibrated_image[
                        0, :] <= ASTRI_CAM_CHANNEL_THRESHOLD] = 0
                    calibrated_image[0, calibrated_image[
                        0, :] > ASTRI_CAM_CHANNEL_THRESHOLD] = 0
                    calibrated_image = calibrated_image.sum(axis=0)

                    #print(pe_image.shape)
                    #print(calibrated_image.shape)
                    #print(uncalibrated_image.shape)
                    #print(pedestal.shape)
                    #print(gain.shape)
                    #print(pixel_pos.shape)
                    #print(pixel_pos[0])
                    #print(pixel_pos[1])

                    # CONVERTING GEOMETRY (1D TO 2D) ##########################

                    pe_image_2d = geometry_converter.astri_to_2d_array(
                        pe_image, crop=crop)
                    calibrated_image_2d = geometry_converter.astri_to_2d_array(
                        calibrated_image, crop=crop)
                    uncalibrated_image_2d = geometry_converter.astri_to_3d_array(
                        uncalibrated_image, crop=crop)
                    pedestal_2d = geometry_converter.astri_to_3d_array(
                        pedestal, crop=crop)
                    gains_2d = geometry_converter.astri_to_3d_array(gain,
                                                                    crop=crop)
                    pixel_pos_2d = geometry_converter.astri_to_3d_array(
                        pixel_pos, crop=crop)

                    #print(pe_image_2d.shape)
                    #print(calibrated_image_2d.shape)
                    #print(uncalibrated_image_2d.shape)
                    #print(pedestal_2d.shape)
                    #print(gains_2d.shape)
                    #print(pixel_pos_2d.shape)
                    #sys.exit(0)

                    # GET PIXEL MASK ##########################################

                    pixel_mask = geometry_converter.astri_pixel_mask(
                        crop
                    )  # 1 for pixels with actual data, 0 for virtual (blank) pixels

                    # MAKE METADATA ###########################################

                    metadata = {}

                    metadata[
                        'version'] = 1  # Version of the pywicta fits format

                    if crop:
                        metadata['cam_id'] = "ASTRI_CROPPED"
                    else:
                        metadata['cam_id'] = "ASTRI"

                    metadata['tel_id'] = tel_id
                    metadata['event_id'] = event_id
                    metadata['simtel'] = simtel_file_path

                    metadata['tel_trig'] = len(event.trig.tels_with_trigger)

                    metadata['energy'] = quantity_to_tuple(
                        event.mc.energy, 'TeV')
                    metadata['mc_az'] = quantity_to_tuple(event.mc.az, 'rad')
                    metadata['mc_alt'] = quantity_to_tuple(event.mc.alt, 'rad')
                    metadata['mc_corex'] = quantity_to_tuple(
                        event.mc.core_x, 'm')
                    metadata['mc_corey'] = quantity_to_tuple(
                        event.mc.core_y, 'm')
                    metadata['mc_hfi'] = quantity_to_tuple(
                        event.mc.h_first_int, 'm')

                    metadata['count'] = int(event.count)

                    metadata['run_id'] = int(event.dl0.obs_id)
                    metadata['tel_data'] = len(event.dl0.tels_with_data)

                    metadata['foclen'] = quantity_to_tuple(
                        event.inst.subarray.tel[tel_id].optics.
                        equivalent_focal_length, 'm')
                    metadata['tel_posx'] = quantity_to_tuple(
                        event.inst.subarray.tel_coords[tel_id].x, 'm')
                    metadata['tel_posy'] = quantity_to_tuple(
                        event.inst.subarray.tel_coords[tel_id].y, 'm')
                    metadata['tel_posz'] = quantity_to_tuple(
                        event.inst.subarray.tel_coords[tel_id].z, 'm')

                    # TODO: Astropy fails to store the following data in FITS files
                    #metadata['uid'] = os.getuid()
                    #metadata['datetime'] = str(datetime.datetime.now())
                    #metadata['version'] = VERSION
                    #metadata['argv'] = " ".join(sys.argv).encode('ascii', errors='ignore').decode('ascii')
                    #metadata['python'] = " ".join(sys.version.splitlines()).encode('ascii', errors='ignore').decode('ascii')
                    #metadata['system'] = " ".join(os.uname())

                    # SAVE THE IMAGE ##########################################

                    output_file_path_template = "{}_TEL{:03d}_EV{:05d}.fits"

                    if output_directory is not None:
                        simtel_basename = os.path.basename(simtel_file_path)
                        prefix = os.path.join(output_directory,
                                              simtel_basename)
                    else:
                        prefix = simtel_file_path

                    output_file_path = output_file_path_template.format(
                        prefix, tel_id, event_id)

                    print("saving", output_file_path)

                    images.save_benchmark_images(
                        img=calibrated_image_2d,
                        pe_img=pe_image_2d,
                        adc_sums_img=uncalibrated_image_2d,
                        pedestal_img=pedestal_2d,
                        gains_img=gains_2d,
                        pixel_pos=pixel_pos_2d,
                        pixel_mask=pixel_mask,
                        metadata=metadata,
                        output_file_path=output_file_path)
コード例 #23
0
ファイル: load_one_event.py プロジェクト: ParsonsRD/ctapipe
"""
very simple example that loads a single event into memory, for exploration
purposes
"""
import sys

from ctapipe.calib import CameraCalibrator
from ctapipe.io import event_source
from ctapipe.utils import get_dataset_path

if __name__ == '__main__':

    calib = CameraCalibrator(r1_product="HESSIOR1Calibrator")

    if len(sys.argv) >= 2:
        filename = sys.argv[1]
    else:
        filename = get_dataset_path("gamma_test_large.simtel.gz")

    with event_source(filename, max_events=1) as source:
        for event in source:
            calib.calibrate(event)

    print(event)
コード例 #24
0
class ImageSumDisplayerTool(Tool):
    description = Unicode(__doc__)
    name = "ctapipe-image-sum-display"

    infile = Unicode(
        help='input simtelarray file',
        default="/Users/kosack/Data/CTA/Prod3/gamma.simtel.gz").tag(
            config=True)
    telgroup = Integer(help='telescope group number',
                       default=1).tag(config=True)

    max_events = Integer(help='stop after this many events if non-zero',
                         default_value=0,
                         min=0).tag(config=True)

    output_suffix = Unicode(help='suffix (file extension) of output '
                            'filenames to write images '
                            'to (no writing is done if blank). '
                            'Images will be named [EVENTID][suffix]',
                            default_value="").tag(config=True)

    aliases = Dict({
        'infile': 'ImageSumDisplayerTool.infile',
        'telgroup': 'ImageSumDisplayerTool.telgroup',
        'max-events': 'ImageSumDisplayerTool.max_events',
        'output-suffix': 'ImageSumDisplayerTool.output_suffix'
    })
    classes = List([
        CameraCalibrator,
    ])

    def setup(self):
        # load up the telescope types table (need to first open a file, a bit of
        # a hack until a proper insturment module exists) and select only the
        # telescopes with the same camera type
        data = next(hessio_event_source(self.infile, max_events=1))
        camtypes = get_camera_types(data.inst)
        group = camtypes.groups[self.telgroup]
        self._selected_tels = group['tel_id'].data
        self._base_tel = self._selected_tels[0]
        self.log.info("Telescope group %d: %s with %s camera", self.telgroup,
                      group[0]['tel_type'], group[0]['cam_type'])
        self.log.info("SELECTED TELESCOPES:{}".format(self._selected_tels))
        self.calibrator = CameraCalibrator(self.config, self)

    def start(self):
        geom = None
        imsum = None
        disp = None

        for data in hessio_event_source(self.infile,
                                        allowed_tels=self._selected_tels,
                                        max_events=self.max_events):

            self.calibrator.calibrate(data)

            if geom is None:
                x, y = data.inst.pixel_pos[self._base_tel]
                flen = data.inst.optical_foclen[self._base_tel]
                geom = CameraGeometry.guess(x, y, flen)
                imsum = np.zeros(shape=x.shape, dtype=np.float)
                disp = CameraDisplay(geom, title=geom.cam_id)
                disp.add_colorbar()
                disp.cmap = 'viridis'

            if len(data.dl0.tels_with_data) <= 2:
                continue

            imsum[:] = 0
            for telid in data.dl0.tels_with_data:
                imsum += data.dl1.tel[telid].image[0]

            self.log.info("event={} ntels={} energy={}" \
                          .format(data.r0.event_id,
                                  len(data.dl0.tels_with_data),
                                  data.mc.energy))
            disp.image = imsum
            plt.pause(0.1)

            if self.output_suffix is not "":
                filename = "{:020d}{}".format(data.r0.event_id,
                                              self.output_suffix)
                self.log.info("saving: '{}'".format(filename))
                plt.savefig(filename)
コード例 #25
0
ファイル: simple_pipeline.py プロジェクト: epuesche/ctapipe
The most basic pipeline, using no special features of the framework other 
than a for-loop. This is useful for debugging and profiling of speed.
"""

import sys

import numpy as np

from ctapipe.calib import CameraCalibrator
from ctapipe.io.hessio import hessio_event_source

if __name__ == '__main__':

    filename = sys.argv[1]

    source = hessio_event_source(filename, max_events=None)

    cal = CameraCalibrator(None, None)

    for data in source:

        print("EVENT: {}, ENERGY: {:.2f}, TELS:{}"
              .format(data.r0.event_id,
                      data.mc.energy,
                      len(data.dl0.tels_with_data))
              )

        cal.calibrate(data)

        # now the calibrated images are in data.dl1.tel[x].image
コード例 #26
0
ax2 = fig0.add_subplot(122)

ax1.set_title('Lab data')
ax1.set_ylabel('amplitude')
ax1.set_xlabel('time [ns]')

ax2.set_title('MC data')
ax2.set_ylabel('amplitude')
ax2.set_xlabel('time [ns]')

######### CAMERA DATA p.e. ###########
cal = CameraCalibrator(r1_product="TargetioR1Calibrator")
try:
    for event_r1 in tqdm(event_source(args.labfile, max_events=args.maxevents),
                         total=args.maxevents):
        cal.calibrate(event_r1)  # Not needed as it is already R1 data?
        print('\n\nCamera Event\n\n')
        if args.lab_pix == None:
            for i in range(0, 64):
                if args.lab_thresh == None:
                    ax1.plot(range(len(event_r1.r1.tel[0].waveform[0][0])),
                             event_r1.r1.tel[0].waveform[0][i] / args.mv2pe,
                             color='C0')
                else:
                    if max(event_r1.r1.tel[0].waveform[0]
                           [i]) / args.mv2pe > args.lab_thresh:
                        print('plotting only lab pixel: ', i)
                        ax1.plot(range(len(event_r1.r1.tel[0].waveform[0][0])),
                                 event_r1.r1.tel[0].waveform[0][i] /
                                 args.mv2pe,
                                 color='C0')
コード例 #27
0
class SingleTelEventDisplay(Tool):
    name = "ctapipe-display-single-tel"
    description = Unicode(__doc__)

    infile = Unicode(help="input file to read", default='').tag(config=True)
    tel = Int(help='Telescope ID to display', default=0).tag(config=True)
    channel = Integer(help="channel number to display", min=0,
                      max=1).tag(config=True)
    write = Bool(help="Write out images to PNG files",
                 default=False).tag(config=True)
    clean = Bool(help="Apply image cleaning", default=False).tag(config=True)
    hillas = Bool(help="Apply and display Hillas parametrization",
                  default=False).tag(config=True)
    samples = Bool(help="Show each sample", default=False).tag(config=True)
    display = Bool(help="Display results in interactive window",
                   default_value=True).tag(config=True)
    delay = Float(help='delay between events in s',
                  default_value=0.01,
                  min=0.001).tag(config=True)
    progress = Bool(help='display progress bar',
                    default_value=True).tag(config=True)

    aliases = Dict({
        'infile': 'EventSourceFactory.input_url',
        'tel': 'SingleTelEventDisplay.tel',
        'max-events': 'EventSourceFactory.max_events',
        'channel': 'SingleTelEventDisplay.channel',
        'write': 'SingleTelEventDisplay.write',
        'clean': 'SingleTelEventDisplay.clean',
        'hillas': 'SingleTelEventDisplay.hillas',
        'samples': 'SingleTelEventDisplay.samples',
        'display': 'SingleTelEventDisplay.display',
        'delay': 'SingleTelEventDisplay.delay',
        'progress': 'SingleTelEventDisplay.progress'
    })

    classes = List([EventSourceFactory, CameraCalibrator])

    def setup(self):

        self.event_source = EventSourceFactory.produce(config=self.config,
                                                       tool=self)
        self.event_source.allowed_tels = [
            self.tel,
        ]

        self.calibrator = CameraCalibrator(config=self.config,
                                           tool=self,
                                           eventsource=self.event_source)

        self.log.info('SELECTING EVENTS FROM TELESCOPE {}'.format(self.tel))

    def start(self):

        disp = None

        for event in tqdm(self.event_source,
                          desc='Tel{}'.format(self.tel),
                          total=self.event_source.max_events,
                          disable=~self.progress):

            self.log.debug(event.trig)
            self.log.debug("Energy: {}".format(event.mc.energy))

            self.calibrator.calibrate(event)

            if disp is None:
                geom = event.inst.subarray.tel[self.tel].camera
                self.log.info(geom)
                disp = CameraDisplay(geom)
                # disp.enable_pixel_picker()
                disp.add_colorbar()
                if self.display:
                    plt.show(block=False)

            # display the event
            disp.axes.set_title('CT{:03d} ({}), event {:06d}'.format(
                self.tel, geom.cam_id, event.r0.event_id))

            if self.samples:
                # display time-varying event
                data = event.dl0.tel[self.tel].pe_samples[self.channel]
                for ii in range(data.shape[1]):
                    disp.image = data[:, ii]
                    disp.set_limits_percent(70)
                    plt.suptitle("Sample {:03d}".format(ii))
                    if self.display:
                        plt.pause(self.delay)
                    if self.write:
                        plt.savefig('CT{:03d}_EV{:10d}_S{:02d}.png'.format(
                            self.tel, event.r0.event_id, ii))
            else:
                # display integrated event:
                im = event.dl1.tel[self.tel].image[self.channel]

                if self.clean:
                    mask = tailcuts_clean(geom,
                                          im,
                                          picture_thresh=10,
                                          boundary_thresh=7)
                    im[~mask] = 0.0

                disp.image = im

                if self.hillas:
                    try:
                        ellipses = disp.axes.findobj(Ellipse)
                        if len(ellipses) > 0:
                            ellipses[0].remove()

                        params = hillas_parameters(geom, image=im)
                        disp.overlay_moments(params,
                                             color='pink',
                                             lw=3,
                                             with_label=False)
                    except HillasParameterizationError:
                        pass

                if self.display:
                    plt.pause(self.delay)
                if self.write:
                    plt.savefig('CT{:03d}_EV{:010d}.png'.format(
                        self.tel, event.r0.event_id))

        self.log.info("FINISHED READING DATA FILE")

        if disp is None:
            self.log.warning(
                'No events for tel {} were found in {}. Try a '
                'different EventIO file or another telescope'.format(
                    self.tel, self.infile), )

        pass
コード例 #28
0
def process_file(input_file,
                 config,
                 return_input_file=False,
                 product='SimTelEventSource'):

    event_source = EventSourceFactory.produce(
        input_url=input_file.as_posix(),
        max_events=config.n_events if config.n_events > 1 else None,
        product=product,
    )

    #event_source.allowed_tels = config.allowed_telescope_ids # if we only want one telescope later

    calibrator = CameraCalibrator(
        eventsource=event_source,
        r1_product='HESSIOR1Calibrator',
        extractor_product=config.integrator,
    )

    telescope_event_information = []
    array_event_information = []
    for event in tqdm(event_source, disable=config.silent):
        if number_of_valid_triggerd_cameras(
                event, config) < config.min_number_of_valid_triggered_cameras:
            continue

        calibrator.calibrate(event)
        try:
            image_features, reconstruction, _ = process_event(event, config)
            event_features = event_information(event, image_features,
                                               reconstruction, config)
            array_event_information.append(event_features)
            telescope_event_information.append(image_features)
        except TooFewTelescopesException:
            continue

    telescope_events = pd.concat(telescope_event_information)
    if not telescope_events.empty:
        telescope_events.set_index(
            ['run_id', 'array_event_id', 'telescope_id'],
            drop=True,
            verify_integrity=True,
            inplace=True)

    array_events = pd.DataFrame(array_event_information)
    if not array_events.empty:
        array_events.set_index(['run_id', 'array_event_id'],
                               drop=True,
                               verify_integrity=True,
                               inplace=True)

    run_information = read_simtel_mc_information(
        input_file)  ### TODO: adapt to real data
    df_runs = pd.DataFrame([run_information])
    if not df_runs.empty:
        df_runs.set_index('run_id',
                          drop=True,
                          verify_integrity=True,
                          inplace=True)

    if return_input_file:
        return df_runs, array_events, telescope_events, input_file
    return df_runs, array_events, telescope_events
コード例 #29
0
class MuonDisplayerTool(Tool):
    name = 'ctapipe-display-muons'
    description = t.Unicode(__doc__)

    events = t.Unicode("",
                       help="input event data file").tag(config=True)

    outfile = t.Unicode("muons.hdf5", help='HDF5 output file name').tag(
        config=True)

    display = t.Bool(
        help='display the camera events', default=False
    ).tag(config=True)

    classes = t.List([
        CameraCalibrator, EventSourceFactory
    ])

    aliases = t.Dict({
        'input': 'MuonDisplayerTool.events',
        'outfile': 'MuonDisplayerTool.outfile',
        'display': 'MuonDisplayerTool.display',
        'max_events': 'EventSourceFactory.max_events',
        'allowed_tels': 'EventSourceFactory.allowed_tels',
    })

    def setup(self):
        if self.events == '':
            raise ToolConfigurationError("please specify --input <events file>")
        self.log.debug("input: %s", self.events)
        self.source = EventSourceFactory.produce(input_url=self.events)
        self.calib = CameraCalibrator(
            config=self.config, tool=self, eventsource=self.source
        )
        self.writer = HDF5TableWriter(self.outfile, "muons")

    def start(self):

        numev = 0
        self.num_muons_found = defaultdict(int)

        for event in tqdm(self.source, desc='detecting muons'):

            self.calib.calibrate(event)
            muon_evt = analyze_muon_event(event)

            if numev == 0:
                _exclude_some_columns(event.inst.subarray, self.writer)

            numev += 1

            if not muon_evt['MuonIntensityParams']:
                # No telescopes  contained a good muon
                continue
            else:
                if self.display:
                    plot_muon_event(event, muon_evt)

                for tel_id in muon_evt['TelIds']:
                    idx = muon_evt['TelIds'].index(tel_id)
                    intens_params = muon_evt['MuonIntensityParams'][idx]

                    if intens_params is not None:
                        ring_params = muon_evt['MuonRingParams'][idx]
                        cam_id = str(event.inst.subarray.tel[tel_id].camera)
                        self.num_muons_found[cam_id] += 1
                        self.log.debug("INTENSITY: %s", intens_params)
                        self.log.debug("RING: %s", ring_params)
                        self.writer.write(table_name=cam_id,
                                          containers=[intens_params,
                                                      ring_params])

                self.log.info(
                    "Event Number: %d, found %s muons",
                    numev, dict(self.num_muons_found)
                )

    def finish(self):
        Provenance().add_output_file(self.outfile,
                                     role='dl1.tel.evt.muon')
        self.writer.close()
コード例 #30
0
from ctapipe.coordinates import HorizonFrame, CameraFrame, NominalFrame

cleaning_level = {
    'LSTCam': (3.5, 7.5, 2),  # ?? (3, 6) for Abelardo...
    'FlashCam': (4, 8, 2),  # there is some scaling missing?
    'ASTRICam': (5, 7, 2),
}

input_url = get_dataset_path('gamma_test_large.simtel.gz')

with event_source(input_url=input_url) as source:
    calibrator = CameraCalibrator(eventsource=source, )

    for event in source:

        calibrator.calibrate(event)

        nominal_frame = NominalFrame(
            origin=SkyCoord(alt=70 * u.deg, az=0 * u.deg, frame=HorizonFrame))

        nom_delta_az = []
        nom_delta_alt = []
        photons = []

        for tel_id, dl1 in event.dl1.tel.items():
            camera = event.inst.subarray.tels[tel_id].camera
            focal_length = event.inst.subarray.tels[
                tel_id].optics.equivalent_focal_length
            image = dl1.image[0]

            # telescope mc info
コード例 #31
0
class ImageSumDisplayerTool(Tool):
    description = Unicode(__doc__)
    name = "ctapipe-display-imagesum"

    infile = Unicode(
        help='input simtelarray file',
        default="/Users/kosack/Data/CTA/Prod3/gamma.simtel.gz"
    ).tag(config=True)

    telgroup = Integer(
        help='telescope group number', default=1
    ).tag(config=True)

    max_events = Integer(
        help='stop after this many events if non-zero', default_value=0, min=0
    ).tag(config=True)

    output_suffix = Unicode(
        help='suffix (file extension) of output '
             'filenames to write images '
             'to (no writing is done if blank). '
             'Images will be named [EVENTID][suffix]',
        default_value=""
    ).tag(config=True)

    aliases = Dict({
        'infile': 'ImageSumDisplayerTool.infile',
        'telgroup': 'ImageSumDisplayerTool.telgroup',
        'max-events': 'ImageSumDisplayerTool.max_events',
        'output-suffix': 'ImageSumDisplayerTool.output_suffix'
    })

    classes = List([CameraCalibrator, SimTelEventSource])

    def setup(self):
        # load up the telescope types table (need to first open a file, a bit of
        # a hack until a proper insturment module exists) and select only the
        # telescopes with the same camera type

        self.reader = SimTelEventSource(
            input_url=self.infile, max_events=self.max_events
        )

        for event in self.reader:
            camtypes = event.inst.subarray.to_table().group_by('camera_type')
            event.inst.subarray.info(printer=self.log.info)
            break

        group = camtypes.groups[self.telgroup]
        self._selected_tels = list(group['id'].data)
        self._base_tel = self._selected_tels[0]
        self.log.info(
            "Telescope group %d: %s", self.telgroup,
            str(event.inst.subarray.tel[self._selected_tels[0]])
        )
        self.log.info(f"SELECTED TELESCOPES:{self._selected_tels}")

        self.calibrator = CameraCalibrator(
            parent=self, eventsource=self.reader
        )

        self.reader.allowed_tels = self._selected_tels

    def start(self):
        geom = None
        imsum = None
        disp = None

        for event in self.reader:

            self.calibrator.calibrate(event)

            if geom is None:
                geom = event.inst.subarray.tel[self._base_tel].camera
                imsum = np.zeros(shape=geom.pix_x.shape, dtype=np.float)
                disp = CameraDisplay(geom, title=geom.cam_id)
                disp.add_colorbar()
                disp.cmap = 'viridis'

            if len(event.dl0.tels_with_data) <= 2:
                continue

            imsum[:] = 0
            for telid in event.dl0.tels_with_data:
                imsum += event.dl1.tel[telid].image[0]

            self.log.info(
                "event={} ntels={} energy={}".format(
                    event.r0.event_id, len(event.dl0.tels_with_data),
                    event.mc.energy
                )
            )
            disp.image = imsum
            plt.pause(0.1)

            if self.output_suffix is not "":
                filename = "{:020d}{}".format(
                    event.r0.event_id, self.output_suffix
                )
                self.log.info(f"saving: '{filename}'")
                plt.savefig(filename)
コード例 #32
0
class DisplayDL1Calib(Tool):
    name = "DisplayDL1Calib"
    description = "Calibrate dl0 data to dl1, and plot the photoelectron " \
                  "images."

    telescope = Int(None, allow_none=True,
                    help='Telescope to view. Set to None to display all '
                         'telescopes.').tag(config=True)

    aliases = Dict(dict(f='EventFileReaderFactory.input_path',
                        r='EventFileReaderFactory.reader',
                        max_events='EventFileReaderFactory.max_events',
                        extractor='ChargeExtractorFactory.extractor',
                        window_width='ChargeExtractorFactory.window_width',
                        t0='ChargeExtractorFactory.t0',
                        window_shift='ChargeExtractorFactory.window_shift',
                        sig_amp_cut_HG='ChargeExtractorFactory.sig_amp_cut_HG',
                        sig_amp_cut_LG='ChargeExtractorFactory.sig_amp_cut_LG',
                        lwt='ChargeExtractorFactory.lwt',
                        clip_amplitude='CameraDL1Calibrator.clip_amplitude',
                        T='DisplayDL1Calib.telescope',
                        O='ImagePlotter.output_path'
                        ))
    flags = Dict(dict(D=({'ImagePlotter': {'display': True}},
                         "Display the photoelectron images on-screen as they "
                         "are produced.")
                      ))
    classes = List([EventFileReaderFactory,
                    ChargeExtractorFactory,
                    CameraDL1Calibrator,
                    ImagePlotter
                    ])

    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.reader = None
        self.calibrator = None
        self.plotter = None

    def setup(self):
        kwargs = dict(config=self.config, tool=self)

        reader_factory = EventFileReaderFactory(**kwargs)
        reader_class = reader_factory.get_class()
        self.reader = reader_class(**kwargs)

        self.calibrator = CameraCalibrator(origin=self.reader.origin, **kwargs)

        self.plotter = ImagePlotter(**kwargs)

    def start(self):
        source = self.reader.read()
        for event in source:
            self.calibrator.calibrate(event)

            tel_list = event.r0.tels_with_data

            if self.telescope:
                if self.telescope not in tel_list:
                    continue
                tel_list = [self.telescope]
            for telid in tel_list:
                self.plotter.plot(event, telid)

    def finish(self):
        self.plotter.finish()
コード例 #33
0
class AnalyseData:
    def __init__(self):
        self.pixel_mask = [1] * 2048
        self.calib = CameraCalibrator(None, None)
        self.filename = '/Users/armstrongt/Workspace/CTA/MCValidation/data/bypass2_enoise_pe100.simtel.gz'

    # def __init__(self):
    #     self.file_reader = None
    #     self.r1 = None
    #     self.dl0 = None
    #     self.dl1 = None
    #     self.calculator = None

    def plot_peds(self, event, peds, pedvars):
        """ make a quick plot of the pedestal values"""
        pixid = np.arange(len(peds))
        plt.subplot(1, 2, 1)
        plt.scatter(pixid, peds)
        plt.title("Pedestals for event {}".format(event.r0.event_id))

        plt.subplot(1, 2, 2)
        plt.scatter(pixid, pedvars)
        plt.title("Ped Variances for event {}".format(event.r0.event_id))

    def calc_pedestals(self):
        start = 15
        end = None

        for event in hessio_event_source(self.filename):
            for telid in event.r0.tels_with_data:
                for chan in range(event.r0.tel[telid].adc_samples.shape[0]):
                    traces = event.r0.tel[telid].adc_samples[chan, ...]
                    peds, pedvars = pedestals.calc_pedestals_from_traces(
                        traces, start, end)

                    print("Number of samples: {}".format(traces.shape[1]))
                    print("Calculate over window:({},{})".format(start, end))
                    print("PEDS:", peds)
                    print("VARS:", pedvars)
                    print("-----")

        self.plot_peds(event, peds, pedvars)
        plt.show()

    def get_image(self):

        all_pe = []
        for event in hessio_event_source(self.filename):
            for telid in event.r0.tels_with_data:
                self.calib.calibrate(event)
                im = event.dl1.tel[telid].image
                # print(im[0])
                all_pe = all_pe + list(im[0])
        return all_pe

    def get_charge(self):
        fig = plt.figure(1)
        ax = fig.add_subplot(111)

        calculator = ChargeResolutionCalculator(config=None, tool=None)
        calculator2 = ChargeResolutionCalculator(config=None, tool=None)

        pevals = [
            1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 20,
            21, 23, 24, 26, 28, 30, 32, 35, 37, 40, 43, 46, 49, 53, 57, 61, 65,
            70, 75, 81, 86, 93, 100, 107, 114, 123, 132, 141, 151, 162, 174,
            187, 200, 215, 231, 247, 265, 284, 305, 327, 351, 376, 403, 432,
            464, 497, 533, 572, 613, 657, 705, 756, 811, 869, 932, 1000
        ]

        for n, i in enumerate(pevals):
            self.filename = '/Users/armstrongt/Workspace/CTA/MCValidation/data/bypass2_enoise_pe_e%s.simtel.gz' % n
            ntrig = 0
            source = hessio_event_source(self.filename,
                                         allowed_tels=None,
                                         max_events=None)
            for event in source:
                self.calib.calibrate(event)
                true_charge = event.mc.tel[
                    1].photo_electron_image * self.pixel_mask
                measured_charge = event.dl1.tel[1].image[0] * self.pixel_mask
                true_charge2 = np.asarray(
                    [int(i)] * len(measured_charge)) * self.pixel_mask
                calculator.add_charges(true_charge, measured_charge)
                calculator2.add_charges(true_charge2, measured_charge)
                ntrig = ntrig + 1

        x, res, res_error, scaled_res, scaled_res_error = calculator.get_charge_resolution(
        )
        x2, res2, res_error2, scaled_res2, scaled_res_error2 = calculator2.get_charge_resolution(
        )
        ax.errorbar(x,
                    res,
                    yerr=res_error,
                    marker='x',
                    linestyle="None",
                    label='MC Charge Res')
        ax.errorbar(x2,
                    res2,
                    yerr=res_error2,
                    marker='x',
                    color='C1',
                    linestyle="None",
                    label='\'Lab\' Charge Res')
        x = np.logspace(np.log10(0.9), np.log10(1000 * 1.1), 100)
        requirement = ChargeResolutionCalculator.requirement(x)
        goal = ChargeResolutionCalculator.goal(x)
        poisson = ChargeResolutionCalculator.poisson(x)
        r_p = ax.plot(x, requirement, 'r', ls='--', label='Requirement')
        g_p = ax.plot(x, goal, 'g', ls='--', label='Goal')
        p_p = ax.plot(x, poisson, c='0.75', ls='--', label='Poisson')
        plt.legend()
        plt.yscale('log')
        plt.xscale('log')
        plt.xlabel('true charge')
        plt.ylabel('charge resolution')
        plt.show()

    def get_trig_eff(self):
        fig = plt.figure(1)
        ax = fig.add_subplot(111)

        pevals = [
            1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 20,
            21, 23, 24, 26, 28, 30, 32, 35, 37, 40, 43, 46, 49, 53, 57, 61, 65,
            70, 75, 81, 86, 93, 100, 107, 114, 123, 132, 141, 151, 162, 174,
            187, 200, 215, 231, 247, 265, 284, 305, 327, 351, 376, 403, 432,
            464, 497, 533, 572, 613, 657, 705, 756, 811, 869, 932, 1000
        ]

        sum_image = []
        sum_true_charge = []
        sum_true_charge2 = []
        trig = []
        for n, i in enumerate(pevals):
            self.filename = '/Users/armstrongt/Workspace/CTA/MCValidation/data/bypass2_enoise_pe_e%s.simtel.gz' % n
            ntrig = 0
            source = hessio_event_source(self.filename,
                                         allowed_tels=None,
                                         max_events=None)
            sum_image_i = []
            sum_true_charge_i = []
            for event in source:
                self.calib.calibrate(event)
                true_charge = event.mc.tel[
                    1].photo_electron_image * self.pixel_mask
                measured_charge = event.dl1.tel[1].image[0]
                true_charge2 = np.asarray([int(i)] * len(measured_charge))
                sum_image_i.append(sum(measured_charge))
                sum_true_charge_i.append(sum(true_charge))
                ntrig = ntrig + 1

            sum_true_charge2.append(10 * i)
            sum_image.append(np.mean(sum_image_i))
            sum_true_charge.append(np.mean(sum_true_charge_i))
            trig.append(ntrig)

        plt.plot(sum_image, trig, label='measured')
        plt.plot(sum_true_charge2, trig, label='true input')
        plt.plot(sum_true_charge, trig, label='true measured')
        plt.xlabel('total charge')
        plt.ylabel('trigger efficiency')
        plt.legend()

        plt.show()

    def go(self):
        fig = plt.figure()
        ax = fig.add_subplot(111)
        disp = None
        source = hessio_event_source(self.filename, requested_event=24)
        for event in source:
            self.calib.calibrate(event)
            for i in range(50):
                ipix = np.random.randint(0, 2048)
                samp = event.dl0.tel[1]['pe_samples'][0][ipix]
                # plt.plot(range(len(samp)),samp)

            plt.show()
            if disp is None:
                geom = event.inst.subarray.tel[1].camera
                disp = CameraDisplay(geom)
                # disp.enable_pixel_picker()
                disp.add_colorbar()
                plt.show(block=False)
            #
            im = event.dl1.tel[1].image[0]
            mask = tailcuts_clean(geom,
                                  im,
                                  picture_thresh=10,
                                  boundary_thresh=5)
            im[~mask] = 0.0
            maxpe = max(event.dl1.tel[1].image[0])
            disp.image = im
            print(np.mean(im), '+/-', np.std(im))

        plt.show()
コード例 #34
0
class MuonDisplayerTool(Tool):
    name = 'ctapipe-display-muons'
    description = t.Unicode(__doc__)

    infile = t.Unicode(
        help='input file name',
        default=get_dataset('gamma_test_large.simtel.gz')).tag(config=True)

    outfile = t.Unicode(help='output file name', default=None).tag(config=True)

    display = t.Bool(help='display the camera events',
                     default=False).tag(config=True)

    classes = t.List([
        CameraCalibrator,
    ])

    aliases = t.Dict({
        'infile': 'MuonDisplayerTool.infile',
        'outfile': 'MuonDisplayerTool.outfile',
        'display': 'MuonDisplayerTool.display'
    })

    def setup(self):
        self.calib = CameraCalibrator()

    def start(self):

        output_parameters = {
            'MuonEff': [],
            'ImpactP': [],
            'RingWidth': [],
            'RingCont': [],
            'RingComp': [],
            'RingPixComp': [],
            'Core_x': [],
            'Core_y': [],
            'Impact_x_arr': [],
            'Impact_y_arr': [],
            'MCImpactP': [],
            'ImpactDiff': [],
            'RingSize': [],
            'RingRadius': [],
            'NTels': []
        }

        numev = 0
        num_muons_found = 0

        for event in event_source(self.infile):
            self.log.info("Event Number: %d, found %d muons", numev,
                          num_muons_found)
            self.calib.calibrate(event)
            muon_evt = analyze_muon_event(event)

            numev += 1

            if not muon_evt[
                    'MuonIntensityParams']:  # No telescopes contained a good muon
                continue
            else:
                if self.display:
                    plot_muon_event(event, muon_evt)

                ntels = len(event.r0.tels_with_data)
                #if(len( event.r0.tels_with_data) <= 1):
                #continue
                #print("event.r0.tels_with_data", event.r0.tels_with_data)
                for tid in muon_evt['TelIds']:
                    idx = muon_evt['TelIds'].index(tid)
                    if muon_evt['MuonIntensityParams'][idx] is not None:
                        print("pos, tid", event.inst.subarray.positions[tid],
                              tid)
                        tel_x = event.inst.subarray.positions[tid][0]
                        tel_y = event.inst.subarray.positions[tid][1]
                        core_x = event.mc.core_x  # MC Core x
                        core_y = event.mc.core_y  # MC Core y
                        rec_impact_x = muon_evt['MuonIntensityParams'][
                            idx].impact_parameter_pos_x
                        rec_impact_y = muon_evt['MuonIntensityParams'][
                            idx].impact_parameter_pos_y
                        print("rec_impact_x, rec_impact_y", rec_impact_x,
                              rec_impact_y)
                        print("event.mc.core_x, event.mc.core_y",
                              event.mc.core_x, event.mc.core_y)
                        impact_mc = np.sqrt(
                            np.power(core_x - tel_x, 2) +
                            np.power(core_y - tel_y, 2))
                        print("simulated impact", impact_mc)
                        # Coordinate transformation to move the impact point to array coordinates
                        rec_impact_x_arr = tel_x + rec_impact_x
                        rec_impact_y_arr = tel_y + rec_impact_y
                        print("impact_x_arr, impact_y_arr", rec_impact_x_arr,
                              rec_impact_y_arr)
                        # Distance between core of the showe and impact parameter
                        impact_diff = np.sqrt(
                            np.power(core_x - rec_impact_x_arr, 2) +
                            np.power(core_y - rec_impact_y_arr, 2))
                        print("impact_diff ", impact_diff)
                        self.log.info("** Muon params: %s",
                                      muon_evt['MuonIntensityParams'][idx])

                        output_parameters['MuonEff'].append(
                            muon_evt['MuonIntensityParams']
                            [idx].optical_efficiency_muon)
                        output_parameters['ImpactP'].append(
                            muon_evt['MuonIntensityParams']
                            [idx].impact_parameter.value)
                        output_parameters['RingWidth'].append(
                            muon_evt['MuonIntensityParams']
                            [idx].ring_width.value)
                        output_parameters['RingCont'].append(
                            muon_evt['MuonRingParams'][idx].ring_containment)
                        output_parameters['RingComp'].append(
                            muon_evt['MuonIntensityParams']
                            [idx].ring_completeness)
                        output_parameters['RingPixComp'].append(
                            muon_evt['MuonIntensityParams']
                            [idx].ring_pix_completeness)
                        output_parameters['Core_x'].append(
                            event.mc.core_x.value)
                        output_parameters['Core_y'].append(
                            event.mc.core_y.value)
                        output_parameters['Impact_x_arr'].append(
                            rec_impact_x_arr.value)
                        output_parameters['Impact_y_arr'].append(
                            rec_impact_y_arr.value)
                        output_parameters['MCImpactP'].append(impact_mc.value)
                        output_parameters['ImpactDiff'].append(
                            impact_diff.value)
                        output_parameters['RingSize'].append(
                            muon_evt['MuonIntensityParams'][idx].ring_size)
                        output_parameters['RingRadius'].append(
                            muon_evt['MuonRingParams'][idx].ring_radius.value)
                        output_parameters['NTels'].append(ntels)

                        print_muon(muon_evt, printer=self.log.info)
                        num_muons_found += 1

        t = Table(output_parameters)
        t['ImpactP'].unit = 'm'
        t['RingWidth'].unit = 'deg'
        #t['MCImpactP'].unit = 'm'
        if self.outfile:
            t.write(self.outfile)
コード例 #35
0
class MuonDisplayerTool(Tool):
    name = 'ctapipe-display-muons'
    description = t.Unicode(__doc__)

    events = t.Unicode("",
                       help="input event data file").tag(config=True)

    outfile = t.Unicode("muons.hdf5", help='HDF5 output file name').tag(
        config=True)

    display = t.Bool(
        help='display the camera events', default=False
    ).tag(config=True)

    classes = t.List([
        CameraCalibrator, EventSource
    ])

    aliases = t.Dict({
        'input': 'MuonDisplayerTool.events',
        'outfile': 'MuonDisplayerTool.outfile',
        'display': 'MuonDisplayerTool.display',
        'max_events': 'EventSource.max_events',
        'allowed_tels': 'EventSource.allowed_tels',
    })

    def setup(self):
        if self.events == '':
            raise ToolConfigurationError("please specify --input <events file>")
        self.log.debug("input: %s", self.events)
        self.source = event_source(self.events)
        self.calib = CameraCalibrator(
            config=self.config, tool=self, eventsource=self.source
        )
        self.writer = HDF5TableWriter(self.outfile, "muons")

    def start(self):

        numev = 0
        self.num_muons_found = defaultdict(int)

        for event in tqdm(self.source, desc='detecting muons'):

            self.calib.calibrate(event)
            muon_evt = analyze_muon_event(event)

            if numev == 0:
                _exclude_some_columns(event.inst.subarray, self.writer)

            numev += 1

            if not muon_evt['MuonIntensityParams']:
                # No telescopes  contained a good muon
                continue
            else:
                if self.display:
                    plot_muon_event(event, muon_evt)

                for tel_id in muon_evt['TelIds']:
                    idx = muon_evt['TelIds'].index(tel_id)
                    intens_params = muon_evt['MuonIntensityParams'][idx]

                    if intens_params is not None:
                        ring_params = muon_evt['MuonRingParams'][idx]
                        cam_id = str(event.inst.subarray.tel[tel_id].camera)
                        self.num_muons_found[cam_id] += 1
                        self.log.debug("INTENSITY: %s", intens_params)
                        self.log.debug("RING: %s", ring_params)
                        self.writer.write(table_name=cam_id,
                                          containers=[intens_params,
                                                      ring_params])

                self.log.info(
                    "Event Number: %d, found %s muons",
                    numev, dict(self.num_muons_found)
                )

    def finish(self):
        Provenance().add_output_file(self.outfile,
                                     role='dl1.tel.evt.muon')
        self.writer.close()
コード例 #36
0
class DisplayDL1Calib(Tool):
    name = "DisplayDL1Calib"
    description = "Calibrate dl0 data to dl1, and plot the photoelectron " \
                  "images."

    telescope = Int(
        None,
        allow_none=True,
        help='Telescope to view. Set to None to display all '
        'telescopes.'
    ).tag(config=True)

    aliases = Dict(
        dict(
            max_events='EventSourceFactory.max_events',
            extractor='ChargeExtractorFactory.product',
            window_width='ChargeExtractorFactory.window_width',
            t0='ChargeExtractorFactory.t0',
            window_shift='ChargeExtractorFactory.window_shift',
            sig_amp_cut_HG='ChargeExtractorFactory.sig_amp_cut_HG',
            sig_amp_cut_LG='ChargeExtractorFactory.sig_amp_cut_LG',
            lwt='ChargeExtractorFactory.lwt',
            clip_amplitude='CameraDL1Calibrator.clip_amplitude',
            T='DisplayDL1Calib.telescope',
            O='ImagePlotter.output_path'
        )
    )
    flags = Dict(
        dict(
            D=({
                'ImagePlotter': {
                    'display': True
                }
            }, "Display the photoelectron images on-screen as they "
               "are produced.")
        )
    )
    classes = List([
        EventSourceFactory, ChargeExtractorFactory, CameraDL1Calibrator,
        ImagePlotter
    ])

    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.eventsource = None
        self.calibrator = None
        self.plotter = None

    def setup(self):
        kwargs = dict(config=self.config, tool=self)

        self.eventsource = EventSourceFactory.produce(
            input_url=get_dataset_path("gamma_test.simtel.gz"), **kwargs
        )

        self.calibrator = CameraCalibrator(
            eventsource=self.eventsource, **kwargs
        )

        self.plotter = ImagePlotter(**kwargs)

    def start(self):
        for event in self.eventsource:
            self.calibrator.calibrate(event)

            tel_list = event.r0.tels_with_data

            if self.telescope:
                if self.telescope not in tel_list:
                    continue
                tel_list = [self.telescope]
            for telid in tel_list:
                self.plotter.plot(event, telid)

    def finish(self):
        self.plotter.finish()
コード例 #37
0
class PedestalGenerator(Tool):
    name = "PedestalGenerator"
    description = "Generate the a pickle file of Pedestals for " \
                  "either MC or data files."

    telescopes = Int(1,
                     help='Telescopes to include from the event file. '
                     'Default = 1').tag(config=True)
    pixel = Int(None, allow_none=True,
                help='Which pixel to use, defaul = all').tag(config=True)
    output_name = Unicode(
        'extracted_pedestals',
        help='path where to store the output extracted pedestal hdf5 '
        'file').tag(config=True)
    input_path = Unicode(help='Path to directory containing data').tag(
        config=True)

    max_events = Int(1,
                     help='Maximum number of events to use').tag(config=True)

    t0 = Int(0, help='Timeslice to start pedestal').tag(config=True)

    window_width = Int(
        10, help='length of window within which to determine pedestal').tag(
            config=True)

    debug = Bool(False, "plot resulting histograms").tag(config=True)

    aliases = Dict(
        dict(input_path='PedestalGenerator.input_path',
             max_events='PedestalGenerator.max_events',
             window_width='PedestalGenerator.window_width',
             t0='PedestalGenerator.t0',
             T='PedestalGenerator.telescopes',
             p='PedestalGenerator.pixel',
             o='PedestalGenerator.output_name',
             dd='PedestalGenerator.debug'))
    classes = List([
        EventSourceFactory, HESSIOEventSource, TargetIOEventSource,
        ChargeExtractorFactory, CameraDL1Calibrator, CameraCalibrator
    ])

    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.eventsource = None
        self.r1 = None
        self.dl0 = None
        self.dl1 = None
        self.cal = None
        self.run_list = None
        self.file_list = None
        self.baseline_bins = np.arange(0, 7, 7 / 17.)
        self.baseline_start_rms = []
        self.baseline_start_mean = []
        self.baseline_end_rms = []
        self.baseline_end_mean = []
        self.waveform_rms = []
        self.waveform_mean = []
        self.pulse_max = []
        self.pulse_fwhm = []
        self.pltnsb = [0.01, 0.05, 0.100, 0.200, 0.300, 0.500]

    def setup(self):
        kwargs = dict(config=self.config, tool=self)
        self.run_list = np.loadtxt('%s/../runlist.txt' % self.input_path,
                                   unpack=True)
        self.file_list = listdir('%s' % self.input_path)

        self.dl0 = CameraDL0Reducer(**kwargs)

        self.dl1 = CameraDL1Calibrator(**kwargs)

        self.cal = CameraCalibrator(
            eventsource=EventSourceFactory.produce(input_url="%s/%s" %
                                                   (self.input_path,
                                                    self.file_list[0]),
                                                   max_events=1))

    def start(self):
        for n, run in enumerate(self.run_list[0]):
            self.baseline_start_rms.append([])
            self.baseline_start_mean.append([])
            self.baseline_end_rms.append([])
            self.baseline_end_mean.append([])
            self.waveform_rms.append([])
            self.waveform_mean.append([])
            self.pulse_max.append([])
            self.pulse_fwhm.append([])

            # if self.run_list[6][n] not in self.pltnsb:
            #     print('lets save some time!')
            #     continue
            #check
            if str(int(run)) not in self.file_list[n]:
                print(str(int(run)), self.file_list[n])
                print('check runlist.txt order, needs to be sorted?')
                self.file_list.sort()
                if str(int(run)) not in self.file_list[n]:
                    print('Sorting didn\'t seem to help, giving up.')
                    exit()
                else:
                    print('Sorted and sorted.')
            file_name = "%s/%s" % (self.input_path, self.file_list[n])
            print(file_name)

            try:
                source = EventSourceFactory.produce(input_url=file_name,
                                                    max_events=self.max_events)

                for event in tqdm(source):
                    self.cal.calibrate(event)
                    self.dl0.reduce(event)
                    self.dl1.calibrate(event)

                    teldata = event.r1.tel[self.telescopes].waveform[0]

                    if self.pixel is None:

                        self.baseline_start_mean[n].append(
                            np.mean(np.mean(teldata[:, 0:20], axis=1)))
                        self.baseline_start_rms[n].append(
                            np.mean(np.std(teldata[:, 0:20], axis=1)))

                        self.baseline_end_mean[n].append(
                            np.mean(np.mean(teldata[:, -20:], axis=1)))
                        self.baseline_end_rms[n].append(
                            np.mean(np.std(teldata[:, -20:], axis=1)))

                        self.waveform_mean[n].append(
                            np.mean(np.mean(teldata, axis=1)))
                        self.waveform_rms[n].append(
                            np.mean(np.std(teldata, axis=1)))

                        pls_max = []
                        pls_fwhm = []

                        nm = len(teldata[0])
                        nmrange = np.arange(nm)
                        mean = np.mean(np.multiply(teldata, np.arange(nm)),
                                       axis=1)
                        #sigma = np.mean(teldata*(range(nm) - mean)**2, axis=1)

                        for i in range(0, 2048):
                            popt, pcov = curve_fit(gaus,
                                                   nmrange,
                                                   teldata[i],
                                                   p0=[1, mean[i], 3])
                            spline = UnivariateSpline(
                                nmrange,
                                gaus(nmrange, *popt) -
                                np.max(gaus(nmrange, *popt)) / 2,
                                s=0)
                            #print(nm, mean, sigma, popt)
                            #print(spline)
                            #exit()
                            try:
                                r1, r2 = spline.roots()
                            except ValueError:
                                r1 = 0
                                r2 = 0
                            fwhm = r2 - r1
                            mx = max(gaus(range(nm), *popt))
                            pls_max.append(mx)
                            pls_fwhm.append(fwhm)
                        self.pulse_fwhm[n].append(np.mean(pls_fwhm))
                        self.pulse_max[n].append(np.mean(pls_max))

                    else:

                        self.baseline_start_mean[n].append(
                            np.mean(teldata[self.pixel, 0:20]))
                        self.baseline_start_rms[n].append(
                            np.std(teldata[self.pixel, 0:20]))

                        self.baseline_end_mean[n].append(
                            np.mean(teldata[self.pixel, -20:]))
                        self.baseline_end_rms[n].append(
                            np.std(teldata[self.pixel, -20:]))

                        self.waveform_mean[n].append(
                            np.mean(teldata[self.pixel, :]))
                        self.waveform_rms[n].append(
                            np.std(teldata[self.pixel, :]))

                        n = len(teldata[0])
                        mean = sum(
                            range(len(teldata[0])) * (teldata[self.pixel])) / n
                        sigma = sum((teldata[self.pixel]) *
                                    (range(len(teldata[0])) - mean)**2) / n
                        popt, pcov = curve_fit(gaus,
                                               range(len(teldata[0])),
                                               teldata[self.pixel],
                                               p0=[1, mean, sigma])
                        spline = UnivariateSpline(
                            range(len(teldata[0])),
                            gaus(range(len(teldata[0])), *popt) -
                            np.max(gaus(range(len(teldata[0])), *popt)) / 2,
                            s=0)
                        r1, r2 = spline.roots()
                        fwhm = r2 - r1
                        mx = max(gaus(range(len(teldata[0])), *popt))
                        self.pulse_max[n].append(mx)
                        self.pulse_fwhm[n].append(fwhm)

            except FileNotFoundError:
                stop = 0
                print('file_not_found')

    def finish(self):
        if self.debug:

            fig1 = plt.figure(1)
            ax1 = fig1.add_subplot(111)
            fig2 = plt.figure(2)
            ax2 = fig2.add_subplot(111)
            fig3 = plt.figure(3)
            ax3 = fig3.add_subplot(111)
            fig4 = plt.figure(4)
            ax4 = fig4.add_subplot(111)
            fig5 = plt.figure(5)
            ax5 = fig5.add_subplot(111)
            fig6 = plt.figure(6)
            ax6 = fig6.add_subplot(111)
            fig7 = plt.figure(7)
            ax7 = fig7.add_subplot(111)
            fig8 = plt.figure(8)
            ax8 = fig8.add_subplot(111)

            for n in range(len(self.baseline_start_rms)):
                if len(self.baseline_start_mean[n]) > 0:
                    ax1.hist(self.baseline_start_mean[n],
                             bins=50,
                             alpha=0.9,
                             histtype='stepfilled',
                             label='%s MHz' % str(1000 * self.run_list[6][n]))
                    ax2.hist(self.baseline_start_rms[n],
                             bins=50,
                             alpha=0.9,
                             histtype='stepfilled',
                             label='%s MHz' % str(1000 * self.run_list[6][n]))
                    ax3.hist(self.baseline_end_mean[n],
                             bins=50,
                             alpha=0.9,
                             histtype='stepfilled',
                             label='%s MHz' % str(1000 * self.run_list[6][n]))
                    ax4.hist(self.baseline_end_rms[n],
                             bins=50,
                             alpha=0.9,
                             histtype='stepfilled',
                             label='%s MHz' % str(1000 * self.run_list[6][n]))
                    ax5.hist(self.waveform_mean[n],
                             bins=50,
                             alpha=0.9,
                             histtype='stepfilled',
                             label='%s MHz' % str(1000 * self.run_list[6][n]))
                    ax6.hist(self.waveform_rms[n],
                             bins=50,
                             alpha=0.9,
                             histtype='stepfilled',
                             label='%s MHz' % str(1000 * self.run_list[6][n]))
                    ax7.hist(self.pulse_max[n],
                             bins=50,
                             alpha=0.9,
                             histtype='stepfilled',
                             label='%s MHz' % str(1000 * self.run_list[6][n]))
                    ax8.hist(self.pulse_fwhm[n],
                             bins=50,
                             alpha=0.9,
                             histtype='stepfilled',
                             label='%s MHz' % str(1000 * self.run_list[6][n]))

            ax1.set_title('baseline_start_mean')
            ax2.set_title('baseline_start_rms')
            ax3.set_title('baseline_end_mean')
            ax4.set_title('baseline_end_rms')
            ax5.set_title('waveform_mean')
            ax6.set_title('waveform_rms')
            ax7.set_title('pulse_max')
            ax8.set_title('pulse_fwhm')

            ax1.legend()
            ax2.legend()
            ax3.legend()
            ax4.legend()
            ax5.legend()
            ax6.legend()
            ax7.legend()
            ax8.legend()
            plt.show()

        if not path.isdir(self.output_name):
            makedirs(self.output_name)

        columns_str = [
            'baselineStartMean', 'baselineStartRMS', 'baselineEndMean',
            'baselineEndRMS', 'baselineWaveformMean', 'baselineWaveformRMS',
            'pulseMAX', 'pulseFWHM'
        ]
        for n in range(len(self.baseline_start_rms)):
            if len(self.baseline_start_mean[n]) > 0:
                print(self.baseline_start_mean[n])
                out_array = np.array([
                    self.baseline_start_mean[n], self.baseline_start_rms[n],
                    self.baseline_end_mean[n], self.baseline_end_rms[n],
                    self.waveform_mean[n], self.waveform_rms[n],
                    self.pulse_max[n], self.pulse_fwhm[n]
                ])
                print(out_array, columns_str)
                data = pd.DataFrame(out_array.T, columns=columns_str)
                data.to_hdf(
                    '%s/extracted_pedestals_%sMHz.h5' %
                    (self.output_name, str(1000 * self.run_list[6][n])),
                    'table',
                    append=True)
                # columns_str.append('%sMHz_baselineStartMean' % str(1000*self.run_list[6][n]))
                # columns_str.append('%sMHz_baselineStartRMS' % str(1000*self.run_list[6][n]))
                # columns_str.append('%sMHz_baselineEndMean' % str(1000*self.run_list[6][n]))
                # columns_str.append('%sMHz_baselineEndRMS' % str(1000*self.run_list[6][n]))
                # columns_str.append('%sMHz_baselineWaveformMean' % str(1000*self.run_list[6][n]))
                # columns_str.append('%sMHz_baselineWaveformRMS' % str(1000*self.run_list[6][n]))

        # out_array = np.concatenate((self.baseline_start_mean,self.baseline_start_rms,
        #                             self.baseline_end_mean, self.baseline_end_rms,
        #                             self.waveform_mean, self.waveform_rms), axis=0)

        # data = pd.DataFrame(out_array.T, columns=columns_str)
        # data.columns = data.columns.str.split('_', expand=True)
        # print(data)
        # data.to_hdf(self.output_name, 'table', append=True)
        print('Done!')
コード例 #38
0
    'ASTRICam': (5, 7, 2),
}


input_url = get_dataset_path('gamma_test_large.simtel.gz')
event_source = EventSourceFactory.produce(input_url=input_url)

calibrator = CameraCalibrator(
    eventsource=event_source,
)

reco = HillasReconstructor()

for event in event_source:
    print('Event', event.count)
    calibrator.calibrate(event)

    # mapping of telescope_id to parameters for stereo reconstruction
    hillas_containers = {}
    pointing_azimuth = {}
    pointing_altitude = {}
    time_gradients = {}

    for telescope_id, dl1 in event.dl1.tel.items():
        camera = event.inst.subarray.tels[telescope_id].camera

        image = dl1.image[0]
        peakpos = dl1.peakpos[0]

        # cleaning
        boundary, picture, min_neighbors = cleaning_level[camera.cam_id]
コード例 #39
0
def extract_images(simtel_file_path,
                   tel_id_filter_list=None,
                   event_id_filter_list=None,
                   output_directory=None):

    # EXTRACT IMAGES ##########################################################

    # hessio_event_source returns a Python generator that streams data from an
    # EventIO/HESSIO MC data file (e.g. a standard CTA data file).
    # This generator contains ctapipe.core.Container instances ("event").
    #
    # Parameters:
    # - max_events: maximum number of events to read
    # - allowed_tels: select only a subset of telescope, if None, all are read.
    source = hessio_event_source(simtel_file_path,
                                 allowed_tels=tel_id_filter_list)

    # ITERATE OVER EVENTS #####################################################

    calib = CameraCalibrator(None, None)

    for event in source:

        calib.calibrate(event)  # calibrate the event

        event_id = int(event.dl0.event_id)

        if (event_id_filter_list is None) or (event_id
                                              in event_id_filter_list):

            #print("event", event_id)

            # ITERATE OVER IMAGES #############################################

            for tel_id in event.trig.tels_with_trigger:

                tel_id = int(tel_id)

                if tel_id in tel_id_filter_list:

                    #print("telescope", tel_id)

                    # CHECK THE IMAGE GEOMETRY ################################

                    #print("checking geometry")

                    x, y = event.inst.subarray.tel[
                        tel_id].camera.pix_x, event.inst.subarray.tel[
                            tel_id].camera.pix_y
                    foclen = event.inst.subarray.tel[
                        tel_id].optics.equivalent_focal_length
                    geom = CameraGeometry.guess(x, y, foclen)

                    if (geom.pix_type != "hexagonal") or (geom.cam_id !=
                                                          "DigiCam"):
                        raise ValueError(
                            "Telescope {}: error (the input image is not a valide DigiCam telescope image) -> {} ({})"
                            .format(tel_id, geom.pix_type, geom.cam_id))

                    # GET IMAGES ##############################################

                    pe_image = event.mc.tel[
                        tel_id].photo_electron_image  # 1D np array

                    #uncalibrated_image = event.dl0.tel[tel_id].adc_sums  # ctapipe 0.3.0
                    uncalibrated_image = event.r0.tel[
                        tel_id].adc_sums  # ctapipe 0.4.0
                    pedestal = event.mc.tel[tel_id].pedestal
                    gain = event.mc.tel[tel_id].dc_to_pe
                    pixel_pos = (event.inst.subarray.tel[tel_id].camera.pix_x,
                                 event.inst.subarray.tel[tel_id].camera.pix_y)

                    calibrated_image = event.dl1.tel[tel_id].image

                    #print(pe_image.shape)
                    #print(calibrated_image.shape)
                    #print(uncalibrated_image.shape)
                    #print(pedestal.shape)
                    #print(gain.shape)
                    #print(pixel_pos.shape)
                    #print(pixel_pos[0])
                    #print(pixel_pos[1])

                    # CONVERTING GEOMETRY (1D TO 2D) ##########################

                    buffer_id_str = geom.cam_id + "0"

                    geom2d, pe_image_2d = ctapipe_geom_converter.convert_geometry_1d_to_2d(
                        geom, pe_image, buffer_id_str, add_rot=0)
                    geom2d, calibrated_image_2d = ctapipe_geom_converter.convert_geometry_1d_to_2d(
                        geom, calibrated_image[0], buffer_id_str, add_rot=0)

                    geom2d, uncalibrated_image_2d = ctapipe_geom_converter.convert_geometry_1d_to_2d(
                        geom, uncalibrated_image[0], buffer_id_str, add_rot=0)
                    geom2d, pedestal_2d = ctapipe_geom_converter.convert_geometry_1d_to_2d(
                        geom, pedestal[0], buffer_id_str, add_rot=0)
                    geom2d, gains_2d = ctapipe_geom_converter.convert_geometry_1d_to_2d(
                        geom, gain[0], buffer_id_str, add_rot=0)

                    # Make a mock pixel position array...
                    pixel_pos_2d = np.array(
                        np.meshgrid(
                            np.linspace(pixel_pos[0].min(), pixel_pos[0].max(),
                                        pe_image_2d.shape[0]),
                            np.linspace(pixel_pos[1].min(), pixel_pos[1].max(),
                                        pe_image_2d.shape[1])))

                    # PUT NAN IN BLANK PIXELS #################################

                    calibrated_image_2d[np.logical_not(geom2d.mask)] = np.nan
                    pe_image_2d[np.logical_not(geom2d.mask)] = np.nan

                    uncalibrated_image_2d[np.logical_not(geom2d.mask)] = np.nan
                    pedestal_2d[np.logical_not(geom2d.mask)] = np.nan
                    gains_2d[np.logical_not(geom2d.mask)] = np.nan

                    pixel_pos_2d[0, np.logical_not(geom2d.mask)] = np.nan
                    pixel_pos_2d[1, np.logical_not(geom2d.mask)] = np.nan

                    ###########################################################

                    # The ctapipe geometry converter operate on one channel
                    # only and then takes and return a 2D array but pywicta
                    # fits files keep all channels and thus takes 3D arrays...

                    uncalibrated_image_2d = np.array([uncalibrated_image_2d])
                    pedestal_2d = np.array([pedestal_2d])
                    gains_2d = np.array([gains_2d])

                    ###########################################################

                    #print(pe_image_2d.shape)
                    #print(calibrated_image_2d.shape)
                    #print(uncalibrated_image_2d.shape)
                    #print(pedestal_2d.shape)
                    #print(gains_2d.shape)

                    #img = pixel_pos_2d
                    #print(img[1])

                    #import matplotlib.pyplot as plt
                    #im = plt.imshow(img[1])
                    #plt.colorbar(im)
                    #plt.show()
                    #sys.exit(0)

                    # GET PIXEL MASK ##########################################

                    pixel_mask = geom2d.mask.astype(
                        int
                    )  # 1 for pixels with actual data, 0 for virtual (blank) pixels

                    # MAKE METADATA ###########################################

                    metadata = {}

                    metadata[
                        'version'] = 1  # Version of the pywicta fits format

                    metadata['cam_id'] = "DigiCam"

                    metadata['tel_id'] = tel_id
                    metadata['event_id'] = event_id
                    metadata['simtel'] = simtel_file_path

                    metadata['tel_trig'] = len(event.trig.tels_with_trigger)

                    metadata['energy'] = quantity_to_tuple(
                        event.mc.energy, 'TeV')
                    metadata['mc_az'] = quantity_to_tuple(event.mc.az, 'rad')
                    metadata['mc_alt'] = quantity_to_tuple(event.mc.alt, 'rad')
                    metadata['mc_corex'] = quantity_to_tuple(
                        event.mc.core_x, 'm')
                    metadata['mc_corey'] = quantity_to_tuple(
                        event.mc.core_y, 'm')
                    metadata['mc_hfi'] = quantity_to_tuple(
                        event.mc.h_first_int, 'm')

                    metadata['count'] = int(event.count)

                    metadata['run_id'] = int(event.dl0.obs_id)
                    metadata['tel_data'] = len(event.dl0.tels_with_data)

                    metadata['foclen'] = quantity_to_tuple(
                        event.inst.subarray.tel[tel_id].optics.
                        equivalent_focal_length, 'm')
                    metadata['tel_posx'] = quantity_to_tuple(
                        event.inst.subarray.tel_coords[tel_id].x, 'm')
                    metadata['tel_posy'] = quantity_to_tuple(
                        event.inst.subarray.tel_coords[tel_id].y, 'm')
                    metadata['tel_posz'] = quantity_to_tuple(
                        event.inst.subarray.tel_coords[tel_id].z, 'm')

                    # TODO: Astropy fails to store the following data in FITS files
                    #metadata['uid'] = os.getuid()
                    #metadata['datetime'] = str(datetime.datetime.now())
                    #metadata['version'] = VERSION
                    #metadata['argv'] = " ".join(sys.argv).encode('ascii', errors='ignore').decode('ascii')
                    #metadata['python'] = " ".join(sys.version.splitlines()).encode('ascii', errors='ignore').decode('ascii')
                    #metadata['system'] = " ".join(os.uname())

                    # SAVE THE IMAGE ##########################################

                    output_file_path_template = "{}_TEL{:03d}_EV{:05d}.fits"

                    if output_directory is not None:
                        simtel_basename = os.path.basename(simtel_file_path)
                        prefix = os.path.join(output_directory,
                                              simtel_basename)
                    else:
                        prefix = simtel_file_path

                    output_file_path = output_file_path_template.format(
                        prefix, tel_id, event_id)

                    print("saving", output_file_path)

                    images.save_benchmark_images(
                        img=calibrated_image_2d,
                        pe_img=pe_image_2d,
                        adc_sums_img=uncalibrated_image_2d,
                        pedestal_img=pedestal_2d,
                        gains_img=gains_2d,
                        pixel_pos=pixel_pos_2d,
                        pixel_mask=pixel_mask,
                        metadata=metadata,
                        output_file_path=output_file_path)
コード例 #40
0
class ChargeResolutionGenerator(Tool):
    name = "ChargeResolutionGenerator"
    description = "Generate the a pickle file of ChargeResolutionFile for " \
                  "either MC or data files."

    telescopes = Int(1,help='Telescopes to include from the event file. '
                           'Default = 1').tag(config=True)
    output_name = Unicode('charge_resolution',
                          help='Name of the output charge resolution hdf5 '
                               'file').tag(config=True)
    input_path = Unicode(help='Path to directory containing data').tag(config=True)

    max_events = Int(1, help='Maximum number of events to use').tag(config=True)

    plot_cam = Bool(False, "enable plotting of individual camera").tag(config=True)

    use_true_pe = Bool(False, "Use true mc p.e.").tag(config=True)

    calibrator = Unicode('HESSIOR1Calibrator', help='which calibrator to use, default = HESSIOR1Calibrator').tag(config=True)

    aliases = Dict(dict(input_path='ChargeResolutionGenerator.input_path',
                        calibrator='ChargeResolutionGenerator.calibrator',
                        max_events='ChargeResolutionGenerator.max_events',
                        extractor='ChargeExtractorFactory.product',
                        window_width='ChargeExtractorFactory.window_width',
                        t0='ChargeExtractorFactory.t0',
                        window_shift='ChargeExtractorFactory.window_shift',
                        sig_amp_cut_HG='ChargeExtractorFactory.sig_amp_cut_HG',
                        sig_amp_cut_LG='ChargeExtractorFactory.sig_amp_cut_LG',
                        lwt='ChargeExtractorFactory.lwt',
                        clip_amplitude='CameraDL1Calibrator.clip_amplitude',
                        radius='CameraDL1Calibrator.radius',
                        max_pe='ChargeResolutionCalculator.max_pe',
                        T='ChargeResolutionGenerator.telescopes',
                        o='ChargeResolutionGenerator.output_name',
                        plot_cam='ChargeResolutionGenerator.plot_cam',
                        use_true_pe='ChargeResolutionGenerator.use_true_pe'
                        ))
    classes = List([EventSourceFactory,
                    HESSIOEventSource,
                    TargetIOEventSource,
                    ChargeExtractorFactory,
                    CameraDL1Calibrator,
                    ChargeResolutionCalculator,
                    CameraCalibrator
                    ])

    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.eventsource = None
        self.r1 = None
        self.dl0 = None
        self.dl1 = None
        self.calculator = None
        self.cal = None

    def setup(self):
        kwargs = dict(config=self.config, tool=self)
        self.dl0 = CameraDL0Reducer(**kwargs)

        self.dl1 = CameraDL1Calibrator(**kwargs)

        self.cal = CameraCalibrator(r1_product=self.calibrator)

        self.calculator = ChargeResolutionCalculator(**kwargs)


    def start(self):
        run_list = np.loadtxt('%s/runlist.txt' % self.input_path, unpack=True)
        plot_cam = False
        plot_delay = 0.5
        disp = None

        if debug:
            fig=plt.figure(1)
            ax=fig.add_subplot(111)
        for n, run in enumerate(run_list[0]):
            # TODO remove need for hardcoded file name
            if self.calibrator == "TargetIOR1Calibrator":
                file_name = "%s/Run%s_r1.tio" % (self.input_path, int(run))
                print(file_name)
            elif self.calibrator == "HESSIOR1Calibrator":
                file_name = "%s/sim_tel/run%s.simtel.gz" % (self.input_path, int(run))
                print(file_name)

            try:
                source = EventSourceFactory.produce(input_url =file_name, max_events=self.max_events)
                true_pe = []
                # lab_pe = []
                for event in tqdm(source):
                    self.cal.calibrate(event)
                    self.dl0.reduce(event)
                    self.dl1.calibrate(event)
                    input_pe = run_list[3][n]

                    if self.plot_cam == True:
                        if disp is None:
                            geom = event.inst.subarray.tel[self.telescopes].camera
                            disp = CameraDisplay(geom)
                            disp.add_colorbar()
                            plt.show(block=False)
                        im = event.dl1.tel[self.telescopes].image[0]
                        disp.image = im
                        plt.pause(plot_delay)

                    true_charge_mc = event.mc.tel[self.telescopes].photo_electron_image
                    measured_charge = event.dl1.tel[self.telescopes].image[0]
                    true_charge_lab = np.asarray([input_pe]*len(measured_charge))
                    true_pe.append(true_charge_mc)
                    if self.use_true_pe:
                        true_charge=true_charge_mc
                    else:
                        true_charge=true_charge_lab.astype(int)

                    self.calculator.add_charges(true_charge, measured_charge)

                    if debug:
                        plt.errorbar(input_pe, np.mean(true_pe), np.std(true_pe),color='k')
            except FileNotFoundError:
                stop=0
                print('file_not_found')
        if debug:
            plt.xscale('log')
            plt.yscale('log')
            plt.plot([0,1000],[0,1000], 'k:')
            plt.xlabel('Input p.e.')
            plt.ylabel('True mc p.e.')
            plt.show()
    def finish(self):
        out_file = '%s/charge_resolution_test.h5' % self.input_path
        self.calculator.save(self.output_name)
def extract_images(simtel_file_path,
                   tel_id_filter_list=None,
                   event_id_filter_list=None,
                   output_directory=None):

    # EXTRACT IMAGES ##########################################################

    # hessio_event_source returns a Python generator that streams data from an
    # EventIO/HESSIO MC data file (e.g. a standard CTA data file).
    # This generator contains ctapipe.core.Container instances ("event").
    # 
    # Parameters:
    # - max_events: maximum number of events to read
    # - allowed_tels: select only a subset of telescope, if None, all are read.
    source = hessio_event_source(simtel_file_path, allowed_tels=tel_id_filter_list)

    # ITERATE OVER EVENTS #####################################################

    calib = CameraCalibrator(None, None)

    for event in source:

        calib.calibrate(event)  # calibrate the event

        event_id = int(event.dl0.event_id)

        if (event_id_filter_list is None) or (event_id in event_id_filter_list):

            #print("event", event_id)

            # ITERATE OVER IMAGES #############################################

            for tel_id in event.trig.tels_with_trigger:

                tel_id = int(tel_id)

                if tel_id in tel_id_filter_list:

                    #print("telescope", tel_id)

                    # CHECK THE IMAGE GEOMETRY ################################

                    #print("checking geometry")

                    x, y = event.inst.pixel_pos[tel_id]
                    foclen = event.inst.optical_foclen[tel_id]
                    geom = CameraGeometry.guess(x, y, foclen)

                    if (geom.pix_type != "hexagonal") or (geom.cam_id != "LSTCam"):
                        raise ValueError("Telescope {}: error (the input image is not a valide LSTCam telescope image) -> {} ({})".format(tel_id, geom.pix_type, geom.cam_id))

                    # GET IMAGES ##############################################

                    pe_image = event.mc.tel[tel_id].photo_electron_image   # 1D np array

                    #uncalibrated_image = event.dl0.tel[tel_id].adc_sums  # ctapipe 0.3.0
                    uncalibrated_image = event.r0.tel[tel_id].adc_sums    # ctapipe 0.4.0
                    pedestal = event.mc.tel[tel_id].pedestal
                    gain = event.mc.tel[tel_id].dc_to_pe
                    pixel_pos = event.inst.pixel_pos[tel_id]

                    calibrated_image = event.dl1.tel[tel_id].image

                    calibrated_image[1, calibrated_image[0,:] <= LST_CAM_CHANNEL_THRESHOLD] = 0
                    calibrated_image[0, calibrated_image[0,:] >  LST_CAM_CHANNEL_THRESHOLD] = 0
                    calibrated_image = calibrated_image.sum(axis=0)

                    #print(pe_image.shape)
                    #print(calibrated_image.shape)
                    #print(uncalibrated_image.shape)
                    #print(pedestal.shape)
                    #print(gain.shape)
                    #print(pixel_pos.shape)
                    #print(pixel_pos[0])
                    #print(pixel_pos[1])

                    # CONVERTING GEOMETRY (1D TO 2D) ##########################

                    buffer_id_str = geom.cam_id + "0"

                    geom2d, pe_image_2d =           ctapipe_geom_converter.convert_geometry_1d_to_2d(geom, pe_image,           buffer_id_str, add_rot=0)
                    geom2d, calibrated_image_2d =   ctapipe_geom_converter.convert_geometry_1d_to_2d(geom, calibrated_image,   buffer_id_str, add_rot=0)

                    geom2d, uncalibrated_image_2d_ch0 = ctapipe_geom_converter.convert_geometry_1d_to_2d(geom, uncalibrated_image[0], buffer_id_str, add_rot=0)
                    geom2d, uncalibrated_image_2d_ch1 = ctapipe_geom_converter.convert_geometry_1d_to_2d(geom, uncalibrated_image[1], buffer_id_str, add_rot=0)
                    geom2d, pedestal_2d_ch0 =           ctapipe_geom_converter.convert_geometry_1d_to_2d(geom, pedestal[0],           buffer_id_str, add_rot=0)
                    geom2d, pedestal_2d_ch1 =           ctapipe_geom_converter.convert_geometry_1d_to_2d(geom, pedestal[1],           buffer_id_str, add_rot=0)
                    geom2d, gains_2d_ch0 =              ctapipe_geom_converter.convert_geometry_1d_to_2d(geom, gain[0],               buffer_id_str, add_rot=0)
                    geom2d, gains_2d_ch1 =              ctapipe_geom_converter.convert_geometry_1d_to_2d(geom, gain[1],               buffer_id_str, add_rot=0)

                    # Make a mock pixel position array...
                    pixel_pos_2d = np.array(np.meshgrid(np.linspace(pixel_pos[0].min(), pixel_pos[0].max(), pe_image_2d.shape[0]),
                                                        np.linspace(pixel_pos[1].min(), pixel_pos[1].max(), pe_image_2d.shape[1])))

                    ###########################################################

                    # The ctapipe geometry converter operate on one channel
                    # only and then takes and return a 2D array but datapipe
                    # fits files keep all channels and thus takes 3D arrays...

                    uncalibrated_image_2d = np.array([uncalibrated_image_2d_ch0, uncalibrated_image_2d_ch1])
                    pedestal_2d = np.array([pedestal_2d_ch0, pedestal_2d_ch1 ])
                    gains_2d = np.array([gains_2d_ch0, gains_2d_ch1])

                    # PUT NAN IN BLANK PIXELS #################################

                    calibrated_image_2d[np.logical_not(geom2d.mask)] = np.nan
                    pe_image_2d[np.logical_not(geom2d.mask)] = np.nan

                    uncalibrated_image_2d[0, np.logical_not(geom2d.mask)] = np.nan
                    uncalibrated_image_2d[1, np.logical_not(geom2d.mask)] = np.nan
                    pedestal_2d[0, np.logical_not(geom2d.mask)] = np.nan
                    pedestal_2d[1, np.logical_not(geom2d.mask)] = np.nan
                    gains_2d[0, np.logical_not(geom2d.mask)] = np.nan
                    gains_2d[1, np.logical_not(geom2d.mask)] = np.nan

                    pixel_pos_2d[0, np.logical_not(geom2d.mask)] = np.nan
                    pixel_pos_2d[1, np.logical_not(geom2d.mask)] = np.nan

                    ###########################################################

                    #print(pe_image_2d.shape)
                    #print(calibrated_image_2d.shape)
                    #print(uncalibrated_image_2d.shape)
                    #print(pedestal_2d.shape)
                    #print(gains_2d.shape)

                    #img = pixel_pos_2d
                    #print(img[1])

                    #import matplotlib.pyplot as plt
                    #im = plt.imshow(img[1])
                    #plt.colorbar(im)
                    #plt.show()
                    #sys.exit(0)

                    # GET PIXEL MASK ##########################################

                    pixel_mask = geom2d.mask.astype(int)  # 1 for pixels with actual data, 0 for virtual (blank) pixels

                    # MAKE METADATA ###########################################

                    metadata = {}

                    metadata['version'] = 1    # Version of the datapipe fits format

                    metadata['cam_id'] = "LSTCam"

                    metadata['tel_id'] = tel_id
                    metadata['event_id'] = event_id
                    metadata['simtel'] = simtel_file_path

                    metadata['tel_trig'] = len(event.trig.tels_with_trigger)

                    metadata['energy'] =  quantity_to_tuple(event.mc.energy, 'TeV')
                    metadata['mc_az'] = quantity_to_tuple(event.mc.az, 'rad')
                    metadata['mc_alt'] = quantity_to_tuple(event.mc.alt, 'rad')
                    metadata['mc_corex'] = quantity_to_tuple(event.mc.core_x, 'm')
                    metadata['mc_corey'] = quantity_to_tuple(event.mc.core_y, 'm')
                    metadata['mc_hfi'] = quantity_to_tuple(event.mc.h_first_int, 'm')

                    metadata['count'] = int(event.count)
                    
                    metadata['run_id'] = int(event.dl0.run_id)
                    metadata['tel_data'] = len(event.dl0.tels_with_data)

                    metadata['foclen'] = quantity_to_tuple(event.inst.optical_foclen[tel_id], 'm')
                    metadata['tel_posx'] = quantity_to_tuple(event.inst.tel_pos[tel_id][0], 'm')
                    metadata['tel_posy'] = quantity_to_tuple(event.inst.tel_pos[tel_id][1], 'm')
                    metadata['tel_posz'] = quantity_to_tuple(event.inst.tel_pos[tel_id][2], 'm')

                    # TODO: Astropy fails to store the following data in FITS files
                    #metadata['uid'] = os.getuid()
                    #metadata['datetime'] = str(datetime.datetime.now())
                    #metadata['version'] = VERSION
                    #metadata['argv'] = " ".join(sys.argv).encode('ascii', errors='ignore').decode('ascii')
                    #metadata['python'] = " ".join(sys.version.splitlines()).encode('ascii', errors='ignore').decode('ascii')
                    #metadata['system'] = " ".join(os.uname())

                    # SAVE THE IMAGE ##########################################

                    output_file_path_template = "{}_TEL{:03d}_EV{:05d}.fits"

                    if output_directory is not None:
                        simtel_basename = os.path.basename(simtel_file_path)
                        prefix = os.path.join(output_directory, simtel_basename)
                    else:
                        prefix = simtel_file_path

                    output_file_path = output_file_path_template.format(prefix,
                                                                        tel_id,
                                                                        event_id)

                    print("saving", output_file_path)

                    images.save_benchmark_images(img = calibrated_image_2d,
                                                 pe_img = pe_image_2d,
                                                 adc_sums_img = uncalibrated_image_2d,
                                                 pedestal_img = pedestal_2d,
                                                 gains_img = gains_2d,
                                                 pixel_pos = pixel_pos_2d,
                                                 pixel_mask = pixel_mask,
                                                 metadata = metadata,
                                                 output_file_path = output_file_path)
コード例 #42
0
class FlatFieldGenerator(Tool):
    name = "FlatFieldGenerator"
    description = "Generate the a pickle file of FlatField for " \
                  "either MC or data files."

    telescopes = Int(1,
                     help='Telescopes to include from the event file. '
                     'Default = 1').tag(config=True)
    output_name = Unicode('extracted_flatfield',
                          help='Name of the output extracted flat field hdf5 '
                          'file').tag(config=True)
    infile = Unicode(help='Path to file containing data').tag(config=True)

    max_events = Int(1,
                     help='Maximum number of events to use').tag(config=True)

    plot_cam = Bool(False,
                    "enable plotting of individual camera").tag(config=True)

    use_true_pe = Bool(False, "Use true mc p.e.").tag(config=True)

    calibrator = Unicode(
        'HESSIOR1Calibrator',
        help='which calibrator to use, default = HESSIOR1Calibrator').tag(
            config=True)
    debug = Bool(False, "plot resulting histograms").tag(config=True)

    aliases = Dict(
        dict(infile='FlatFieldGenerator.infile',
             calibrator='FlatFieldGenerator.calibrator',
             max_events='FlatFieldGenerator.max_events',
             extractor='ChargeExtractorFactory.product',
             window_width='ChargeExtractorFactory.window_width',
             t0='ChargeExtractorFactory.t0',
             window_shift='ChargeExtractorFactory.window_shift',
             sig_amp_cut_HG='ChargeExtractorFactory.sig_amp_cut_HG',
             sig_amp_cut_LG='ChargeExtractorFactory.sig_amp_cut_LG',
             lwt='ChargeExtractorFactory.lwt',
             clip_amplitude='CameraDL1Calibrator.clip_amplitude',
             radius='CameraDL1Calibrator.radius',
             T='FlatFieldGenerator.telescopes',
             o='FlatFieldGenerator.output_name',
             plot_cam='FlatFieldGenerator.plot_cam',
             use_true_pe='FlatFieldGenerator.use_true_pe',
             dd='FlatFieldGenerator.debug'))
    classes = List([
        EventSourceFactory, HESSIOEventSource, TargetIOEventSource,
        ChargeExtractorFactory, CameraDL1Calibrator, CameraCalibrator
    ])

    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.eventsource = None
        self.r1 = None
        self.dl0 = None
        self.dl1 = None
        self.calculator = None
        self.cal = None
        self.aver = None
        self.cross = None
        self.glob_peak = None
        self.local_peak = None
        self.neighbour = None
        self.reconstructed_image_array = []
        self.mean_reconstructed_image_array = None
        self.mean_true_image_array = None
        self.event_count = 0
        self.geom = None
        self.disp = None

    def setup(self):
        kwargs = dict(config=self.config, tool=self)
        self.dl0 = CameraDL0Reducer(**kwargs)
        self.dl1 = CameraDL1Calibrator(**kwargs)
        self.cal = CameraCalibrator(r1_product=self.calibrator)
        self.cross = CrossCorrelation()
        self.glob_peak = GlobalPeakIntegrator()
        self.local_peak = LocalPeakIntegrator()
        self.neighbour = NeighbourPeakIntegrator()
        self.aver = AverageWfPeakIntegrator()

    def start(self):
        fig1 = plt.figure(3)
        ax1 = fig1.add_subplot(111, aspect='equal')
        try:
            source = EventSourceFactory.produce(input_url=self.infile,
                                                max_events=self.max_events)

            for event in tqdm(source):
                self.cal.calibrate(event)
                self.dl0.reduce(event)
                self.dl1.calibrate(event)

                if self.disp is None:
                    self.geom = event.inst.subarray.tel[self.telescopes].camera
                    self.mean_reconstructed_image_array = np.zeros(
                        len(self.geom.pix_id))
                    self.mean_true_image_array = np.zeros(len(
                        self.geom.pix_id))
                    self.disp = 1
                    if self.debug:
                        self.disp = CameraDisplay(self.geom)
                        self.disp.add_colorbar()

                # reco_array = self.cross.get_charge(event.r1.tel[self.telescopes].waveform[0])['charge']
                # reco_array = self.glob_peak.extract_charge(event.r1.tel[self.telescopes].waveform)[0][0]
                reco_array = self.local_peak.extract_charge(
                    event.r1.tel[self.telescopes].waveform
                )[0][
                    0]  #/ np.mean(self.local_peak.extract_charge(event.r1.tel[self.telescopes].waveform)[0][0])
                true_array = event.mc.tel[
                    self.
                    telescopes].photo_electron_image  #/ np.mean(event.mc.tel[self.telescopes].photo_electron_image)
                # print(true_array)
                # print(reco_array)
                # exit()
                # plt.scatter(event.mc.tel[self.telescopes].photo_electron_image,reco_array)
                # plt.show()
                #
                # exit()
                # reco_array = self.aver.extract_charge(event.r1.tel[self.telescopes].waveform)[0][0]
                # reco_array = self.neighbour.extract_charge(event.r1.tel[self.telescopes].waveform)[0][0]
                # print(reco_array)
                # exit()
                # print(event.mc.tel[self.telescopes].photo_electron_image)

                self.mean_true_image_array = np.add(self.mean_true_image_array,
                                                    true_array)
                self.mean_reconstructed_image_array = np.add(
                    self.mean_reconstructed_image_array, reco_array)
                # print(self.mean_true_image_array)
                # print(self.mean_reconstructed_image_array)
                # dist = np.sqrt(self.geom.pix_x.value**2 + self.geom.pix_y.value**2)
                # plt.scatter( self.mean_true_image_array/np.mean(self.mean_true_image_array), self.mean_reconstructed_image_array/np.mean(self.mean_reconstructed_image_array), c = dist, alpha=0.4)
                # ax1.set_ylim(0,2)
                # ax1.set_xlim(0,2)
                # plt.draw()
                # plt.pause(0.4)
                # plt.cla()

                # self.reconstructed_image_array.append(event.dl1.tel[self.telescopes].image[0])
                self.event_count += 1
        except FileNotFoundError:
            print('file_not_found')

    def finish(self):
        # out_file = open(self.output_name)
        # out_file.write('#PixID meanIllum\n')
        # for i in range(len(self.reconstructed_image_array)):
        #     out_file.write('%s\t%s\n' % (self.geom.pix_id, self.reconstructed_image_array))
        # out_file.close()
        self.mean_reconstructed_image_array = self.mean_reconstructed_image_array / self.event_count
        self.mean_true_image_array = self.mean_true_image_array / self.event_count
        if self.debug:
            # mean_image = np.mean(self.reconstructed_image_array,axis=0)/np.mean(np.mean(self.reconstructed_image_array))
            mean_image = self.mean_reconstructed_image_array
            self.disp.image = self.mean_true_image_array

            # fig = plt.figure(3)
            # plt.hist(self.mean_true_image_array/self.mean_true_image_array.mean(), alpha = 0.5, label='true')
            # plt.hist( self.mean_reconstructed_image_array/self.mean_reconstructed_image_array.mean(), alpha = 0.5, label='reco')
            # plt.legend()
            # from IPython import embed
            # embed()
            # self.disp.norm = 'log'
            # self.disp.set_limits_minmax(40.5,44.5)
            plt.show()