<commit_before>import os
import inspect
import logging
import numpy as np
import progressbar
from threading import Timer
from collections import namedtuple, Mapping, OrderedDict

from pybar.analysis.analyze_raw_data import AnalyzeRawData
from pybar.fei4.register_utils import invert_pixel_mask, make_box_pixel_mask_from_col_row
from pybar.fei4_run_base import Fei4RunBase
from pybar.run_manager import RunManager

from basil.utils.BitLogic import BitLogic


class M26TelescopeScan(Fei4RunBase):
    '''External trigger scan with FE-I4 and up to 6 Mimosa26 telescope planes.

    For use with external scintillator (user RX0), TLU (use RJ45), FE-I4 HitOR (USBpix self-trigger).

    Note:
    Set up trigger in DUT configuration file (e.g. dut_configuration_mio.yaml).
    '''
    _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": 0,  # artificially limiting the trigger rate, in BCs (25ns)
        "col_span": [1, 79],  # 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": True,  # if True, apply inverted Enable pixel mask to Imon pixel mask
        "no_data_timeout": 120,  # no data timeout after which the scan will be aborted, in seconds
        "scan_timeout": 120,  # timeout for scan after which the scan will be stopped, in seconds
        "max_triggers": False,  # maximum triggers after which the scan will be stopped, in seconds
        "enable_tdc": False,  # if True, enables TDC (use RX2)
        "reset_rx_on_error": False  # long scans have a high propability for ESD related data transmission errors; recover and continue here
    }

    def init_dut(self): 
        map(lambda channel: channel.reset(), self.dut.get_modules('m26_rx'))
        self.dut['jtag'].reset()
        
        if 'm26_configuration' in self._conf:
            m26_config_file =  os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))), self._conf['m26_configuration'])
            
            logging.info('Loading m26 configuration file %s', m26_config_file)
            self.dut.set_configuration(m26_config_file)
            
            IR={"BSR_ALL":'00101',"DEV_ID_ALL":'01110',"BIAS_DAC_ALL":'01111',"LINEPAT0_REG_ALL":'10000',
                "DIS_DISCRI_ALL":'10001',"SEQUENCER_PIX_REG_ALL":'10010',"CONTROL_PIX_REG_ALL":'10011',
                "LINEPAT1_REG_ALL":'10100',"SEQUENCER_SUZE_REG_ALL":'10101',"HEADER_REG_ALL":'10110',
                "CONTROL_SUZE_REG_ALL":'10111',
                "CTRL_8b10b_REG0_ALL":'11000',"CTRL_8b10b_REG1_ALL":'11001',"RO_MODE1_ALL":'11101',
                "RO_MODE0_ALL":'11110',
                "BYPASS_ALL":'11111'}
            ## write JTAG
            irs = ["BIAS_DAC_ALL","BYPASS_ALL","BSR_ALL","RO_MODE0_ALL","RO_MODE1_ALL",
            "DIS_DISCRI_ALL","LINEPAT0_REG_ALL","LINEPAT1_REG_ALL","CONTROL_PIX_REG_ALL","SEQUENCER_PIX_REG_ALL",
            "HEADER_REG_ALL","CONTROL_SUZE_REG_ALL","SEQUENCER_SUZE_REG_ALL","CTRL_8b10b_REG0_ALL",
            "CTRL_8b10b_REG1_ALL"]
            for i,ir in enumerate(irs):
                logging.info('Programming M26 JATG configuration reg %s', ir)
                logging.debug(self.dut[ir][:])
                self.dut['jtag'].scan_ir([BitLogic(IR[ir])]*6)
                ret = self.dut['jtag'].scan_dr([self.dut[ir][:]])[0]
            ## read JTAG  and check
            irs=["DEV_ID_ALL","BSR_ALL","BIAS_DAC_ALL","RO_MODE1_ALL","RO_MODE0_ALL",
               "DIS_DISCRI_ALL","LINEPAT0_REG_ALL","LINEPAT1_REG_ALL","CONTROL_PIX_REG_ALL",
               "SEQUENCER_PIX_REG_ALL",
               "HEADER_REG_ALL","CONTROL_SUZE_REG_ALL","SEQUENCER_SUZE_REG_ALL","CTRL_8b10b_REG0_ALL",
               "CTRL_8b10b_REG1_ALL","BYPASS_ALL"]
            ret={}
            for i,ir in enumerate(irs):
                logging.info('Reading M26 JATG configuration reg %s', ir)
                self.dut['jtag'].scan_ir([BitLogic(IR[ir])]*6)
                ret[ir]= self.dut['jtag'].scan_dr([self.dut[ir][:]])[0]
            ## check
            for k,v in ret.iteritems():
                if k=="CTRL_8b10b_REG1_ALL":
                    pass
                elif k=="BSR_ALL":
                    pass #TODO mask clock bits and check others
                elif self.dut[k][:]!=v:
                    logging.error("JTAG data does not match %s get=%s set=%s"%(k,v,self.dut[k][:]))
                else:
                    logging.info("Checking M26 JTAG %s ok"%k)        
            #START procedure
            logging.info('Starting M26')
            temp=self.dut['RO_MODE0_ALL'][:]
              #disable extstart
            for reg in self.dut["RO_MODE0_ALL"]["RO_MODE0"]:
                reg['En_ExtStart']=0
                reg['JTAG_Start']=0
            self.dut['jtag'].scan_ir([BitLogic(IR['RO_MODE0_ALL'])]*6)
            self.dut['jtag'].scan_dr([self.dut['RO_MODE0_ALL'][:]])
              #JTAG start
            for reg in self.dut["RO_MODE0_ALL"]["RO_MODE0"]:
                reg['JTAG_Start']=1
            self.dut['jtag'].scan_ir([BitLogic(IR['RO_MODE0_ALL'])]*6)
            self.dut['jtag'].scan_dr([self.dut['RO_MODE0_ALL'][:]])
            for reg in self.dut["RO_MODE0_ALL"]["RO_MODE0"]:
                reg['JTAG_Start']=0
            self.dut['jtag'].scan_ir([BitLogic(IR['RO_MODE0_ALL'])]*6)
            self.dut['jtag'].scan_dr([self.dut['RO_MODE0_ALL'][:]])
              #write original configuration
            self.dut['RO_MODE0_ALL'][:]=temp
            self.dut['jtag'].scan_ir([BitLogic(IR['RO_MODE0_ALL'])]*6)
            self.dut['jtag'].scan_dr([self.dut['RO_MODE0_ALL'][:]])
              #readback?
            self.dut['jtag'].scan_ir([BitLogic(IR['RO_MODE0_ALL'])]*6)
            self.dut['jtag'].scan_dr([self.dut['RO_MODE0_ALL'][:]]*6)           
        else:
            logging.info('Skipping m26 configuration')
   

    def configure(self):
        commands = []
        commands.extend(self.register.get_commands("ConfMode"))
        # Enable
        enable_pixel_mask = make_box_pixel_mask_from_col_row(column=self.col_span, row=self.row_span)
        if not self.overwrite_enable_mask:
            enable_pixel_mask = np.logical_and(enable_pixel_mask, self.register.get_pixel_register_value('Enable'))
        self.register.set_pixel_register_value('Enable', enable_pixel_mask)
        commands.extend(self.register.get_commands("WrFrontEnd", same_mask_for_all_dc=False, name='Enable'))
        # Imon
        if self.use_enable_mask_for_imon:
            imon_pixel_mask = invert_pixel_mask(enable_pixel_mask)
        else:
            imon_pixel_mask = make_box_pixel_mask_from_col_row(column=self.col_span, row=self.row_span, default=1, value=0)  # 0 for selected columns, else 1<commit_msg>ENH: Add Remote Control for Agilent E3644A<commit_after>import os
