예제 #1
0
    def calculate_dead_fraction_all(self, output_channel, local_variables):
        
        log.debug("Calculating dead fractions for output: %i", output_channel)

        # local_variables is a list of IOVSets (one for each input channel), 
        # for this output channel.
        # Why would you call it local_variables?
        
        #prev_states = []
        
        dead_frac_iovs = IOVSet()
        calc_dead_frac = self.calculate_dead_fraction
        # loop over smallest IOV chunks for this output channel
        for since, until, states in process_iovs(self.run_iovs, *local_variables):
            run_iov = states[0]
            # state_iovs is now a list of iovs, one for each input channel mapped
            # to this output channel
            state_iovs = states[1:]
            
            states = [s.good for s in state_iovs]
                
            if run_iov._is_empty:
                # Ignore regions outside runs.
                continue
            
            iov_state = calc_dead_frac(since, until, output_channel, 
                                       states, state_iovs)
                                       
            dead_frac_iovs.add(since, until, output_channel, *iov_state)
            
        return dead_frac_iovs.solidify(DCSOFL_IOV)
예제 #2
0
 def merge_input_information(self, channel, *inputs):
     """
     Join up the information which was used to make a decision across 
     multiple variables.
     """
     result = IOVSet()
     for since, until, states in process_iovs(*inputs):
         info = tuple(state._orig_iov[3:] for state in states)
         result.add(since, until, channel, info)
         
     return result.solidify(GoodIOV) 
예제 #3
0
    def merge_inputs(self, channel, *inputs):
        """
        Merge multiple variables together for one input channel.
        Each 'inputs' arg is an IOVSet that corresponds to this input channel.
        """
        # inputs must correspond to and be in sync with subdetector.variables...?

        result = IOVSet()
        # combine the IOVSets into smallest chunks using process_iovs
        for since, until, states in process_iovs(*inputs):
            # Get the worst state for the list of vectors
            state = self.merge_variable_states(states)
            result.add(since, until, channel, state)
            
        return result.solidify(GoodIOV)
예제 #4
0
    def make_good_iovs(self, iovs):

        # Filter out channels which are permanently dead
        excluded_channels = self.excluded_channels
        if excluded_channels:
            iovs = iovs.empty(i for i in iovs
                              if i.channel not in excluded_channels)

        chans, iovsets = iovs.chans_iovsets

        result = IOVSet()
        for since, until, states in process_iovs(*iovsets):
            if not all(s and s.powerStatus for s in states):
                result.add(since, until, self.defect_name, True, "")

        return result.solidify(DefectIOV)
예제 #5
0
    def merge_globals(self, output_channel, dead_frac_iovs, global_variables):
        """
        Merge together global states to decide a final code
        
        If the dead fraction is unavailable, writes -1.
        """
        result_iovs = IOVSet()
        if self.run_iovs is not None:
            # run_iovs are used to constrain to what runs the calculator will
            # write. If there is a hole in `run_iovs`, then no records are emitted.
            state_ranges = process_iovs(self.run_iovs, dead_frac_iovs,
                                        *global_variables)
        else:
            state_ranges = process_iovs(dead_frac_iovs, *global_variables)

        for since, until, states in state_ranges:
            if self.run_iovs:
                # No run_iovs were specified, so run for all available input data
                run_iov, dead_frac_iov = states[:2]

                if run_iov._is_empty:
                    # We're outside of a run, don't write an IoV.
                    continue

                states = states[1:]
            else:
                dead_frac_iov = states[0]

            if not dead_frac_iov._is_empty:
                dead_fraction, thrust, n_config, n_working = dead_frac_iov[4:]
            else:
                dead_fraction, thrust, n_config, n_working = -1., 0., -1, -1
                states = states[1:]

            code = self.dq_worst(states)
            state = dead_fraction, thrust, n_config, n_working

            if code is WHITE:
                # Don't write empty regions
                continue

            result_iovs.add(since, until, output_channel, code, *state)

        return result_iovs.solidify(DCSOFL_IOV)
예제 #6
0
    def calculate_good_iovs(self, lbtime, subdetector):
        magnets = Magnets()
        result = magnets.run(lbtime)
        by_defect = result.by_channel

        toroid_ramp = by_defect.get("GLOBAL_TOROID_RAMPING", IOVSet())
        solenoid_ramp = by_defect.get("GLOBAL_SOLENOID_RAMPING", IOVSet())

        self.input_hashes = [hash(toroid_ramp), hash(solenoid_ramp)]
        result = IOVSet()

        events = process_iovs(toroid_ramp, solenoid_ramp)
        for since, until, (toroid, solenoid) in events:
            if toroid or solenoid:
                result.add(since, until, "LCD_MAGNETS_RAMPING", True, "")

        self.iovs = result.solidify(DefectIOV)

        return self
