CMS 3D CMS Logo

Public Member Functions | Public Attributes

ShapeTools::ShapeBuilder Class Reference

Inherits HiggsAnalysis::CombinedLimit::ModelTools::ModelBuilder.

List of all members.

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

Detailed Description

Definition at line 7 of file ShapeTools.py.


Constructor & Destructor Documentation

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

Member Function Documentation

def ShapeTools::ShapeBuilder::argSetToString (   self,
  argset 
)

Definition at line 467 of file ShapeTools.py.

00468                                    :
00469         names = []
00470         it = argset.createIterator()
00471         while True:
00472             arg = it.Next()
00473             if not arg: break
00474             names.append(arg.GetName())
00475         return ",".join(names)
00476 
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.

00369                                                     :
00370         shapeUp = self.getShape(channel,process,syst+"Up",allowNoSyst=True)    
        return shapeUp != None
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"]

Member Data Documentation

Definition at line 101 of file ShapeTools.py.

Definition at line 8 of file ShapeTools.py.

Definition at line 8 of file ShapeTools.py.