import inspect
import logging
import numpy as np
import progressbar
import time
import sys
from threading import Timer
from collections import namedtuple, Mapping, OrderedDict

from pybar.analysis.analyze_raw_data import AnalyzeRawData
from pybar.fei4.register_utils import invert_pixel_mask, make_box_pixel_mask_from_col_row
from pybar.fei4_run_base import Fei4RunBase
from pybar.run_manager import RunManager

from basil.utils.BitLogic import BitLogic

from basil.dut import Dut

class M26TelescopeScan(Fei4RunBase):
    '''External trigger scan with FE-I4 and up to 6 Mimosa26 telescope planes.

    For use with external scintillator (user RX0), TLU (use RJ45), FE-I4 HitOR (USBpix self-trigger).

    Note:
    Set up trigger in DUT configuration file (e.g. dut_configuration_mio.yaml).
    '''
    _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": 0,  # artificially limiting the trigger rate, in BCs (25ns)
        "col_span": [1, 79],  # 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": True,  # if True, apply inverted Enable pixel mask to Imon pixel mask
        "no_data_timeout": 120,  # no data timeout after which the scan will be aborted, in seconds
        "scan_timeout": 60,  # timeout for scan after which the scan will be stopped, in seconds
        "max_triggers": False,  # maximum triggers after which the scan will be stopped, in seconds
        "enable_tdc": False,  # if True, enables TDC (use RX2)
        "reset_rx_on_error": True,  # long scans have a high propability for ESD related data transmission errors; recover and continue here
        "remote": True # if True, Powersupply remote is enabled
    }

    def init_dut(self): 
        
        if self.remote:
            dut = Dut('agilent_e3644a_pyserial.yaml')
            dut.init()
            status = dut['Powersupply'].get_enable()
            time.sleep(0.15)    
            status = status.replace("\n", "").replace("\r", "")
            status = int(status) #convert string to float in order to compare values!
            if status == 1:
                logging.info("Output of powersupply is ON, status: %s"%status)
            else:
                logging.info("Output of powersupply is OFF, status: %s" % status)  # TODO: STOP READOUT!!!
                #abort(msg='Scan timeout was reached')
                #stop_current_run(msg='OFF')
            current = dut['Powersupply'].get_current()
            current = current.replace("\n", "").replace("\r", "")
            logging.info('Current:  %s A', current)
            current = float(current)  # convert string to float in order to compare values!
        else:
            logging.info('No remote enabled')

        map(lambda channel: channel.reset(), self.dut.get_modules('m26_rx'))
        self.dut['jtag'].reset()

        if 'force_config_mimosa26' in self._conf and not self._conf['force_config_mimosa26'] and self.remote and current >= 3.3: #check if force_config is False
                logging.info('Skipping m26 configuration, m26 is already configured')
        else:     
            if 'm26_configuration' in self._conf and self._conf['m26_configuration']:
                m26_config_file =  os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))), self._conf['m26_configuration'])

                logging.info('Loading m26 configuration file %s', m26_config_file)
                self.dut.set_configuration(m26_config_file)

                IR={"BSR_ALL":'00101',"DEV_ID_ALL":'01110',"BIAS_DAC_ALL":'01111',"LINEPAT0_REG_ALL":'10000',
                    "DIS_DISCRI_ALL":'10001',"SEQUENCER_PIX_REG_ALL":'10010',"CONTROL_PIX_REG_ALL":'10011',
                    "LINEPAT1_REG_ALL":'10100',"SEQUENCER_SUZE_REG_ALL":'10101',"HEADER_REG_ALL":'10110',
                    "CONTROL_SUZE_REG_ALL":'10111',
                    "CTRL_8b10b_REG0_ALL":'11000',"CTRL_8b10b_REG1_ALL":'11001',"RO_MODE1_ALL":'11101',
                    "RO_MODE0_ALL":'11110',
                    "BYPASS_ALL":'11111'}
                ## write JTAG
                irs = ["BIAS_DAC_ALL","BYPASS_ALL","BSR_ALL","RO_MODE0_ALL","RO_MODE1_ALL",
                "DIS_DISCRI_ALL","LINEPAT0_REG_ALL","LINEPAT1_REG_ALL","CONTROL_PIX_REG_ALL","SEQUENCER_PIX_REG_ALL",
                "HEADER_REG_ALL","CONTROL_SUZE_REG_ALL","SEQUENCER_SUZE_REG_ALL","CTRL_8b10b_REG0_ALL",
                "CTRL_8b10b_REG1_ALL"]
                for i,ir in enumerate(irs):
                    logging.info('Programming M26 JATG configuration reg %s', ir)
                    logging.debug(self.dut[ir][:])
                    self.dut['jtag'].scan_ir([BitLogic(IR[ir])]*6)
                    ret = self.dut['jtag'].scan_dr([self.dut[ir][:]])[0]
                    
                if self.remote:    
                    current = dut['Powersupply'].get_current()
                    current = current.replace("\n", "").replace("\r", "")
                    logging.info('Current:  %s A', current)  
                ## read JTAG  and check
                irs=["DEV_ID_ALL","BSR_ALL","BIAS_DAC_ALL","RO_MODE1_ALL","RO_MODE0_ALL",
                   "DIS_DISCRI_ALL","LINEPAT0_REG_ALL","LINEPAT1_REG_ALL","CONTROL_PIX_REG_ALL",
                   "SEQUENCER_PIX_REG_ALL",
                   "HEADER_REG_ALL","CONTROL_SUZE_REG_ALL","SEQUENCER_SUZE_REG_ALL","CTRL_8b10b_REG0_ALL",
                   "CTRL_8b10b_REG1_ALL","BYPASS_ALL"]
                ret={}
                for i,ir in enumerate(irs):
                    logging.info('Reading M26 JATG configuration reg %s', ir)
                    self.dut['jtag'].scan_ir([BitLogic(IR[ir])]*6)
                    ret[ir]= self.dut['jtag'].scan_dr([self.dut[ir][:]])[0]
                
                if self.remote:
                    current = dut['Powersupply'].get_current()
                    current = current.replace("\n", "").replace("\r", "")
                    logging.info('Current:  %s A', current)    
                ## check
                for k,v in ret.iteritems():
                    if k=="CTRL_8b10b_REG1_ALL":
                        pass
                    elif k=="BSR_ALL":
                        pass #TODO mask clock bits and check others
                    elif self.dut[k][:]!=v:
                        logging.error("JTAG data does not match %s get=%s set=%s"%(k,v,self.dut[k][:]))
                    else:
                        logging.info("Checking M26 JTAG %s ok"%k)
                    
                if self.remote:    
                    current = dut['Powersupply'].get_current()
                    current = current.replace("\n", "").replace("\r", "")
                    logging.info('Current:  %s A', current)    
                #START procedure
                logging.info('Starting M26')
                temp=self.dut['RO_MODE0_ALL'][:]
                  #disable extstart
                for reg in self.dut["RO_MODE0_ALL"]["RO_MODE0"]:
                    reg['En_ExtStart']=0
                    reg['JTAG_Start']=0
                self.dut['jtag'].scan_ir([BitLogic(IR['RO_MODE0_ALL'])]*6)
                self.dut['jtag'].scan_dr([self.dut['RO_MODE0_ALL'][:]])
                  #JTAG start
                for reg in self.dut["RO_MODE0_ALL"]["RO_MODE0"]:
                    reg['JTAG_Start']=1
                self.dut['jtag'].scan_ir([BitLogic(IR['RO_MODE0_ALL'])]*6)
                self.dut['jtag'].scan_dr([self.dut['RO_MODE0_ALL'][:]])
                for reg in self.dut["RO_MODE0_ALL"]["RO_MODE0"]:
                    reg['JTAG_Start']=0
                self.dut['jtag'].scan_ir([BitLogic(IR['RO_MODE0_ALL'])]*6)
                self.dut['jtag'].scan_dr([self.dut['RO_MODE0_ALL'][:]])
                  #write original configuration
                self.dut['RO_MODE0_ALL'][:]=temp
                self.dut['jtag'].scan_ir([BitLogic(IR['RO_MODE0_ALL'])]*6)
                self.dut['jtag'].scan_dr([self.dut['RO_MODE0_ALL'][:]])
                  #readback?
                self.dut['jtag'].scan_ir([BitLogic(IR['RO_MODE0_ALL'])]*6)
                self.dut['jtag'].scan_dr([self.dut['RO_MODE0_ALL'][:]]*6)
                
                if self.remote:
                    current = dut['Powersupply'].get_current()
                    current = current.replace("\n", "").replace("\r", "")
                    logging.info('Current:  %s A', current)
            else:
                logging.info('Skipping m26 configuration')
            
    def configure(self):
        commands = []
        commands.extend(self.register.get_commands("ConfMode"))
        # Enable
        enable_pixel_mask = make_box_pixel_mask_from_col_row(column=self.col_span, row=self.row_span)
        if not self.overwrite_enable_mask:
            enable_pixel_mask = np.logical_and(enable_pixel_mask, self.register.get_pixel_register_value('Enable'))
        self.register.set_pixel_register_value('Enable', enable_pixel_mask)
        commands.extend(self.register.get_commands("WrFrontEnd", same_mask_for_all_dc=False, name='Enable'))
        # Imon
        if self.use_enable_mask_for_imon:
            imon_pixel_mask = invert_pixel_mask(enable_pixel_mask)
        else:
            imon_pixel_mask = make_box_pixel_mask_from_col_row(column=self.col_span, row=self.row_span, default=1, value=0)  # 0 for selected columns, else 1
{'fraction_non_alphanumeric': 0.12362132352941177, 'fraction_numerical': 0.02877987132352941, 'mean_word_length': 2.4727707959305807, 'pattern_counts': {'":': 63, '<': 3, '<?xml version=': 0, '>': 4, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4648736', 'n_tokens_mistral': 5949, 'n_tokens_neox': 5518, 'n_words': 1081}