예제 #7
0
    def make_good_iovs(self, iovs):
        """
        The absence of an IoV means that channel is out of config.
        """

        seen_channels = set()
        result = IOVSet()
        for since, until, channel, (state, ) in process_iovs_mc(iovs):
            seen_channels.add(channel)
            if state._is_empty:
                # There is an IoV hole for this channel.
                result.add(since, until, channel, OUT_OF_CONFIG)

        # Need to deal with channels which were not seen at all for the query
        # range, since they will not appear in the above loop
        all_channels = self.subdetector.input_channel_set

        for missing_channel in (all_channels - seen_channels):
            result.add(0, 2**63 - 1, missing_channel, OUT_OF_CONFIG)

        return result.solidify(GoodIOV)
예제 #8
0
class IDBSDefectWriter:
    """
    Class for writing BS defects to an sqlite file
    """
    def __init__(self,
                 fileName,
                 forceNew=False,
                 dbName='IDBSDQ',
                 tag='nominal',
                 user='******'):
        """
        Initialise database connection 
        """
        self.defect = None
        self.iovs = IOVSet()
        self.user = user

        #self.allowedDefects = DefectsDB('').defect_names

        if not fileName: fileName = 'tmp.' + str(os.getpid()) + '.db'

        self.connect(fileName, forceNew, dbName, tag)

        pass

    def __del__(self):
        """
        Delete db to clear connection
        """

        os.system('[[ -f tmp.%s.db ]] && rm tmp.%s.db' %
                  (os.getpid(), os.getpid()))
        del self.db
        pass

    def connect(self,
                fileName,
                forceNew=False,
                dbName='IDBSDQ',
                tag='nominal'):
        """
        Open connection to defect DB
        """

        connString = 'sqlite://;schema=%s;dbname=%s' % (fileName, dbName)

        if forceNew and os.path.exists(fileName):
            os.remove(fileName)

        self.db = DefectsDB(
            connString, read_only=False, create=True, tag=(tag, 'HEAD')
        )  # Second tag is for virtual defects, which we are not interested in

        self.officialDb = DefectsDB()

        return

    def defectType(self, t):
        """
        Set defect type
        """
        self.defect = t

    def add(self,
            runMin=0,
            runMax=(1 << 31) - 1,
            lbMin=0,
            lbMax=(1 << 32) - 1):
        """
        Add iovs which are NOT defective to the list
        Note, lbMax is exclusive here (and inclusive when shown on defect web page). 
        """

        # Make since and until and convert to syntactially nice RunLumiType
        since = RunLumiType((runMin << 32) + lbMin)
        until = RunLumiType((runMax << 32) + lbMax)

        # IoVs which are not defective (i.e. beamspot good)
        self.iovs.add(since, until, self.defect, False)
        return

    def complete(self, runMin, runMax):
        """
        Complete a list of IoVs to cover all LBs in a run, treating empty ones as having 'emptyState'

        """

        # Create an IOV set covering the entire run(s)
        run_lbs = fetch_iovs("EOR",
                             runs=(runMin, runMax),
                             what=[],
                             with_channel=False)

        #         run_lbs = IOVSet()
        #         lbMin = 1
        #         lbMax = (1 << 32) -1  # Note, lbMax is exclusive
        #         since = RunLumiType((runMin << 32)+lbMin)
        #         until = RunLumiType((runMax << 32)+lbMax)
        #         run_lbs.add(since, until)

        if not len(run_lbs):
            print "WARNING: No LBs in run according to EOR_Params - are we running before the run has finished?"

        def lbsStartAtOne(iov):
            "Change LBs starting at 0 to start at 1"
            return iov._replace(since=RunLumi(iov.since.run, 1))

        # Start LBs from 1 rather than 0 (at request of P. Onyisi) as long as run has more than one LB (else skip)
        run_lbs = [lbsStartAtOne(iov) for iov in run_lbs if iov.until.lumi > 1]

        # Empty IOV set for adding full list of LBs too
        iovs = IOVSet()

        # Ask official DB if an IoV is currently defective so can unset only those if doing reprocessing
        defectsCurrentlyInDb = self.officialDb.retrieve(
            (runMin, 0), (runMax + 1, 0), [self.defect])

        # Order IOVs to avoid since > until
        self.iovs = IOVSet(sorted(self.iovs))

        #for since, until, (run_lb, iov, dbDefect) in process_iovs(run_lbs.solidify(RANGEIOV_VAL), self.iovs.solidify(DEFECTIOV_VAL), defectsCurrentlyInDb):
        for since, until, (run_lb, iov, dbDefect) in process_iovs(
                run_lbs, self.iovs.solidify(DEFECTIOV_VAL),
                defectsCurrentlyInDb):
            if not run_lb: continue  # Check valid

            #             # Start LBs from 1 rather than 0 (at request of P. Onyisi)
            #             # If this makes since==until, i.e. it was a [0->1) LB range then skip
            #             if since.lumi==0:
            #                 since = RunLumiType((since.run << 32)+since.lumi+1)
            #                 if since==until: continue

            # Add iovs from self.iovs treating empty ones as defective (i.e. beamspot bad/missing)
            if iov:
                # These are not defective
                if dbDefect and dbDefect.present:
                    # Only store not defective IoVs if they are present on the Db so we can unset them
                    # (don't want to write not present defects to Db unless really chaning an existing defect)
                    iovs.add(since, until, self.defect, False)
            else:
                # These are defective
                iovs.add(since, until, self.defect, True)

        self.iovs = iovs
        return

    def writeDefects(self, tag='nominal', nonpresent=False):
        """
        Write all defects to the database.  If 'nonpresent' is True then write the absent ones too
        """

        with self.db.storage_buffer:
            for since, until, defect, present in self.iovs:
                if not present and not nonpresent: continue
                #print since, until, present
                self._writeDefect(defect, since, until, present=present)

    def _writeDefect(self,
                     defect,
                     since,
                     until,
                     tag='nominal',
                     description='',
                     comment='',
                     present=True,
                     recoverable=False):
        """
        Write a single defect to the database
        """

        if not defect in self.db.defect_names:
            self.db.create_defect(defect, description)

        self.db.insert(defect, since, until, comment, self.user, present,
                       recoverable)

        return

    def dump(self, filename=None):
        """
        Dump defects to a file given by filename or stdout if no filename given
        """

        from DQUtils.utils import pprint_objects

        if filename is not None:
            f = open(filename.replace('.db', '.txt'), "w")
            # If not defects then nothing will be in the database and we write an empty file
            if len(self.iovs):
                pprint_objects(
                    self.db.retrieve(primary_only=True, nonpresent=True), f)
            f.close()
        else:
            if len(self.iovs):
                self.iovs.pprint()
            else:
                print '\nNo DQ defects'

        #         with open(filename.replace('.db', '.txt'), "w") as f:
        #             pprint_objects(self.db.retrieve(), f)

        return
