![]() |
![]() |
Inherits HiggsAnalysis::CombinedLimit::ModelTools::ModelBuilder.
Public Member Functions | |
def | __init__ |
def | argSetToString |
def | doCombination |
def | doCombinedDataset |
def | doIndividualModels |
def | doObservables |
------------------------------------------ -------- ModelBuilder interface ---------- ------------------------------------------ | |
def | getData |
def | getExtraNorm |
def | getPdf |
def | getShape |
------------------------------------- -------- Low level helpers ---------- ------------------------------------- | |
def | isShapeSystematic |
def | prepareAllShapes |
-------------------------------------- -------- High level helpers ---------- -------------------------------------- | |
def | shape2Data |
def | shape2Pdf |
Public Attributes | |
pdfModes | |
wsp | |
wspnames |
Definition at line 7 of file ShapeTools.py.
def ShapeTools::ShapeBuilder::__init__ | ( | self, | |
datacard, | |||
options | |||
) |
Definition at line 8 of file ShapeTools.py.
00009 : 00010 ModelBuilder.__init__(self,datacard,options) 00011 if not datacard.hasShapes: 00012 raise RuntimeError, "You're using a ShapeBuilder for a model that has no shapes" 00013 if options.libs: 00014 for lib in options.libs: 00015 ROOT.gSystem.Load(lib) 00016 self.wspnames = {} self.wsp = None
def ShapeTools::ShapeBuilder::argSetToString | ( | self, | |
argset | |||
) |
Definition at line 467 of file ShapeTools.py.
def ShapeTools::ShapeBuilder::doCombination | ( | self | ) |
Definition at line 77 of file ShapeTools.py.
00078 : 00079 ## Contrary to Number-counting models, here each channel PDF already contains the nuisances 00080 ## So we just have to build the combined pdf 00081 if len(self.DC.bins) > 1 or self.options.forceSimPdf: 00082 for (postfixIn,postfixOut) in [ ("","_s"), ("_bonly","_b") ]: 00083 simPdf = ROOT.RooSimultaneous("model"+postfixOut, "model"+postfixOut, self.out.binCat) 00084 for b in self.DC.bins: 00085 pdfi = self.out.pdf("pdf_bin%s%s" % (b,postfixIn)) 00086 simPdf.addPdf(pdfi, b) 00087 self.out._import(simPdf) 00088 else: 00089 self.out._import(self.out.pdf("pdf_bin%s" % self.DC.bins[0]).clone("model_s"), ROOT.RooFit.Silence()) 00090 self.out._import(self.out.pdf("pdf_bin%s_bonly" % self.DC.bins[0]).clone("model_b"), ROOT.RooFit.Silence()) 00091 if self.options.fixpars: 00092 pars = self.out.pdf("model_s").getParameters(self.out.obs) 00093 iter = pars.createIterator() 00094 while True: 00095 arg = iter.Next() 00096 if arg == None: break; 00097 if arg.InheritsFrom("RooRealVar") and arg.GetName() != "r": arg.setConstant(True);
def ShapeTools::ShapeBuilder::doCombinedDataset | ( | self | ) |
Definition at line 196 of file ShapeTools.py.
00197 : 00198 if len(self.DC.bins) == 1 and not self.options.forceSimPdf: 00199 data = self.getData(self.DC.bins[0],self.options.dataname).Clone(self.options.dataname) 00200 self.out._import(data) 00201 return 00202 if self.out.mode == "binned": 00203 combiner = ROOT.CombDataSetFactory(self.out.obs, self.out.binCat) 00204 for b in self.DC.bins: combiner.addSetBin(b, self.getData(b,self.options.dataname)) 00205 self.out.data_obs = combiner.done(self.options.dataname,self.options.dataname) 00206 self.out._import(self.out.data_obs) 00207 elif self.out.mode == "unbinned": 00208 combiner = ROOT.CombDataSetFactory(self.out.obs, self.out.binCat) 00209 for b in self.DC.bins: combiner.addSetAny(b, self.getData(b,self.options.dataname)) 00210 self.out.data_obs = combiner.doneUnbinned(self.options.dataname,self.options.dataname) 00211 self.out._import(self.out.data_obs) 00212 else: raise RuntimeException, "Only combined datasets are supported" 00213 #print "Created combined dataset with ",self.out.data_obs.numEntries()," entries, out of:" #for b in self.DC.bins: print " bin", b, ": entries = ", self.getData(b,self.options.dataname).numEntries()
def ShapeTools::ShapeBuilder::doIndividualModels | ( | self | ) |
Definition at line 39 of file ShapeTools.py.
00040 : 00041 for b in self.DC.bins: 00042 pdfs = ROOT.RooArgList(); bgpdfs = ROOT.RooArgList() 00043 coeffs = ROOT.RooArgList(); bgcoeffs = ROOT.RooArgList() 00044 for p in self.DC.exp[b].keys(): # so that we get only self.DC.processes contributing to this bin 00045 if self.DC.exp[b][p] == 0: continue 00046 (pdf,coeff) = (self.getPdf(b,p), self.out.function("n_exp_bin%s_proc_%s" % (b,p))) 00047 extranorm = self.getExtraNorm(b,p) 00048 if extranorm: 00049 self.doObj("n_exp_final_bin%s_proc_%s" % (b,p), "prod", "n_exp_bin%s_proc_%s, %s" % (b,p, extranorm)) 00050 coeff = self.out.function("n_exp_final_bin%s_proc_%s" % (b,p)) 00051 pdfs.add(pdf); coeffs.add(coeff) 00052 if not self.DC.isSignal[p]: 00053 bgpdfs.add(pdf); bgcoeffs.add(coeff) 00054 if self.options.verbose: print "Creating RooAddPdf %s with %s elements" % ("pdf_bin"+b, coeffs.getSize()) 00055 sum_s = ROOT.RooAddPdf("pdf_bin%s" % b, "", pdfs, coeffs) 00056 sum_b = ROOT.RooAddPdf("pdf_bin%s_bonly" % b, "", bgpdfs, bgcoeffs) 00057 if b in self.pdfModes: 00058 sum_s.setAttribute('forceGen'+self.pdfModes[b].title()) 00059 sum_b.setAttribute('forceGen'+self.pdfModes[b].title()) 00060 if len(self.DC.systs): 00061 ## rename the pdfs 00062 sum_s.SetName("pdf_bin%s_nuis" % b); sum_b.SetName("pdf_bin%s_bonly_nuis" % b) 00063 # now we multiply by all the nuisances, but avoiding nested products 00064 # so we first make a list of all nuisances plus the RooAddPdf 00065 sumPlusNuis_s = ROOT.RooArgList(self.out.nuisPdfs); sumPlusNuis_s.add(sum_s) 00066 sumPlusNuis_b = ROOT.RooArgList(self.out.nuisPdfs); sumPlusNuis_b.add(sum_b) 00067 # then make RooProdPdf and import it 00068 pdf_s = ROOT.RooProdPdf("pdf_bin%s" % b, "", sumPlusNuis_s) 00069 pdf_b = ROOT.RooProdPdf("pdf_bin%s_bonly" % b, "", sumPlusNuis_b) 00070 if b in self.pdfModes: 00071 pdf_s.setAttribute('forceGen'+self.pdfModes[b].title()) 00072 pdf_b.setAttribute('forceGen'+self.pdfModes[b].title()) 00073 self.out._import(pdf_s, ROOT.RooFit.RenameConflictNodes(b)) 00074 self.out._import(pdf_b, ROOT.RooFit.RecycleConflictNodes(), ROOT.RooFit.Silence()) 00075 else: 00076 self.out._import(sum_s, ROOT.RooFit.RenameConflictNodes(b)) self.out._import(sum_b, ROOT.RooFit.RecycleConflictNodes(), ROOT.RooFit.Silence())
def ShapeTools::ShapeBuilder::doObservables | ( | self | ) |
------------------------------------------ -------- ModelBuilder interface ---------- ------------------------------------------
Definition at line 20 of file ShapeTools.py.
00021 : 00022 if (self.options.verbose > 1): stderr.write("Using shapes: qui si parra' la tua nobilitate\n") 00023 self.prepareAllShapes(); 00024 if len(self.DC.bins) > 1 or self.options.forceSimPdf: 00025 ## start with just a few channels 00026 strexpr="CMS_channel[" + ",".join(["%s=%d" % (l,i) for i,l in enumerate(self.DC.bins[:5])]) + "]"; 00027 self.doVar(strexpr); 00028 self.out.binCat = self.out.cat("CMS_channel"); 00029 ## then add all the others, to avoid a too long factory string 00030 for i,l in enumerate(self.DC.bins[5:]): self.out.binCat.defineType(l,i+5) 00031 if self.options.verbose: stderr.write("Will use category 'CMS_channel' to identify the %d channels\n" % self.out.binCat.numTypes()) 00032 self.out.obs = ROOT.RooArgSet() 00033 self.out.obs.add(self.out.binVars) 00034 self.out.obs.add(self.out.binCat) 00035 else: 00036 self.out.obs = self.out.binVars 00037 self.doSet("observables",self.out.obs) 00038 if len(self.DC.obs) != 0: self.doCombinedDataset()
def ShapeTools::ShapeBuilder::getData | ( | self, | |
channel, | |||
process, | |||
syst = "" , |
|||
_cache = {} |
|||
) |
Definition at line 310 of file ShapeTools.py.
00310 {}): 00311 return self.shape2Data(self.getShape(channel,process,syst),channel,process)
def ShapeTools::ShapeBuilder::getExtraNorm | ( | self, | |
channel, | |||
process | |||
) |
Definition at line 371 of file ShapeTools.py.
00372 : 00373 postFix="Sig" if (process in self.DC.isSignal and self.DC.isSignal[process]) else "Bkg" 00374 terms = [] 00375 shapeNominal = self.getShape(channel,process) 00376 if shapeNominal == None: 00377 # FIXME no extra norm for dummy pdfs (could be changed) 00378 return None 00379 if shapeNominal.InheritsFrom("RooAbsPdf"): 00380 # return nominal multiplicative normalization constant 00381 normname = "shape%s_%s_%s%s_norm" % (postFix,process,channel, "_") 00382 if self.out.arg(normname): return normname 00383 else: return None 00384 normNominal = 0 00385 if shapeNominal.InheritsFrom("TH1"): normNominal = shapeNominal.Integral() 00386 elif shapeNominal.InheritsFrom("RooDataHist"): normNominal = shapeNominal.sumEntries() 00387 else: return None 00388 if normNominal == 0: raise RuntimeError, "Null norm for channel %s, process %s" % (channel,process) 00389 for (syst,nofloat,pdf,args,errline) in self.DC.systs: 00390 if "shape" not in pdf: continue 00391 if errline[channel][process] != 0: 00392 if pdf[-1] == "?" and not self.isShapeSystematic(channel,process,syst): continue 00393 shapeUp = self.getShape(channel,process,syst+"Up") 00394 shapeDown = self.getShape(channel,process,syst+"Down") 00395 if shapeUp.ClassName() != shapeNominal.ClassName(): raise RuntimeError, "Mismatched shape types for channel %s, process %s, syst" % (channel,process,syst) 00396 if shapeDown.ClassName() != shapeNominal.ClassName(): raise RuntimeError, "Mismatched shape types for channel %s, process %s, syst" % (channel,process,syst) 00397 kappaUp,kappaDown = 1,1 00398 if shapeNominal.InheritsFrom("TH1"): 00399 kappaUp,kappaDown = shapeUp.Integral(),shapeDown.Integral() 00400 elif shapeNominal.InheritsFrom("RooDataHist"): 00401 kappaUp,kappaDown = shapeUp.sumEntries(),shapeDown.sumEntries() 00402 if not kappaUp > 0: raise RuntimeError, "Bogus norm %r for channel %s, process %s, systematic %s Up" % (kappaUp, channel,process,syst) 00403 if not kappaDown > 0: raise RuntimeError, "Bogus norm %r for channel %s, process %s, systematic %s Down" % (kappaDown, channel,process,syst) 00404 kappaUp /=normNominal; kappaDown /= normNominal 00405 if abs(kappaUp-1) < 1e-3 and abs(kappaDown-1) < 1e-3: continue 00406 # if errline[channel][process] == <x> it means the gaussian should be scaled by <x> before doing pow 00407 # for convenience, we scale the kappas 00408 kappasScaled = [ pow(x, errline[channel][process]) for x in kappaDown,kappaUp ] 00409 terms.append("AsymPow(%f,%f,%s)" % (kappasScaled[0], kappasScaled[1], syst)) return ",".join(terms) if terms else None;
def ShapeTools::ShapeBuilder::getPdf | ( | self, | |
channel, | |||
process, | |||
_cache = {} |
|||
) |
Definition at line 312 of file ShapeTools.py.
00312 {}): 00313 postFix="Sig" if (process in self.DC.isSignal and self.DC.isSignal[process]) else "Bkg" 00314 if _cache.has_key((channel,process)): return _cache[(channel,process)] 00315 shapeNominal = self.getShape(channel,process) 00316 nominalPdf = self.shape2Pdf(shapeNominal,channel,process) 00317 if shapeNominal == None: return nominalPdf # no point morphing a fake shape 00318 morphs = []; shapeAlgo = None 00319 for (syst,nofloat,pdf,args,errline) in self.DC.systs: 00320 if not "shape" in pdf: continue 00321 if errline[channel][process] == 0: continue 00322 allowNoSyst = (pdf[-1] == "?") 00323 pdf = pdf.replace("?","") 00324 if shapeAlgo == None: shapeAlgo = pdf 00325 elif pdf != shapeAlgo: 00326 errmsg = "ERROR for channel %s, process %s. " % (channel,process) 00327 errmsg += "Requesting morphing %s for systematic %s after having requested %s. " % (pdf, syst, shapeAlgo) 00328 raise RuntimeError, errmsg+" One can use only one morphing algorithm for a given shape"; 00329 if errline[channel][process] != 0: 00330 if allowNoSyst and not self.isShapeSystematic(channel,process,syst): continue 00331 shapeUp = self.getShape(channel,process,syst+"Up") 00332 shapeDown = self.getShape(channel,process,syst+"Down") 00333 if shapeUp.ClassName() != shapeNominal.ClassName(): raise RuntimeError, "Mismatched shape types for channel %s, process %s, syst %s" % (channel,process,syst) 00334 if shapeDown.ClassName() != shapeNominal.ClassName(): raise RuntimeError, "Mismatched shape types for channel %s, process %s, syst %s" % (channel,process,syst) 00335 morphs.append((syst,errline[channel][process],self.shape2Pdf(shapeUp,channel,process),self.shape2Pdf(shapeDown,channel,process))) 00336 if len(morphs) == 0: return nominalPdf 00337 if shapeAlgo == "shapeN": stderr.write("Warning: the shapeN implementation in RooStats and L&S are different\n") 00338 pdfs = ROOT.RooArgList(nominalPdf) 00339 coeffs = ROOT.RooArgList() 00340 minscale = 1 00341 for (syst,scale,pdfUp,pdfDown) in morphs: 00342 pdfs.add(pdfUp); pdfs.add(pdfDown); 00343 if scale == 1: 00344 coeffs.add(self.out.var(syst)) 00345 else: # must scale it :-/ 00346 coeffs.add(self.doObj("%s_scaled_%s_%s" % (syst,channel,process), "prod","%s, %s" % (scale,syst))) 00347 if scale < minscale: minscale = scale 00348 qrange = minscale; qalgo = 0; 00349 if shapeAlgo[-1] == "*": 00350 qalgo = 100 00351 shapeAlgo = shapeAlgo[:-1] 00352 if shapeAlgo == "shape": shapeAlgo = self.options.defMorph 00353 if "shapeL" in shapeAlgo: qrange = 0; 00354 elif "shapeN" in shapeAlgo: qalgo = -1; 00355 if "2a" in shapeAlgo: # old shape2 00356 if not nominalPdf.InheritsFrom("RooHistPdf"): raise RuntimeError, "Algorithms 'shape2', 'shapeL2', shapeN2' only work with histogram templates" 00357 if nominalPdf.dataHist().get().getSize() != 1: raise RuntimeError, "Algorithms 'shape2', 'shapeL2', shapeN2' only work in one dimension" 00358 xvar = nominalPdf.dataHist().get().first() 00359 _cache[(channel,process)] = ROOT.VerticalInterpHistPdf("shape%s_%s_%s_morph" % (postFix,channel,process), "", xvar, pdfs, coeffs, qrange, qalgo) 00360 elif "2" in shapeAlgo: # new faster shape2 00361 if not nominalPdf.InheritsFrom("RooHistPdf"): raise RuntimeError, "Algorithms 'shape2', 'shapeL2', shapeN2' only work with histogram templates" 00362 if nominalPdf.dataHist().get().getSize() != 1: raise RuntimeError, "Algorithms 'shape2', 'shapeL2', shapeN2' only work in one dimension" 00363 xvar = nominalPdf.dataHist().get().first() 00364 _cache[(channel,process)] = ROOT.FastVerticalInterpHistPdf("shape%s_%s_%s_morph" % (postFix,channel,process), "", xvar, pdfs, coeffs, qrange, qalgo) 00365 else: 00366 _cache[(channel,process)] = ROOT.VerticalInterpPdf("shape%s_%s_%s_morph" % (postFix,channel,process), "", pdfs, coeffs, qrange, qalgo) 00367 return _cache[(channel,process)]
def ShapeTools::ShapeBuilder::getShape | ( | self, | |
channel, | |||
process, | |||
syst = "" , |
|||
_fileCache = {} , |
|||
_cache = {} , |
|||
allowNoSyst = False |
|||
) |
------------------------------------- -------- Low level helpers ---------- -------------------------------------
Definition at line 217 of file ShapeTools.py.
00217 {},_cache={},allowNoSyst=False): 00218 if _cache.has_key((channel,process,syst)): 00219 if self.options.verbose > 1: print "recyling (%s,%s,%s) -> %s\n" % (channel,process,syst,_cache[(channel,process,syst)].GetName()) 00220 return _cache[(channel,process,syst)]; 00221 postFix="Sig" if (process in self.DC.isSignal and self.DC.isSignal[process]) else "Bkg" 00222 bentry = None 00223 if self.DC.shapeMap.has_key(channel): bentry = self.DC.shapeMap[channel] 00224 elif self.DC.shapeMap.has_key("*"): bentry = self.DC.shapeMap["*"] 00225 else: raise KeyError, "Shape map has no entry for channel '%s'" % (channel) 00226 names = [] 00227 if bentry.has_key(process): names = bentry[process] 00228 elif bentry.has_key("*"): names = bentry["*"] 00229 elif self.DC.shapeMap["*"].has_key(process): names = self.DC.shapeMap["*"][process] 00230 elif self.DC.shapeMap["*"].has_key("*"): names = self.DC.shapeMap["*"]["*"] 00231 else: raise KeyError, "Shape map has no entry for process '%s', channel '%s'" % (process,channel) 00232 if len(names) == 1 and names[0] == "FAKE": return None 00233 if syst != "": 00234 if len(names) == 2: 00235 if allowNoSyst: return None 00236 raise RuntimeError, "Can't find systematic "+syst+" for process '%s', channel '%s'" % (process,channel) 00237 names = [names[0], names[2]] 00238 else: 00239 names = [names[0], names[1]] 00240 strmass = "%d" % self.options.mass if self.options.mass % 1 == 0 else str(self.options.mass) 00241 finalNames = [ x.replace("$PROCESS",process).replace("$CHANNEL",channel).replace("$SYSTEMATIC",syst).replace("$MASS",strmass) for x in names ] 00242 if not _fileCache.has_key(finalNames[0]): 00243 trueFName = finalNames[0] 00244 if not os.path.exists(trueFName) and not os.path.isabs(trueFName) and os.path.exists(self.options.baseDir+"/"+trueFName): 00245 trueFName = self.options.baseDir+"/"+trueFName; 00246 _fileCache[finalNames[0]] = ROOT.TFile.Open(trueFName) 00247 file = _fileCache[finalNames[0]]; objname = finalNames[1] 00248 if not file: raise RuntimeError, "Cannot open file %s (from pattern %s)" % (finalNames[0],names[0]) 00249 if ":" in objname: # workspace:obj or ttree:xvar or th1::xvar 00250 (wname, oname) = objname.split(":") 00251 if (file,wname) not in self.wspnames : 00252 self.wspnames[(file,wname)] = file.Get(wname) 00253 self.wsp = self.wspnames[(file,wname)] 00254 if not self.wsp: raise RuntimeError, "Failed to find %s in file %s (from pattern %s, %s)" % (wname,finalNames[0],names[1],names[0]) 00255 if self.wsp.ClassName() == "RooWorkspace": 00256 ret = self.wsp.data(oname) 00257 if not ret: ret = self.wsp.pdf(oname) 00258 if not ret: raise RuntimeError, "Object %s in workspace %s in file %s does not exist or it's neither a data nor a pdf" % (oname, wname, finalNames[0]) 00259 # Fix the fact that more than one entry can refer to the same object 00260 ret = ret.Clone() 00261 ret.SetName("shape%s_%s_%s%s" % (postFix,process,channel, "_"+syst if syst else "")) 00262 _cache[(channel,process,syst)] = ret 00263 if not syst: 00264 normname = "%s_norm" % (oname) 00265 norm = self.wsp.arg(normname) 00266 if norm: 00267 if normname in self.DC.flatParamNuisances: 00268 self.DC.flatParamNuisances[normname] = False # don't warn if not found 00269 norm.setAttribute("flatParam") 00270 norm.SetName("shape%s_%s_%s%s_norm" % (postFix,process,channel, "_")) 00271 self.out._import(norm, ROOT.RooFit.RecycleConflictNodes()) 00272 if self.options.verbose > 1: print "import (%s,%s) -> %s\n" % (finalNames[0],objname,ret.GetName()) 00273 return ret; 00274 elif self.wsp.ClassName() == "TTree": 00275 ##If it is a tree we will convert it in RooDataSet . Then we can decide if we want to build a 00276 ##RooKeysPdf or if we want to use it as an unbinned dataset 00277 if not self.wsp: raise RuntimeError, "Failed to find %s in file %s (from pattern %s, %s)" % (wname,finalNames[0],names[1],names[0]) 00278 self.doVar("%s[%f,%f]" % (oname,self.wsp.GetMinimum(oname),self.wsp.GetMaximum(oname))) 00279 #Check if it is weighted 00280 self.doVar("__WEIGHT__[0.,1000.]") 00281 rds = ROOT.RooDataSet("shape%s_%s_%s%s" % (postFix,process,channel, "_"+syst if syst else ""), "shape%s_%s_%s%s" % (postFix,process,channel, "_"+syst if syst else ""),self.wsp,ROOT.RooArgSet(self.out.var(oname)),"","__WEIGHT__") 00282 rds.var = oname 00283 _cache[(channel,process,syst)] = rds 00284 if self.options.verbose > 1: print "import (%s,%s) -> %s\n" % (finalNames[0],wname,rds.GetName()) 00285 return rds 00286 elif self.wsp.InheritsFrom("TH1"): 00287 ##If it is a Histogram we will convert it in RooDataSet preserving the bins 00288 if not self.wsp: raise RuntimeError, "Failed to find %s in file %s (from pattern %s, %s)" % (wname,finalNames[0],names[1],names[0]) 00289 name = "shape%s_%s_%s%s" % (postFix,process,channel, "_"+syst if syst else "") 00290 # don't make it twice 00291 for X in _neverDelete: 00292 if X.InheritsFrom("TNamed") and X.GetName() == name: return X 00293 self.doVar("%s[%f,%f]" % (oname,self.wsp.GetXaxis().GetXmin(),self.wsp.GetXaxis().GetXmax())) 00294 rds = ROOT.RooDataHist(name, name, ROOT.RooArgList(self.out.var(oname)), self.wsp) 00295 rds.var = oname 00296 if self.options.verbose > 1: stderr.write("import (%s,%s) -> %s\n" % (finalNames[0],wname,rds.GetName())) 00297 _neverDelete.append(rds) 00298 return rds 00299 else: 00300 raise RuntimeError, "Object %s in file %s has unrecognized type %s" (wname, finalNames[0], self.wsp.ClassName()) 00301 else: # histogram 00302 ret = file.Get(objname); 00303 if not ret: 00304 if allowNoSyst: return None 00305 raise RuntimeError, "Failed to find %s in file %s (from pattern %s, %s)" % (objname,finalNames[0],names[1],names[0]) 00306 ret.SetName("shape%s_%s_%s%s" % (postFix,process,channel, "_"+syst if syst else "")) 00307 if self.options.verbose > 1: print "import (%s,%s) -> %s\n" % (finalNames[0],objname,ret.GetName()) 00308 _cache[(channel,process,syst)] = ret 00309 return ret
def ShapeTools::ShapeBuilder::isShapeSystematic | ( | self, | |
channel, | |||
process, | |||
syst | |||
) |
Definition at line 368 of file ShapeTools.py.
def ShapeTools::ShapeBuilder::prepareAllShapes | ( | self | ) |
-------------------------------------- -------- High level helpers ---------- --------------------------------------
Definition at line 101 of file ShapeTools.py.
00102 : 00103 shapeTypes = []; shapeBins = []; shapeObs = {} 00104 self.pdfModes = {} 00105 for ib,b in enumerate(self.DC.bins): 00106 databins = {}; bgbins = {} 00107 for p in [self.options.dataname]+self.DC.exp[b].keys(): 00108 if len(self.DC.obs) == 0 and p == self.options.dataname: continue 00109 if p != self.options.dataname and self.DC.exp[b][p] == 0: continue 00110 shape = self.getShape(b,p); norm = 0; 00111 if shape == None: # counting experiment 00112 if not self.out.var("CMS_fakeObs"): 00113 self.doVar("CMS_fakeObs[0,1]"); 00114 self.out.var("CMS_fakeObs").setBins(1); 00115 self.doSet("CMS_fakeObsSet","CMS_fakeObs"); 00116 shapeObs["CMS_fakeObsSet"] = self.out.set("CMS_fakeObsSet") 00117 if p == self.options.dataname: 00118 self.pdfModes[b] = 'binned' 00119 shapeTypes.append("RooDataHist") 00120 else: 00121 shapeTypes.append("RooAbsPdf"); 00122 elif shape.ClassName().startswith("TH1"): 00123 shapeTypes.append("TH1"); shapeBins.append(shape.GetNbinsX()) 00124 norm = shape.Integral() 00125 if p == self.options.dataname: 00126 if self.options.poisson > 0 and norm > self.options.poisson: 00127 self.pdfModes[b] = 'poisson' 00128 else: 00129 self.pdfModes[b] = 'binned' 00130 for i in xrange(1, shape.GetNbinsX()+1): 00131 if shape.GetBinContent(i) > 0: databins[i] = True 00132 elif not self.DC.isSignal[p]: 00133 for i in xrange(1, shape.GetNbinsX()+1): 00134 if shape.GetBinContent(i) > 0: bgbins[i] = True 00135 elif shape.InheritsFrom("RooDataHist"): 00136 shapeTypes.append("RooDataHist"); 00137 shapeBins.append(shape.numEntries()) 00138 shapeObs[self.argSetToString(shape.get())] = shape.get() 00139 norm = shape.sumEntries() 00140 if p == self.options.dataname: 00141 if self.options.poisson > 0 and norm > self.options.poisson: 00142 self.pdfModes[b] = 'poisson' 00143 else: 00144 self.pdfModes[b] = 'binned' 00145 elif shape.InheritsFrom("RooDataSet"): 00146 shapeTypes.append("RooDataSet"); 00147 shapeObs[self.argSetToString(shape.get())] = shape.get() 00148 norm = shape.sumEntries() 00149 if p == self.options.dataname: self.pdfModes[b] = 'unbinned' 00150 elif shape.InheritsFrom("TTree"): 00151 shapeTypes.append("TTree"); 00152 if p == self.options.dataname: self.pdfModes[b] = 'unbinned' 00153 elif shape.InheritsFrom("RooAbsPdf"): 00154 shapeTypes.append("RooAbsPdf"); 00155 else: raise RuntimeError, "Currently supporting only TH1s, RooDataHist and RooAbsPdfs" 00156 if norm != 0: 00157 if p == self.options.dataname: 00158 if len(self.DC.obs): 00159 if self.DC.obs[b] == -1: self.DC.obs[b] = norm 00160 elif abs(norm-self.DC.obs[b]) > 0.01: 00161 if not self.options.noCheckNorm: raise RuntimeError, "Mismatch in normalizations for observed data in bin %s: text %f, shape %f" % (b,self.DC.obs[b],norm) 00162 else: 00163 if self.DC.exp[b][p] == -1: self.DC.exp[b][p] = norm 00164 elif self.DC.exp[b][p] > 0 and abs(norm-self.DC.exp[b][p]) > 0.01*max(1,self.DC.exp[b][p]): 00165 if not self.options.noCheckNorm: raise RuntimeError, "Mismatch in normalizations for bin %s, process %s: rate %f, shape %f" % (b,p,self.DC.exp[b][p],norm) 00166 if len(databins) > 0: 00167 for i in databins.iterkeys(): 00168 if i not in bgbins: stderr.write("Channel %s has bin %d fill in data but empty in all backgrounds\n" % (b,i)) 00169 if shapeTypes.count("TH1"): 00170 self.out.maxbins = max(shapeBins) 00171 if self.options.verbose: stderr.write("Will use binning variable CMS_th1x with %d bins\n" % self.out.maxbins) 00172 self.doVar("CMS_th1x[0,%d]" % self.out.maxbins); self.out.var("CMS_th1x").setBins(self.out.maxbins) 00173 self.out.binVar = self.out.var("CMS_th1x") 00174 shapeObs['CMS_th1x'] = self.out.binVar 00175 if shapeTypes.count("TH1") == len(shapeTypes): 00176 self.out.mode = "binned" 00177 self.out.binVars = ROOT.RooArgSet(self.out.binVar) 00178 elif shapeTypes.count("RooDataSet") > 0 or shapeTypes.count("TTree") > 0 or len(shapeObs.keys()) > 1: 00179 self.out.mode = "unbinned" 00180 if self.options.verbose: stderr.write("Will try to work with unbinned datasets\n") 00181 if self.options.verbose: stderr.write("Observables: %s\n" % str(shapeObs.keys())) 00182 if len(shapeObs.keys()) != 1: 00183 self.out.binVars = ROOT.RooArgSet() 00184 for obs in shapeObs.values(): 00185 self.out.binVars.add(obs, False) 00186 else: 00187 self.out.binVars = shapeObs.values()[0] 00188 self.out._import(self.out.binVars) 00189 else: 00190 self.out.mode = "binned" 00191 if self.options.verbose: stderr.write("Will try to make a binned dataset\n") 00192 if self.options.verbose: stderr.write("Observables: %s\n" % str(shapeObs.keys())) 00193 if len(shapeObs.keys()) != 1: 00194 raise RuntimeError, "There's more than once choice of observables: %s\n" % str(shapeObs.keys()) 00195 self.out.binVars = shapeObs.values()[0] self.out._import(self.out.binVars)
def ShapeTools::ShapeBuilder::shape2Data | ( | self, | |
shape, | |||
channel, | |||
process, | |||
_cache = {} |
|||
) |
Definition at line 410 of file ShapeTools.py.
00410 {}): 00411 postFix="Sig" if (process in self.DC.isSignal and self.DC.isSignal[process]) else "Bkg" 00412 if shape == None: 00413 name = "shape%s_%s_%s" % (postFix,channel,process) 00414 if not _cache.has_key(name): 00415 obs = ROOT.RooArgSet(self.out.var("CMS_fakeObs")) 00416 obs.setRealValue("CMS_fakeObs",0.5); 00417 if self.out.mode == "binned": 00418 self.out.var("CMS_fakeObs").setBins(1) 00419 rdh = ROOT.RooDataHist(name, name, obs) 00420 rdh.set(obs, self.DC.obs[channel]) 00421 _cache[name] = rdh 00422 else: 00423 rds = ROOT.RooDataSet(name, name, obs) 00424 if self.DC.obs[channel] == float(int(self.DC.obs[channel])): 00425 for i in range(int(self.DC.obs[channel])): rds.add(obs) 00426 else: 00427 rds.add(obs, self.DC.obs[channel]) 00428 _cache[name] = rds 00429 return _cache[name] 00430 if not _cache.has_key(shape.GetName()): 00431 if shape.ClassName().startswith("TH1"): 00432 rebinh1 = ROOT.TH1F(shape.GetName()+"_rebin", "", self.out.maxbins, 0.0, float(self.out.maxbins)) 00433 for i in range(1,min(shape.GetNbinsX(),self.out.maxbins)+1): 00434 rebinh1.SetBinContent(i, shape.GetBinContent(i)) 00435 rdh = ROOT.RooDataHist(shape.GetName(), shape.GetName(), ROOT.RooArgList(self.out.binVar), rebinh1) 00436 self.out._import(rdh) 00437 _cache[shape.GetName()] = rdh 00438 elif shape.ClassName() in ["RooDataHist", "RooDataSet"]: 00439 return shape 00440 else: raise RuntimeError, "shape2Data not implemented for %s" % shape.ClassName() 00441 return _cache[shape.GetName()]
def ShapeTools::ShapeBuilder::shape2Pdf | ( | self, | |
shape, | |||
channel, | |||
process, | |||
_cache = {} |
|||
) |
Definition at line 442 of file ShapeTools.py.
00442 {}): 00443 postFix="Sig" if (process in self.DC.isSignal and self.DC.isSignal[process]) else "Bkg" 00444 if shape == None: 00445 name = "shape%s_%s_%s" % (postFix,channel,process) 00446 if not _cache.has_key(name): 00447 _cache[name] = ROOT.RooUniform(name, name, ROOT.RooArgSet(self.out.var("CMS_fakeObs"))) 00448 return _cache[name] 00449 if not _cache.has_key(shape.GetName()+"Pdf"): 00450 if shape.ClassName().startswith("TH1"): 00451 rdh = self.shape2Data(shape,channel,process) 00452 rhp = self.doObj("%sPdf" % shape.GetName(), "HistPdf", "{%s}, %s" % (self.out.binVar.GetName(), shape.GetName())) 00453 _cache[shape.GetName()+"Pdf"] = rhp 00454 elif shape.InheritsFrom("RooAbsPdf"): 00455 _cache[shape.GetName()+"Pdf"] = shape 00456 elif shape.InheritsFrom("RooDataHist"): 00457 rhp = ROOT.RooHistPdf("%sPdf" % shape.GetName(), "", shape.get(), shape) 00458 self.out._import(rhp) 00459 _cache[shape.GetName()+"Pdf"] = rhp 00460 elif shape.InheritsFrom("RooDataSet"): 00461 rkp = ROOT.RooKeysPdf("%sPdf" % shape.GetName(), "", self.out.var(shape.var), shape,3,1.5); 00462 self.out._import(rkp) 00463 _cache[shape.GetName()+"Pdf"] = rkp 00464 else: 00465 raise RuntimeError, "shape2Pdf not implemented for %s" % shape.ClassName() 00466 return _cache[shape.GetName()+"Pdf"]
Definition at line 101 of file ShapeTools.py.
Definition at line 8 of file ShapeTools.py.
Definition at line 8 of file ShapeTools.py.