def _evalExpression(stringExpr,cluster): """ Auxiliary method to evaluate a string expression using the weights of the elements in the cluster. Replaces the elements in stringExpr (in bracket notation) by their weights and evaluate the expression. e.g. computes the total weight of string expressions such as "[[[e^+]],[[e^-]]]+[[[mu^+]],[[mu^-]]]" or ratios of weights of string expressions such as "[[[e^+]],[[e^-]]]/[[[mu^+]],[[mu^-]]]" and so on... :parameter stringExpr: string containing the expression to be evaluated :parameter cluster: cluster of elements (ElementCluster object) :returns: xsection for the expression. Can be a XSection object, a float or not numerical (None,string,...) """ #Get model for final state particles (database particles): model = cluster.dataset.globalInfo._databaseParticles #Get txname final state: if not hasattr(cluster.txnames[0],'finalState'): finalState = ['MET','MET'] else: finalState = cluster.txnames[0].finalState if not hasattr(cluster.txnames[0],'intermediateState'): intermediateState = None else: intermediateState = cluster.txnames[0].intermediateState #Get cross section info from cluster (to generate zero cross section values): infoList = cluster.elements[0].weight.getInfo() #Get weights for elements appearing in stringExpr weightsDict = {} evalExpr = stringExpr.replace("'","").replace(" ","") for i,elStr in enumerate(elementsInStr(evalExpr)): el = element.Element(elStr,intermediateState=intermediateState, finalState=finalState,model=model) weightsDict['w%i'%i] = crossSection.XSectionList(infoList) for el1 in cluster.elements: if el1 == el: weightsDict['w%i'%i] += el1.weight evalExpr = evalExpr.replace(elStr,'w%i'%i) weightsDict.update({"Cgtr" : cGtr, "cGtr" : cGtr, "cSim" : cSim, "Csim" : cSim}) exprvalue = eval(evalExpr, weightsDict) if type(exprvalue) == type(crossSection.XSectionList()): if len(exprvalue) != 1: logger.error("Evaluation of expression "+evalExpr+" returned multiple values.") return exprvalue[0] #Return XSection object return exprvalue
def _evalConditions(cluster, analysis): """ If analysis type == upper limit (ULanalysis), evaluates the analysis conditions inside an element cluster. If analysis type == efficiency map (EManalysis), returns None :parameter cluster: cluster of elements (ElementCluster object) :parameter analysis: analysis to obtain the conditions (ULanalysis or EManalysis object) :returns: list of condition values (floats) if analysis type == upper limit. None, otherwise. """ if type(analysis) == type(EManalysis()): return None elif type(analysis) == type(ULanalysis()): if not analysis.conditions: return analysis.conditions conditions = {} # Loop over conditions for cond in analysis.conditions: exprvalue = _evalExpression(cond,cluster,analysis) if type(exprvalue) == type(crossSection.XSectionList()): conditions[cond] = exprvalue[0].value else: conditions[cond] = exprvalue return conditions
def applyMultipliers(self, xsecs, ssmultipliers): """ apply the given multipliers to the cross sections """ for pids in ssmultipliers.keys(): if type(pids) not in [list, tuple]: logger.error( "signal strength multipliers need to be supplied as a dictionary, with the keys being tuples of the mothers' pids, e.g. { (1000021, -1000001 ): 0.9, .... }" ) sys.exit() if len(pids) != 2: logger.warning( "currently we always only have two mothers, so why are the signal strength multipliers given for %d mothers?" % len(pids)) known_pids = [3000006] ## here we can define some exceptional pids for pid in pids: if type(pid) == int and (abs(pid) < 1000000 or (abs(pid) > 3000000 and abs(pid) not in known_pids)): logger.warning( "signal strength multiplier for pid %d supplied. what does that mean?" % pid) for x in xsecs: for pids, multiplier in ssmultipliers.items(): if self.match(pids, x.pid): x.value = x.value * multiplier break # return xsecs newx = crossSection.XSectionList() for x in xsecs: if x.value.asNumber(pb) > 0.: newx.add(x) return newx
def compute(self, sqrts, slhafile, lhefile=None, unlink=True, loFromSlha=None, pythiacard=None): """ Run pythia and compute SUSY cross sections for the input SLHA file. :param sqrts: sqrt{s} to run Pythia, given as a unum (e.g. 7.*TeV) :param slhafile: SLHA file :param lhefile: LHE file. If None, do not write pythia output to file. If file does not exist, write pythia output to this file name. If file exists, read LO xsecs from this file (does not run pythia). :param unlink: Clean up temp directory after running pythia :param loFromSlha: If True, uses the LO xsecs from the SLHA file to compute the higher order xsecs :param pythiaCard: Optional path to pythia.card. If None, uses /etc/pythia.card :returns: XSectionList object """ sqrts = self._checkSqrts(sqrts) self._checkSLHA(slhafile) if lhefile: if os.path.isfile(lhefile): logger.warning("Using LO cross sections from " + lhefile) logger.error( "Cross section retrieval from lhefile currently not implemented" ) sys.exit() else: logger.info("Writing pythia LHE output to " + lhefile) if loFromSlha: logger.info("Using LO cross sections from " + slhafile) xsecsInfile = crossSection.getXsecFromSLHAFile(slhafile) loXsecs = crossSection.XSectionList() for xsec in xsecsInfile: if xsec.info.order == 0 and xsec.info.sqrts == sqrts: loXsecs.add(xsec) else: logger.info("get LO cross sections from pythia%d" % self.pythiaVersion) tool = toolBox.ToolBox().get("pythia%d" % self.pythiaVersion) tool.nevents = self.nevents tool.sqrts = sqrts / TeV tool.pythiacard = pythiacard loXsecs = tool.run(slhafile, lhefile, unlink=unlink) self.loXsecs = loXsecs self.loXsecs.sort() self.xsecs = self.addHigherOrders(sqrts, slhafile) self.xsecs.sort() #for xsec in self.loXsecs: # logger.debug ( "now writing out xsecs: %s" % xsec.value ) logger.debug("how many NLL xsecs? %d" % len(self.xsecs)) return self.xsecs
def _getElementsFrom(smsTopList, analysis): """ Get elements, that are constrained by the analysis. Loop over all elements in smsTopList and returns a copy of the elements which are constrained by the analysis (have efficiency != 0). The copied elements have their weights multiplied by their respective efficiencies and the cross-sections not matching the analysis center-of-mass energy are removed. :parameter analysis: analysis to be considered (ULanalysis or EManalysis object) :parameter smsTopList: list of topologies containing elements (TopologyList object) :returns: list of elements (Element objects) """ elements = [] for el in smsTopList.getElements(): eff = analysis.getEfficiencyFor(el) if eff == 0.: continue element = el.copy() element.weight = crossSection.XSectionList() for xsec in el.weight: if xsec.info.sqrts == analysis.sqrts: element.weight.add(copy.deepcopy(xsec * eff)) if len(element.weight) > 0: elements.append(element) return elements
def cSim(*weights): """ Define the auxiliar similar function. Return the maximum relative difference between any element weights of the list, normalized to [0,1]. :returns: XSectionList object with the values for each label. """ for weight in weights: if type(weight) != type(crossSection.XSectionList()): logger.error("Trying to evaluate non-xsection objects") import sys sys.exit() # Make sure both xsec lists have the same entries (add zero xsecs for the # missing entries) infoList = [] for weight in weights: for info in weight.getInfo(): if not info in infoList: infoList.append(info) zeros = crossSection.XSectionList(infoList) for weight in weights: weight.combineWith(zeros) # Evaluate the inequality for each cross-section info result = crossSection.XSectionList() for info in infoList: res = 0. xsecRes = crossSection.XSection() xsecRes.info = info for weightA in weights: for weightB in weights: a = weightA.getXsecsFor(info.label)[0].value / fb b = weightB.getXsecsFor(info.label)[0].value / fb if a + b == 0.: continue res = max(res, abs(a - b) / abs(a + b)) xsecRes.value = res result.add(xsecRes) return result
def cGtr(weightA, weightB): """ Define the auxiliary greater function. Return a number between 0 and 1 depending on how much it is violated (0 = A > B, 1 = A << B). :returns: XSectioList object with the values for each label. """ if type(weightA) != type(crossSection.XSectionList()) or \ type(weightB) != type(crossSection.XSectionList()): logger.error("Trying to evaluate non-xsection objects") import sys sys.exit() # Make sure both xsec lists have the same entries (add zero xsecs for the # missing entries) infoList = weightA.getInfo() for info in weightB.getInfo(): if not info in infoList: infoList.append(info) if not infoList: # If there are no cross-sections, can not evaluate return 'N/A' zeros = crossSection.XSectionList(infoList) weightA.combineWith(zeros) weightB.combineWith(zeros) # Evaluate the inequality for each cross-section info result = crossSection.XSectionList() for info in infoList: a = weightA.getXsecsFor(info.label)[0].value / fb b = weightB.getXsecsFor(info.label)[0].value / fb xsecRes = crossSection.XSection() xsecRes.info = info if a + b == 0.: xsecRes.value = 'N/A' else: xsecRes.value = (abs(a - b) - (a - b)) / (2. * (a + b)) result.add(xsecRes) return result
def _evalExpression(stringExpr,cluster): """ Auxiliary method to evaluate a string expression using the weights of the elements in the cluster. Replaces the elements in stringExpr (in bracket notation) by their weights and evaluate the expression. e.g. computes the total weight of string expressions such as "[[[e^+]],[[e^-]]]+[[[mu^+]],[[mu^-]]]" or ratios of weights of string expressions such as "[[[e^+]],[[e^-]]]/[[[mu^+]],[[mu^-]]]" and so on... :parameter stringExpr: string containing the expression to be evaluated :parameter cluster: cluster of elements (ElementCluster object) :returns: xsection for the expression. Can be a XSection object, a float or not numerical (None,string,...) """ #Get cross section info from cluster (to generate zero cross section values): infoList = cluster.elements[0].weight.getInfo() #Generate elements appearing in the string expression with zero cross sections: elements = [] for elStr in elementsInStr(stringExpr): el = element.Element(elStr) el.weight = crossSection.XSectionList(infoList) elements.append(el) #Replace elements in strings by their weights and add weights from cluster to the elements list: expr = stringExpr[:].replace("'","").replace(" ","") for iel, el in enumerate(elements): expr = expr.replace(str(el), "elements["+ str(iel) +"].weight") for el1 in cluster.elements: if el1.particlesMatch(el): el.weight.combineWith(el1.weight) el.combineMotherElements(el1) ## keep track of all mothers if expr.find("Cgtr") >= 0 or expr.find("Csim") >= 0: expr = expr.replace("Cgtr", "cGtr") expr = expr.replace("Csim", "cSim") exprvalue = eval(expr) if type(exprvalue) == type(crossSection.XSectionList()): if len(exprvalue) != 1: logger.error("Evaluation of expression "+expr+" returned multiple values.") return exprvalue[0] #Return XSection object return exprvalue
def getTotalWeight(self): """ Return the sum of all topologies total weights. """ sumw = crossSection.XSectionList() for topo in self: topoweight = topo.getTotalWeight() if topoweight: sumw.combineWith(topoweight) return sumw
def getTotalXSec(self): """ Return the sum over the cross-sections of all elements belonging to the cluster. :returns: sum of weights of all the elements in the cluster (XSectionList object) """ totxsec = crossSection.XSectionList() for el in self.elements: totxsec.combineWith(el.weight) return totxsec
def _evalExpression(stringExpr,cluster): """ Auxiliary method to evaluate a string expression using the weights of the elements in the cluster. Replaces the elements in stringExpr (in bracket notation) by their weights and evaluate the expression. e.g. computes the total weight of string expressions such as "[[[e^+]],[[e^-]]]+[[[mu^+]],[[mu^-]]]" or ratios of weights of string expressions such as "[[[e^+]],[[e^-]]]/[[[mu^+]],[[mu^-]]]" and so on... :parameter stringExpr: string containing the expression to be evaluated :parameter cluster: cluster of elements (ElementCluster object) :returns: xsection for the expression. Can be a XSection object, a float or not numerical (None,string,...) """ #Get cross section info from cluster (to generate zero cross section values): infoList = cluster.elements[0].weight.getInfo() #Get final state info finalStates = cluster.elements[0].getFinalStates() #Get weights for elements appearing in stringExpr weightsDict = {} evalExpr = stringExpr.replace("'","").replace(" ","") for i,elStr in enumerate(elementsInStr(evalExpr)): el = element.Element(elStr) el.setFinalState(finalStates) weightsDict['w%i'%i] = crossSection.XSectionList(infoList) for el1 in cluster.elements: if el1.particlesMatch(el): weightsDict['w%i'%i].combineWith(el1.weight) el.combineMotherElements(el1) evalExpr = evalExpr.replace(elStr,'w%i'%i) weightsDict.update({"Cgtr" : cGtr, "cGtr" : cGtr, "cSim" : cSim, "Csim" : cSim}) exprvalue = eval(evalExpr, weightsDict) if type(exprvalue) == type(crossSection.XSectionList()): if len(exprvalue) != 1: logger.error("Evaluation of expression "+evalExpr+" returned multiple values.") return exprvalue[0] #Return XSection object return exprvalue
def getTotalWeight(self): """ Return the sum of all elements weights. :returns: sum of weights of all elements (XSection object) """ if len(self.elementList) == 0: return None sumw = crossSection.XSectionList() for element in self.elementList: sumw.combineWith(element.weight) return sumw
def getTotalXSec(self): """ Return the sum over the cross sections of all elements belonging to the cluster. :returns: sum of weights of all the elements in the cluster (XSectionList object) """ totxsec = crossSection.XSectionList() for el in self: totxsec += el.weight if len(totxsec) != 1: logger.error("Cluster total cross section should have a single value") raise SModelSError() return totxsec[0]
def testGraph(self): """ draw ascii graph """ from smodels.tools import asciiGraph from smodels.theory import lheReader, lheDecomposer, crossSection filename = "./testFiles/lhe/simplyGluino.lhe" reader = lheReader.LheReader(filename) event = reader.next() element = lheDecomposer.elementFromEvent(event, crossSection.XSectionList()) d1=self.orig().split("\n") d2=asciiGraph.asciidraw ( element, border=True ).split("\n") #for (idx,line) in enumerate(d1): # print "%d >>%s<< >>%s<<" % (idx,line, d2[idx] ) #print d1==d2 reader.close() self.assertEqual(d1,d2)
def testReader(self): """ test the LheReader """ from smodels.theory import lheReader, lheDecomposer, crossSection from smodels.tools.physicsUnits import GeV filename = "./testFiles/lhe/simplyGluino.lhe" reader = lheReader.LheReader(filename) event = reader.next() element = lheDecomposer.elementFromEvent(event, crossSection.XSectionList()) s=str(element) assert ( s == "[[[q,q]],[[q,q]]]" ) b0=element.branches[0] sb0=str(b0) assert ( sb0 == "[[q,q]]" ) assert ( b0.masses[0]-675*GeV ) < .1*GeV assert ( b0.masses[1]-600*GeV ) < .1*GeV
def __init__(self, info=None): """ Initializes the element. If info is defined, tries to generate the element using it. :parameter info: string describing the element in bracket notation (e.g. [[[e+],[jet]],[[e-],[jet]]]) """ self.branches = [Branch(), Branch()] self.weight = crossSection.XSectionList() self.motherElements = [] self.elID = 0 self.covered = False self.tested = False if info: # Create element from particle string if type(info) == type(str()): elements = elementsInStr(info) if not elements or len(elements) > 1: nel = 0 if elements: nel = len(elements) logger.error( "Malformed input string. Number of elements " "is %d (expected 1) in: ``%s''", nel, info) return None else: el = elements[0] branches = elementsInStr(el[1:-1]) if not branches or len(branches) != 2: logger.error( "Malformed input string. Number of " "branches is %d (expected 2) in: ``%s''", len(branches), info) return None self.branches = [] for branch in branches: self.branches.append(Branch(branch)) # Create element from branch pair elif type(info) == type([]) and type(info[0]) == type(Branch()): for ib, branch in enumerate(info): self.branches[ib] = branch.copy()
def _evalExpression(stringExpr,cluster,analysis): """ Auxiliary method to evaluate a string expression using the weights of the elements in the cluster. Replaces the elements in stringExpr (in bracket notation) by their weights and evaluate the expression. e.g. computes the total weight of string expressions such as "[[[e^+]],[[e^-]]]+[[[mu^+]],[[mu^-]]]" or ratios of weights of string expressions such as "[[[e^+]],[[e^-]]]/[[[mu^+]],[[mu^-]]]" and so on... :parameter stringExpr: string containing the expression to be evaluated :parameter cluster: cluster of elements (ElementCluster object) :parameter analysis: analysis (ULanalysis object). Just used to print the error message :returns: value for the expression. Can be a XSectionList object, a float or not numerical (None,string,...) """ #Generate elements appearing in the string expression with zero cross-sections: elements = [] for elStr in elementsInStr(stringExpr): el = element.Element(elStr) elements.append(el) #Replace elements in strings by their weights and add weights from cluster to the elements list: expr = stringExpr[:].replace("'","").replace(" ","") for iel, el in enumerate(elements): expr = expr.replace(str(el), "elements["+ str(iel) +"].weight") for el1 in cluster.elements: if el1.particlesMatch(el): el.weight.combineWith(el1.weight) el.combineMotherElements(el1) ## keep track of all mothers if expr.find("Cgtr") >= 0 or expr.find("Csim") >= 0: expr = expr.replace("Cgtr", "cGtr") expr = expr.replace("Csim", "cSim") logger.warning(analysis.label + " using deprecated functions " "'Cgtr'/'Csim'. Auto-replacing with 'cGtr'/'cSim'.") exprvalue = eval(expr) if type(exprvalue) == type(crossSection.XSectionList()): if len(exprvalue) != 1: logger.error("Evaluation of expression "+expr+" returned multiple values.") return exprvalue else: return exprvalue
def __init__(self, info=None, finalState=None, intermediateState=None, model=None): """ Initializes the element. If info is defined, tries to generate the element using it. :parameter info: string describing the element in bracket notation (e.g. [[[e+],[jet]],[[e-],[jet]]]) :parameter finalState: list containing the final state labels for each branch (e.g. ['MET', 'HSCP'] or ['MET','MET']) :parameter intermediateState: nested list containing intermediate state labels for each branch (e.g. [['gluino'], ['gluino']]) :parameter model: The model (Model object) to be used when converting particle labels to particle objects (only used if info, finalState or intermediateState != None). """ self.branches = [Branch(), Branch()] self.weight = crossSection.XSectionList( ) # gives the weight for all decays promptly self.decayLabels = [] self.motherElements = [ self ] #The motheElements includes self to keep track of merged elements self.elID = 0 self.coveredBy = set() self.testedBy = set() if info: # Create element from particle string if type(info) == type(str()): elements = elementsInStr(info) if not elements or len(elements) > 1: nel = 0 if elements: nel = len(elements) logger.error( "Malformed input string. Number of elements " "is %d (expected 1) in: ``%s''", nel, info) return None else: el = elements[0] branches = elementsInStr(el[1:-1]) if not branches or len(branches) != 2: logger.error( "Malformed input string. Number of " "branches is %d (expected 2) in: ``%s''", len(branches), info) return None self.branches = [] if intermediateState: if len(intermediateState) != len(branches): raise SModelSError( "Number of intermediate states (%i) does not match number of branches (%i)" % (len(intermediateState), len(branches))) else: intermediateState = [None] * len(branches) if finalState: if len(finalState) != len(branches): raise SModelSError( "Number of final states (%i) does not match number of branches (%i)" % (len(finalState), len(branches))) else: finalState = [None] * len(branches) for ibr, branch in enumerate(branches): if branch == '[*]': self.branches.append( InclusiveBranch( finalState[ibr], intermediateState=intermediateState[ibr], model=model)) else: self.branches.append( Branch(branch, finalState[ibr], intermediateState[ibr], model=model)) # Create element from branch pair elif isinstance(info, list) and all( isinstance(x, (Branch, InclusiveBranch)) for x in info): self.branches = [br.copy() for br in info] else: raise SModelSError( "Can not create element from input type %s" % type(info)) self.setEinfo()
def compute(self, sqrts, slhafile, lhefile=None, unlink=True, loFromSlha=None, pythiacard=None, ssmultipliers=None): """ Run pythia and compute SUSY cross sections for the input SLHA file. :param sqrts: sqrt{s} to run Pythia, given as a unum (e.g. 7.*TeV) :param slhafile: SLHA file :param lhefile: LHE file. If None, do not write pythia output to file. If file does not exist, write pythia output to this file name. If file exists, read LO xsecs from this file (does not run pythia). :param unlink: Clean up temp directory after running pythia :param loFromSlha: If True, uses the LO xsecs from the SLHA file to compute the higher order xsecs :param pythiaCard: Optional path to pythia.card. If None, uses smodels/etc/pythia.card :param ssmultipliers: optionally supply signal strengh multipliers, given as dictionary of the tuple of the mothers' pids as keys and multipliers as values, e.g { (1000001,1000021):1.1 }. :returns: XSectionList object """ sqrts = self._checkSqrts(sqrts) self._checkSLHA(slhafile) if lhefile: if os.path.isfile(lhefile): logger.warning("Using LO cross sections from " + lhefile) logger.error( "Cross section retrieval from lhefile currently not implemented" ) sys.exit() else: logger.info("Writing pythia LHE output to " + lhefile) if loFromSlha: logger.info("Using LO cross sections from " + slhafile) xsecsInfile = crossSection.getXsecFromSLHAFile(slhafile) loXsecs = crossSection.XSectionList() for xsec in xsecsInfile: if xsec.info.order == 0 and abs(xsec.info.sqrts - sqrts).asNumber(TeV) < 1e-5: loXsecs.add(xsec) if ssmultipliers != None: logger.warning( "supplied signal strength multipliers, but LO xsecs are taken from file. Will not apply them" ) else: logger.info("get LO cross sections from pythia%d" % self.pythiaVersion) tool = self.getPythia() tool.tempdir = None # reset, to make sure it works in parallel mode tool.nevents = self.nevents tool.sqrts = sqrts / TeV tool.pythiacard = pythiacard loXsecs = tool.run(slhafile, lhefile, unlink=unlink) if ssmultipliers != None: loXsecs = self.applyMultipliers(loXsecs, ssmultipliers) self.loXsecs = loXsecs self.loXsecs.sort() self.xsecs = self.addHigherOrders(sqrts, slhafile) self.xsecs.sort() #for xsec in self.loXsecs: # logger.debug ( "now writing out xsecs: %s" % xsec.value ) logger.debug("how many NLL xsecs? %d" % len(self.xsecs)) return self.xsecs
def computeXSec(sqrts, maxOrder, nevts, slhafile, lhefile=None, unlink=True, loFromSlha=None, pythiacard=None): """ Run pythia and compute SUSY cross sections for the input SLHA file. :param sqrts: sqrt{s} to run Pythia, given as a unum (e.g. 7.*TeV) :param maxOrder: maximum order to compute the cross section, given as an integer if maxOrder == 0, compute only LO pythia xsecs if maxOrder == 1, apply NLO K-factors from NLLfast (if available) if maxOrder == 2, apply NLO+NLL K-factors from NLLfast (if available) :param nevts: number of events for pythia run :param slhafile: SLHA file :param lhefile: LHE file. If None, do not write pythia output to file. If file does not exist, write pythia output to this file name. If file exists, read LO xsecs from this file (does not run pythia). :param unlink: Clean up temp directory after running pythia :param loFromSlha: If True, uses the LO xsecs from the SLHA file to compute the higher order xsecs :param pythiaCard: Optional path to pythia.card. If None, uses /etc/pythia.card :returns: XSectionList object """ if not os.path.isfile(slhafile): logger.error("SLHA file %s not found.", slhafile) raise SModelSError() try: f = pyslha.readSLHAFile(slhafile) except pyslha.ParseError as e: logger.error("File cannot be parsed as SLHA file: %s" % e) raise SModelSError() if type(sqrts) == type(float) or type(sqrts) == type(int): logger.warning("sqrt(s) given as scalar, will add TeV as unit.") sqrts = float(sqrts) * TeV smaxorder = {"LO": 0, "NLO": 1, "NLL": 2} if maxOrder in smaxorder.keys(): logger.warning("maxorder given as string, please supply integer.") maxOrder = smaxorder[maxOrder] if lhefile: if os.path.isfile(lhefile): logger.warning("Using LO cross sections from " + lhefile) else: logger.info("Writing pythia LHE output to " + lhefile) if loFromSlha: logger.info("Using LO cross sections from " + slhafile) xsecsInfile = crossSection.getXsecFromSLHAFile(slhafile) loXsecs = crossSection.XSectionList() for xsec in xsecsInfile: if xsec.info.order == 0 and xsec.info.sqrts == sqrts: loXsecs.add(xsec) else: if not lhefile or not os.path.isfile(lhefile): lheFile = runPythia(slhafile, nevts, sqrts / TeV, lhefile, unlink=unlink, pythiacard=pythiacard) else: lheFile = open(lhefile, 'r') loXsecs = crossSection.getXsecFromLHEFile(lheFile) xsecs = loXsecs wlabel = str(int(sqrts / TeV)) + ' TeV' if maxOrder == 0: wlabel += ' (LO)' elif maxOrder == 1: wlabel += ' (NLO)' elif maxOrder >= 2: wlabel += ' (NLO+NLL)' for ixsec, xsec in enumerate(xsecs): xsecs[ixsec].info.label = wlabel xsecs[ixsec].info.order = maxOrder if maxOrder > 0: pIDs = loXsecs.getPIDpairs() for pID in pIDs: k = 0. kNLO, kNLL = nllFast.getKfactorsFor(pID, sqrts, slhafile) if maxOrder == 1 and kNLO: k = kNLO elif maxOrder == 2 and kNLL and kNLO: k = kNLO * kNLL elif maxOrder > 2 and kNLL and kNLO: logger.warning("Unkown xsec order, using NLL+NLO k-factor, " "if available") k = kNLO * kNLL k = float(k) for i, xsec in enumerate(xsecs): if set(xsec.pid) == set(pID): # Apply k-factor xsecs[i] = xsec * k # Remove zero cross sections while len(xsecs) > 0 and xsecs.getMinXsec() == 0. * pb: for xsec in xsecs: if xsec.value == 0. * pb: xsecs.delete(xsec) break if maxOrder > 0 and len(xsecs) == 0: logger.warning("No NLO or NLL cross sections available.") return xsecs
argparser.add_argument('-T', nargs='?', help="Tx name, will look up lhe file in " "../regression/Tx_1.lhe. Will be overriden by the " "'--lhe' argument", type=types.StringType, default='T1') argparser.add_argument('-l', '--lhe', nargs='?', help="LHE file name, supplied directly. Takes " "precedence over '-T' argument.", type=types.StringType, default='') argparser.add_argument('-b', '--border', action='store_true', help="draw a border around the graph") args = argparser.parse_args() path = os.path.join(installation.installDirectory(), "inputFiles/lhe/") filename = os.path.join(path, args.T + "_1.lhe") if args.lhe != "": filename = args.lhe reader = lheReader.LheReader(filename) event = reader.next() element = lheDecomposer.elementFromEvent(event, crossSection.XSectionList()) print(asciidraw(element, border=args.border))
def run( self, slhafile, lhefile=None, unlink=True ): """ Execute pythia_lhe with n events, at sqrt(s)=sqrts. :param slhafile: input SLHA file :param lhefile: option to write LHE output to file; if None, do not write output to disk. If lhe file exists, use its events for xsecs calculation. :param unlink: Clean up temp directory after running pythia :returns: List of cross sections """ if lhefile and os.path.isfile ( lhefile ): lheFile = open(lhefile, 'r') xsecsInfile = crossSection.getXsecFromSLHAFile(slhafile) loXsecs = crossSection.XSectionList() for xsec in xsecsInfile: if xsec.info.order == LO and \ float (xsec.info.sqrts.asNumber(TeV)) == self.sqrts: loXsecs.add(xsec) return loXsecs #Change pythia card, if defined: if self.pythiacard: pythiacard_default = self.cfgfile self.cfgfile = self.pythiacard # Check if template config file exists if unlink: self.unlink() else: self.tempdir = None self.replaceInCfgFile({"NEVENTS": self.nevents, "SQRTS":1000 * self.sqrts}) self.setParameter("MSTP(163)", "6") if unlink==False: logger.info ( "keeping temporary directory at %s" % self.tempDirectory() ) r = self.checkInstallation() if r == False: logger.info ( "Installation check failed." ) sys.exit() self.replaceInCfgFile({"NEVENTS": self.nevents, "SQRTS":1000 * self.sqrts}) self.setParameter("MSTP(163)", "6") lhedata = self._run(slhafile, unlink=unlink ) if not "<LesHouchesEvents" in lhedata: pythiadir = "%s/log" % self.tempDirectory() logger.error("No LHE events found in pythia output %s" % pythiadir ) if not os.path.exists ( pythiadir ): logger.error ("Will dump pythia output to %s" % pythiadir ) f=open ( pythiadir, "w" ) for line in lhedata: f.write ( line ) f.close() raise SModelSError( "No LHE events found in %s" % pythiadir ) #Reset pythia card to its default value if self.pythiacard: self.cfgfile = pythiacard_default #if not unlink: # lhefile = self.tempdir + "/events.lhe" # Generate file object with lhe events if lhefile: lheFile = open(lhefile, 'w') lheFile.write(lhedata) lheFile.close() lheFile = open(lhefile, 'r') else: # Create memory only file object if sys.version[0]=="2": lhedata = unicode ( lhedata ) lheFile = io.StringIO(lhedata) return crossSection.getXsecFromLHEFile ( lheFile )