<commit_before>#!/usr/bin/env python2

import logging
from optparse import OptionParser
import numpy as np
from time import time, strftime, gmtime, sleep

from pybar.run_manager import RunManager, run_status
from pybar.scans.scan_ext_trigger import ExtTriggerScan
from pybar.daq.readout_utils import build_events_from_raw_data, is_trigger_word

import sys
sys.path.append('/home/telescope/eudaq/python/')
from PyEUDAQWrapper import PyProducer


class EudaqExtTriggerScan(ExtTriggerScan):
    '''External trigger scan that connects to EUDAQ producer (EUDAQ 1.4 and higher).
    '''
    _default_run_conf = {
        "trig_count": 0,  # FE-I4 trigger count, number of consecutive BCs, 0 means 16, from 0 to 15
        "trigger_latency": 232,  # FE-I4 trigger latency, in BCs, external scintillator / TLU / HitOR: 232, USBpix self-trigger: 220
        "trigger_delay": 8,  # trigger delay, in BCs
        "trigger_rate_limit": 1000,  # artificially limiting the trigger rate, in BCs (25ns)
        "col_span": [1, 80],  # defining active column interval, 2-tuple, from 1 to 80
        "row_span": [1, 336],  # defining active row interval, 2-tuple, from 1 to 336
        "overwrite_enable_mask": False,  # if True, use col_span and row_span to define an active region regardless of the Enable pixel register. If False, use col_span and row_span to define active region by also taking Enable pixel register into account.
        "use_enable_mask_for_imon": False,  # if True, apply inverted Enable pixel mask to Imon pixel mask
        "no_data_timeout": None,  # no data timeout after which the scan will be aborted, in seconds
        "scan_timeout": None,  # timeout for scan after which the scan will be stopped, in seconds
        "max_triggers": 0,  # maximum triggers after which the scan will be stopped, if 0, no maximum triggers are set
        "enable_tdc": False  # if True, enables TDC (use RX2)
    }

    def scan(self):
        self.data_error_occurred = False
        self.last_trigger_number = None
        clock_cycles = self.dut['TLU']['TRIGGER_CLOCK_CYCLES']
        if clock_cycles:
            self.max_trigger_counter = 2 ** (clock_cycles - 1)
        else:
            self.max_trigger_counter = 2 ** 31
        start = time()
        lvl1_command = self.register.get_commands("zeros", length=self.trigger_delay)[0] + self.register.get_commands("LV1")[0] + self.register.get_commands("zeros", length=self.trigger_rate_limit)[0]
        self.register_utils.set_command(lvl1_command)

        self.remaining_data = np.ndarray((0,), dtype=np.uint32)

        with self.readout(**self.scan_parameters._asdict()):
            got_data = False
            while not self.stop_run.wait(1.0):
                if not got_data:
                    if self.fifo_readout.data_words_per_second() > 0:
                        got_data = True
                        logging.info('Taking data...')
                else:
                    triggers = self.dut['TLU']['TRIGGER_COUNTER']
                    data_words = self.fifo_readout.data_words_per_second()
                    logging.info('Runtime: %s\nTriggers: %d\nData words/s: %s\n' % (strftime('%H:%M:%S', gmtime(time() - start)), triggers, str(data_words)))
                    if self.max_triggers and triggers >= self.max_triggers:
                        self.stop(msg='Trigger limit was reached: %i' % self.max_triggers)

        pp.SendEvent(self.remaining_data)

        logging.info('Total amount of triggers collected: %d', self.dut['TLU']['TRIGGER_COUNTER'])

#     def analyze(self):
#         pass

    def handle_err(self, exc):
        self.err_queue.put(exc)
#         self.abort(msg='%s' % exc[1])
#         pp.logging(...)
        logging.warning(exc[1])
        self.data_error_occurred = True

    def handle_data(self, data):
        events = build_events_from_raw_data(data[0])
        for item in events:
            if item.shape[0] == 0:
                continue
            if is_trigger_word(item[0]):
                if self.remaining_data.shape[0] > 0:
                    # check trigger number
                    if is_trigger_word(self.remaining_data[0]):
                        trigger_number = self.remaining_data[0] & (self.max_trigger_counter - 1)
                        if self.last_trigger_number is not None and ((self.last_trigger_number + 1 != trigger_number and self.last_trigger_number + 1 != self.max_trigger_counter) or (self.last_trigger_number + 1 == self.max_trigger_counter and trigger_number != 0)):
                            if self.data_error_occurred:
                                if trigger_number > self.last_trigger_number:<commit_msg>ENH: use super<commit_after>#!/usr/bin/env python2

import logging
from optparse import OptionParser
import numpy as np
from time import time, strftime, gmtime, sleep

