Example #1
0
    def extract_condition(self, current, words, partType):

        # layout condition
        words = self.layout_condition(words)

        # checking number of arguments
        if len(words) < 3:
            logging.getLogger('MA5').error("condition '" + str(words) +
                                           "' is not correct.")
            return None

        # looking for observable
        # determining if doubleCondition case
        doubleCondition = False
        if words[0] not in self.main.observables.full_list:
            if words[2] not in self.main.observables.full_list:
                logging.getLogger('MA5').error(
                    "no observable found in condition '" + str(words) + "'")
                return None
            else:
                doubleCondition = True

        # double condition case
        if doubleCondition:

            # checking number of arguments
            if len(words) < 5:
                logging.getLogger('MA5').error("condition '" + str(words) +
                                               "' is not correct.")
                return None

            # extracting threshold
            try:
                threshold1 = float(words[0])
            except:
                logging.getLogger('MA5').error("'" + words[0] +
                                               "' must be a float value.")
                return None

            # extracting operator
            operator1 = self.extract_operator(words[1])
            if operator1 == OperatorType.UNKNOWN:
                logging.getLogger('MA5').error("operator '" + words[1] +
                                               "' is unknown.")
                return None

        # extracting threshold
        try:
            threshold = float(words[-1])
        except:
            logging.getLogger('MA5').error("'" + words[-1] +
                                           "' must be a float value.")
            return None

        # extracting operator
        operator = self.extract_operator(words[-2])
        if operator == OperatorType.UNKNOWN:
            logging.getLogger('MA5').error("operator '" + words[-2] +
                                           "' is unknown.")
            return None

        # extracting observable
        obsName = words[0]
        if doubleCondition:
            obsName = words[2]

        if partType == None and obsName not in self.main.observables.cut_event_list:
            logging.getLogger('MA5').error("observable '"+obsName+"' cannot be used for "+\
                          "rejecting an event.")
            return None
        if partType != None and obsName not in self.main.observables.cut_candidate_list:
            logging.getLogger('MA5').error("observable '"+obsName+"' cannot be used for "+\
                          "rejecting a candidate.")
            return None

        obsRef = self.main.observables.get(obsName)
        if partType == ArgumentType.COMBINATION and (len(
                obsRef.args) == 0 or obsRef.args[0] == ArgumentType.PARTICLE):
            logging.getLogger('MA5').error(
                "observable '" + obsName +
                "' can be used on a particle but not a combination of particles"
            )
            return None

        # Case with arguments
        arguments = []
        if (partType!=None and len(obsRef.args)>1) or \
           (partType==None and len(obsRef.args)>0) :

            # Checking opening-brace
            if (doubleCondition and words[3]!='(') or \
               (not doubleCondition and words[1]!='(')    :
                logging.getLogger('MA5').error("wrong syntax for the condition '" +\
                              str(words)+"'")
                return None

            # Checking closing-brace
            if words[-3] != ")":
                logging.getLogger('MA5').error("wrong syntax for the condition '" +\
                              str(words)+"'")
                return None

            # Creating new obsRef
            if partType == None:
                obsRef2 = obsRef
            else:
                obsRef2 = ObservableBase.Clone(obsRef,\
                                               args=obsRef.args[1:])

            # Extracting arguments
            if doubleCondition:
                arguments=self.extract_arguments(words[4:-3],\
                                                 obsName,\
                                                 obsRef2)
            else:
                arguments=self.extract_arguments(words[2:-3],\
                                                 obsName,\
                                                 obsRef2)

            # Checking arguments
            if arguments == None:
                return None

        # Case with no arguments
        else:
            if (doubleCondition and len(words)!=5) or \
               (not doubleCondition and len(words)!=3) :
                logging.getLogger('MA5').error("wrong number of arguments in the condition '"+\
                              str(words)+"'")
                return None

        # Checking operator consistency with double condition
        if doubleCondition:
            if not (  ( operator1 in [OperatorType.GREATER,OperatorType.GREATER_EQUAL] ) \
                      and \
                      ( operator  in [OperatorType.GREATER,OperatorType.GREATER_EQUAL] ) ) \
               and \
               not (  ( operator1 in [OperatorType.LESS,OperatorType.LESS_EQUAL] ) \
                      and \
                      ( operator  in [OperatorType.LESS,OperatorType.LESS_EQUAL] ) ):
                logging.getLogger('MA5').error(
                    'double conditions allowed are : < obs < , > obs >')
                return None

        # Storing condition
        if doubleCondition:
            current.sequence.append(ConditionSequence())
            if operator1 == OperatorType.LESS:
                newOperator1 = OperatorType.GREATER
            elif operator1 == OperatorType.GREATER:
                newOperator1 = OperatorType.LESS
            elif operator1 == OperatorType.LESS_EQUAL:
                newOperator1 = OperatorType.GREATER_EQUAL
            elif operator1 == OperatorType.GREATER_EQUAL:
                newOperator1 = OperatorType.LESS_EQUAL
            condition1 = ConditionType(obsRef, arguments, newOperator1,
                                       threshold1)
            current.sequence[-1].sequence.append(condition1)
            current.sequence[-1].sequence.append(ConditionConnector('and'))
            condition2 = ConditionType(obsRef, arguments, operator, threshold)
            current.sequence[-1].sequence.append(condition2)
        else:
            condition = ConditionType(obsRef, arguments, operator, threshold)
            current.sequence.append(condition)

        return True