예제 #9
0
    def complete(self, runMin, runMax):
        """
        Complete a list of IoVs to cover all LBs in a run, treating empty ones as having 'emptyState'

        """

        # Create an IOV set covering the entire run(s)
        run_lbs = fetch_iovs("EOR",
                             runs=(runMin, runMax),
                             what=[],
                             with_channel=False)

        #         run_lbs = IOVSet()
        #         lbMin = 1
        #         lbMax = (1 << 32) -1  # Note, lbMax is exclusive
        #         since = RunLumiType((runMin << 32)+lbMin)
        #         until = RunLumiType((runMax << 32)+lbMax)
        #         run_lbs.add(since, until)

        if not len(run_lbs):
            print "WARNING: No LBs in run according to EOR_Params - are we running before the run has finished?"

        def lbsStartAtOne(iov):
            "Change LBs starting at 0 to start at 1"
            return iov._replace(since=RunLumi(iov.since.run, 1))

        # Start LBs from 1 rather than 0 (at request of P. Onyisi) as long as run has more than one LB (else skip)
        run_lbs = [lbsStartAtOne(iov) for iov in run_lbs if iov.until.lumi > 1]

        # Empty IOV set for adding full list of LBs too
        iovs = IOVSet()

        # Ask official DB if an IoV is currently defective so can unset only those if doing reprocessing
        defectsCurrentlyInDb = self.officialDb.retrieve(
            (runMin, 0), (runMax + 1, 0), [self.defect])

        # Order IOVs to avoid since > until
        self.iovs = IOVSet(sorted(self.iovs))

        #for since, until, (run_lb, iov, dbDefect) in process_iovs(run_lbs.solidify(RANGEIOV_VAL), self.iovs.solidify(DEFECTIOV_VAL), defectsCurrentlyInDb):
        for since, until, (run_lb, iov, dbDefect) in process_iovs(
                run_lbs, self.iovs.solidify(DEFECTIOV_VAL),
                defectsCurrentlyInDb):
            if not run_lb: continue  # Check valid

            #             # Start LBs from 1 rather than 0 (at request of P. Onyisi)
            #             # If this makes since==until, i.e. it was a [0->1) LB range then skip
            #             if since.lumi==0:
            #                 since = RunLumiType((since.run << 32)+since.lumi+1)
            #                 if since==until: continue

            # Add iovs from self.iovs treating empty ones as defective (i.e. beamspot bad/missing)
            if iov:
                # These are not defective
                if dbDefect and dbDefect.present:
                    # Only store not defective IoVs if they are present on the Db so we can unset them
                    # (don't want to write not present defects to Db unless really chaning an existing defect)
                    iovs.add(since, until, self.defect, False)
            else:
                # These are defective
                iovs.add(since, until, self.defect, True)

        self.iovs = iovs
        return
