def pseudoevent(self, score=True, update=True): """Called once per pseudoevent. If 'score' is True, run the consumer algorithm. If 'update' is True, run the producer algorithm. """ self.pseudoEventNumber += 1 outputRecord = OutputRecord(self.pseudoEventNumber, SELECTALL, pseudo=True) for segment in self.segmentRecords: currentContext = segment.pmmlModel.dataContext while not isinstance(currentContext, pmml.DataContext): currentContext.clear() currentContext = currentContext.parentContext currentContext.clear() groupsToKeys = {} for aggregate in segment.aggregates: groupName = aggregate.groupField if groupName is not None and groupName not in groupsToKeys: # find aggregates for this segment groupsToKeys[groupName] = aggregate.updators.keys() outputSegment = OutputSegment(segment) if len(groupsToKeys) == 0: if score: if segment.state() is MATURE or segment.state() is LOCKED: scores = segment.consumerAlgorithm.score( self.pseudoEventNumber, segment.pmmlModel.dataContext.get) else: scores = IMMATURE else: scores = INVALID if segment.pmmlOutput is not None: outputSegment.fields = segment.pmmlOutput.evaluate( segment.pmmlModel.dataContext.get, scores) if update and segment.state() is not LOCKED: self.updateSegment(segment, pseudoEvent=True) else: groupFields = groupsToKeys.keys() groupFields.sort() for groupField in groupFields: groupValues = groupsToKeys[groupField] for value in groupValues: segment.pmmlModel.dataContext.setOverride( {groupField: value}, False) if score: if segment.state() is MATURE or segment.state( ) is LOCKED: scores = segment.consumerAlgorithm.score( self.pseudoEventNumber, segment.pmmlModel.dataContext.get) else: scores = IMMATURE else: scores = INVALID outputMiniEvent = OutputMiniEvent() if segment.pmmlOutput is not None: outputMiniEvent.fields = segment.pmmlOutput.evaluate( segment.pmmlModel.dataContext.get, scores) segment.pmmlModel.dataContext.releaseOverride() if segment.consumerAlgorithm.pseudoOutputAll: outputSegment.minievents.append(outputMiniEvent) if not segment.consumerAlgorithm.pseudoOutputAll: outputSegment.minievents.append(outputMiniEvent) if update and segment.state() is not LOCKED: self.updateSegment(segment, pseudoEvent=True) outputRecord.segments.append(outputSegment) # clear all of the aggregates for aggregate in segment.aggregates: aggregate.flush() return outputRecord
def event(self, score=True, update=True, explicitSegments=None, predictedName=None): """Called once per event. If 'score' is True, run the consumer algorithm. If 'update' is True, run the producer algorithm. If 'explicitSegments' is a list of SegmentRecords, use these segments instead of finding the right ones. If 'predictedName' is a string, use this instead of what Output requires (for the case of no Output block). """ logInfo = self.logger.getEffectiveLevel() <= logging.INFO logDebug = self.logger.getEffectiveLevel() <= logging.DEBUG # increment the data stream self.eventNumber += 1 if logDebug: self.logger.debug("========== Starting event %d" % self.eventNumber) elif self.eventNumber % 1000 == 0: self.logger.info("========== Starting event %d" % self.eventNumber) self.metadata.startTiming("Time to advance through data") self.dataStream.next() self.metadata.stopTiming("Time to advance through data") self.logger.debug("Loaded a record from the data stream.") # update the PMML's header self.eventStamp.attrib["number"] = self.eventNumber self.timeStamp.children[0].text = [ datetime.datetime.today().isoformat() ] # find the matching segments if explicitSegments is None: segmentMatches = [] self.metadata.startTiming("Time searching for blacklisted items") blacklisted = self.segmentationScheme.blacklisted( self.pmmlModel.dataContext.get) self.metadata.stopTiming("Time searching for blacklisted items") if not blacklisted: self.metadata.startTiming("Time to look up existing segments") matchCandidates = self._getMatchCandidates() if self.multipleModelMethod is SELECTFIRST: for index in matchCandidates: segmentRecord = self.segmentRecords[index] if segmentRecord.predicateMatches( self.pmmlModel.dataContext.get): segmentMatches = [segmentRecord] break elif self.multipleModelMethod is SELECTALL: segmentMatches = [ self.segmentRecords[index] for index in matchCandidates if self.segmentRecords[index].predicateMatches( self.pmmlModel.dataContext.get) ] elif self.multipleModelMethod is SELECTONLY: segmentMatches = [self.segmentRecords[0]] self.metadata.stopTiming("Time to look up existing segments") if len(segmentMatches) == 0: self.metadata.startTiming( "Time to find and create new PMML segments") match = self.segmentationScheme.getMatch( self.pmmlModel.dataContext.get) self.metadata.stopTiming( "Time to find and create new PMML segments") if not match: if logInfo: self.logger.info(" ".join([ "Event %d did not match any segment descriptions; discarding." % self.eventNumber, "Data=%s" % self.pmmlModel.dataContext.contextString() ])) else: match = self._makeSegmentRecord(match, autoSegment=True) segmentMatches.append(match) else: if logInfo: self.logger.info(" ".join([ "Event %d matches a user blacklisted item, and will be ignored." % self.eventNumber, "Data=%s" % self.pmmlModel.dataContext.contextString() ])) else: segmentMatches = explicitSegments syncNumberSource = getattr(self.consumerUpdateScheme, "timeFieldName", None) if syncNumberSource is None: syncNumber = self.eventNumber else: syncNumber = self.pmmlModel.dataContext.get(syncNumberSource) # possibly do custom processing if self.customProcessing is not None: self.metadata.startTiming("Score calculation, total") matchingSegments = [s.userFriendly for s in segmentMatches] if logDebug: self.logger.debug( "About to enter customProcessing.doEvent() for event %d." % self.eventNumber) output = self.customProcessing.doEvent( syncNumber, self.eventNumber, self.pmmlModel.dataContext.get, matchingSegments) if logDebug: self.logger.debug("Finished customProcessing.doEvent().") for segmentMatch in segmentMatches: segmentMatch.pmmlModel.dataContext.clear() self.pmmlModel.dataContext.clear() self.metadata.stopTiming("Score calculation, total") return output # run the algorithms and create the output self.metadata.startTiming("Score calculation, total") outputRecord = OutputRecord(self.eventNumber, self.multipleModelMethod) ### big loop over segmentMatches for segmentMatch in segmentMatches: for l in self.logger, self.metadata: if "segment" in l.differentLevel: seglevels = l.differentLevel["segment"] segname = segmentMatch.name() if segname in seglevels: l.setLevel(seglevels[segname]) else: l.setLevel(l.eventLogLevel) else: l.setLevel(l.eventLogLevel) logInfo = self.logger.getEffectiveLevel() <= logging.INFO logDebug = self.logger.getEffectiveLevel() <= logging.DEBUG if logDebug: self.logger.debug( "Segment %s (%s) matched in event %d." % (segmentMatch.name(), segmentMatch.expressionTree, self.eventNumber)) if syncNumberSource is not None: syncNumber = segmentMatch.pmmlModel.dataContext.get( syncNumberSource) for aggregate in segmentMatch.aggregates: aggregate.increment(syncNumber, segmentMatch.pmmlModel.dataContext.get) if score and segmentMatch.pmmlModel.isScorable: if segmentMatch.state() is MATURE or segmentMatch.state( ) is LOCKED: if logDebug: self.logger.debug( "About to enter consumerAlgorithm.score() for event %d, segment %s." % (self.eventNumber, segmentMatch.name())) scores = segmentMatch.consumerAlgorithm.score( syncNumber, segmentMatch.pmmlModel.dataContext.get) if logDebug: self.logger.debug( "Finished consumerAlgorithm.score().") else: scores = IMMATURE else: scores = INVALID outputSegment = OutputSegment(segmentMatch) # override Output block if predictedName is not None: if scores is INVALID or scores is IMMATURE: outputSegment.fields = [(predictedName, scores)] elif scores is None: outputSegment.fields = [(predictedName, MISSING)] else: outputSegment.fields = [ (predictedName, scores.get(pmml.OutputField.predictedValue, MISSING)) ] # use Output block elif segmentMatch.pmmlOutput is not None: outputSegment.fields = segmentMatch.pmmlOutput.evaluate( segmentMatch.pmmlModel.dataContext.get, scores) outputRecord.segments.append(outputSegment) if update and segmentMatch.state() is not LOCKED: if logDebug: self.logger.debug( "About to enter producerAlgorithm.update() for event %d, segment %s." % (self.eventNumber, segmentMatch.name())) self.updateSegment(segmentMatch) if logDebug: self.logger.debug("Finished producerAlgorithm.update().") # clear the cache of each of the segment DataContexts segmentMatch.pmmlModel.dataContext.clear() # END big loop over segmentMatches for l in self.logger, self.metadata: l.setLevel(l.eventLogLevel) self.pmmlModel.dataContext.clear() self.metadata.stopTiming("Score calculation, total") return outputRecord
def verify(modelVerificationConfig, engine, logger, outputWriter): modelsWithVerification = [] if modelVerificationConfig.attrib.get("checkModel", True): if engine.pmmlModel.exists(pmml.ModelVerification): engine.pmmlModel.segmentRecord = None modelsWithVerification.append(engine.pmmlModel) if modelVerificationConfig.attrib.get("checkSegments", True): for segment in engine.segmentRecords: if segment.pmmlModel.exists(pmml.ModelVerification): segment.pmmlModel.segmentRecord = segment if segment.pmmlModel not in modelsWithVerification: modelsWithVerification.append(segment.pmmlModel) haltOnFailures = (modelVerificationConfig.attrib.get("onFailures", "halt") == "halt") reportInScores = modelVerificationConfig.attrib.get("reportInScores", False) for model in modelsWithVerification: logger.info("Evaluating ModelVerification in model %s%s." % (model.tag, model.fileAndLine())) for verificationBlockCounter, verification in enumerate(model.matches(pmml.ModelVerification)): verification.initialize() # the verificaiton block acts as a fake data stream engine.resetDataStream(verification) segmentRecord = model.segmentRecord while True: try: if segmentRecord is None: outputRecord = engine.event(score=True, update=False, explicitSegments=None, predictedName=verification.predictedName) else: outputRecord = engine.event(score=True, update=False, explicitSegments=[segmentRecord], predictedName=verification.predictedName) if len(outputRecord.segments) == 0: results = [(f, MISSING) for f in verification.predicted] else: results = outputRecord.segments[0].fields if reportInScores and outputWriter: verificationErrorsBlock = OutputRecord(outputRecord.eventNumber, SELECTONLY) verificationErrorsSegment = OutputSegment(None) verificationErrorsBlock.segments = [verificationErrorsSegment] for name, resultValue in results: if name in verification.column: expectedValue = verification.get(name) if isinstance(resultValue, (float, int, long)): try: expectedValue = float(expectedValue) except AttributeError: verified = False else: zeroThreshold = verification.zeroThreshold[name] if abs(expectedValue) <= zeroThreshold: verified = (abs(resultValue) <= zeroThreshold) else: precision = verification.precision[name] verified = ((expectedValue * (1. - precision)) <= resultValue <= (expectedValue * (1. + precision))) else: verified = (expectedValue == resultValue) if not verified: modelName = model.attrib.get("modelName", None) if modelName is not None: modelName = ", modelName \"%s\"" % modelName else: modelName = "" errorString = "Verification failure in ModelVerification %d%s in model %s%s%s, row %d (\"<%s>\"): %s (\"%s\") expected to be %s, calculated to be %s" % (verificationBlockCounter, verification.fileAndLine(), model.tag, model.fileAndLine(), modelName, verification.table.index, verification.table.rows[verification.table.index].content(), name, verification.column[name], str(expectedValue), str(resultValue)) if haltOnFailures: raise ModelVerificationError, errorString else: logger.error(errorString) if reportInScores and outputWriter: verificationErrorsSegment.fields.append((name, resultValue)) if reportInScores and outputWriter: eventTags = [("model", "%s on line %s" % (model.tag, str(getattr(model, "lineStart", "unknown"))))] modelName = model.attrib.get("modelName", None) if modelName is not None: eventTags.append(("modelName", modelName)) eventTags.append(("block", str(verificationBlockCounter))) outputWriter.write(verificationErrorsBlock, eventTags=eventTags, eventName="ModelVerificationFailures") except StopIteration: break logger.info("Done with ModelVerification in model %s%s." % (model.tag, model.fileAndLine()))
def pseudoevent(self, score=True, update=True): """Called once per pseudoevent. If 'score' is True, run the consumer algorithm. If 'update' is True, run the producer algorithm. """ self.pseudoEventNumber += 1 outputRecord = OutputRecord(self.pseudoEventNumber, SELECTALL, pseudo=True) for segment in self.segmentRecords: currentContext = segment.pmmlModel.dataContext while not isinstance(currentContext, pmml.DataContext): currentContext.clear() currentContext = currentContext.parentContext currentContext.clear() groupsToKeys = {} for aggregate in segment.aggregates: groupName = aggregate.groupField if groupName is not None and groupName not in groupsToKeys: # find aggregates for this segment groupsToKeys[groupName] = aggregate.updators.keys() outputSegment = OutputSegment(segment) if len(groupsToKeys) == 0: if score: if segment.state() is MATURE or segment.state() is LOCKED: scores = segment.consumerAlgorithm.score(self.pseudoEventNumber, segment.pmmlModel.dataContext.get) else: scores = IMMATURE else: scores = INVALID if segment.pmmlOutput is not None: outputSegment.fields = segment.pmmlOutput.evaluate(segment.pmmlModel.dataContext.get, scores) if update and segment.state() is not LOCKED: self.updateSegment(segment, pseudoEvent=True) else: groupFields = groupsToKeys.keys() groupFields.sort() for groupField in groupFields: groupValues = groupsToKeys[groupField] for value in groupValues: segment.pmmlModel.dataContext.setOverride({groupField: value}, False) if score: if segment.state() is MATURE or segment.state() is LOCKED: scores = segment.consumerAlgorithm.score(self.pseudoEventNumber, segment.pmmlModel.dataContext.get) else: scores = IMMATURE else: scores = INVALID outputMiniEvent = OutputMiniEvent() if segment.pmmlOutput is not None: outputMiniEvent.fields = segment.pmmlOutput.evaluate(segment.pmmlModel.dataContext.get, scores) segment.pmmlModel.dataContext.releaseOverride() if segment.consumerAlgorithm.pseudoOutputAll: outputSegment.minievents.append(outputMiniEvent) if not segment.consumerAlgorithm.pseudoOutputAll: outputSegment.minievents.append(outputMiniEvent) if update and segment.state() is not LOCKED: self.updateSegment(segment, pseudoEvent=True) outputRecord.segments.append(outputSegment) # clear all of the aggregates for aggregate in segment.aggregates: aggregate.flush() return outputRecord
def event(self, score=True, update=True, explicitSegments=None, predictedName=None): """Called once per event. If 'score' is True, run the consumer algorithm. If 'update' is True, run the producer algorithm. If 'explicitSegments' is a list of SegmentRecords, use these segments instead of finding the right ones. If 'predictedName' is a string, use this instead of what Output requires (for the case of no Output block). """ # increment the data stream self.eventNumber += 1 self.metadata.startTiming("Time to advance through data") self.dataStream.next() self.metadata.stopTiming("Time to advance through data") # update the PMML's header self.eventStamp.attrib["number"] = self.eventNumber self.timeStamp.children[0].text = [datetime.datetime.today().isoformat()] # find the matching segments if explicitSegments is None: segmentMatches = [] self.metadata.startTiming("Time searching for blacklisted items") blacklisted = self.segmentationScheme.blacklisted(self.pmmlModel.dataContext.get) self.metadata.stopTiming("Time searching for blacklisted items") if not blacklisted: self.metadata.startTiming("Time to look up existing segments") matchCandidates = self._getMatchCandidates() if self.multipleModelMethod is SELECTFIRST: for index in matchCandidates: segmentRecord = self.segmentRecords[index] if segmentRecord.predicateMatches(self.pmmlModel.dataContext.get): segmentMatches = [segmentRecord] break elif self.multipleModelMethod is SELECTALL: segmentMatches = [ self.segmentRecords[index] for index in matchCandidates if self.segmentRecords[index].predicateMatches(self.pmmlModel.dataContext.get)] elif self.multipleModelMethod is SELECTONLY: segmentMatches = [self.segmentRecords[0]] self.metadata.stopTiming("Time to look up existing segments") if len(segmentMatches) == 0: self.metadata.startTiming("Time to find and create new PMML segments") match = self.segmentationScheme.getMatch(self.pmmlModel.dataContext.get) self.metadata.stopTiming("Time to find and create new PMML segments") if not match: if self.logInfo: self.logger.info(" ".join([ "Event %d did not match any segment descriptions; discarding." % self.eventNumber, "Data=%s" % self.pmmlModel.dataContext.contextString() ])) else: match = self._makeSegmentRecord(match, autoSegment=True) segmentMatches.append(match) else: if self.logInfo: self.logger.info(" ".join([ "Event %d matches a user blacklisted item, and will be ignored." % self.eventNumber, "Data=%s" % self.pmmlModel.dataContext.contextString() ])) else: segmentMatches = explicitSegments # run the algorithms and create the output self.metadata.startTiming("Score calculation, total") outputRecord = OutputRecord(self.eventNumber, self.multipleModelMethod) for segmentMatch in segmentMatches: if self.logDebug: self.logger.debug("Segment %s matched." % segmentMatch.expressionTree) syncNumberSource = getattr(self.consumerUpdateScheme, "timeFieldName", None) if syncNumberSource is None: syncNumber = self.eventNumber else: syncNumber = segmentMatch.pmmlModel.dataContext.get(syncNumberSource) for aggregate in segmentMatch.aggregates: aggregate.increment(syncNumber, segmentMatch.pmmlModel.dataContext.get) if score and segmentMatch.pmmlModel.isScorable: if segmentMatch.state() is MATURE or segmentMatch.state() is LOCKED: scores = segmentMatch.consumerAlgorithm.score(syncNumber, segmentMatch.pmmlModel.dataContext.get) else: scores = IMMATURE else: scores = INVALID outputSegment = OutputSegment(segmentMatch) # override Output block if predictedName is not None: if scores is INVALID or scores is IMMATURE: outputSegment.fields = [(predictedName, scores)] elif scores is None: outputSegment.fields = [(predictedName, MISSING)] else: outputSegment.fields = [(predictedName, scores.get(pmml.OutputField.predictedValue, MISSING))] # use Output block elif segmentMatch.pmmlOutput is not None: outputSegment.fields = segmentMatch.pmmlOutput.evaluate(segmentMatch.pmmlModel.dataContext.get, scores) outputRecord.segments.append(outputSegment) if update and segmentMatch.state() is not LOCKED: self.updateSegment(segmentMatch) # clear the cache of each of the segment DataContexts segmentMatch.pmmlModel.dataContext.clear() self.pmmlModel.dataContext.clear() self.metadata.stopTiming("Score calculation, total") return outputRecord
def event(self, score=True, update=True, explicitSegments=None, predictedName=None): """Called once per event. If 'score' is True, run the consumer algorithm. If 'update' is True, run the producer algorithm. If 'explicitSegments' is a list of SegmentRecords, use these segments instead of finding the right ones. If 'predictedName' is a string, use this instead of what Output requires (for the case of no Output block). """ logInfo = self.logger.getEffectiveLevel() <= logging.INFO logDebug = self.logger.getEffectiveLevel() <= logging.DEBUG # increment the data stream self.eventNumber += 1 if logDebug: self.logger.debug("========== Starting event %d" % self.eventNumber) elif self.eventNumber % 1000 == 0: self.logger.info("========== Starting event %d" % self.eventNumber) self.metadata.startTiming("Time to advance through data") self.dataStream.next() self.metadata.stopTiming("Time to advance through data") self.logger.debug("Loaded a record from the data stream.") # update the PMML's header self.eventStamp.attrib["number"] = self.eventNumber self.timeStamp.children[0].text = [datetime.datetime.today().isoformat()] # find the matching segments if explicitSegments is None: segmentMatches = [] self.metadata.startTiming("Time searching for blacklisted items") blacklisted = self.segmentationScheme.blacklisted(self.pmmlModel.dataContext.get) self.metadata.stopTiming("Time searching for blacklisted items") if not blacklisted: self.metadata.startTiming("Time to look up existing segments") matchCandidates = self._getMatchCandidates() if self.multipleModelMethod is SELECTFIRST: for index in matchCandidates: segmentRecord = self.segmentRecords[index] if segmentRecord.predicateMatches(self.pmmlModel.dataContext.get): segmentMatches = [segmentRecord] break elif self.multipleModelMethod is SELECTALL: segmentMatches = [ self.segmentRecords[index] for index in matchCandidates if self.segmentRecords[index].predicateMatches(self.pmmlModel.dataContext.get)] elif self.multipleModelMethod is SELECTONLY: segmentMatches = [self.segmentRecords[0]] self.metadata.stopTiming("Time to look up existing segments") if len(segmentMatches) == 0: self.metadata.startTiming("Time to find and create new PMML segments") match = self.segmentationScheme.getMatch(self.pmmlModel.dataContext.get) self.metadata.stopTiming("Time to find and create new PMML segments") if not match: if logInfo: self.logger.info(" ".join([ "Event %d did not match any segment descriptions; discarding." % self.eventNumber, "Data=%s" % self.pmmlModel.dataContext.contextString() ])) else: match = self._makeSegmentRecord(match, autoSegment=True) segmentMatches.append(match) else: if logInfo: self.logger.info(" ".join([ "Event %d matches a user blacklisted item, and will be ignored." % self.eventNumber, "Data=%s" % self.pmmlModel.dataContext.contextString() ])) else: segmentMatches = explicitSegments syncNumberSource = getattr(self.consumerUpdateScheme, "timeFieldName", None) if syncNumberSource is None: syncNumber = self.eventNumber else: syncNumber = self.pmmlModel.dataContext.get(syncNumberSource) # possibly do custom processing if self.customProcessing is not None: self.metadata.startTiming("Score calculation, total") matchingSegments = [s.userFriendly for s in segmentMatches] if logDebug: self.logger.debug("About to enter customProcessing.doEvent() for event %d." % self.eventNumber) output = self.customProcessing.doEvent(syncNumber, self.eventNumber, self.pmmlModel.dataContext.get, matchingSegments) if logDebug: self.logger.debug("Finished customProcessing.doEvent().") for segmentMatch in segmentMatches: segmentMatch.pmmlModel.dataContext.clear() self.pmmlModel.dataContext.clear() self.metadata.stopTiming("Score calculation, total") return output # run the algorithms and create the output self.metadata.startTiming("Score calculation, total") outputRecord = OutputRecord(self.eventNumber, self.multipleModelMethod) ### big loop over segmentMatches for segmentMatch in segmentMatches: for l in self.logger, self.metadata: if "segment" in l.differentLevel: seglevels = l.differentLevel["segment"] segname = segmentMatch.name() if segname in seglevels: l.setLevel(seglevels[segname]) else: l.setLevel(l.eventLogLevel) else: l.setLevel(l.eventLogLevel) logInfo = self.logger.getEffectiveLevel() <= logging.INFO logDebug = self.logger.getEffectiveLevel() <= logging.DEBUG if logDebug: self.logger.debug("Segment %s (%s) matched in event %d." % (segmentMatch.name(), segmentMatch.expressionTree, self.eventNumber)) if syncNumberSource is not None: syncNumber = segmentMatch.pmmlModel.dataContext.get(syncNumberSource) for aggregate in segmentMatch.aggregates: aggregate.increment(syncNumber, segmentMatch.pmmlModel.dataContext.get) if score and segmentMatch.pmmlModel.isScorable: if segmentMatch.state() is MATURE or segmentMatch.state() is LOCKED: if logDebug: self.logger.debug("About to enter consumerAlgorithm.score() for event %d, segment %s." % (self.eventNumber, segmentMatch.name())) scores = segmentMatch.consumerAlgorithm.score(syncNumber, segmentMatch.pmmlModel.dataContext.get) if logDebug: self.logger.debug("Finished consumerAlgorithm.score().") else: scores = IMMATURE else: scores = INVALID outputSegment = OutputSegment(segmentMatch) # override Output block if predictedName is not None: if scores is INVALID or scores is IMMATURE: outputSegment.fields = [(predictedName, scores)] elif scores is None: outputSegment.fields = [(predictedName, MISSING)] else: outputSegment.fields = [(predictedName, scores.get(pmml.OutputField.predictedValue, MISSING))] # use Output block elif segmentMatch.pmmlOutput is not None: outputSegment.fields = segmentMatch.pmmlOutput.evaluate(segmentMatch.pmmlModel.dataContext.get, scores) outputRecord.segments.append(outputSegment) if update and segmentMatch.state() is not LOCKED: if logDebug: self.logger.debug("About to enter producerAlgorithm.update() for event %d, segment %s." % (self.eventNumber, segmentMatch.name())) self.updateSegment(segmentMatch) if logDebug: self.logger.debug("Finished producerAlgorithm.update().") # clear the cache of each of the segment DataContexts segmentMatch.pmmlModel.dataContext.clear() # END big loop over segmentMatches for l in self.logger, self.metadata: l.setLevel(l.eventLogLevel) self.pmmlModel.dataContext.clear() self.metadata.stopTiming("Score calculation, total") return outputRecord