示例#1
0
def getVarNames( dataset, effName='efficiency' ):
	""".. function:: getVarNames( dataset, effName='efficiency' ) -> [ binnedvar1,...], effName

	From a dataset extract which binned variables have and returns
	the list of the variable's names and the efficiency name 
	
	:param dataset: dataset
	:type dataset: ROOT.RooDataSet
	:param effName: efficiency name. Default value: 'efficiency'
	:type effName: string
	:return: 2-tuple composed by a list with the names of the binned variables and a string with the 
	         name of the efficiency
	:rtype: list of strings, string

	:raise AttributeError: not found the efficiency name introduced 
	"""
	#---- Checking the variables in dataset
	_swapDict = getVarDict( dataset )
	#---  All the binned variables in the dataset
	datasetVarList = filter( lambda x: x.lower().find(effName) == -1, _swapDict.iterkeys() )
	#--- Name of the efficiency
	effList = filter( lambda x: x.lower().find(effName) != -1, _swapDict.iterkeys() )
	#---- Sanity check: should have only one name 
	if len(effList) < 1:
		message ="""There is no efficiency variable called '%s'in the RooDataSet '%s'""" % (effName, dataset.GetName())
		printError( isbinnedVar.__module__+'.'+isbinnedVar.__name__, message, AttributeError )
	elif len(effList) > 1:
		message ="""It cannot be possible to parse the efficiency name, found '%s' in the RooDataSet '%s'\n""" % (str(effList), dataset.GetName())
		message +="""Check your root file and let only one variable to contain the name '%s'""" % effName
		printError( isbinnedVar.__module__+'.'+isbinnedVar.__name__, message, AttributeError )

	return datasetVarList, effList[0] 
示例#2
0
def graphclassname(tnp, dataname):
    """.. function:: graphclassname( tnp, dataname ) -> name

	Giving a pytnp instance and a RooDataSet name contained in it, the
	function returns a string which defines the graph class that RooDataSet
	belongs. A graph class is defined by the keys ``effType``, ``objectType``
	and ``methodUsed``
	
	:param tnp: object instance of pytnp class
	:type tnp: pytnp
	:param dataname: name of the RooDataSet
	:type str: string
	:return name: name of the graph class
	:rtype: string

	:raise UserWarning: when the RooDataSet do not belong to the pyntp instance introduced
	"""
    #-- Check dataset
    try:
        return tnp[dataname]['effType'] + '_' + tnp[dataname][
            'objectType'] + '_' + tnp[dataname]['methodUsed']
    except KeyError:
        message = "The RooDataSet '%s' do not belong to the pyntp instance introduced" % dataname
        printError(graphclassname.__module__ + '.' + graphclassname.__name__,
                   message, UserWarning)
示例#3
0
	def write(self, fileOut, vartouse):
		""".. method:: write( fileOut ) 

		Create a root file with all the RooDataSets and TH2F maps of 
		the instance.

		:param fileOut: name of the output root file
		:type fileOut: string

		:raise IOError: problems opening the file
		"""
		import os
		import ROOT

		f = ROOT.TFile(fileOut,'RECREATE')
		if f.IsZombie():
			message = 'Cannot open \'%s\' file. Check your permissions' % fileOut
			printError( self.__module__+'.write', message, IOError )
		
		howDatasets = 0
		for name,dataSet in self.RooDataSet.iteritems():
			# Use only the variables introduced by the user
			argset = dataSet.get()
			allvariables = argset.contentsString().split(',')
			newvariables = ROOT.RooArgSet()
			for var in vartouse:
				#Checking it is in the argset
				if not var in allvariables:
					message = "Variable '%s' is not in the RooDataSet '%s'" % ( var, dataSet.GetName())
					printError( self.__module__+'.write', message, RuntimeError )
				newvariables.add( argset[var] )	
			#And the efficiency
			newvariables.add( argset[self.effName] )
			# The new RooDataSet	
			newdataSet = dataSet.reduce( newvariables )	
			newdataSet.Write(name.replace('/','_'))
			try:
				for namehisto,histoTuple in self[name]['TH2F'].iteritems():
					for histo in histoTuple:
						#Watch out: not use the key name because we have 3 histos
						histo.Write('TH2F_'+histo.GetName().replace('/','_'))
						howDatasets += 1
			except KeyError:
				pass
		f.Close()
		
		#--- Check you have first the TH2F keys in your RooDataSet dict
		if howDatasets == 0:
			try:
				os.remove( fileOut )
			except IOError:
				#Why can't you remove something you have create =
				pass
			message = "Do not stored any TH2F map. You must use 'plotEffMap' method first."
			printWarning( self.__module__, message )
示例#4
0
def getVarDict(dataset, __effName='efficiency'):
    """.. function:: getVarDict( dataset, effName='efficiency' ) -> dict

	Given a RooDataSet, the function returns a dictionary whose keys are
	the binned variables and efficiency names and the values are a 
	dictionary with some useful info::

	  { 'var1': { 'latexName': 'blaba', 'unit': 'unit',
	              'binN': NumberBins, 'arrayBins' : (val1,...,valN+1)
	            },
		... 
          }
	
	:param dataset: dataset
	:type dataset: ROOT.RooDataSet
	:param effName: efficiency name
	:type effName: string
	:return: see above
	:rtype: dict

	:raise TypeError: if the dataset is not a ROOT.RooDataSet
	:raise AttributeError: not found the effiency name introduced 
	"""
    import ROOT

    varinfo = {}
    try:
        arg = dataset.get()
    except AttributeError:
        message = 'The object \'%s\' is not a RooDataSet' % str(dataset)
        printError(getVarDict.__module__ + '.' + getVarDict.__name__, message,
                   TypeError)
    #-- Get the list with the name of the variables
    varList = arg.contentsString().split(',')
    for name in varList:
        if isinstance(arg[name], ROOT.RooCategory):
            continue
        binN, arrayBinPointer = getBinning(arg[name])
        # Some memory problems with the Double array--> to tuple
        arrayBin = tuple([arrayBinPointer[i] for i in xrange(binN + 1)])
        varinfo[name] = { 'unit': arg[name].getUnit(), 'latexName': arg[name].getTitle().Data(), \
          'binN' : binN, 'arrayBins': arrayBin
          } #Note: some TString instance--> normalizing to str with Data method
    try:
        effName = filter(lambda x: x.lower().find(__effName) != -1,
                         [i for i in varinfo.iterkeys()])[0]
    except IndexError:
        message = 'The RooDataSet \'%s\' does not have the \'%s\' variable as efficiency' % (
            dataset.GetName(), __effName)
        printError(getVarDict.__module__ + '.' + getVarDict.__name__, message,
                   AttributeError)

    varinfo[effName]['latexName'] = '#varepsilon'

    return varinfo
示例#5
0
def tableEff(dataset, effName='efficiency'):
    """
	tableEff( dataset, 'effName' ) --> tableDict

	Giving a RooDataSet, the function returns a dictionary where every 
	key is the 'variables' of the RooDataSet. Each value is a 
	list of tuples (var, varErrorLo, varErrorHigh):
	
	:param dataset: dataset
	:type dataset: ROOT.RooDataSet
	:param effName: efficiency name
	:type effName: string
	:return: dict with efficiency values and binned variables
	:rtype: dict
	
	The output dictionary looks like::
		
		{ 
		  'efficiency': [ (eff1,effLo1,effHi1), (eff2,effLo2,effHi2), ... ],
		  'var_x'      : [ (varX1,xLo1,xHi1), (varX2,xLo2,xHi2), .... ],
		  'var_y'      : [ (varY1,yLo1,yHi1), (varY2,yLo2,yHi2), .... ],
		  ...
		}

	.. note:: There is another version to extract the table, see the function :func:`listTableEff`, a little more efficient than this one	
	"""
    #--- Getting variables from dataset, note that if dataset is not a RooDataSet,
    #--- getVarDict raise an AttributeError exception
    _swapDict = getVarDict(dataset)
    datasetVarList = [i for i in _swapDict.iterkeys()]
    #--- Is efficiency in dataset?
    if not effName in datasetVarList:
        message = 'Do not found \'%s\' as the name of the efficiency in the dataset \'%s\'' % (
            effName, dataSet.GetName())
        printError(tableEff.__module__ + '.' + tableEff.__name__, message,
                   KeyError)

    #--- Extract the RooArgSet (container of variables)
    argset = dataset.get()
    #--- Output table dictionary
    _table = dict([(var, []) for var in _swapDict.iterkeys()])
    #--- Looping all the 'events'
    for ev in xrange(dataset.numEntries()):
        #--- event
        dataset.get(ev)
        for varName, valueList in _table.iteritems():
            variable = argset[varName]
            valueList.append(
                (variable.getVal(), variable.getVal() + variable.getErrorLo(),
                 variable.getVal() + variable.getErrorHi()))
    #-- In principle, I don't have to control errors: getVarDict is coherent with dataset.get, the same variables must
    #-- exist
    return _table
示例#6
0
def getVarDict( dataset, __effName='efficiency' ):
	""".. function:: getVarDict( dataset, effName='efficiency' ) -> dict

	Given a RooDataSet, the function returns a dictionary whose keys are
	the binned variables and efficiency names and the values are a 
	dictionary with some useful info::

	  { 'var1': { 'latexName': 'blaba', 'unit': 'unit',
	              'binN': NumberBins, 'arrayBins' : (val1,...,valN+1)
	            },
		... 
          }
	
	:param dataset: dataset
	:type dataset: ROOT.RooDataSet
	:param effName: efficiency name
	:type effName: string
	:return: see above
	:rtype: dict

	:raise TypeError: if the dataset is not a ROOT.RooDataSet
	:raise AttributeError: not found the effiency name introduced 
	"""
	import ROOT 

	varinfo = {}
	try:
		arg = dataset.get()
	except AttributeError:
		message = 'The object \'%s\' is not a RooDataSet' % str(dataset)
		printError( getVarDict.__module__+'.'+getVarDict.__name__, message, TypeError )
	#-- Get the list with the name of the variables
	varList = arg.contentsString().split(',')
	for name in varList:
		if isinstance(arg[name],ROOT.RooCategory):
			continue
		binN, arrayBinPointer = getBinning( arg[name] )
		# Some memory problems with the Double array--> to tuple
		arrayBin = tuple( [ arrayBinPointer[i] for i in xrange(binN+1) ] )
		varinfo[name] = { 'unit': arg[name].getUnit(), 'latexName': arg[name].getTitle().Data(), \
				'binN' : binN, 'arrayBins': arrayBin 
				} #Note: some TString instance--> normalizing to str with Data method
	try:
		effName = filter( lambda x: x.lower().find(__effName) != -1, [i for i in varinfo.iterkeys()] )[0]
	except IndexError:
		message = 'The RooDataSet \'%s\' does not have the \'%s\' variable as efficiency' % (dataset.GetName(), __effName)
		printError( getVarDict.__module__+'.'+getVarDict.__name__, message, AttributeError )

	varinfo[effName]['latexName'] = '#varepsilon'

	return varinfo
示例#7
0
def tableEff( dataset, effName = 'efficiency' ):
	"""
	tableEff( dataset, 'effName' ) --> tableDict

	Giving a RooDataSet, the function returns a dictionary where every 
	key is the 'variables' of the RooDataSet. Each value is a 
	list of tuples (var, varErrorLo, varErrorHigh):
	
	:param dataset: dataset
	:type dataset: ROOT.RooDataSet
	:param effName: efficiency name
	:type effName: string
	:return: dict with efficiency values and binned variables
	:rtype: dict
	
	The output dictionary looks like::
		
		{ 
		  'efficiency': [ (eff1,effLo1,effHi1), (eff2,effLo2,effHi2), ... ],
		  'var_x'      : [ (varX1,xLo1,xHi1), (varX2,xLo2,xHi2), .... ],
		  'var_y'      : [ (varY1,yLo1,yHi1), (varY2,yLo2,yHi2), .... ],
		  ...
		}

	.. note:: There is another version to extract the table, see the function :func:`listTableEff`, a little more efficient than this one	
	"""
	#--- Getting variables from dataset, note that if dataset is not a RooDataSet,
	#--- getVarDict raise an AttributeError exception
	_swapDict = getVarDict( dataset )
	datasetVarList = [ i for i in _swapDict.iterkeys() ]
	#--- Is efficiency in dataset?
	if not effName in datasetVarList:
		message = 'Do not found \'%s\' as the name of the efficiency in the dataset \'%s\'' % (effName,dataSet.GetName())
		printError( tableEff.__module__+'.'+tableEff.__name__, message, KeyError )
	
	#--- Extract the RooArgSet (container of variables)
	argset = dataset.get()
	#--- Output table dictionary
	_table = dict( [ (var, []) for var in _swapDict.iterkeys() ] )
	#--- Looping all the 'events'
	for ev in xrange( dataset.numEntries() ):
		#--- event
		dataset.get(ev)
		for varName, valueList in _table.iteritems():
			variable = argset[varName]
			valueList.append( (variable.getVal(), variable.getVal()+variable.getErrorLo(), variable.getVal()+variable.getErrorHi()) )
	#-- In principle, I don't have to control errors: getVarDict is coherent with dataset.get, the same variables must
	#-- exist
	return _table