Example #2
0
    def extract_sequence(self, current, sequence, partType):

        # Remove extra braces
        words = self.clean_sequence(sequence)
        # Loop over the words
        iword = 0
        while iword < len(words):

            # opening brace
            if words[iword] == '(':

                # opening-brace is allowed ?
                if len(current.sequence)!=0 and \
                   current.sequence[-1].__class__.__name__!='ConditionConnector':
                    logging.getLogger('MA5').error(
                        'opening-brace can be used at first position or after a logical connector'
                    )
                    return None

                # looking for the correspondig closing-brace
                nbrace = 1
                endBrace = -1
                for j in range(iword + 1, len(words)):
                    if words[j] == '(':
                        nbrace += 1
                    elif words[j] == ')':
                        nbrace -= 1
                    if nbrace == 0:
                        endBrace = j
                        break

                # closing-brace found ?
                if endBrace == -1:
                    logging.getLogger('MA5').error(
                        'no closing-brace for all opening-braces')
                    return None

                # add a new sequence
                current.sequence.append(ConditionSequence())
                res=self.extract_sequence(current.sequence[-1],\
                                          words[iword+1:endBrace],\
                                          partType)
                if res == None:
                    return None
                iword = endBrace

            # connector
            elif words[iword] in ['or', 'and']:
                if len(current.sequence)==0 or \
                       current.sequence[-1].__class__.__name__=="ConditionConnector":
                    logging.getLogger('MA5').error("connector '"+words[iword]+\
                                  "' must be used only after a condition block")
                else:
                    current.sequence.append(ConditionConnector(words[iword]))

            # other
            else:

                # cut condition is allowed ?
                if len(current.sequence)!=0 and \
                   current.sequence[-1].__class__.__name__!='ConditionConnector':
                    logging.getLogger('MA5').error("cut condition beginning by '"+words[iword]+\
                                  "' must be used at first position or " +\
                                  "after a logical connector")
                    return None

                # looking for the end of the block condition
                endCondition = -1
                for j in range(iword + 1, len(words)):
                    if words[j] in ['and', 'or']:
                        endCondition = j
                        break

                if endCondition != -1:
                    res=self.extract_condition(current,\
                                               words[iword:endCondition],\
                                               partType)
                    if res == None:
                        return None
                    iword = endCondition - 1
                else:
                    res=self.extract_condition(current,\
                                               words[iword:],\
                                               partType)
                    if res == None:
                        return None
                    break  # quit while loop

            # incrementing
            iword += 1

        # Last check
        if current.sequence[-1].__class__.__name__ == "ConditionConnector":
            logging.getLogger('MA5').error("a condition cannot be finished with a connector '" +\
                          current.sequence[-1].GetStringDisplay()+"'.")
            return None

        return True