Exemple #1
0
 def getSignalTreeFromJob(self, job, dilepton, cut="", useNLL=False):
         if len(self.runRanges) > 1:
                 log.logError("Should only have one runRange when calling getTreeFromJob")
         
         runRange = self.runRanges[0]
         
         signalType = job.split("_")[0]
         
         append = {}
         append["2016"] = "_Summer16"
         append["2017"] = "_Fall17"
         append["2018"] = "_Autumn18"
         
         if useNLL:
                 path = locations[runRange.era]["dataSetPathSignalNLL%s"%signalType]
         else:
                 path = locations[runRange.era]["dataSetPathSignal%s"%signalType]
         tree = ROOT.TChain()
         tree.Add(readTrees(path, dilepton)[job+append[runRange.era]])
         
         if (cut != ""):
                 log.logDebug("Cutting tree down to: %s" % cut)
                 if tree.GetEntries() > 0:
                         tree = tree.CopyTree(cut)
                 log.logError("Tree size: %d entries" % (tree.GetEntries()))
         
         if (tree != None):
                 tree.SetDirectory(0)
         
         return tree
Exemple #2
0
        def clone(self):
                if (self.is2DHistogram):
                        log.logError("Cloning of 2d histograms not supported!")
                        return None

                cloneHistogram = ROOT.TH1F(self.histogram)
                clone = Result(cloneHistogram)
                clone.dataName = self.dataName
                clone.dataVersion = self.dataVersion
                clone.taskName = self.taskName
                clone.flagName = self.flagName
                clone.dataType = self.dataType
                clone.scaled = self.scaled

                clone.unscaledIntegral = self.unscaledIntegral
                clone.scalingFactor = self.scalingFactor
                clone.luminosity = self.luminosity
                clone.xSection = self.xSection
                clone.kFactor = self.kFactor
                clone.nEvents = self.nEvents
                clone.__scaledAndAdded = self.__scaledAndAdded
                clone.currentIntegralError = self.currentIntegralError

                clone.title = self.title

                # not supported
                self.is2DHistogram = False
                return clone
Exemple #3
0
 def getTreeFromJob(self, job, dilepton, cut="", useNLL=False):
         if len(self.runRanges) > 1:
                 log.logError("Should only have one runRange when calling getTreeFromJob")
         
         runRange = self.runRanges[0]
         
         if useNLL:
                 path = locations[runRange.era].dataSetPathNLL
         else:
                 path = locations[runRange.era].dataSetPath
         tree = ROOT.TChain()
         tree.Add(readTrees(path, dilepton)[job])
         
         cut = cut + runRange.runCut
         if useNLL:
                 cut = cut + " && vetoHEM == 1"
         
         if (cut != ""):
                 log.logDebug("Cutting tree down to: %s" % cut)
                 if tree.GetEntries() > 0:
                         tree = tree.CopyTree(cut)
                 log.logError("Tree size: %d entries" % (tree.GetEntries()))
         
         if (tree != None):
                 tree.SetDirectory(0)
         
         return tree
Exemple #4
0
def provideNCanvas(n=2, title="Same Sign Dilepton SUSY analysis"):
    if (n < 1):
        log.logError("'%d' is not a valid number of pads!")
        return None
    if (n == 1):
        [c1, pad1, pad2] = provideDoubleCanvas()
        return [c1, [pad1]]
    if (n == 2):
        [c1, pad1, pad2] = provideDoubleCanvas()
        return [c1, [pad1, pad2]]
    if (n == 3):
        [c1, pad1, pad2, pad3, pad4] = provideQuadCanvas()
        return [c1, [pad1, pad2, pad3]]
    if (n == 4):
        [c1, pad1, pad2, pad3, pad4] = provideQuadCanvas()
        return [c1, [pad1, pad2, pad3, pad4]]

    # window settings
    theCanvasSizeX = 1520
    theCanvasSizeY = 920
    theScreenSizeX = 1680
    theScreenSizeY = 1050

    # canvas
    posX = int(theScreenSizeX * 0.04)
    posY = int(theScreenSizeY * 0.03)
    #posX = (theScreenSizeX - theCanvasSizeX) / 2
    #posY = (theScreenSizeY - theCanvasSizeY) / 2
    c1 = TCanvas('c1', title, posX, posY, theCanvasSizeX, theCanvasSizeY)

    i = int(math.ceil(-0.5 + 0.5 * math.sqrt(4.0 * n + 1.0)))
    nRows = i
    nColumns = i + 1

    log.logDebug("no. of columns: %d" % nColumns)
    log.logDebug("no. of rows: %d" % nRows)

    c1.Divide(nColumns, nRows, 0.0001, 0.0001)

    pads = []
    iPad = 1
    for iRow in range(0, nRows):
        for iColumn in range(0, nColumns):
            if (iPad <= n):
                c1.cd(iPad)
                pad = TPad('pad%d' % iPad, 'Pad for %dth histogram' % iPad,
                           0.03, 0.03, 0.97, 0.97, 0)
                pad.Draw()
                pads.extend([pad])
                iPad += 1

    log.logDebug("Pads: %s" % pads)
    return [c1, pads]