示例#8
0
    def __check_keywords__(self, keywords):
        """.. method:: __check_keywords__( keywords ) 

		Checks the keywords passed to the constructor

		:raise KeyError: invalid keyword
		:raise TypeError: invalid format of ``variables``
		"""
        #FIXME : ojo, dataset ha quedado huerfana...
        #--- Keys valid
        valid_keys = [
            'resonance', 'dataset', 'mcTrue', 'variables', 'effName',
            'configfile'
        ]
        #---- Some initializations using user inputs ---#
        dataset = ''
        for i in keywords.keys():
            if not i in valid_keys:
                message = 'Invalid instance of pytnp: you can not use %s as key argument, ' % i
                message += 'key arguments valids are \'%s\'' % str(valid_keys)
                #	print help(self.__init__)
                printError(
                    self.__check_keywords__.__module__ +
                    '.___check_keywords__', message, KeyError)
            #---Checking the correct format and storing
            #---the names provided by the user
            elif i == 'resonance':
                #Message to be sended if the value is not a tuple
                message ='Not valid resonance=%s key; resonance key must be a tuple containing (\'name\',\'nameInLatex\')' \
                  % str(keywords['resonance'])
                if len(keywords['resonance']) != 2:
                    printError(self.__module__, message, KeyError)
                else:
                    #Checking the tuple format is (name, nameInLatex)
                    if keywords['resonance'][0].find('#') != -1 \
                      or keywords['resonance'][0].find('{') != -1  :
                        printError(self.__module__, message, KeyError)
                    #--- Storing resonance provided by user
                    self.resonance = keywords['resonance'][0]
                    self.resLatex = keywords['resonance'][1]
            elif i == 'effName':
                self.effName = keywords[i]
            elif i == 'dataset':
                dataset = keywords[i]
            elif i == 'variables':
                #-- Sanity checks
                if not isinstance(keywords[i], list):
                    message = 'Not valid \'variables=%s\' key; must be a list containing n variables names' % str(
                        keywords[i])
                    printError(self.__module__, message, TypeError)
                else:
                    self.userVariables = [var for var in keywords[i]]
            elif i == 'configfile':
                self.configfile = keywords[i]
            #elif i == 'mcTrue' --> TO BE DEPRECATED OR ACTIVATED?

        return dataset
示例#9
0
def isEffNoNull(dataset, effName='efficiency'):
    """.. function:: isEffNoNull( dataset, effName='efficiency' ) -> bool

	Given a dataset, the function evaluates if the variable
	effName has any value different from zero returning True,
	otherwise return False.
	
	:param dataset: dataset
	:type dataset: ROOT.RooDataSet
	:param effName: efficiency name
	:type effName: string
	:return: True if the dataset contains at least one efficiency value different zero
	:rtype: bool

	:raise AttributeError: not found the effiency name introduced 
	"""
    #-- Checking efficiency is there
    isEff = isVar(dataset, effName)
    if not isEff:
        message = """There is no efficiency variable called '%s'in the RooDataSet '%s'""" % (
            effName, dataset.GetName())
        printError(isEffNoNull.__module__ + '.' + isEffNoNull.__name__,
                   message, AttributeError)
    #_swapDict = getVarDict( dataset )
    #effList = filter( lambda x: x.lower().find(effName) != -1, _swapDict.iterkeys() )
    #if len(effList) < 1:
    #	message ="""There is no efficiency variable called '%s'in the RooDataSet '%s'""" % (effName, dataset.GetName())
    #	printError( isEffNoNull.__module__+'.'+isEffNoNull.__name__, message, AttributeError )
    #elif len(effList) > 1:
    #	message ="""It cannot be possible to parse the efficiency name, found '%s'in the RooDataSet '%s'\n""" % (str(effList), dataset.GetName())
    #	message +="""Check your root file and let only one variable to contain the name '%s'""" % effName
    #	printError( isEffNoNull.__module__+'.'+isEffNoNull.__name__, message, AttributeError )

    _table = tableEff(dataset, effName)
    # FIXME: Comparation between double and 0.0 -- better abs(var) < 1e-10, for example
    zeroList = filter(
        lambda
        (var, varLo, varHi): var == 0.0 and varLo == 0.0 and varHi == 0.0,
        _table[effName])

    if len(zeroList) == len(_table[effName]):
        return False
    else:
        return True
示例#10
0
    def write(self, fileOut):
        """.. method:: write( fileOut ) 

		Create a root file with all the RooDataSets and TH2F maps of 
		the instance.

		:param fileOut: name of the output root file
		:type fileOut: string

		:raise IOError: problems opening the file
		"""
        import os
        import ROOT

        f = ROOT.TFile(fileOut, 'RECREATE')
        if f.IsZombie():
            message = 'Cannot open \'%s\' file. Check your permissions' % fileOut
            printError(self.__module__ + '.write', message, IOError)

        howDatasets = 0
        for name, dataSet in self.RooDataSet.iteritems():
            dataSet.Write(name.replace('/', '_'))
            try:
                for namehisto, histoTuple in self[name]['TH2F'].iteritems():
                    for histo in histoTuple:
                        #Watch out: not use the key name because we have 3 histos
                        histo.Write('TH2F_' +
                                    histo.GetName().replace('/', '_'))
                        howDatasets += 1
            except KeyError:
                pass
        f.Close()

        #--- Check you have first the TH2F keys in your RooDataSet dict
        if howDatasets == 0:
            try:
                os.remove(fileOut)
            except IOError:
                #Why can't you remove something you have create =
                pass
            message = "Do not stored any TH2F map. You must use 'plotEffMap' method first."
            printWarning(self.__module__, message)
示例#11
0
	def write(self, fileOut):
		""".. method:: write( fileOut ) 

		Create a root file with all the RooDataSets and TH2F maps of 
		the instance.

		:param fileOut: name of the output root file
		:type fileOut: string

		:raise IOError: problems opening the file
		"""
		import os
		import ROOT

		f = ROOT.TFile(fileOut,'RECREATE')
		if f.IsZombie():
			message = 'Cannot open \'%s\' file. Check your permissions' % fileOut
			printError( self.__module__+'.write', message, IOError )
		
		howDatasets = 0
		for name,dataSet in self.RooDataSet.iteritems():
			dataSet.Write(name.replace('/','_'))
			try:
				for namehisto,histoTuple in self[name]['TH2F'].iteritems():
					for histo in histoTuple:
						#Watch out: not use the key name because we have 3 histos
						histo.Write('TH2F_'+histo.GetName().replace('/','_'))
						howDatasets += 1
			except KeyError:
				pass
		f.Close()
		
		#--- Check you have first the TH2F keys in your RooDataSet dict
		if howDatasets == 0:
			try:
				os.remove( fileOut )
			except IOError:
				#Why can't you remove something you have create =
				pass
			message = "Do not stored any TH2F map. You must use 'plotEffMap' method first."
			printWarning( self.__module__, message )
示例#12
0
	def __check_keywords__(self, keywords ):
		""".. method:: __check_keywords__( keywords ) 

		Checks the keywords passed to the constructor

		:raise KeyError: invalid keyword
		:raise TypeError: invalid format of ``variables``
		"""
		#FIXME : ojo, dataset ha quedado huerfana...
		#--- Keys valid
		valid_keys = ['resonance', 'dataset', 'mcTrue','variables', 'effName', 'configfile' ]
		#---- Some initializations using user inputs ---#
		dataset = ''
		for i in keywords.keys():
			if not i in valid_keys:
				message = 'Invalid instance of pytnp: you can not use %s as key argument, ' % i
				message += 'key arguments valids are \'%s\'' % str(valid_keys)
			#	print help(self.__init__)
				printError( self.__check_keywords__.__module__+'.___check_keywords__', message, KeyError )
			#---Checking the correct format and storing
			#---the names provided by the user
			elif i == 'resonance':
				#Message to be sended if the value is not a tuple
				message ='Not valid resonance=%s key; resonance key must be a tuple containing (\'name\',\'nameInLatex\')' \
						% str(keywords['resonance'])
				if len(keywords['resonance']) != 2:
					printError( self.__module__, message, KeyError )
				else:
					#Checking the tuple format is (name, nameInLatex)
					if keywords['resonance'][0].find('#') != -1 \
							or keywords['resonance'][0].find('{') != -1  :
						printError( self.__module__, message, KeyError )
					#--- Storing resonance provided by user
					self.resonance = keywords['resonance'][0]
					self.resLatex  = keywords['resonance'][1]
			elif i == 'effName':
				self.effName = keywords[i]
			elif i == 'dataset':
				dataset = keywords[i]
			elif i == 'variables':
				#-- Sanity checks
				if not isinstance(keywords[i], list):
                                        message ='Not valid \'variables=%s\' key; must be a list containing n variables names' % str(keywords[i])
					printError( self.__module__, message, TypeError )
				else:
					self.userVariables = [ var for var in keywords[i] ]
			elif i == 'configfile':
				self.configfile = keywords[i]
			#elif i == 'mcTrue' --> TO BE DEPRECATED OR ACTIVATED?

		return dataset
示例#13
0
def isEffNoNull( dataset, effName='efficiency' ):
	""".. function:: isEffNoNull( dataset, effName='efficiency' ) -> bool

	Given a dataset, the function evaluates if the variable
	effName has any value different from zero returning True,
	otherwise return False.
	
	:param dataset: dataset
	:type dataset: ROOT.RooDataSet
	:param effName: efficiency name
	:type effName: string
	:return: True if the dataset contains at least one efficiency value different zero
	:rtype: bool

	:raise AttributeError: not found the effiency name introduced 
	"""
	#-- Checking efficiency is there
	isEff = isVar( dataset, effName )
	if not isEff:
		message ="""There is no efficiency variable called '%s'in the RooDataSet '%s'""" % (effName, dataset.GetName())
		printError( isEffNoNull.__module__+'.'+isEffNoNull.__name__, message, AttributeError )
	#_swapDict = getVarDict( dataset )
	#effList = filter( lambda x: x.lower().find(effName) != -1, _swapDict.iterkeys() )
	#if len(effList) < 1:
	#	message ="""There is no efficiency variable called '%s'in the RooDataSet '%s'""" % (effName, dataset.GetName())
	#	printError( isEffNoNull.__module__+'.'+isEffNoNull.__name__, message, AttributeError )
	#elif len(effList) > 1:
	#	message ="""It cannot be possible to parse the efficiency name, found '%s'in the RooDataSet '%s'\n""" % (str(effList), dataset.GetName())
	#	message +="""Check your root file and let only one variable to contain the name '%s'""" % effName
	#	printError( isEffNoNull.__module__+'.'+isEffNoNull.__name__, message, AttributeError )

	_table = tableEff( dataset, effName )
	# FIXME: Comparation between double and 0.0 -- better abs(var) < 1e-10, for example
	zeroList = filter( lambda (var,varLo,varHi): var == 0.0 and varLo == 0.0 and varHi == 0.0,  _table[effName] )
	
	if len(zeroList) == len(_table[effName]):
		return False
	else:
		return True
