diff --git a/__analysis__.py b/__analysis__.py index 7c447659..00cddd76 100644 --- a/__analysis__.py +++ b/__analysis__.py @@ -139,7 +139,7 @@ def sampleSpecs(self, tag = "") : def sampleSpecDict(looper) : looper.setupSteps(minimal = True) sampleSpec = next( s for s in confSamples if s.weightedName == looper.name ) - return {"name":looper.name, "outputFileName":looper.steps[0].outputFileName, + return {"name":looper.name, "outputFileName":looper.steps[0].outputFileName, "nInDivide": sampleSpec.nInDivide, "color":sampleSpec.color, "markerStyle":sampleSpec.markerStyle, "nCheck":self.sampleDict[sampleSpec.name].nCheck } return [ sampleSpecDict(looper) for looper in self.listsOfLoopers[tag] ] ############ diff --git a/__organizer__.py b/__organizer__.py index 6ca086a8..bb55d523 100644 --- a/__organizer__.py +++ b/__organizer__.py @@ -27,8 +27,12 @@ def __init__(self,samples,dirs = None,keys = [], prefixesNoScale=[]) : [ hist.Scale( 1.0 / sample['nJobs'] ) for hist,sample in zip(self[key],samples) if hist ] elif any([key.startswith(prefix) for prefix in prefixesNoScale]): continue - else: [ hist.Scale(sample["xs"]/sample['nEventsIn']) for hist,sample in zip(self[key],samples) - if hist and sample['nEventsIn'] and "xs" in sample ] + else: + for hist, sample in zip(self[key], samples): + if hist and "xs" in sample: + hist.Scale(sample["xs"]) + if sample['nEventsIn'] and sample["nInDivide"]: + hist.Scale(1.0 / sample['nEventsIn']) def __str__(self) : return "%s: %s"%self.nameTitle diff --git a/__plotter__.py b/__plotter__.py index 0f7bae41..92d5b8a2 100644 --- a/__plotter__.py +++ b/__plotter__.py @@ -20,13 +20,6 @@ def combineBinContentAndError(histo, binToContainCombo, binToBeKilled) : histo.SetBinError(binToContainCombo, math.sqrt(xflowError**2+currentError**2)) -def mcLumi(nEvents=None, w=None, xs=None): - """see docs/mcLumi.txt""" - if not w*xs: - return 0.0 - return nEvents**2/(w*xs) - - def sampleName(sample): if len(sample.get("sources", [])) == 1: return sample["sources"][0]["name"] @@ -38,12 +31,16 @@ def sampleInfo(samples, trim=""): out = [] for sample in samples: if "xs" in sample: - xs = sample["xs"] - lumi = mcLumi(nEvents=sample["nEventsIn"], - w=sample["weightIn"], - xs=sample["xs"]) + xsIn = sample["xs"] + xsEff = sample["xs"] * sample["weightIn"] + if sample["nInDivide"] and sample["nEventsIn"]: + xsEff /= sample["nEventsIn"] + + # see docs/mcLumi.txt + lumi = sample["nEventsIn"] / xsEff if xsEff else 0.0 elif "lumi" in sample: - xs = None + xsIn = None + xsEff = None lumi = sample["lumi"] else: assert False, sample @@ -51,11 +48,13 @@ def sampleInfo(samples, trim=""): name = sampleName(sample) if trim: name = name.replace(trim, "") + out.append((name, - "%d" % sample['nEventsIn'], + "%g" % sample['nEventsIn'], # %g handles 'float epsilon less than nearest int' better than %d "%3.2e" % sample['weightIn'], "%3.2e" % (lumi/1.0e3), - "%3.2e" % (xs*1.0e3) if xs is not None else "", + "%3.2e" % (xsIn*1.0e3) if xsIn is not None else "", + "%3.2e" % (xsEff*1.0e3) if xsEff is not None else "", )) return out @@ -508,7 +507,7 @@ def printSampleList(self, x, rows=[], header="", sigma=None): text.SetTextSize(0.38*text.GetTextSize()) defSize = text.GetTextSize() - rows = [("name", "nEventsIn", "weightIn", "lumi(/fb)", "xs(fb)")] + rows + rows = [("name", "nEventsIn", "weightIn", "lumi(/fb)", "xsIn(fb)", "xsEff(fb)")] + rows realRows = filter(lambda x: len(x[1]), rows) if len(realRows) == 1: return diff --git a/samples/__init__.py b/samples/__init__.py index cb831b19..bc1b95d1 100644 --- a/samples/__init__.py +++ b/samples/__init__.py @@ -13,14 +13,21 @@ def printNumberEvents(sampleHolder, treeName='tree'): def test(sampleHolder) : return [(name,len(eval(ss.filesCommand))) for name,ss in sorted(sampleHolder.items())] -def specify(names = [], overrideLumi = None, xsPostWeights = None, effectiveLumi = None, nFilesMax = None, nEventsMax = None, weights = [], color = 1, markerStyle = 1 , weightedName = None) : +def specify(names=[], overrideLumi=None, xsPostWeights=None, effectiveLumi=None, nFilesMax=None, nEventsMax=None, weights=[], nInDivide=True, color=1, markerStyle=1 , weightedName=None): assert not (overrideLumi and type(names)==list) if type(names) != list : names = [names] if type(weights) != list : weights = [weights] - samplespec = collections.namedtuple("samplespec", "name weightedName overrideLumi xsPostWeights effectiveLumi nFilesMax nEventsMax weights color markerStyle") + + if not nInDivide: # typically, all events are required for correct normalization + for s in ["nFilesMax", "nEventsMax", "effectiveLumi"]: + x = eval(s) + if x is not None: + print "WARNING: nInDivide=False, but %s=%s (%s)" % (s, x, str(names)) + + samplespec = collections.namedtuple("samplespec", "name weightedName overrideLumi xsPostWeights effectiveLumi nFilesMax nEventsMax weights nInDivide color markerStyle") weightNames = [w if type(w)==str else w.name for w in weights] - return [samplespec(name,'.'.join([name]+weightNames),overrideLumi,xsPostWeights,effectiveLumi,nFilesMax,nEventsMax,weights,color,markerStyle) for name in names] - + return [samplespec(name, '.'.join([name]+weightNames), overrideLumi, xsPostWeights, effectiveLumi, nFilesMax, nEventsMax, weights, nInDivide, color, markerStyle) for name in names] + class SampleHolder(dict) : sample = collections.namedtuple("sample", "filesCommand xs lumi ptHatMin nCheck") def __init__(self) : self.inclusiveGroups = [] @@ -35,6 +42,7 @@ def update(self, other) : for group in other.inclusiveGroups : self.addInclusiveGroup(group) def add(self, name, filesCommand = None, xs = None, lumi = None, ptHatMin = None, nCheck = None) : + assert "/" not in name, "name '%s' contains at least one /" % name assert name not in self, "%s already specified" % name assert lumi or xs, "Underspecified sample: %s"%name assert not (lumi and (xs or ptHatMin)), "Overspecified sample: %s"%name diff --git a/sites/uw_cmsTemplate.condor b/sites/uw_cmsTemplate.condor index 7857f36e..402986a9 100644 --- a/sites/uw_cmsTemplate.condor +++ b/sites/uw_cmsTemplate.condor @@ -6,6 +6,8 @@ transfer_output_files = OUTFLAG Should_Transfer_Files = YES WhenToTransferOutput = ON_EXIT +Requirements = HAS_CMS_HDFS + Output = JOBFLAG_$(Cluster)_$(Process).stdout Error = JOBFLAG_$(Cluster)_$(Process).stderr Log = JOBFLAG_$(Cluster)_$(Process).log diff --git a/steps/other.py b/steps/other.py index 21539cef..fd3d9813 100644 --- a/steps/other.py +++ b/steps/other.py @@ -46,14 +46,13 @@ class skimmer(analysisStep): created. """ - def __init__(self, mainChain=True, otherChains=True, extraVars=[], haddOutput=False): + def __init__(self, mainChain=True, otherChains=True, extraVars=[], haddOutput=False, suffix="skim"): assert mainChain or extraVars self.outputTree = None self.moreName = "(see below)" - for var in ["mainChain", "otherChains", "extraVars"]: + for var in ["mainChain", "otherChains", "extraVars", "haddOutput", "suffix"]: setattr(self, var, eval(var)) self.addresses = None - self.haddOutput = haddOutput def requiresNoSetBranchAddress(self): return True # check @@ -141,7 +140,7 @@ def endFunc(self, chains): self.outputFile.Close() def outputSuffix(self): - return "_skim.root" + return "_%s.root" % self.suffix def modifiedFileName(self, s): l = s.split("/")