Exemple #5
0
    def _calculateRatios(self):
        if (self.hasHistograms):
            tempRatioUp = None
            tempRatioDown = None
            nBin = 0
            for iBin in range(1, 1 + self.denominator.GetNbinsX()):
                den = self.denominator.GetBinContent(iBin)
                denError = self.denominator.GetBinError(iBin)
                denUp = self.denominatorUp.GetBinContent(iBin)
                denUpError = self.denominatorUp.GetBinError(iBin)
                denDown = self.denominatorDown.GetBinContent(iBin)
                denDownError = self.denominatorDown.GetBinError(iBin)
                #~ log.logDebug("den: %f +- %f" % (den, denError))
                #~ log.logDebug("denup: %f +- %f" % (denUp, denUpError))
                #~ log.logDebug("dendown: %f +- %f" % (denDown, denDownError))

                x = self.denominator.GetBinCenter(iBin)
                width = self.denominator.GetBinWidth(iBin)

                # assure that bin is in view range
                if (self.xMin < x and x < self.xMax):
                    ratioUp = Ratio(denUp, den, math.pow(denUpError, 2.0),
                                    math.pow(denError, 2.0), x, width)
                    ratioDown = Ratio(denDown, den,
                                      math.pow(denDownError, 2.0),
                                      math.pow(denError, 2.0), x, width)

                    #~ log.logInfo("ratioUp: %f, ratioDown: %f" % (ratioUp.ratio, ratioDown.ratio))

                    if (tempRatioUp != None):
                        tempRatioUp.addRatio(ratioUp)
                        tempRatioDown.addRatio(ratioDown)
                    else:
                        tempRatioUp = ratioUp
                        tempRatioDown = ratioDown

                    #~ if (tempRatioUp.isFullEnough(self.rebinErrorBoundary) and tempRatioDown.isFullEnough(self.rebinErrorBoundary)):
                    if (iBin == self.binMerging[nBin]):
                        nBin = nBin + 1
                        self.__ratiosUp__.append(tempRatioUp)
                        self.__ratiosDown__.append(tempRatioDown)
                        tempRatioUp = None
                        tempRatioDown = None

            if (tempRatioUp != None):
                self.__ratiosUp__.append(tempRatioUp)
                self.__ratiosDown__.append(tempRatioDown)
        else:
            log.logError(
                "Trying to calculate error ratios, but histograms not set!")
Exemple #6
0
        def getHistogramFromFile(self, fileName, histoPath):
                log.logDebug("Getting histogram '%s'\n  from file %s" % (histoPath, fileName))

                file = TFile(fileName, 'READ')
                histogram = file.Get(histoPath)

                if (histogram == None):
                        log.logError("Could not get histogram '%s'\n  from file %s" % (histoPath, fileName))
                        file.Close()
                        return None
                else:
                        histogram.SetDirectory(0)
                        histogram.Sumw2()
                        file.Close()
                        return histogram
Exemple #7
0
        def integral(self):
                #log.logDebug("bin1: %f" % self.histogram.GetBinContent(1))

                #a = self.histogram.GetBinContent(1)
                #if (a == ):
                #       log.logError("NAN!")

                try:
                        min = 0
                        binMin = self.histogram.FindBin(min)
                        binMax = self.histogram.FindBin(Result.xMax)
                        return self.histogram.Integral(binMin, binMax)
                except:
                        log.logError("Cannot get histogram integral")
                        return - 1