示例#14
0
def getVarNames(dataset, effName='efficiency'):
    """.. function:: getVarNames( dataset, effName='efficiency' ) -> [ binnedvar1,...], effName

	From a dataset extract which binned variables have and returns
	the list of the variable's names and the efficiency name 
	
	:param dataset: dataset
	:type dataset: ROOT.RooDataSet
	:param effName: efficiency name. Default value: 'efficiency'
	:type effName: string
	:return: 2-tuple composed by a list with the names of the binned variables and a string with the 
	         name of the efficiency
	:rtype: list of strings, string

	:raise AttributeError: not found the efficiency name introduced 
	"""
    #---- Checking the variables in dataset
    _swapDict = getVarDict(dataset)
    #---  All the binned variables in the dataset
    datasetVarList = filter(lambda x: x.lower().find(effName) == -1,
                            _swapDict.iterkeys())
    #--- Name of the efficiency
    effList = filter(lambda x: x.lower().find(effName) != -1,
                     _swapDict.iterkeys())
    #---- Sanity check: should have only one name
    if len(effList) < 1:
        message = """There is no efficiency variable called '%s'in the RooDataSet '%s'""" % (
            effName, dataset.GetName())
        printError(isbinnedVar.__module__ + '.' + isbinnedVar.__name__,
                   message, AttributeError)
    elif len(effList) > 1:
        message = """It cannot be possible to parse the efficiency name, found '%s' in the RooDataSet '%s'\n""" % (
            str(effList), dataset.GetName())
        message += """Check your root file and let only one variable to contain the name '%s'""" % effName
        printError(isbinnedVar.__module__ + '.' + isbinnedVar.__name__,
                   message, AttributeError)

    return datasetVarList, effList[0]
示例#15
0
def graphclassname( tnp, dataname ):
	""".. function:: graphclassname( tnp, dataname ) -> name

	Giving a pytnp instance and a RooDataSet name contained in it, the
	function returns a string which defines the graph class that RooDataSet
	belongs. A graph class is defined by the keys ``effType``, ``objectType``
	and ``methodUsed``
	
	:param tnp: object instance of pytnp class
	:type tnp: pytnp
	:param dataname: name of the RooDataSet
	:type str: string
	:return name: name of the graph class
	:rtype: string

	:raise UserWarning: when the RooDataSet do not belong to the pyntp instance introduced
	"""
	#-- Check dataset
	try:
		return tnp[dataname]['effType']+'_'+tnp[dataname]['objectType']+'_'+tnp[dataname]['methodUsed']
	except KeyError:
		message = "The RooDataSet '%s' do not belong to the pyntp instance introduced" % dataname
		printError( graphclassname.__module__+'.'+graphclassname.__name__, message, UserWarning )
示例#16
0
def getEff( dataSet, input_effName='efficiency', **keywords):
	""".. function:: getEff(dataset, effName='efficiency', var1=value[,var2=value2, ...]) -> eff, effErrorLow, effErrorHigh (,dict)

	Giving a binned variables returns the efficiency which 
	corresponds to those values. There is 2 output signatures 
	depending of the argument variables introduced; if the 
	variables are the exhausted set of the RooDataSet, the output
	will be a tuple of efficiency (CASE 1). Otherwise if the
	input variables don't cover all the RooDataSet binned 
	variables, the output will be the efficiency tuple plus
	a dictionary which the names of the resting variables as keys
	and the tuples of their bin values as values (CASE 2).
	
	:param dataset: dataset
	:type dataset: ROOT.RooDataSet
	:param input_effName: efficiency name
	:type input_effName: string
	:keyword var: var=value
	:rtype var: object
	:return: tuple with efficiency values (and a dictionary)
	:rtype: float,float,float(,dict)
	
	:raise UserWarning: if do not introduce at least one variable as keyword
	"""
	#---- Checking the variables in dataset
	_swapDict = getVarDict( dataSet )
	#---  All the binned variables in the dataset
	datasetVarList, effName = getVarNames( dataSet, input_effName )

	varList = []
	nameVarList = []
	for var,value in keywords.iteritems():
		if not isbinnedVar( dataSet, var, effName, warning=True ):
			raise KeyError
		varList.append( (var,value) )
		nameVarList.append( var )
	#---- Sanity check
	if len(nameVarList) < 1:
		message ="""You must introduce at least one variable"""
		printError( getEff.__module__+'.'+getEff.__name__, message, UserWarning )
	#--- Variables the user don't ask. This is the case when the user
	#--- wants a list of efficiency given a fixed value of one variable
	noAskVar = filter( lambda x: x not in nameVarList, datasetVarList )
	listReturn = False
	effVarList = None
	if len(noAskVar) != 0:
		listReturn = True
		effVarList = []
	#---- Sanity check
	if len( varList ) > len(datasetVarList):#FIXME---> can be more than 2 variables...
		message ="""You are using more variables than in dataset '%s'""" % dataSet.GetName()
		printError(getEff.__module__+'.'+getEff.__name__, message, AttributeError )

	#-- Get the table of efficiencies
	tableList = listTableEff( dataSet ) 

	for valDict in tableList:
		#--  From the list of the variables we want the efficiencies (varList), put the value inside  
		#--- of the ranges (valDict[var][1:][i]) in the list 
		fList = filter( lambda (var,value): valDict[var][1:][0] <= value and valDict[var][1:][1] > value , varList )
		#--  If our variables are all the variables available, we have 1-to-1 correspondence
		#--- with a efficiency value-> return this value
		if not listReturn and len(fList) == len( varList ):
			return valDict[effName]
		#--  If our variables are less than the variables available, we're going to return
		#--- a list with the (restOfvariables,efficiencies) in order to recover the 1-to-1 correspondence
		elif listReturn and len(fList) != 0:
			restVarDict = dict( [ (_name, valDict[_name]) for _name in noAskVar ] )
			effVarList.append( (valDict[effName],restVarDict) )

	if listReturn and len(effVarList) > 0 :
		#--output: (tuple,dict) where tuple is efficiency values and dict have the
		#--- names of the variables as keys and tuple as values  
		return effVarList

	message = '\033[1;34mpytnp.getEff Info: There is no bin where live '
	for var,val in varList:
		message += var+'='+str(val)+', '
	message = message[:-2]+'\033[1;m'
	print message

	# FIXME: Strange behaviour with version 3_6_1_patch4 (really with the RooFit (3.12 ??) included in this version:
	#        The values of the listTableEff do not fill correctly. All the dictionary is filled of the same value (the last found value)
	#        Still have this problem with RooFit 3.13, root-v5.27, python 2.6 ... 
	return None
示例#17
0
	def __extract__(self, Dir, dictObjects, regexp):
		""".. method:: 	__extract__(dir, dictT, regexp) -> dict
	 	
		Recursive function to extract from a 'tag and probe' ROOT file all
		the relevant information. Returning a dictionary which stores all (TCanvas,
		RooFitResult,) RooDataSet (and RooPlot) with matches with regexp::

		  {# 'TCanvas': 
		   #           {'directory/subdirectory/.../nameOfTCanvas' : <ROOT.TCanvas object>,
		   #	     ...
		   #	     },
		   # 'RooFitResult' : 
		   #           { 'directory/subdirectory/.../nameOfRooFitResult': <ROOT.RooFitResult object>,
		   #	     ...
		   #           },
	 	    'RooDataSet':
		              { 'directory/subdirectory/.../nameOfRooDataSet': <ROOT.RooDataSet object>,
		              ...
		              },
		  }

		:param dir: root TDirectory (note TFile inherit from TDirectory) where to extract
		:type dir: ROOT.TDirectory
		:param dictT: directory where to store the information extracted 
		:type dictT: dict
		:param regexp: ?? (TO BE CHECKED)
		:type regexp: string

		:return: dictionary (see above)
		:rtype: dict

		:raise AttributeError: the root file is not an standard T&P

		.. warning:: 
		     
		   DEPRECATED TCanvas, RooFitResult and RooPlot storage
		            
	 	"""
		if pytnp.counter%100 == 0:
			print '.',
			sys.stdout.flush()
		# FIXED-------------------------------------------------
	 	#_dirSave = ROOT.gDirectory
	 	#Python --> _dirSave is a reference to ROOT.gDirectory, 
		#           so whenever gDirectory changes, _dirSaves 
		#           changes too. I can't use the gDirectory
		#-------------------------------------------------------
	 	_dirSave = Dir
		#Storing the father->child info
		try:
			listOfKeys = Dir.GetListOfKeys()
		##-- Checking that is a Tag and Probe fit 
		##   file. IF it is not, then we find
		##   some not expected TKeys (as TTree, etc.. )
		except AttributeError:
			message = """The root file is not an standard T&P fit file""" 
			printError( self.__module__, message, AttributeError )
	 	for key in Dir.GetListOfKeys():
	 		className = key.GetClassName()
	 		if key.IsFolder():
	 			##-- Extracting the Folder from Dir
				_subdir = Dir.Get(key.GetName())
	 			##-- And browsing inside recursively
				pytnp.counter += 1
	 			dictObjects = self.__extract__(_subdir,dictObjects,regexp)
	 			##-- To avoid segmentation faults, we need to return
				##   at the original directory in order to continue
				##   extracting subdirectories (or elements of the directory)
	 			_dirSave.cd()
	 		##-- Storing in the dictionary the interesting objects
		        elif className in self.classNames:
				pytnp.counter += 1
				#--Skipping if not match (Note that anything.find('') gives 0
				if (Dir.GetPath()+key.GetName()).find(regexp) == -1:
					continue
				try:
					#Asuming unique id object-->complet path
					dictObjects[className][Dir.GetPath().split(':/')[1]+'/'+key.GetName()] = Dir.Get(key.GetName())
				except KeyError:
					dictObjects[className] = { Dir.GetPath().split(':/')[1]+'/'+key.GetName(): Dir.Get(key.GetName()) }
	 
	 	return dictObjects
示例#18
0
	def __getType__(self, name, structure):
		""".. method:: __getType__( 'RooDataSet name', dictionary ) -> dictionary

		Build a dictionary where the key is the pathname (in standard T&P format)
		and the values are also dictionaries storing relevant info of the dataset.

		:raise ValueError: file root format incorrect
		:raise AttributeError: Misuse of configuration file
		"""
		import re
		from management import parserConfig
		#-- Dictionary to store 
		structure[name] = { 'effType': {}, 'objectType': {}, 'methodUsed': {}, 'isMC' : {} }
		#-- Extracting
		pathname = name.split('/')
		if len(pathname) != 3:
			#-- The storage format is not in T6P standard
			message = 'The format of the \'%s\' file is not in T&P standard.' % self.__fileroot__.GetName()
			printError( self.__module__, message, ValueError )

		effType = pathname[0]
		objectType = pathname[1]
		methodUsed = pathname[2]
		#-- Mapping
		#--- Check and put values provided by the user
		try:
			#--- If not enter config, self.configfile is None and 
			#--- parserConfig raise a TypeError exception.
			#--- If is not there some key, the AttributeError is raised
			try:
				tupleAttr = parserConfig( self.configfile, self.resonance+'::'+name )
			except AttributeError:
				Message = "If the error above is related with the identifier:\n"
				Message += "Coherence broken between configuration file and 'pytnp' instanciation\n"
				Message += "Check you have a object called '%s' in your configuration file" % self.resonance
				printError( self.__module__+'.pytnp', Message, AttributeError )
			#--- If nothing the tupleAttr is None so NameError exception too
			structure[name]['effType'] = tupleAttr[0]
			structure[name]['objectType'] = tupleAttr[1]
			structure[name]['isMC'] = tupleAttr[2]
			#FIXME: To be implemented
			#try:
			#	structure[name]['legend'] = tupleAttr[3]
			#except IndexError:
			#	pass
		except (NameError,TypeError):
			#---- Type of efficiency
			if effType == 'histoTrigger':
				structure[name]['effType'] = 'Trigger'
			elif effType == 'histoMuFromTk':
				structure[name]['effType'] =  'MuonID'
			else:
				structure[name]['effType'] = 'unknown'
			#---- Type of efficiency
			structure[name]['objectType'] = objectType.split('_')[0]
			#---- Is mcTrue
			regexp = re.compile( '\S*_(?P<mc>mcTrue)' )
			try:
				# Check if it mcTrue
				regexp.search( objectType ).group( 'mc' )
				structure[name]['isMC'] = 1
			except AttributeError:
				structure[name]['isMC'] = 0
		#---- Method Used
		structure[name]['methodUsed'] = methodUsed

		return structure