from pybar.run_manager import RunManager, run_status
from pybar.scans.scan_ext_trigger import ExtTriggerScan
from pybar.daq.readout_utils import build_events_from_raw_data, is_trigger_word

import sys
sys.path.append('/home/telescope/eudaq/python/')
from PyEUDAQWrapper import PyProducer


class EudaqExtTriggerScan(ExtTriggerScan):
    '''External trigger scan that connects to EUDAQ producer (EUDAQ 1.4 and higher).
    '''
    _default_run_conf = {
        "trig_count": 0,  # FE-I4 trigger count, number of consecutive BCs, 0 means 16, from 0 to 15
        "trigger_latency": 232,  # FE-I4 trigger latency, in BCs, external scintillator / TLU / HitOR: 232, USBpix self-trigger: 220
        "trigger_delay": 8,  # trigger delay, in BCs
        "trigger_rate_limit": 1000,  # artificially limiting the trigger rate, in BCs (25ns)
        "col_span": [1, 80],  # defining active column interval, 2-tuple, from 1 to 80
        "row_span": [1, 336],  # defining active row interval, 2-tuple, from 1 to 336
        "overwrite_enable_mask": False,  # if True, use col_span and row_span to define an active region regardless of the Enable pixel register. If False, use col_span and row_span to define active region by also taking Enable pixel register into account.
        "use_enable_mask_for_imon": False,  # if True, apply inverted Enable pixel mask to Imon pixel mask
        "no_data_timeout": None,  # no data timeout after which the scan will be aborted, in seconds
        "scan_timeout": None,  # timeout for scan after which the scan will be stopped, in seconds
        "max_triggers": 0,  # maximum triggers after which the scan will be stopped, if 0, no maximum triggers are set
        "enable_tdc": False  # if True, enables TDC (use RX2)
    }

    def scan(self):
        self.data_error_occurred = False
        self.last_trigger_number = None
        clock_cycles = self.dut['TLU']['TRIGGER_CLOCK_CYCLES']
        if clock_cycles:
            self.max_trigger_counter = 2 ** (clock_cycles - 1)
        else:
            self.max_trigger_counter = 2 ** 31
        start = time()
        lvl1_command = self.register.get_commands("zeros", length=self.trigger_delay)[0] + self.register.get_commands("LV1")[0] + self.register.get_commands("zeros", length=self.trigger_rate_limit)[0]
        self.register_utils.set_command(lvl1_command)

        self.remaining_data = np.ndarray((0,), dtype=np.uint32)

        with self.readout(**self.scan_parameters._asdict()):
            got_data = False
            while not self.stop_run.wait(1.0):
                if not got_data:
                    if self.fifo_readout.data_words_per_second() > 0:
                        got_data = True
                        logging.info('Taking data...')
                else:
                    triggers = self.dut['TLU']['TRIGGER_COUNTER']
                    data_words = self.fifo_readout.data_words_per_second()
                    logging.info('Runtime: %s\nTriggers: %d\nData words/s: %s\n' % (strftime('%H:%M:%S', gmtime(time() - start)), triggers, str(data_words)))
                    if self.max_triggers and triggers >= self.max_triggers:
                        self.stop(msg='Trigger limit was reached: %i' % self.max_triggers)

        pp.SendEvent(self.remaining_data)

        logging.info('Total amount of triggers collected: %d', self.dut['TLU']['TRIGGER_COUNTER'])

#     def analyze(self):
#         pass

    def handle_err(self, exc):
        super(EudaqExtTriggerScan, self).handle_err(exc=exc)
        self.data_error_occurred = True

    def handle_data(self, data):
        events = build_events_from_raw_data(data[0])
        for item in events:
            if item.shape[0] == 0:
                continue
            if is_trigger_word(item[0]):
                if self.remaining_data.shape[0] > 0:
                    # check trigger number
                    if is_trigger_word(self.remaining_data[0]):
                        trigger_number = self.remaining_data[0] & (self.max_trigger_counter - 1)
                        if self.last_trigger_number is not None and ((self.last_trigger_number + 1 != trigger_number and self.last_trigger_number + 1 != self.max_trigger_counter) or (self.last_trigger_number + 1 == self.max_trigger_counter and trigger_number != 0)):
                            if self.data_error_occurred:
                                if trigger_number > self.last_trigger_number:
{'fraction_non_alphanumeric': 0.0968682505399568, 'fraction_numerical': 0.016846652267818573, 'mean_word_length': 2.6006998444790046, 'pattern_counts': {'":': 24, '<': 3, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1672528', 'n_tokens_mistral': 2943, 'n_tokens_neox': 2727, 'n_words': 750}