Exemple #8
0
def getTrees(theConfig, datasets, central=True):
	import dataInterface
	#~ theDataInterface = dataInterface.dataInterface(dataVersion=dataVersion)
	theDataInterface = dataInterface.DataInterface(theConfig.dataSetPath,theConfig.dataVersion)
	treePathOFOS = "/EMuDileptonTree"
	treePathEE = "/EEDileptonTree"
	treePathMM = "/MuMuDileptonTree"

	treesMCOFOS = ROOT.TList()
	treesMCEE = ROOT.TList()
	treesMCMM = ROOT.TList()

	if central:
		cut = theConfig.selection.cut + " && abs(eta1) < 1.4 && abs(eta2) < 1.4"
	else:
		cut = theConfig.selection.cut + " && 1.6 <= TMath::Max(abs(eta1),abs(eta2)) && !(abs(eta1) > 1.4 && abs(eta1) < 1.6) && !(abs(eta2) > 1.4 && abs(eta2) < 1.6)"

	for dataset in datasets:
		scale = 0.0

		# dynamic scaling
		jobs = dataInterface.InfoHolder.theDataSamples[theConfig.dataVersion][dataset]
		if (len(jobs) > 1):
			log.logDebug("Scaling and adding more than one job: %s" % (jobs))
		for job in jobs:
			treeMCOFOSraw = theDataInterface.getTreeFromJob(theConfig.flag, theConfig.task, job, treePathOFOS, dataVersion=theConfig.dataVersion, cut=theConfig.selection.cut)
			treeMCEEraw = theDataInterface.getTreeFromJob(theConfig.flag, theConfig.task, job, treePathEE, dataVersion=theConfig.dataVersion, cut=theConfig.selection.cut)
			treeMCMMraw = theDataInterface.getTreeFromJob(theConfig.flag, theConfig.task, job, treePathMM, dataVersion=theConfig.dataVersion, cut=theConfig.selection.cut)

			dynNTotal = theDataInterface.getEventCount(job, theConfig.flag, theConfig.task)
			dynXsection = theDataInterface.getCrossSection(job)
			dynScale = dynXsection * theConfig.runRange.lumi / dynNTotal
			if (dynScale != scale):
				log.logInfo("dyn scale for %s (%s): n = %d, x = %f => %f" % (job, dataset, dynNTotal, dynXsection, dynScale))
				scale = dynScale
			else:
				log.logError("No dynamic scale applied. This should never happen!")

			# convert trees
			treesMCOFOS.Add(dataInterface.DataInterface.convertDileptonTree(treeMCOFOSraw, weight=scale))
			treesMCEE.Add(dataInterface.DataInterface.convertDileptonTree(treeMCEEraw, weight=scale))
			treesMCMM.Add(dataInterface.DataInterface.convertDileptonTree(treeMCMMraw, weight=scale))

	treeMCOFOStotal = ROOT.TTree.MergeTrees(treesMCOFOS)
	treeMCEEtotal = ROOT.TTree.MergeTrees(treesMCEE)
	treeMCMMtotal = ROOT.TTree.MergeTrees(treesMCMM)

	return (treeMCOFOStotal, treeMCEEtotal, treeMCMMtotal)
Exemple #9
0
	def _calculateRatios(self):
		if (self.hasHistograms):
			tempRatioUp = None
			tempRatioDown = None
			nBin = 0
			for iBin in range(1, 1 + self.denominator.GetNbinsX()):
				den = self.denominator.GetBinContent(iBin)
				denError = self.denominator.GetBinError(iBin)
				denUp = self.denominatorUp.GetBinContent(iBin)
				denUpError = self.denominatorUp.GetBinError(iBin)
				denDown = self.denominatorDown.GetBinContent(iBin)
				denDownError = self.denominatorDown.GetBinError(iBin)
				#~ log.logDebug("den: %f +- %f" % (den, denError))
				#~ log.logDebug("denup: %f +- %f" % (denUp, denUpError))
				#~ log.logDebug("dendown: %f +- %f" % (denDown, denDownError))

				x = self.denominator.GetBinCenter(iBin)
				width = self.denominator.GetBinWidth(iBin)

				# assure that bin is in view range
				if (self.xMin < x and x < self.xMax):
					ratioUp = Ratio(denUp, den, math.pow(denUpError, 2.0), math.pow(denError, 2.0), x, width)
					ratioDown = Ratio(denDown, den, math.pow(denDownError, 2.0), math.pow(denError, 2.0), x, width)

					#~ log.logInfo("ratioUp: %f, ratioDown: %f" % (ratioUp.ratio, ratioDown.ratio))

					if (tempRatioUp != None):
						tempRatioUp.addRatio(ratioUp)
						tempRatioDown.addRatio(ratioDown)
					else:
						tempRatioUp = ratioUp
						tempRatioDown = ratioDown

					#~ if (tempRatioUp.isFullEnough(self.rebinErrorBoundary) and tempRatioDown.isFullEnough(self.rebinErrorBoundary)):
					if (iBin == self.binMerging[nBin]):
						nBin = nBin+1
						self.__ratiosUp__.append(tempRatioUp)
						self.__ratiosDown__.append(tempRatioDown)
						tempRatioUp = None
						tempRatioDown = None

			if (tempRatioUp != None):
				self.__ratiosUp__.append(tempRatioUp)
				self.__ratiosDown__.append(tempRatioDown)
		else:
			log.logError("Trying to calculate error ratios, but histograms not set!")