示例#19
0
	def __init__(self, filerootName, **keywords):
		""".. class:: pytnp(filerootName [, resonance=(id,nameLatex), effName='efficiency_name', variables=[varname1,varname2,..], configfile=file,  dataset=type, mcTrue=true ] )
		
		Class encapsulating the contents of a Tag and Probe root file (generated from CMSSW T&P package).
		The root file must have a two-level directory hierarchy, where the RooDataSet 
		(whose actually contains the information) is in the bottom. The pytnp class is based
		in the RooDataSet, a instance of this class returns a dictionary (self) whose keys are
		the names (absolute path) of the RooDataSet, the values are dictionaries themselves with 
		keys storing useful information of the RooDataSet. A generic example is shown::

		  { 
		    'firstlevel/secondlevel/dataset_eff': { 
						           'effType': efficiency_type
						           'binnedVar': binnedvardict
						           'methodUsed': method_used
						           'variables': vardict
						           'dataset': roodataset
						           'isMC': 0|1
						           'eff': efficiencyname
						           'objectType': object_type
						          },
		     ....,
                  }

		where ``firstlevel/secondlevel/dataset_eff`` is the name of the dataset, the
		dictionary values have a ``efficiency_type``, ``method_used`` and ``object_type``
		strings which they going to be extracted from the root file or from the configuration
		file provided by the user. The keys ``binnedVar`` and ``variables`` are 
		dictionaries which contains useful information for the binned variables and all 
		the variables (respectively) in the RooDataSet (see :mod:`pytnp.libpytnp.tnputils.getVarDict`).
		The ``dataset`` key contains the RooDataSet object itself.

		The ``configfile`` keyword can be used to change the values found by the constructor
		when parsing the root file. An example of configuration file::

		    DataNames = { 
		                   # root file name: TnP_Z_DATA_TriggerFromMu_Trigger_ProbeMu11_Eta_Fit.root
				   'ProbeMu11_Eta_Fit': ( "Z#rightarrow#mu#mu, HLTMu11 trigger",'Z_11' ),
				   # root file is: TnP_Z_DATA_TriggerFromMu_Trigger_ProbeMu9_Eta_Fit.root
				   'ProbeMu9_Eta_Fit' : ("Z#rightarrow#mu#mu, HLTMu9 trigger", 'Z_9' ),
				}
		    #Attributes
		    Z_11 = {
		            'tpTree/PASSING_all/fit_eff': ( 'HLT_trigger' , 'Glb_muons' , 0 ),
			    'tpTree/PASSING_all/cnt_eff': ( 'HLT_trigger' , 'Glb_muons' , 1 ),
                           }
	            
		    Z_9  = {
		            'tpTree/PASSING_all/fit_eff': ( 'HLT_trigger' , 'Glb_muons' , 0 ),
			    'tpTree/PASSING_all/cnt_eff': ( 'HLT_trigger' , 'Glb_muons' , 1 ),
			   }

		The ``DataNames`` is a mandatory dictionary. It is used to identify a root file with 
		a ``pytnpname``, the keys are expressions which can describe the name of the 
		root file (using the ``find`` method of a string) and the values are tuples of strings
		with the latex name (to be put in the legends) and the ``pytnpname``. Using this
		identifier it possible to construct another dictionaries with the informationn of
		each dataset (or some dataset) in the root file. The names of the dictionary objects
		must be the same as the ``pytnpname`` defined before; this dictionaries have as keys
		the name of the datasets to be modified and the values are tuples with the 
		``effType``, ``objectType`` and ``isMC`` attributes.


		:param filerootName: name of the root file
		:type filerootName: string		
		:keyword resonance: assigns a (pytnpname,latexName) 
		:type resonance: (strings,string)
		:keyword effName: Providing the efficiency name finded inside the RooDataSets. 
		                  Otherwise, we assume the name ``efficiency``.
				  CAVEAT: all the RooDataSet MUST have the same efficiency name.
		:type effName: string
		:keyword variables: Binned variables considered
		:type variables: list of strings
		:keyword configfile: the configuration file to be used (if any)
		:type configfile: string
		:keyword dataset: Store only dataset matching this effType (TO BE DEPRECATED)
		:type dataset: string
		:keyword mcTrue: Setting True, it stores the mcTrue info and will associate each
		                 dataset with their mcTrue dataset. (TO BE DEPRECATED)
		:type mcTrue: bool

		
		:raise IOError: Invalid root file name
		:raise TypeError: Invalid format of the root file (do not have the proper directory structure)
		:raise KeyError: Invalid name of efficiency, not found in the dataset
		:raise ValueError: Not found the binned variables introduced

		"""
		import ROOT
		from getresname import getResName
		from tnputils import getVarDict, isEffNoNull

		#--- Checking the keys dictionary passed ----#
		dataset = self.__check_keywords__( keywords ) #FIXMEE

		#--- Extracting the members
		print 'Extracting info from '+filerootName+'.',
		sys.stdout.flush()
		fileroot = ROOT.TFile(filerootName)
		#--- Checking the extraction was fine
		if fileroot.IsZombie():
			message = 'Invalid root dataset or root dataset not found, \'%s\'' % filerootName
			printError( self.__module__, message, IOError )
		
		#--- Extract all the objects of the rootfile and put them as attributes of the instance
		self.__dict__ = self.__extract__(fileroot, self.__dict__, dataset) 
		#--- Checking everything was fine
		if not 'RooDataSet' in self.__dict__.keys():
			message = """The root file is not an standard T&P fit file"""
			printError( self.__module, message, TypeError )
		print ''

		self.__fileroot__ = fileroot
		#-- Get the resonances names
		#----- If they had not been provided by the user
		if not self.resonance:
			self.resonance, self.resLatex = getResName( filerootName )
		#--- Encapsulate the hierarchy of the directories:
		for name in self.__dict__['RooDataSet'].iterkeys():
			self.__attrDict__ = self.__getType__(name,self.__attrDict__)
		#--- Associate the names of the mcTrue and counting MC True to a fit_eff
		#----- Getting all the MC True RooDataSets: [ (name,dictionary),...]
		mcTrueData = filter( lambda x: x[1]['isMC'] == 1, self.__attrDict__.iteritems() )
		#---- Loop over all RooDataSets fitted but not MC
		for Name,Dict in filter( lambda x: x[1]['isMC'] == 0 and x[1]['methodUsed'] == 'fit_eff', self.__attrDict__.iteritems() ):
			#---- Getting the parter to mcTrueData: all with the same objectType and effType 
			#------ Can be cnt, fit_eff and sbs
			partner = filter( lambda x: x[1]['objectType'] == Dict['objectType'] and x[1]['effType'] == Dict['effType'], \
					mcTrueData )
			#--- Looping over the MC RooDataSet which is the same efficiency type and category as the fitted RooDataSets
			for mcName, mcDict in partner:
				#---- Only want the reference to fit_eff and cnt_eff mcTrue
				if mcDict['methodUsed'] == 'fit_eff' or mcDict['methodUsed'] == 'cnt_eff' :
					try:
						self.__attrDict__[Name]['refMC'][ mcDict['methodUsed'] ] =  mcName 
					except KeyError:
						self.__attrDict__[Name]['refMC'] = { mcDict['methodUsed'] : mcName }
		_prov = set()
		#--- The dictionary itself contains only the RooDataSets
		#todelete = []
		for name, dataSet in self.__dict__['RooDataSet'].iteritems():
			#try:
			self[name] = self.__attrDict__[name]
				# To get also the no fit_eff --> Except sbs (not implemented yet) and cnt no MC
			#except KeyError:
			#	self[name] = self.__getType__(name,{})[name]
				#--- Skipping sbs, cnt no MC
			#**if self.__attrDict__[name]['methodUsed'] == 'sbs_eff': #or \
					#	( self.__attrDict__[name]['methodUsed'] == 'cnt_eff' and self.__attrDict__[name]['isMC'] == 0):
			#**	self.pop(name)
			#**	todelete.append( name )
			#**	continue

			self[name]['dataset'] = dataSet
			#--To store the categories we have
			_prov.add( self[name]['objectType'] )
		#--- We are not interested about the MC, only in cnt and fit_eff
		#**map( lambda (Name,Dumm): self.__attrDict__.pop(Name), mcTrueData )
		#--- We are not interested about the sbs and cnt not MC
		#**map( lambda y: self.__attrDict__.pop( y[0] ), filter( lambda x: x[1]['isMC'] == 0 and x[1]['methodUsed'] != 'fit_eff',\
		#		self.__attrDict__.iteritems() ) ) 
		#-- Storing the categories we have 
		self.categories = list(_prov)
		#--- Don-'t forget delete also in RooDataSet attribute
		#for name in todelete:
		#	self.RooDataSet.pop( name )
		
		#----- Variables, binned, efficiency, user introduced, ...
		#--- The list will contain those dataset which don't have anyone of the variables entered  
		#--- by the user (in case the user enter someone) and the datasets will be removed
		deleteDataset = set([])
		#--- Getting the variables names of the RooDataSet 
		for name, dataset in self.RooDataSet.iteritems(): 
			self[name]['variables'] = getVarDict(dataset)
			#--- Check that efficiency is in there
			if not self.effName in self[name]['variables'].keys():
				try:
					message = """The efficiency name introduce '%s' is not in the '%s' RooDataSet.\n""" % (keywords['effName'], name )
					message += """I have these variables located:""" 
                                except KeyError:
				        message = """The efficiency name per default 'efficiency' is not in the '%s' RooDataSet.\n""" 
					message +="""You should introduced the name when instance the class =>"""\
							""" a = pytnp( 'filename.root', effName='whatever' )\n"""\
							"""I have these variables located:"""
                                message += ' '
				for i in self[name]['variables']:
					message += i+', '
				message = message[:-2]
				message += '\n\033[1;33m  CAVEAT: The efficiency name \033[1;m\033[1;39mMUST\033[1;m\033[1;33m'\
						'have the same name for all the RooDataSets in the rootfile\033[1;m'	
				printError( self.__module__+'.pytnp', message, KeyError )
			#--- Check the variables introduced by the user are there and
			#------ Setting the binned Variables: extract efficiencies from last list
			message = ''
			_warningPrint = False
			_havetodelete = False
			lostVar = ''
			self[name]['binnedVar'] = {}
			if len(self.userVariables) != 0 :
				for var in self.userVariables:
					if not var in self[name]['variables']:
						lostVar += var+', '
						_warningPrint = True
						_havetodelete = True
					else:
						self[name]['binnedVar'][var] = self[name]['variables'][var] 
				if _havetodelete:
					deleteDataset.add( name ) 
				if _warningPrint:
					lostVar = lostVar[:-2]
					message += """Variable '%s' is not in the '%s' RooDataSet. Skipping it... """ % ( lostVar,name)
					printWarning( self.__module__+'.pytnp', message )
			else:
				#The user didn't introduce binned variables, I take everyone
				self[name]['binnedVar'] = dict([ (var, self[name]['variables'][var]) \
						for var in filter( lambda x: x.lower().find(self.effName) == -1, self[name]['variables'] ) ])
				#if _errorPrint:
				#	message += """  ----> I found: """
				#	for var in self[name]['variables']:
				#		message += var+', '
				#		message = message[:-2]
				#		printError( self.__module__, message, UserWarning )
			self[name]['eff'] = filter( lambda x: x.lower().find(self.effName) != -1, self[name]['variables'] )[0]

		for _dataout in deleteDataset:
			self.pop( _dataout )
			self.RooDataSet.pop( _dataout )
			self.__attrDict__.pop( _dataout )
		
		#-- Something wrong if we pop out all the datasets we had
		if len(self) == 0:
			message = """There is no RooDataSet that fulfill the binned variables introduced""" 
			printError( self.__module__, message, ValueError )


		#--- Extracting those RooDataSet which have null values of efficiency
		_todelete = []
		for name, _datasetObject in self.RooDataSet.iteritems():
			if not isEffNoNull( _datasetObject, self.effName ):
				_todelete.append( name )
				del _datasetObject
				message = "The RooDataSet '%s' have all '%s' values null. Skipping the storage..." % (name, self.effName)
				printWarning( self.__module__+'.pytnp', message )
		map( lambda name: self.pop( name ), _todelete )
		map( lambda name: self.__attrDict__.pop( name ), _todelete )
		for __attr in self.classNames:
			map( lambda name: self.__getattribute__( __attr ).pop( name ) , _todelete )