예제 #10
0
class Pixels(DCSC_DefectTranslate_Subdetector):
    def __init__(self, *args, **kwargs):
        super(Pixels, self).__init__(*args, **kwargs)
        self.translators = [Pixels.pix_color_to_defect_translator]

    @staticmethod
    def pix_color_to_defect_translator(flag_iovs):
        from DCSCalculator2.consts import GREEN
        from DCSCalculator2.variable import DefectIOV
        from DQUtils import process_iovs
        rv = []

        defect_mapping = {
            101: "PIXEL_BARREL_STANDBY",
            102: "PIXEL_LAYER0_STANDBY",
            103: "PIXEL_IBL_STANDBY",
            104: "PIXEL_ENDCAPA_STANDBY",
            105: "PIXEL_ENDCAPC_STANDBY"
        }

        for since, until, states in process_iovs(
                *flag_iovs.by_channel.values()):
            #print states
            for state in states:
                if state.Code != GREEN:
                    badfrac = 'Standby module fraction: ' + str(state.deadFrac)
                    rv.append(
                        DefectIOV(since=since,
                                  until=until,
                                  channel=defect_mapping[state.channel],
                                  present=True,
                                  comment=badfrac))
        return rv

    input_db = "COOLOFL_DCS/CONDBR2"
    folder_base = "/PIXEL/DCS"

    cid_barrel, cid_blayer, cid_ibl = 101, 102, 103
    cid_endcapa, cid_endcapb = 104, 105

    mapping = {
        101: range(722, 1892),
        102: range(436, 722),
        103: range(156, 436),
        104: range(1892, 2036),
        105: range(12, 156),
    }

    variables = [
        DCSC_Variable("FSMSTATUS", lambda iov: iov.FSM_status in
                      ("OK", "WARNING")),
        DCSC_Variable("FSMSTATE", lambda iov: iov.FSM_state == "READY"),
    ]

    # Note barrel and blayer use different deadfraction_caution. Implemented in
    # calculate_iov below.
    dead_fraction_caution = 0.2
    dead_fraction_caution_barrel = 0.05
    dead_fraction_bad = 0.9

    assert dead_fraction_caution_barrel <= dead_fraction_caution, (
        "logic needs changing in calculate_iov before removing this assert")

    def start(self):
        self.bad_modules = IOVSet()

    def tally_additional_info(self, since, until, output_channel, states,
                              state_iovs):
        """
        Figure out which modules are OOC when
        """
        ooc_modules = self.get_ids_which_are(output_channel, states,
                                             OUT_OF_CONFIG)
        ooc_modules = tuple(sorted(ooc_modules))
        self.bad_modules.add(since, until, output_channel, ooc_modules)

    def done(self):
        if logger.isEnabledFor(logging.DEBUG):
            print "The following ranges indicate bad modules:"
            #from pprint import pprint
            #pprint(list(self.bad_modules))

    def calculate_dead_fraction(self, since, until, output_channel, states,
                                state_iovs):
        """
        Compute the dead fraction differently for the barrel and blayer.

        This function is written with the assumption that
        `dead_fraction_caution_barrel` is smaller than `dead_fraction_caution`
        because the new logic is only run if the code is better than Yellow.
        """
        cdf = super(Pixels, self).calculate_dead_fraction
        result = cdf(since, until, output_channel, states, state_iovs)

        self.tally_additional_info(since, until, output_channel, states,
                                   state_iovs)

        code, dead_fraction, thrust, n_config, n_working = result

        if (output_channel not in [self.cid_barrel, self.cid_blayer]
                or code <= YELLOW):
            # Result is already correct
            return result

        # Need to check whether code needs modifying.
        if self.dead_fraction_caution_barrel < dead_fraction < self.dead_fraction_bad:
            code = YELLOW

        return code, dead_fraction, thrust, n_config, n_working

    def initialize_name_mapping(self):
        from DQUtils.db import Databases, get_channel_ids_names

        f = Databases.get_folder("/TDAQ/EnabledResources/ATLAS/PIXEL/Modules",
                                 "COOLONL_TDAQ")
        cids, cnames, cmap = get_channel_ids_names(f)
        self.name_mapping = dict(zip(cids, cnames))
        self.name_mapping_initialized = True

    # TODO: is this ok??
    def get_name_for_input_channel(self, input_channel):
        """
        Transform an input channelid into a name
        """
        #if not getattr(self, "name_mapping_initialized", False):
        #    self.initialize_name_mapping()

        #if input_channel in self.name_mapping:
        #    return (input_channel, self.name_mapping[input_channel])

        return input_channel