Exemple #10
0
        def scale(self, factor):
                if (self.histogram == None):
                        log.logError("Trying to scale empty result")
                        return
                if (self.is2DHistogram):
                        log.logError("Scaling not implemented for 2D histograms.")
                        return

                self.histogram.Scale(factor)
                #log.logDebug("Result: Scaling factor = %f" % (self.scalingFactor))
                if (self.scalingFactor < 0):
                        self.scalingFactor = factor
                else:
                        self.scalingFactor *= factor

                if (self.currentIntegralError > 0.0):
                        self.currentIntegralError *= factor

                #log.logDebug("Result: Scaling factor afterwards = %f" % (self.scalingFactor))
                self.scaled = True
Exemple #11
0
        def integralError(self):
                if (self.currentIntegralError >= 0.0):
                        return self.currentIntegralError
                if (self.is2DHistogram):
                        log.logError("Integral error not implemented for 2D histograms.")
                        return - 1

                if (self.scaled):
                        # have differently scaled histograms been added? (cannot calculate error the usual way)
                        if (self.__scaledAndAdded):
                                log.logError("Result scaled and added, but integral error value not set.")
                                return - 1
                        # usual way
                        if (self.unscaledIntegral < 0 or self.scalingFactor < 0):
                                log.logWarning("Could not determine integral error: unscaled integral or scaling factor not set!")
                                return - 1

                        #log.logDebug("Scaled Error: sqrt(%f) * %f = %f" % (self.unscaledIntegral, self.scalingFactor, sqrt(self.unscaledIntegral) * self.scalingFactor))
                        return sqrt(self.unscaledIntegral) * self.scalingFactor
                else:
                        return sqrt(self.integral())
Exemple #12
0
def parseSLHA(slha, pdgIds=[24]):
	"""
	parse SUSY Les Houches Accord (SLHA) formated strings (e.g. SOFTSUSY output)
	"""
	from re import match
	result = {}
	massBlock = ""
	block = None
	for line in slha.splitlines():		
		blockRe = match("Block ([a-zA-Z]+).*", line)
		if not blockRe == None:
			block = blockRe.group(1)
		if block == "MASS":
			for pdgId in pdgIds:
				pdgIdRe = match("\s*%s\s*([0-9.e\+-]+)"%pdgId, line)
				if not pdgIdRe == None:
					result[pdgId] = float(pdgIdRe.group(1))
	for pdgId in pdgIds:
		if not pdgId in result:
			log.logError("could not find %s"%pdgId)
			log.logDebug(slha)
	return result
Exemple #13
0
        def getTreeFromDataset(self, dataset, dilepton, cut="", useNLL=False):
                tree = ROOT.TChain()
                baseCut = cut
                for runRange in self.runRanges:
                        if useNLL:
                                path = locations[runRange.era].dataSetPathNLL
                        else:
                                path = locations[runRange.era].dataSetPath
                        log.logDebug("Adding %s tree from %s"%(dataset, path))
                        ROOT.TH1.AddDirectory(False)
                        tmpTree = readTrees(path, dilepton)[dataset]
                        ROOT.TH1.AddDirectory(True)
                        tree.Add(tmpTree)
   
                runCuts = []
                runCut = ""
                for runRange in self.runRanges:
                        runCuts.append(runRange.runCut[3:])
                
                if useNLL:
                        runCuts.append("vetoHEM == 1")
                runCut = "&& (%s)"%(" || ".join(runCuts))
                
                cut = cut + runCut
                
                print tree.GetEntries()
                
                if (cut != ""):
                        log.logDebug("Cutting tree down to: %s" % cut)
                        #tree = tree.CopyTree(cut, "", 1000)
                        tree = tree.CopyTree(cut)
                        #log.logError("Tree size: %d entries" % (tree.GetEntries()))

                if (tree != None):
                        tree.SetDirectory(0)
                else:
                        log.logError("Tree invalid")
                return tree