示例#20
0
def newtableLatex( dataset, effName, varX, varY, **keyword ):
	""".. function tableLatex( dataset, effName, 'var_column', 'var_row', [outfile='name.tex', varXname='latex name', varYname='latex name'] ) -> dict

	Giving a RooDataSet and two variables, the function returns a table in latex
	format. If enters the keyword 'outfile' also the table will put
	it into the file.
	(The keyword var is a list with the name of the variables the user want to
	dump. TODO, not yet implemented)
	
	:param dataset: dataset
	:type dataset: ROOT.RooDataSet
	:param effName: efficiency name
	:type effName: string
	:param varX: the name of the variable you want to be as column
	:rtype varX: string
	:param varY: the name of the variable you want to be as row

	.. seealso:: :func:`tableLatex`
	"""
	#TODO:	The keyword var is a list with the name of the variables the user want to dump.
	#TODO: CHECK IF WORKS CORRECTLY
	message = "Use this function with caution! Still in development.\n Use instead the tableLatex function"
	printWarning( newtableLatex, message )

	#---- Checking the variables in dataset
	varDict = getVarDict( dataset )
	#---  All the binned variables in the dataset
	datasetVarList = filter( lambda x: x.lower().find(effName) == -1, varDict.iterkeys() )
	effList = filter( lambda x: x.lower().find(effName) != -1, varDict.iterkeys() )
	#---- Sanity check
	if len(effList) != 1:
		message ="""The RooDataSet '%s' does not contain a variable called '%s' as efficiency"""\
				% ( dataset.GetName(), effName )
		printError( tableLatex.__module__+'.'+tableLatex.__name__, message, AttributeError )
	#---- Variables are there?
	for var in [ varX, varY ]:
		if var not in datasetVarList:
			message ="""The RooDataSet '%s' does not contain a binned variable called '%s'"""\
					% ( dataset.GetName(), var )
			printError( tableLatex.__module__+'.'+tableLatex.__name__, message, AttributeError )
	# The table
	_tableDict = tableEff( dataset, effName )

	bins = {}
	varName = {}
	varUnit  = {}
	for var in [varX, varY]:
		#-- dictionary-List with the min and max values per bin (min,max),...
		bins[var] = [ ( varDict[var]['arrayBins'][i], varDict[var]['arrayBins'][i+1] ) \
				for i in xrange( len(varDict[var]['arrayBins'])-1) ]
		# Latex name of variables, maybe introduced by user otherwise take from construction
		try:
			# Remember to parse linux to latex \theta --> \\theta
			varName[var] = '$'+keywords[var].replace('\\','\\\\')+'$'
		except NameError:
			varName[var] = '$'+varDict[var]['latexName'].replace('\\','\\\\').replace('#','\\')+'$'
		varUnit[var] = varDict[var]['unit']
		if len(varUnit[var]) != 0:
			varUnit[var] = '$({\\rm '+varUnit[var]+'})$'

	#Some usefuls function to deal with latex
	edges = lambda x,y: '(%0.1f, %0.1f)' % (x,y) 
	effsetter = lambda eff,lo,hi: '$%.3f\\pm^{%.3f}_{%.3f}$ & ' % (eff,hi-eff,eff-lo) 
	central = lambda low,high: (high+low)/2.0

	#-- Table latex construction
	toLatex = '\\begin{tabular}{c'
	#-- Number of table columns
	toLatex += 'c'*varDict[varY]['binN']+'}\\hline\n'
	#-- Header (first line)
	toLatex += varName[varX]+varUnit[varX]+' {\\boldmath$\\backslash$}'+\
			varName[varY]+varUnit[varX]+' & '
	#-- varY bins are put on the first line
	for low, high in bins[varY]:
		toLatex += edges(low,high)+' & '
	toLatex = toLatex[:-2]+'\\\\ \\hline\n'
	#--- Finally, fill the table, line by line
	for lowX,highX in bins[varX]:
		toLatex += edges(lowX,highX)+' & '
		for lowY,highY in bins[varY]:
			try:
				eff,effErrorLow,effErrorHig = eval('getEff(dataset,effName,'+\
						varX+'=central(lowX,highX), '+varY+'=central(lowY,highY))')
				toLatex += effsetter(eff,effErrorLow,effErrorHig)
			#Empty bin
			except TypeError:
				toLatex += ' & '
		toLatex = toLatex[:-2]+'\\\\\n'
	toLatex += ' \\hline\n'
    	toLatex += '\\end{tabular}'
	
	print toLatex
	return toLatex
示例#21
0
def tableLatex(dataset, inputEffName = 'efficiency'):
	"""
	tableLatex( dataset, inputEffName ) -> list

	Giving a RooDataSet, the function returns a table in latex format 
	
	:param dataset: dataset
	:type dataset: ROOT.RooDataSet
	:param inputEffName: efficiency name
	:type inputEffName: string
	:return: string in latex format
	:rtype: string
	"""
	#---- Checking the variables in dataset
	_swapDict = getVarDict( dataset )
	#---  All the binned variables in the dataset
	datasetVarList = filter( lambda x: x.lower().find(inputEffName) == -1, _swapDict.iterkeys() )
	_swapeffList = filter( lambda x: x.lower().find(inputEffName) != -1, _swapDict.iterkeys() )
	#---- Sanity check
	if len(_swapeffList) != 1:
		message ="""ERROR: Unexpected Error!! It seems that in '%s' there is no"""\
				""" efficiency variable...""" % dataSet.GetName()
		printError( tableLatex.__module__+'.'+tableLatex.__name__, message, AttributeError )

	effName = _swapeffList[0]

	#Getting table
	effList = listTableEff(dataset)
	## Getting bins of variables
	#---- Dictionary with the bins for each binned variable
	binsTMP = map( lambda nameVar: { nameVar: set([ (i[nameVar][1],i[nameVar][2]) for i in effList ]) }, datasetVarList )
	bins =  {} #List from the map, only each item is a dict. Joining
	for Dict in binsTMP:
		for key,valDict in Dict.iteritems():
			bins[key] = valDict
	for key,SET in bins.iteritems():
		bins[key] = sorted(list(SET))
	#Assuming we have 2 binned variables:
	if len(bins) != 2:
		message = """\033[1;31mtableLatex Error: only two variables, by the moment\033[1;31m"""
		print message
	#FIXME
	etaBins = None
	for i,j in sorted(bins.iteritems()):
		etaBins = j
		etaName = i
		break
	ptBins = None
	KK = 0
	for i,j in sorted(bins.iteritems()):
		if KK == 1:
			ptBins = j
			ptName = i
			break
		KK += 1
	
	etaNbins = len(etaBins)
	ptNbins = len(ptBins)
	#Some usefuls function
	edges = lambda x,y: '(%0.1f, %0.1f)' % (x,y) 
	effsetter = lambda eff,lo,hi: '$%.3f\\pm^{%.3f}_{%.3f}$ & ' % (eff,hi-eff,eff-lo) 
	central = lambda low,high: (high+low)/2.0

	
	toLatex = '\\begin{tabular}{c'
	#Number of columns
	toLatex += 'c'*etaNbins+'}\\hline\n'
	#header
	toLatex += '$p_T^\\mu({\\rm GeV})$ {\\boldmath$\\backslash$}$\\eta^\\mu$  & '
	for low,high in etaBins:
		toLatex += edges(low,high)+' & '
	toLatex = toLatex[:-2]+'\\\\ \\hline\n'
	#Filling the table
	for lowPt,highPt in ptBins:
		toLatex += edges(lowPt,highPt)+' & '
		for lowEta,highEta in etaBins:
			try:
				eff,effErrorLow,effErrorHig = eval('getEff(dataset,inputEffName,'+\
						ptName+'=central(lowPt,highPt), '+etaName+'=central(lowEta,highEta))')
				toLatex += effsetter(eff,effErrorLow,effErrorHig)
			#Empty bin
			except TypeError:
				toLatex += ' & '
		toLatex = toLatex[:-2]+'\\\\\n'
	toLatex += ' \\hline\n'
    	toLatex += '\\end{tabular}'
#
	print toLatex
	return toLatex
示例#22
0
def getResName( aFile, **keywords ):
	""".. function:: getResName( fileName[, config=configfile] ) -> pytnpname,latexstring

	Extract from file name, T&P-like, the resonance
	and returns it plain and in Latex format.

	:param fileName: the root file name
	:type fileName: string
	:keyword config: configuration file to impose the results of this function. 
	                 Makes use of the ``DataNames`` dictionary placed
	:type config: string

	:return: unique identifier (pytnpname) and latex description of this root file
	:rtype: tuple of strings
	
	.. warning::
	   This function is highly dependent of the name of the file (if you don't use a config file).
	   Standard Format:  NameOFResonance_X_blabla.root
	
	:raise KeyError: keyword erroneous
	:raise TypeError: no config file provided and no root file name in standard format
	:raise RuntimeError: somethin wrong happens. Warn to developers

	.. note::
	   Probably will change to ``tnputils`` module
	"""
	import re

	regexp = re.compile( '\D*(?P<NUMBER>\dS)' ) 
	resonance = ''
	resonanceLatex = ''
	# Hardcoded dict: include here new resonances 
	nameDict = { 'JPsi' : ('J/#Psi','JPsi'),
			'Upsilon': ('All #Upsilon','AllUpsilons'),
			'Z' : ('Z#rightarrow#mu#mu','Z')
			}
	# Complements
	adjectDict = { 'DATA' : (' Data', '_DATA'),
			'ReWeight' : (' ReWeight ', '_ReWeight'),
			'GoodCowboys' : (' GCS', '_GoodCowboysAndSeagulls'),
			'_MC_' : (' MC', ''),
			'_Spring10_' : (' MC', ''),
			}
	#-- Add and/or updating the keys, entered by the user
	isDone = False
	for key, _file in keywords.iteritems():
		if key != 'config':
			message = "Invalid argument key '%s', only accepted 'config" % key
			printError( getResName.__module__+'.'+getResName.__name__, message, KeyError )
		#-- Controlling the None case
		if _file:
			for name, value in parserConfig( keywords['config'], 'DataNames' ).iteritems():
				nameDict[name] = value
				isDone = True
			# User rules, so...
			# Posible try!! FIXME!!
			resonanceLatex = nameDict[aFile][0]
			resonance = nameDict[aFile][1]
			return resonance,resonanceLatex

	try:
		num = regexp.search( aFile ).group( 'NUMBER' )
		resonanceLatex = '#Upsilon('+num+')'
		resonance = 'Upsilon'+num

	except AttributeError:
		#Reverse sorted to assure DATA is the last one
		for name, (resLatex,res) in sorted(nameDict.iteritems(),reverse=True):
			if aFile.find( name ) != -1:
				resonanceLatex = resLatex
				resonance = res
		if resonance == '':
			message ="""This function is highly dependent of the \n"""\
					"""name of the file, you need an standard format like:\n"""\
					"""    NameOFResonance_X_blabla.root"""\
					"""Unrecognized name: \033[1;m\033[1;39m  '%s'\033[1;m""" % aFile
			printError( getResName.__module__+'.'+getResName.__name__, message, TypeError )
		
	except:
		message ="""UNEXPECTED ERROR!! Send a e-mail to the developer(s) with all information\n"""\
				"""needed to reproduce this error"""
		printError( getresname.__module__+'.'+getresname.__name__, message, RuntimeError )
	
	#All work is done
	if isDone:
		return resonance, resonanceLatex
	
	#Including others..
	# FIXME: To be DEPRECATED
	for name, (resLatex,res) in sorted(adjectDict.iteritems(),reverse=True):
		if aFile.find( name ) != -1:
			resonanceLatex += resLatex
			resonance += res

	return resonance,resonanceLatex