Exemple #14
0
def getSignalTrees(theConfig, signals, useNLL=False):
    import dataInterface

    treesMCEM = ROOT.TList()
    treesMCEE = ROOT.TList()
    treesMCMM = ROOT.TList()

    runRanges = theConfig.runRanges

    cut = theConfig.selection.cut

    for runRange in runRanges:
        scale = 0.0
        theDataInterface = dataInterface.DataInterface([
            runRange,
        ])
        for signal in signals:
            treeMCEMraw = theDataInterface.getSignalTreeFromJob(signal,
                                                                "EMu",
                                                                cut=cut,
                                                                useNLL=useNLL)
            treeMCEEraw = theDataInterface.getSignalTreeFromJob(signal,
                                                                "EE",
                                                                cut=cut,
                                                                useNLL=useNLL)
            treeMCMMraw = theDataInterface.getSignalTreeFromJob(signal,
                                                                "MuMu",
                                                                cut=cut,
                                                                useNLL=useNLL)

            from helpers import getSignalGenEvents, getSignalXsec
            dynXsection = getSignalXsec(signal, runRange)
            dynNTotal = getSignalGenEvents(signal, runRange)
            dynScale = dynXsection * runRange.lumi / (dynNTotal)

            if (dynScale != scale):
                log.logInfo("dyn scale for %s: n = %d, x = %f => %f" %
                            (signal, dynNTotal, dynXsection, dynScale))
                scale = dynScale
            else:
                log.logError(
                    "No dynamic scale applied. This should never happen!")

            if not treeMCEMraw == None:
                treesMCEM.Add(
                    dataInterface.DataInterface.convertDileptonTree(
                        treeMCEMraw, weight=scale))
            if not treeMCEEraw == None:
                treesMCEE.Add(
                    dataInterface.DataInterface.convertDileptonTree(
                        treeMCEEraw, weight=scale))
            if not treeMCMMraw == None:
                treesMCMM.Add(
                    dataInterface.DataInterface.convertDileptonTree(
                        treeMCMMraw, weight=scale))

    treeMCEMtotal = ROOT.TTree.MergeTrees(treesMCEM)
    treeMCEEtotal = ROOT.TTree.MergeTrees(treesMCEE)
    treeMCMMtotal = ROOT.TTree.MergeTrees(treesMCMM)

    return (treeMCEMtotal, treeMCEEtotal, treeMCMMtotal)
Exemple #15
0
def getTrees(theConfig, datasets, useNLL=False):
    import dataInterface

    treesMCEM = ROOT.TList()
    treesMCEE = ROOT.TList()
    treesMCMM = ROOT.TList()

    runRanges = theConfig.runRanges

    cut = theConfig.selection.cut
    for runRange in runRanges:
        theDataInterface = dataInterface.DataInterface([
            runRange,
        ])

        for dataset in datasets:
            scale = 0.0

            # dynamic scaling
            eventCounts = totalNumberOfGeneratedEvents(
                locations[runRange.era].dataSetPath)
            proc = Process(getattr(Backgrounds[runRange.era], dataset),
                           eventCounts)
            if (len(proc.samples) > 1):
                log.logDebug("Scaling and adding more than one job: %s" %
                             (proc.samples))
            for job, dynNTotal, dynXsection, dynNegWeightFraction in zip(
                    proc.samples, proc.nEvents, proc.xsecs,
                    proc.negWeightFractions):
                treeMCEMraw = theDataInterface.getTreeFromJob(job,
                                                              "EMu",
                                                              cut=cut,
                                                              useNLL=useNLL)
                treeMCEEraw = theDataInterface.getTreeFromJob(job,
                                                              "EE",
                                                              cut=cut,
                                                              useNLL=useNLL)
                treeMCMMraw = theDataInterface.getTreeFromJob(job,
                                                              "MuMu",
                                                              cut=cut,
                                                              useNLL=useNLL)

                #~ dynScale = dynXsection * theConfig.runRange.lumi / dynNTotal
                print runRange.lumi
                dynScale = dynXsection * runRange.lumi / (
                    dynNTotal * (1 - 2 * dynNegWeightFraction))
                if (dynScale != scale):
                    log.logInfo(
                        "dyn scale for %s (%s): n = %d, x = %f => %f" %
                        (job, dataset, dynNTotal, dynXsection, dynScale))
                    scale = dynScale
                else:
                    log.logError(
                        "No dynamic scale applied. This should never happen!")

                # convert trees
                if not treeMCEMraw == None:
                    treesMCEM.Add(
                        dataInterface.DataInterface.convertDileptonTree(
                            treeMCEMraw, weight=scale))
                if not treeMCEEraw == None:
                    treesMCEE.Add(
                        dataInterface.DataInterface.convertDileptonTree(
                            treeMCEEraw, weight=scale))
                if not treeMCMMraw == None:
                    treesMCMM.Add(
                        dataInterface.DataInterface.convertDileptonTree(
                            treeMCMMraw, weight=scale))

    treeMCEMtotal = ROOT.TTree.MergeTrees(treesMCEM)
    treeMCEEtotal = ROOT.TTree.MergeTrees(treesMCEE)
    treeMCMMtotal = ROOT.TTree.MergeTrees(treesMCMM)

    return (treeMCEMtotal, treeMCEEtotal, treeMCMMtotal)
Exemple #16
0
 def setXSection(self, xSection):
         if (xSection <= 0.0):
                 log.logError("Cannot set result cross section to zero or less (%f)" % xSection)
         else:
                 self.xSection = xSection
Exemple #17
0
        def addResult(self, result):
                if (self.histogram == None):
                        log.logWarning("Adding to empty result!")
                        if (result.histogram == None): log.logWarning("... also adding empty result!")
                        return result
                if (result.histogram == None):
                        log.logWarning("Adding empty result!")
                        return self

                if (not self.scaled == result.scaled):
                        log.logError("Cannot add scaled and unscaled results")
                        return None

                if (self.dataType != result.dataType):
                        log.logError("Cannot add results of different data types (%d, %d)" % (self.dataType, results.dataType))
                        return None

                # lumi info
                if (self.luminosity > 0 and result.luminosity > 0):
                        if (self.dataType == InfoHolder.DataTypes.Data):
                                self.luminosity += result.luminosity # for data
                        else:
                                pass # for MC and Unknown
                else:
                        log.logWarning("Adding results without complete luminosity information (%f, %f)" % (self.luminosity, result.luminosity))
                        self.luminosity = -1

                # xSection info
                if (self.xSection > 0 and result.xSection > 0):
                        self.xSection += result.xSection
                else:
                        if (self.dataType != InfoHolder.DataTypes.Data):
                                log.logWarning("Adding results without complete xSection information (%f, %f)" % (self.xSection, result.xSection))
                        self.xSection = -1

                # xSection info
                if (self.kFactor > 0 and result.kFactor > 0):
                        if (self.kFactor != result.kFactor):
                                log.logHighlighted("Adding results with different kFactors (%f, %f). Will not be able to track this any more." % (self.kFactor, result.kFactor))
                                self.kFactor = -1
                else:
                        log.logInfo("Adding results without complete kFactor information (%f, %f)" % (self.kFactor, result.kFactor))
                        self.kFactor = -1

                if (not self.scaled):
                        self.histogram.Add(result.histogram)
                        return self
                if (self.scalingFactor == result.scalingFactor):
                        self.unscaledIntegral += result.unscaledIntegral
                        self.histogram.Add(result.histogram)
                        return self

                log.logDebug("Combining results: %s, %s" % (str(self), str(result)))
                # first calculate new error
                self.currentIntegralError = sqrt(self.integralError() * self.integralError() + result.integralError() * result.integralError())
                # then change histogram
                self.histogram.Add(result.histogram)
                self.unscaledIntegral += result.unscaledIntegral
                self.scalingFactor = -1
                # finally mark result as scaled and added
                self.__scaledAndAdded = True
                log.logDebug("... to: %s" % (str(self)))
                return self