示例#23
0
def getEffFromDict( dataset, input_effName='efficiency', **keywords):
	""".. function:: getEffFromDict(RooDataSet, effName, var1=value[,var2=value2, ...]) -> eff, effErrorLow, effErrorHigh, dict

	Giving a binned variables returns the efficiency which 
	corresponds to those values. If the introduced variables 
	are the exhausted set of the RooDataSet, the output
	will be a tuple of efficiency plus a None object (CASE 1).
	Otherwise if the input variables don't cover all the 
	RooDataSet binned variables, the output will be the 
	efficiency tuple plus a dictionary which the names 
	of the remaining variables and efficiency as keys and 
	the tuples of their values as dictionary values (CASE 2).
	
	:param dataset: dataset
	:type dataset: ROOT.RooDataSet
	:param effName: efficiency name. Default value 'efficiency'
	:type effName: string
	:keyword var1: name of the value with its value
	:rtype var1: float
	:return: tuple with efficiency values and a dictionary (None)
	:rtype: float,float,float,dict

	:raise AttributeError: if the dataset do not contain ``var``
	:raise UserWarning: if do not introduce at least one variable as keyword
	"""
	#---  All the binned variables in the dataset
	datasetVarList, effName = getVarNames( dataset, input_effName )
	#--- Checking if vars are in, and storing them in a list
	nameVarValueList = []
	nameVarList = []
	for var,value in keywords.iteritems():
		if not isbinnedVar( dataset, var, effName ):
			message ="""The RooDataSet '%s' does not contain '%s' as binned variable""" % (dataset.GetName(), var)
			printError( getEff.__module__+'.'+getEff.__name__, message, AttributeError )
		nameVarValueList.append( (var,value) )
		nameVarList.append( var )
	#---- Sanity check
	if len(nameVarList) < 1:
		message ="""You must introduce at least one variable"""
		printError( getEffFromDict.__module__+'.'+getEffFromDict.__name__, message, UserWarning )
	
	#--- Binned variables which are not entered as arguments of this function
	noAskVar = filter( lambda x: x not in nameVarList, datasetVarList )
	#--- Has introduce the user all the binned variables?
	#--- If so, when find the efficiency value just return it
	#--- otherwise it must store all the efficiency values 
	#--- which corresponds to the same variable value (the other
	#--- binned variables will vary).
	isbinnedComplete = False
	dictReturn = None
	noAskStr = ''
	if len(noAskVar) == 0:
		isbinnedComplete = True
	else:
		dictReturn = { effName: [] }
		#-- Want to keep the values of the binned values don't ask by the user
		#-- in order to save them to the dictionary
		tupleNoAskStr = ''
		for var in noAskVar:
			dictReturn[var] = []
			noAskStr += ',_table[\''+var+'\']'
			
	_table = tableEff( dataset, effName )
	
	#-- Checking the position where there are matches
	indexDict = {}
	for var,value in nameVarValueList:
		_ind = 0 
		indexDict[var] = []
		for central,low,high in  _table[var]:
			if low <= value and high > value:
				indexDict[var].append( _ind )
			_ind += 1
	#-- Merging all the matches indexes
	indexList = indexDict.values()
	indexSet = set( indexList[0] )
	for i in xrange(len(indexList)-1):
		indexSet = indexSet.intersection( indexList[i+1] ) 

	_tableList = eval('zip(_table[effName]'+noAskStr+')')
	for i in filter( lambda _ind: _ind in indexSet, xrange(len(_tableList)) ):
		try:
			eff,theOthers = _tableList[i]
			#-- Note the behaviour of tuple: (a,b,c) != ((a,b,c),)
			if len(theOthers) == 3:
				theOthers = (theOthers,)
			dictReturn[effName].append( eff )
			_index = 0
			for name in noAskVar:
				#-- The order of variables are in noAskVar
				dictReturn[name].append( theOthers[_index] )
				_index += 1
		except ValueError:
			#-- Note: due to the zip, the output will be ((eff,effL,effH),)
			eff,effL,effH = _tableList[i][0]
			return eff, effL, effH, None
	
	if (len(dictReturn[effName])) > 0:
		return dictReturn
示例#24
0
def getResName(aFile, **keywords):
    """.. function:: getResName( fileName[, config=configfile] ) -> pytnpname,latexstring

	Extract from file name, T&P-like, the resonance
	and returns it plain and in Latex format.

	:param fileName: the root file name
	:type fileName: string
	:keyword config: configuration file to impose the results of this function. 
	                 Makes use of the ``DataNames`` dictionary placed
	:type config: string

	:return: unique identifier (pytnpname) and latex description of this root file
	:rtype: tuple of strings
	
	.. warning::
	   This function is highly dependent of the name of the file (if you don't use a config file).
	   Standard Format:  NameOFResonance_X_blabla.root
	
	:raise KeyError: keyword erroneous
	:raise TypeError: no config file provided and no root file name in standard format
	:raise RuntimeError: somethin wrong happens. Warn to developers

	.. note::
	   Probably will change to ``tnputils`` module
	"""
    import re

    regexp = re.compile('\D*(?P<NUMBER>\dS)')
    resonance = ''
    resonanceLatex = ''
    # Hardcoded dict: include here new resonances
    nameDict = {
        'JPsi': ('J/#Psi', 'JPsi'),
        'Upsilon': ('All #Upsilon', 'AllUpsilons'),
        'Z': ('Z#rightarrow#mu#mu', 'Z')
    }
    # Complements
    adjectDict = {
        'DATA': (' Data', '_DATA'),
        'ReWeight': (' ReWeight ', '_ReWeight'),
        'GoodCowboys': (' GCS', '_GoodCowboysAndSeagulls'),
        '_MC_': (' MC', ''),
        '_Spring10_': (' MC', ''),
    }
    #-- Add and/or updating the keys, entered by the user
    isDone = False
    for key, _file in keywords.iteritems():
        if key != 'config':
            message = "Invalid argument key '%s', only accepted 'config" % key
            printError(getResName.__module__ + '.' + getResName.__name__,
                       message, KeyError)
        #-- Controlling the None case
        if _file:
            for name, value in parserConfig(keywords['config'],
                                            'DataNames').iteritems():
                nameDict[name] = value
                isDone = True
            # User rules, so...
            # Posible try!! FIXME!!
            resonanceLatex = nameDict[aFile][0]
            resonance = nameDict[aFile][1]
            return resonance, resonanceLatex

    try:
        num = regexp.search(aFile).group('NUMBER')
        resonanceLatex = '#Upsilon(' + num + ')'
        resonance = 'Upsilon' + num

    except AttributeError:
        #Reverse sorted to assure DATA is the last one
        for name, (resLatex, res) in sorted(nameDict.iteritems(),
                                            reverse=True):
            if aFile.find(name) != -1:
                resonanceLatex = resLatex
                resonance = res
        if resonance == '':
            message ="""This function is highly dependent of the \n"""\
              """name of the file, you need an standard format like:\n"""\
              """    NameOFResonance_X_blabla.root"""\
              """Unrecognized name: \033[1;m\033[1;39m  '%s'\033[1;m""" % aFile
            printError(getResName.__module__ + '.' + getResName.__name__,
                       message, TypeError)

    except:
        message ="""UNEXPECTED ERROR!! Send a e-mail to the developer(s) with all information\n"""\
          """needed to reproduce this error"""
        printError(getresname.__module__ + '.' + getresname.__name__, message,
                   RuntimeError)

    #All work is done
    if isDone:
        return resonance, resonanceLatex

    #Including others..
    # FIXME: To be DEPRECATED
    for name, (resLatex, res) in sorted(adjectDict.iteritems(), reverse=True):
        if aFile.find(name) != -1:
            resonanceLatex += resLatex
            resonance += res

    return resonance, resonanceLatex
示例#25
0
def getEffFromDict(dataset, input_effName='efficiency', **keywords):
    """.. function:: getEffFromDict(RooDataSet, effName, var1=value[,var2=value2, ...]) -> eff, effErrorLow, effErrorHigh, dict

	Giving a binned variables returns the efficiency which 
	corresponds to those values. If the introduced variables 
	are the exhausted set of the RooDataSet, the output
	will be a tuple of efficiency plus a None object (CASE 1).
	Otherwise if the input variables don't cover all the 
	RooDataSet binned variables, the output will be the 
	efficiency tuple plus a dictionary which the names 
	of the remaining variables and efficiency as keys and 
	the tuples of their values as dictionary values (CASE 2).
	
	:param dataset: dataset
	:type dataset: ROOT.RooDataSet
	:param effName: efficiency name. Default value 'efficiency'
	:type effName: string
	:keyword var1: name of the value with its value
	:rtype var1: float
	:return: tuple with efficiency values and a dictionary (None)
	:rtype: float,float,float,dict

	:raise AttributeError: if the dataset do not contain ``var``
	:raise UserWarning: if do not introduce at least one variable as keyword
	"""
    #---  All the binned variables in the dataset
    datasetVarList, effName = getVarNames(dataset, input_effName)
    #--- Checking if vars are in, and storing them in a list
    nameVarValueList = []
    nameVarList = []
    for var, value in keywords.iteritems():
        if not isbinnedVar(dataset, var, effName):
            message = """The RooDataSet '%s' does not contain '%s' as binned variable""" % (
                dataset.GetName(), var)
            printError(getEff.__module__ + '.' + getEff.__name__, message,
                       AttributeError)
        nameVarValueList.append((var, value))
        nameVarList.append(var)
    #---- Sanity check
    if len(nameVarList) < 1:
        message = """You must introduce at least one variable"""
        printError(getEffFromDict.__module__ + '.' + getEffFromDict.__name__,
                   message, UserWarning)

    #--- Binned variables which are not entered as arguments of this function
    noAskVar = filter(lambda x: x not in nameVarList, datasetVarList)
    #--- Has introduce the user all the binned variables?
    #--- If so, when find the efficiency value just return it
    #--- otherwise it must store all the efficiency values
    #--- which corresponds to the same variable value (the other
    #--- binned variables will vary).
    isbinnedComplete = False
    dictReturn = None
    noAskStr = ''
    if len(noAskVar) == 0:
        isbinnedComplete = True
    else:
        dictReturn = {effName: []}
        #-- Want to keep the values of the binned values don't ask by the user
        #-- in order to save them to the dictionary
        tupleNoAskStr = ''
        for var in noAskVar:
            dictReturn[var] = []
            noAskStr += ',_table[\'' + var + '\']'

    _table = tableEff(dataset, effName)

    #-- Checking the position where there are matches
    indexDict = {}
    for var, value in nameVarValueList:
        _ind = 0
        indexDict[var] = []
        for central, low, high in _table[var]:
            if low <= value and high > value:
                indexDict[var].append(_ind)
            _ind += 1
    #-- Merging all the matches indexes
    indexList = indexDict.values()
    indexSet = set(indexList[0])
    for i in xrange(len(indexList) - 1):
        indexSet = indexSet.intersection(indexList[i + 1])

    _tableList = eval('zip(_table[effName]' + noAskStr + ')')
    for i in filter(lambda _ind: _ind in indexSet, xrange(len(_tableList))):
        try:
            eff, theOthers = _tableList[i]
            #-- Note the behaviour of tuple: (a,b,c) != ((a,b,c),)
            if len(theOthers) == 3:
                theOthers = (theOthers, )
            dictReturn[effName].append(eff)
            _index = 0
            for name in noAskVar:
                #-- The order of variables are in noAskVar
                dictReturn[name].append(theOthers[_index])
                _index += 1
        except ValueError:
            #-- Note: due to the zip, the output will be ((eff,effL,effH),)
            eff, effL, effH = _tableList[i][0]
            return eff, effL, effH, None

    if (len(dictReturn[effName])) > 0:
        return dictReturn
示例#26
0
def tableLatex(dataset, inputEffName='efficiency'):
    """
	tableLatex( dataset, inputEffName ) -> list

	Giving a RooDataSet, the function returns a table in latex format 
	
	:param dataset: dataset
	:type dataset: ROOT.RooDataSet
	:param inputEffName: efficiency name
	:type inputEffName: string
	:return: string in latex format
	:rtype: string
	"""
    #---- Checking the variables in dataset
    _swapDict = getVarDict(dataset)
    #---  All the binned variables in the dataset
    datasetVarList = filter(lambda x: x.lower().find(inputEffName) == -1,
                            _swapDict.iterkeys())
    _swapeffList = filter(lambda x: x.lower().find(inputEffName) != -1,
                          _swapDict.iterkeys())
    #---- Sanity check
    if len(_swapeffList) != 1:
        message ="""ERROR: Unexpected Error!! It seems that in '%s' there is no"""\
          """ efficiency variable...""" % dataSet.GetName()
        printError(tableLatex.__module__ + '.' + tableLatex.__name__, message,
                   AttributeError)

    effName = _swapeffList[0]

    #Getting table
    effList = listTableEff(dataset)
    ## Getting bins of variables
    #---- Dictionary with the bins for each binned variable
    binsTMP = map(
        lambda nameVar:
        {nameVar: set([(i[nameVar][1], i[nameVar][2]) for i in effList])},
        datasetVarList)
    bins = {}  #List from the map, only each item is a dict. Joining
    for Dict in binsTMP:
        for key, valDict in Dict.iteritems():
            bins[key] = valDict
    for key, SET in bins.iteritems():
        bins[key] = sorted(list(SET))
    #Assuming we have 2 binned variables:
    if len(bins) != 2:
        message = """\033[1;31mtableLatex Error: only two variables, by the moment\033[1;31m"""
        print message
    #FIXME
    etaBins = None
    for i, j in sorted(bins.iteritems()):
        etaBins = j
        etaName = i
        break
    ptBins = None
    KK = 0
    for i, j in sorted(bins.iteritems()):
        if KK == 1:
            ptBins = j
            ptName = i
            break
        KK += 1

    etaNbins = len(etaBins)
    ptNbins = len(ptBins)
    #Some usefuls function
    edges = lambda x, y: '(%0.1f, %0.1f)' % (x, y)
    effsetter = lambda eff, lo, hi: '$%.3f\\pm^{%.3f}_{%.3f}$ & ' % (
        eff, hi - eff, eff - lo)
    central = lambda low, high: (high + low) / 2.0

    toLatex = '\\begin{tabular}{c'
    #Number of columns
    toLatex += 'c' * etaNbins + '}\\hline\n'
    #header
    toLatex += '$p_T^\\mu({\\rm GeV})$ {\\boldmath$\\backslash$}$\\eta^\\mu$  & '
    for low, high in etaBins:
        toLatex += edges(low, high) + ' & '
    toLatex = toLatex[:-2] + '\\\\ \\hline\n'
    #Filling the table
    for lowPt, highPt in ptBins:
        toLatex += edges(lowPt, highPt) + ' & '
        for lowEta, highEta in etaBins:
            try:
                eff,effErrorLow,effErrorHig = eval('getEff(dataset,inputEffName,'+\
                  ptName+'=central(lowPt,highPt), '+etaName+'=central(lowEta,highEta))')
                toLatex += effsetter(eff, effErrorLow, effErrorHig)
            #Empty bin
            except TypeError:
                toLatex += ' & '
        toLatex = toLatex[:-2] + '\\\\\n'
    toLatex += ' \\hline\n'
    toLatex += '\\end{tabular}'
    #
    print toLatex
    return toLatex
示例#27
0
	def plotEff1D( self, name, inputVarName, Lumi ):
		""".. method:: plotEff1D( dataname, variable, Lumi ) 
	
		Given a name directory-like for a ROOT.RooDataSet object,
	 	the function creates a 1-dim plot of 'variable_name' extracted 
		from the object and it will save it in a eps file. Also
		it will store the graph object creating a new key in the
		dataset dictionary::

		   self[nameRooDataSet]['tgraphs'] = { 'class_graph_name': TGraphAsymmErrors, ... }

		:param name: name of the dataset
		:type name: string
		:param variable: binned variable to use
		:type variable: string
		:param Lumi: luminosity
		:type Lumi: string

		:raise KeyError: the dataset is not in the root file (to be changed to NameError)
		:raise KeyError: the binned variable is not in the dataset

		"""
		#import rootlogon
		from tnputils import listTableEff,getEff, graphclassname
		from pytnp.steerplots.plotfunctions import plotAsymGraphXY

		dataset = None
		#-- Getting the class graph name
		_graphclassname = graphclassname( self, name )
		#-- Checking if the object exists
		try:
			dataset = self.RooDataSet[name]
		except KeyError:
		  	message = """you must introduce a valid name, '%s' is not a RooDataSet in the root file""" % name
			printError( self.__module__, message, KeyError )
		#--- Empty dataset
		if self.RooDataSet[name].numEntries() == 0:
			message = """Empty RooDataSet '%s'. Skipping...""" % name
			printWarning( self.__module__+'.plotEff1D',message)
			return None
		#--- Checking variable
		if not inputVarName in self[name]['binnedVar'].keys():
		  	message = """you must introduce a valid binned variable name, '%s' is not in the '%s' RooDataSet\n""" % (inputVarName,name )
			message += """The list of binned variables are '%s'""" % str(self[name]['binnedVar'].keys())  
			printError( self.__module__, message, KeyError )
		
		self[name]['tgraphs'] = { _graphclassname: {} }		
		# Special case: we have only one variable
		if len(self[name]['binnedVar']) == 1:
			graphName = self.resonance+'_'+self[name]['effType']+'_'+self[name]['objectType']+'_'+\
					self[name]['methodUsed']+'__'+inputVarName
                        if self[name]['isMC'] == 1:
				graphName += '__mcTrue'
			#--- Extracting the efficiency values per bin
			plotList = listTableEff( dataset )
			_min = 0
			_max = 0
			#--- Setting the points and extracting the min and max value
			#--- in order to build the frame to plot
			XPoints = []
			YPoints = []
			for varDict in plotList:  
				(eff,effLo,effHi) = varDict[self.effName]
				(var,varLo,varHi) = varDict[inputVarName]
				XPoints.append( (var, varLo, varHi) )
				YPoints.append( (eff, effLo, effHi) )

				_min = min( _min, varLo )
				_max = max( _max, varHi )
			#--- Cosmethics to storing the plot
			#title = self[name]['objectType']+' category'
			xtitle = self[name]['variables'][inputVarName]['latexName']+' '+self[name]['variables'][inputVarName]['unit']
			ytitle = 'efficiency'
			title = '  CMS Preliminary,'+Lumi+' #sqrt{s}=7 TeV  '

			self[name]['tgraphs'][_graphclassname][graphName] =  plotAsymGraphXY( XPoints, YPoints, xtitle, ytitle,\
						returnGraph=True, rangeFrame = (_min,0,_max,1.05), title=title, graphname=graphName ) 

			return 

		
		#-- More than one binned variable
		for varName in filter( lambda x: x != inputVarName, self[name]['binnedVar'].keys()):
                        _otherVarList_ = filter( lambda x: x != varName, self[name]['binnedVar'].keys() )
                        _otherVar_ = ''
                        for i in _otherVarList_:
                                _otherVar_ += i+', '
                        _otherVar_ = _otherVar_[:-2]
                        if len(_otherVar_ ) != 0:
                                _otherVar_ = ' in all the range of \'' +_otherVar_+'\''
			print '\033[1;34m'+name+': \''+varName+'\' bins'+_otherVar_+'\033[1;m'

                        #--- Extracting bins and array of bins
                        binsN = self[name]['variables'][varName]['binN']
                        arrayBins = self[name]['variables'][varName]['arrayBins']
                        for bin in xrange(binsN):
                                arrayBins = self[name]['variables'][varName]['arrayBins']
                                Lo = arrayBins[bin]
                                Hi = arrayBins[bin+1]
                                Central = (Hi+Lo)/2.0
				graphName = self.resonance+'_'+self[name]['effType']+'_'+self[name]['objectType']+'_'+\
						self[name]['methodUsed']+'__'+varName+'_bin'+str(bin)+'_'
                                #graphName = self.resonance+'_'+self[name]['methodUsed']+'_'+self[name]['effType']+'_'+\
                                #                self[name]['objectType']+'__'+varName+'_bin'+str(bin)+'_'
                                #Getting list of efficiency values plus variables
                                _plotList = eval('getEff(dataset,self.effName,'+varName+'='+str(Central)+')')
                                #print _plotList
                                #Extracting info to plot
				#try:
                                (eff,effErrorLo,effErrorHi),otherVarDict = _plotList[0]

                                if len(filter( lambda (eff,__dic): eff[0] == 0.0, _plotList )) == len(_plotList):
					printWarning( self.__module__+'.plotEff1D',"Skipping... Efficiencies in the dataset not calculated")
                                        continue
                                _max = {}
                                _min = {}
				varPoints = {}
				effPoints = {}
                                for otherVarName, val in otherVarDict.iteritems():
					varPoints[otherVarName] = []
					effPoints[otherVarName] = []					
                                        _max[otherVarName] = 0.0
                                        _min[otherVarName] = 0.0
                                for (eff,effLo,effHi),otherVarDict in _plotList:
                                        for otherVarName, (central, low, high) in otherVarDict.iteritems():
                                                _min[otherVarName] = min( _min[otherVarName], low )
                                                _max[otherVarName] = max( _max[otherVarName], high )
						varPoints[otherVarName].append( (central,low,high) ) 
						effPoints[otherVarName].append( (eff, effLo, effHi) )

                                title = self.resLatex+', ('+str(Lo)+','+str(Hi)+') '+self[name]['variables'][varName]['latexName']+' range, '
                                title += self[name]['objectType']+' category'
                                for otherVarName, (central, low, high) in otherVarDict.iteritems():
					graphname = graphName+otherVarName
					if self[name]['isMC'] == 1:
						graphname += '__mcTrue'
					xtitle = self[name]['variables'][otherVarName]['latexName']+\
							' '+self[name]['variables'][otherVarName]['unit']
					ytitle = 'efficiency'
					title = 'CMS Preliminary,'+Lumi+' #sqrt{s}=7 TeV'
					ranges = (_min[otherVarName],0,_max[otherVarName],1.05)
					self[name]['tgraphs'][_graphclassname][graphname] = plotAsymGraphXY( varPoints[otherVarName], effPoints[otherVarName],\
							xtitle, ytitle, returnGraph=True, rangeFrame=ranges, title=title, graphname=graphname)
示例#28
0
def getEff(dataSet, input_effName='efficiency', **keywords):
    """.. function:: getEff(dataset, effName='efficiency', var1=value[,var2=value2, ...]) -> eff, effErrorLow, effErrorHigh (,dict)

	Giving a binned variables returns the efficiency which 
	corresponds to those values. There is 2 output signatures 
	depending of the argument variables introduced; if the 
	variables are the exhausted set of the RooDataSet, the output
	will be a tuple of efficiency (CASE 1). Otherwise if the
	input variables don't cover all the RooDataSet binned 
	variables, the output will be the efficiency tuple plus
	a dictionary which the names of the resting variables as keys
	and the tuples of their bin values as values (CASE 2).
	
	:param dataset: dataset
	:type dataset: ROOT.RooDataSet
	:param input_effName: efficiency name
	:type input_effName: string
	:keyword var: var=value
	:rtype var: object
	:return: tuple with efficiency values (and a dictionary)
	:rtype: float,float,float(,dict)
	
	:raise UserWarning: if do not introduce at least one variable as keyword
	"""
    #---- Checking the variables in dataset
    _swapDict = getVarDict(dataSet)
    #---  All the binned variables in the dataset
    datasetVarList, effName = getVarNames(dataSet, input_effName)

    varList = []
    nameVarList = []
    for var, value in keywords.iteritems():
        if not isbinnedVar(dataSet, var, effName, warning=True):
            raise KeyError
        varList.append((var, value))
        nameVarList.append(var)
    #---- Sanity check
    if len(nameVarList) < 1:
        message = """You must introduce at least one variable"""
        printError(getEff.__module__ + '.' + getEff.__name__, message,
                   UserWarning)
    #--- Variables the user don't ask. This is the case when the user
    #--- wants a list of efficiency given a fixed value of one variable
    noAskVar = filter(lambda x: x not in nameVarList, datasetVarList)
    listReturn = False
    effVarList = None
    if len(noAskVar) != 0:
        listReturn = True
        effVarList = []
    #---- Sanity check
    if len(varList) > len(
            datasetVarList):  #FIXME---> can be more than 2 variables...
        message = """You are using more variables than in dataset '%s'""" % dataSet.GetName(
        )
        printError(getEff.__module__ + '.' + getEff.__name__, message,
                   AttributeError)

    #-- Get the table of efficiencies
    tableList = listTableEff(dataSet)

    for valDict in tableList:
        #--  From the list of the variables we want the efficiencies (varList), put the value inside
        #--- of the ranges (valDict[var][1:][i]) in the list
        fList = filter(
            lambda (var, value): valDict[var][1:][0] <= value and valDict[var][
                1:][1] > value, varList)
        #--  If our variables are all the variables available, we have 1-to-1 correspondence
        #--- with a efficiency value-> return this value
        if not listReturn and len(fList) == len(varList):
            return valDict[effName]
        #--  If our variables are less than the variables available, we're going to return
        #--- a list with the (restOfvariables,efficiencies) in order to recover the 1-to-1 correspondence
        elif listReturn and len(fList) != 0:
            restVarDict = dict([(_name, valDict[_name]) for _name in noAskVar])
            effVarList.append((valDict[effName], restVarDict))

    if listReturn and len(effVarList) > 0:
        #--output: (tuple,dict) where tuple is efficiency values and dict have the
        #--- names of the variables as keys and tuple as values
        return effVarList

    message = '\033[1;34mpytnp.getEff Info: There is no bin where live '
    for var, val in varList:
        message += var + '=' + str(val) + ', '
    message = message[:-2] + '\033[1;m'
    print message

    # FIXME: Strange behaviour with version 3_6_1_patch4 (really with the RooFit (3.12 ??) included in this version:
    #        The values of the listTableEff do not fill correctly. All the dictionary is filled of the same value (the last found value)
    #        Still have this problem with RooFit 3.13, root-v5.27, python 2.6 ...
    return None
示例#29
0
	def plotEffMap( self, name, x, y, Lumi, **keywords ):
		""".. method:: plotEff2D( name, varX, varY, Lumi ) 

		Giving a RooDataSet name in directory-like format,
		the function will do a bi-dimensional plot of 
		efficiency with ``varX`` and ``varY`` variables. Also, it
		will stores the graph within the dataset dictionary
		
		:param name: name of the dataset
		:type name: string
		:param varX: binned variable to be used in the x-axis
		:type varX: string
		:param varY:  binned variable to be used in the y-axis
		:type varY: string
		:param Lumi: luminosity
		:type Lumi: string

		:raise KeyError: the dataset is not in the root file (to be changed to NameError)
		:raise KeyError: some binned variables is not in the dataset

		"""
		import ROOT
		ROOT.gROOT.SetBatch(1)
		import pytnp.steerplots.rootlogon
		from tnputils import getBinning,listTableEff,getEff

		#FIXME: Meter los errores en la misma linea (ahora te salta
		#       de linea (TEXT option)
		try:
			dataSet = self.RooDataSet[name]
		except KeyError:
			message = """There is no RooDataSet with name '%s'""" % name
			printError( self.__module__+'.plotEfMap', message, AttributeError )
		#-- Are the variables in the RooDataSet?
		varNotInDatasetList = filter( lambda var:  not var in self[name]['binnedVar'].keys(), [x, y] )
		if len(varNotInDatasetList) != 0:
			message = 'No binned variable: '
			for var in varNotInDatasetList:
				message += "'%s' " % var
			message += "in the RooDataSet '%s'. Skipping plot generation..." % name
			printWarning( self.__module__+'.plotEffMap', message )
			# --- Skipping plot generation
			return 
		
		#--- Name for the histo and for the plot file to be saved
		histoName = 'TH2F_'+name
		#--- Checking if the histo is already stored and plotted
		if self[name].has_key('TH2'):  #### FIXME: has_key o has_attribute ???
			#-- Skipping, work it's done!
			return None
		#---- Preparing all the stuff
		title = self.resLatex+', '+self[name]['objectType']+' '+self[name]['effType']+' '+dataSet.GetTitle()
		yNbins = self[name]['variables'][y]['binN']
		#arrayBinsY = self[name]['variables'][y]['arrayBins']---> # I need the PyDoubleBuffer
		#------------------------------------------
		__argSet__ = dataSet.get()
		dum, arrayBinsY = getBinning( __argSet__[y] )
		#------------------------------------------
		xNbins = self[name]['variables'][x]['binN']
		#arrayBinsX = self[name]['variables'][x]['arrayBins']---> # I need the PyDoubleBuffer
		#------------------------------------------
		dum, arrayBinsX = getBinning( __argSet__[x] )
		#------------------------------------------
		hTitleOfHist = name.replace('/','_')
		h = ROOT.TH2F( hTitleOfHist, '', xNbins, arrayBinsX, yNbins, arrayBinsY ) 
	  	hlo = h.Clone("eff_lo")
		hlo.SetName( 'low_'+hTitleOfHist )
		hhi = h.Clone("eff_hi")
		hhi.SetName( 'high_'+hTitleOfHist )
		#-- Getting the efficiencies
		_listTableEffList = listTableEff(self.RooDataSet[name])
		#skipPoints = False
		for binDict in _listTableEffList:
			#-- Extract error values
			#if abs(binDict[self[name]['eff']][0]-self.badPoint[0]) < 1e-9:
			#	skipPoints = True
			#	continue
			b = h.FindBin( binDict[x][0] , binDict[y][0] )
			h.SetBinContent(b, binDict[self[name]['eff']][0])
			h.SetBinError(b, (binDict[self[name]['eff']][2]-binDict[self[name]['eff']][1])/2.0 ) # WATCH: Error 'Simetrized' 
			hlo.SetBinContent(b, binDict[self[name]['eff']][1])
			hhi.SetBinContent(b, binDict[self[name]['eff']][2])
		c = ROOT.TCanvas()
		#c.SetLogy(isLog[1]) 
		h.GetYaxis().SetTitle(self[name]['variables'][y]['latexName'])
		h.GetXaxis().SetTitle(self[name]['variables'][x]['latexName'])
		h.GetZaxis().SetTitle(self[name]['variables'][self[name]['eff']]['latexName'])
		#h.SetTitle( title ) --> Out titles
		h.SetTitle( '  CMS Preliminary,'+Lumi+' #sqrt{s}=7 TeV  ' )
		#h.SetTitle('' ) 
		h.Draw('COLZ')
		htext = h.Clone('htext')
		htext.SetMarkerSize(1.0)
		htext.SetMarkerColor(1)
		#if isLog[1]:
		#	ROOT.gStyle.SetPaintTextFormat("1.2f")
		#	htext.Draw('ESAMETEXT0')
		#else:
		ROOT.gStyle.SetPaintTextFormat("1.3f")
		#htext.SetMarkerSize(2.2)
		htext.Draw('SAMETEXTE0')
		#plotName = self.resonance+'_'+name.replace('/','_')+isLog[0]+'.eps'
		plotName = self.resonance+'_'+name.replace('/','_')+'.eps'
		c.SaveAs(plotName)

	#	if skipPoints:
	#		message = '\033[1;33mplotEff2D Warning: Some efficiencies points are failed in the fit, the last plot will skip '\
	#                         'values with %.4f\033[1;m' % self.badPoint[0]
	#		print message

		#FIXME: attribute o llave del diccionario del rootdataset??
		try:
			self[name]['TH2'][histoName] = (h, hlo, hhi)
		except KeyError:
			self[name]['TH2F']  = {} 
			self[name]['TH2F'][histoName] = (h, hlo, hhi)
示例#30
0
def newtableLatex(dataset, effName, varX, varY, **keyword):
    """.. function tableLatex( dataset, effName, 'var_column', 'var_row', [outfile='name.tex', varXname='latex name', varYname='latex name'] ) -> dict

	Giving a RooDataSet and two variables, the function returns a table in latex
	format. If enters the keyword 'outfile' also the table will put
	it into the file.
	(The keyword var is a list with the name of the variables the user want to
	dump. TODO, not yet implemented)
	
	:param dataset: dataset
	:type dataset: ROOT.RooDataSet
	:param effName: efficiency name
	:type effName: string
	:param varX: the name of the variable you want to be as column
	:rtype varX: string
	:param varY: the name of the variable you want to be as row

	.. seealso:: :func:`tableLatex`
	"""
    #TODO:	The keyword var is a list with the name of the variables the user want to dump.
    #TODO: CHECK IF WORKS CORRECTLY
    message = "Use this function with caution! Still in development.\n Use instead the tableLatex function"
    printWarning(newtableLatex, message)

    #---- Checking the variables in dataset
    varDict = getVarDict(dataset)
    #---  All the binned variables in the dataset
    datasetVarList = filter(lambda x: x.lower().find(effName) == -1,
                            varDict.iterkeys())
    effList = filter(lambda x: x.lower().find(effName) != -1,
                     varDict.iterkeys())
    #---- Sanity check
    if len(effList) != 1:
        message ="""The RooDataSet '%s' does not contain a variable called '%s' as efficiency"""\
          % ( dataset.GetName(), effName )
        printError(tableLatex.__module__ + '.' + tableLatex.__name__, message,
                   AttributeError)
    #---- Variables are there?
    for var in [varX, varY]:
        if var not in datasetVarList:
            message ="""The RooDataSet '%s' does not contain a binned variable called '%s'"""\
              % ( dataset.GetName(), var )
            printError(tableLatex.__module__ + '.' + tableLatex.__name__,
                       message, AttributeError)
    # The table
    _tableDict = tableEff(dataset, effName)

    bins = {}
    varName = {}
    varUnit = {}
    for var in [varX, varY]:
        #-- dictionary-List with the min and max values per bin (min,max),...
        bins[var] = [ ( varDict[var]['arrayBins'][i], varDict[var]['arrayBins'][i+1] ) \
          for i in xrange( len(varDict[var]['arrayBins'])-1) ]
        # Latex name of variables, maybe introduced by user otherwise take from construction
        try:
            # Remember to parse linux to latex \theta --> \\theta
            varName[var] = '$' + keywords[var].replace('\\', '\\\\') + '$'
        except NameError:
            varName[var] = '$' + varDict[var]['latexName'].replace(
                '\\', '\\\\').replace('#', '\\') + '$'
        varUnit[var] = varDict[var]['unit']
        if len(varUnit[var]) != 0:
            varUnit[var] = '$({\\rm ' + varUnit[var] + '})$'

    #Some usefuls function to deal with latex
    edges = lambda x, y: '(%0.1f, %0.1f)' % (x, y)
    effsetter = lambda eff, lo, hi: '$%.3f\\pm^{%.3f}_{%.3f}$ & ' % (
        eff, hi - eff, eff - lo)
    central = lambda low, high: (high + low) / 2.0

    #-- Table latex construction
    toLatex = '\\begin{tabular}{c'
    #-- Number of table columns
    toLatex += 'c' * varDict[varY]['binN'] + '}\\hline\n'
    #-- Header (first line)
    toLatex += varName[varX]+varUnit[varX]+' {\\boldmath$\\backslash$}'+\
      varName[varY]+varUnit[varX]+' & '
    #-- varY bins are put on the first line
    for low, high in bins[varY]:
        toLatex += edges(low, high) + ' & '
    toLatex = toLatex[:-2] + '\\\\ \\hline\n'
    #--- Finally, fill the table, line by line
    for lowX, highX in bins[varX]:
        toLatex += edges(lowX, highX) + ' & '
        for lowY, highY in bins[varY]:
            try:
                eff,effErrorLow,effErrorHig = eval('getEff(dataset,effName,'+\
                  varX+'=central(lowX,highX), '+varY+'=central(lowY,highY))')
                toLatex += effsetter(eff, effErrorLow, effErrorHig)
            #Empty bin
            except TypeError:
                toLatex += ' & '
        toLatex = toLatex[:-2] + '\\\\\n'
    toLatex += ' \\hline\n'
    toLatex += '\\end{tabular}'

    print toLatex
    return toLatex