def decompose(lhefile, inputXsecs=None, nevts=None, doCompress=False, doInvisible=False, minmassgap=-1. * GeV): """ Perform LHE-based decomposition. :param lhefile: LHE file with e.g. pythia events :param inputXsecs: xSectionList object with cross sections for the mothers appearing in the LHE file. If None, use information from file. :param nevts: (maximum) number of events used in the decomposition. If None, all events from file are processed. :param doCompress: mass compression option (True/False) :param doInvisible: invisible compression option (True/False) :param minmassgap: minimum mass gap for mass compression (only used if doCompress=True) :returns: list of topologies (TopologyList object) """ if doCompress and minmassgap < 0. * GeV: logger.error( "Asked for compression without specifying minmassgap. Please set minmassgap." ) raise SModelSError() reader = lheReader.LheReader(lhefile, nevts) smsTopList = topology.TopologyList() # Get cross section from file (= event weight, assuming a common weight for # all events) if not inputXsecs: xSectionList = crossSection.getXsecFromLHEFile(lhefile, addEvents=False) else: xSectionList = inputXsecs # Loop over events and decompose for event in reader: momPDG = tuple(sorted(event.getMom())) # Get mother PDGs eventweight = xSectionList.getXsecsFor(momPDG) # Get event element newElement = elementFromEvent(event, eventweight) if not newElement: continue allElements = [newElement] # Perform compression if doCompress or doInvisible: allElements += newElement.compressElement(doCompress, doInvisible, minmassgap) for el in allElements: el.sortBranches() smsTopList.addElement(el) smsTopList._setElementIds() return smsTopList
def testClusterer(self): """ test the mass clusterer """ from smodels.theory import lheReader, lheDecomposer, crossSection from smodels.theory import clusterTools from smodels.experiment.txnameObj import TxName, TxNameData from smodels.experiment.infoObj import Info from smodels.tools.physicsUnits import GeV, pb, fb import copy data = [[ [[ 674.99*GeV, 199.999*GeV], [ 674.99*GeV, 199.999*GeV] ],.03*fb ], [ [[ 725.0001*GeV,200.*GeV], [ 725.0001*GeV,200.*GeV] ], .06*fb ] , [ [[ 750.*GeV,250.*GeV], [ 750.*GeV,250.*GeV] ], .03*fb ] ] info = Info(os.path.join("./database/8TeV/ATLAS/ATLAS-SUSY-2013-05/data/","dataInfo.txt")) globalInfo = Info(os.path.join("./database/8TeV/ATLAS/ATLAS-SUSY-2013-05/","globalInfo.txt")) txnameData=TxNameData(data, "efficiencyMap", Id=1) txname=TxName("./database/8TeV/ATLAS/ATLAS-SUSY-2013-05/data/T2bb.txt",globalInfo,info) txname.txnameData = txnameData filename = "./testFiles/lhe/simplyGluino.lhe" reader = lheReader.LheReader(filename) event = reader.next() reader.close() event_xsec=event.metainfo["totalxsec"] self.assertTrue ( abs ( event_xsec - 0.262 * pb ) < .1 *pb ) xsecs = crossSection.getXsecFromLHEFile(filename) element = lheDecomposer.elementFromEvent(event, xsecs ) element.txname=None e0=copy.deepcopy(element) ## has a gluino with mass of 675 GeV ## make a second element with a slightly different gluino mass e1=copy.deepcopy(element) e1.branches[0].masses[0]=725*GeV e1.branches[1].masses[0]=725*GeV e0.txname = txname e1.txname = txname # lets now cluster the two different gluino masses. newel=clusterTools.groupAll ( [e0,e1] ) newmasses=newel.getAvgMass() self.assertTrue ( newmasses==None ) ## in the case of efficiency maps the avg mass is none ## since it makes no sense txname.txnameData.dataTag = 'upperLimits' newel=clusterTools.clusterElements ( [e0,e1], 5. ) ## this example gives an avg cluster mass of 700 gev self.assertTrue ( newel[0].getAvgMass()[0][0] == 700. * GeV ) newel=clusterTools.clusterElements ( [e0,e1], .5 ) #in this example the distance is not in maxdist, so we dont cluster self.assertTrue ( len(newel)==2 )
def decompose(lhefile, inputXsecs=None, nevts=None, doCompress=False, doInvisible=False, minmassgap=-1. * GeV ): """ Perform LHE-based decomposition. :param lhefile: LHE file with e.g. pythia events :param inputXsecs: xSectionList object with cross-sections for the mothers appearing in the LHE file. If None, use information from file. :param nevts: (maximum) number of events used in the decomposition. If None, all events from file are processed. :param doCompress: mass compression option (True/False) :param doInvisible: invisible compression option (True/False) :param minmassgap: minimum mass gap for mass compression (only used if doCompress=True) :returns: list of topologies (TopologyList object) """ if doCompress and minmassgap < 0. * GeV: logger.error("Asked for compression without specifying minmassgap. Please set minmassgap.") import sys sys.exit() reader = lheReader.LheReader(lhefile, nevts) smsTopList = topology.TopologyList() # Get cross-section from file (= event weight, assuming a common weight for # all events) if not inputXsecs: xSectionList = crossSection.getXsecFromLHEFile(lhefile, addEvents=False) else: xSectionList = inputXsecs # Loop over events and decompose for event in reader: momPDG = tuple(sorted(event.getMom())) # Get mother PDGs eventweight = xSectionList.getXsecsFor(momPDG) # Get event element newElement = elementFromEvent(event, eventweight) allElements = [newElement] # Perform compression if doCompress or doInvisible: allElements += newElement.compressElement(doCompress, doInvisible, minmassgap) for el in allElements: top = topology.Topology(el) smsTopList.addList([top]) return smsTopList
def getModelDataFrom(self,inputFile): """ Reads the input file (LHE or SLHA) and extract the relevant information (masses, widths, BRs and cross-sections). If a http address is given, it will attempt to download the file. :param inputFile: input file (SLHA or LHE) :return: dictionary with masses, dictionary with decays and XSectionList object """ #Download input file, if requested if inputFile.startswith("http") or inputFile.startswith("ftp"): logger.info("Asked for remote slhafile %s. Fetching it." % inputFile) import requests import os.path r = requests.get(inputFile) if r.status_code != 200: logger.error("Could not retrieve remote file %d: %s" %(r.status_code, r.reason)) raise SModelSError() basename = os.path.basename(inputFile) f = open(basename, "w") f.write(r.text) f.close() inputFile = basename #Trick to suppress pyslha error messages: import sys storeErr = sys.stderr #Try to read file assuming it is an SLHA file: try: sys.stderr = None res = pyslha.readSLHAFile(inputFile) massDict = res.blocks['MASS'] #Make sure both PDG signs appear in massDict for pdg,mass in massDict.items(): if not -pdg in massDict: massDict[-pdg] = abs(mass) decaysDict = res.decays xsections = crossSection.getXsecFromSLHAFile(inputFile) #If fails assume it is an LHE file: except (IOError,AttributeError,KeyError): massDict,decaysDict = lheReader.getDictionariesFrom(inputFile) xsections = crossSection.getXsecFromLHEFile(inputFile) logger.info("Using LHE input. All unstable particles will be assumed to have prompt decays.") logger.info("Using LHE input. All particles not appearing in the events will be removed from the model.") finally: sys.stderr = storeErr return massDict,decaysDict,xsections
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 )
def run( self, slhaFile, lhefile=None, unlink=True ): """ Run pythia8. :param slhaFile: 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 temporary files after run? :returns: List of cross sections """ #Change pythia configuration file, if defined: if self.pythiacard: pythiacard_default = self.cfgfile self.cfgfile = self.pythiacard self.xsecs = {} logger.debug ( "wrapper.run()" ) slha = self.checkFileExists(slhaFile) logger.debug ( "file check: " + slha ) cfg = self.absPath(self.cfgfile) logger.debug("running with cfgfile " + str(cfg)) lhefile = self.tempDirectory() + "/events.lhe" cmd = "%s -n %d -f %s -s %d -c %s -l %s" % \ ( self.executablePath, self.nevents, slha, self.sqrts, cfg, lhefile ) xmldoc = self.executablePath.replace ( "pythia8.exe", "xml.doc" ) logger.debug ( "exe path=%s" % self.executablePath ) self.checkInstallation ( compile=True ) if os.path.exists (xmldoc ): logger.debug ( "xml.doc found at %s." % xmldoc ) with open ( xmldoc ) as f: xmlDir = f.read() toadd = os.path.join ( os.path.dirname ( xmldoc ) , xmlDir.strip() ) logger.debug ( "adding -x %s" % toadd ) cmd += " -x %s" % toadd logger.debug("Now running ''%s''" % str(cmd) ) out = executor.getoutput(cmd) logger.debug ( "out=%s" % out ) if not os.path.isfile(lhefile): raise SModelSError( "LHE file %s not found" % lhefile ) lheF = open(lhefile,'r') lhedata = lheF.read() lheF.close() os.remove(lhefile) if not "<LesHouchesEvents" in lhedata: raise SModelSError("No LHE events found in pythia output") if not unlink: tempfile = self.tempDirectory() + "/log" f = open( tempfile, "w") f.write (cmd + "\n\n\n") f.write (out + "\n") f.write (lhedata + "\n") f.close() logger.info ( "stored everything in %s" % tempfile ) # Create memory only file object if sys.version[0]=="2": lhedata = unicode( lhedata ) lheFile = io.StringIO(lhedata) ret = getXsecFromLHEFile(lheFile) #Reset pythia card to its default value if self.pythiacard: self.cfgfile = pythiacard_default return ret
def testClusterer(self): """ test the mass clusterer """ from smodels.theory import lheReader, lheDecomposer, crossSection from smodels.theory import clusterTools from smodels.experiment.txnameObj import TxName, TxNameData from smodels.experiment.infoObj import Info from smodels.tools.physicsUnits import GeV, pb, fb import copy data = [[[[674.99 * GeV, 199.999 * GeV], [674.99 * GeV, 199.999 * GeV]], .03 * fb], [[[725.0001 * GeV, 200. * GeV], [725.0001 * GeV, 200. * GeV]], .06 * fb], [[[750. * GeV, 250. * GeV], [750. * GeV, 250. * GeV]], .03 * fb]] info = Info( os.path.join("./database/8TeV/ATLAS/ATLAS-SUSY-2013-05/data/", "dataInfo.txt")) globalInfo = Info( os.path.join("./database/8TeV/ATLAS/ATLAS-SUSY-2013-05/", "globalInfo.txt")) txnameData = TxNameData(data, "efficiencyMap", Id=1) txname = TxName( "./database/8TeV/ATLAS/ATLAS-SUSY-2013-05/data/T2bb.txt", globalInfo, info) txname.txnameData = txnameData filename = "./testFiles/lhe/simplyGluino.lhe" reader = lheReader.LheReader(filename) event = reader.next() reader.close() event_xsec = event.metainfo["totalxsec"] self.assertTrue(abs(event_xsec - 0.262 * pb) < .1 * pb) xsecs = crossSection.getXsecFromLHEFile(filename) element = lheDecomposer.elementFromEvent(event, xsecs) element.txname = None e0 = copy.deepcopy(element) ## has a gluino with mass of 675 GeV ## make a second element with a slightly different gluino mass e1 = copy.deepcopy(element) e1.branches[0].masses[0] = 725 * GeV e1.branches[1].masses[0] = 725 * GeV e0.txname = txname e1.txname = txname # lets now cluster the two different gluino masses. newel = clusterTools.groupAll([e0, e1]) newmasses = newel.getAvgMass() self.assertTrue( newmasses == None) ## in the case of efficiency maps the avg mass is none ## since it makes no sense txname.txnameData.dataTag = 'upperLimits' newel = clusterTools.clusterElements([e0, e1], 5.) ## this example gives an avg cluster mass of 700 gev self.assertTrue(newel[0].getAvgMass()[0][0] == 700. * GeV) newel = clusterTools.clusterElements([e0, e1], .5) #in this example the distance is not in maxdist, so we dont cluster self.assertTrue(len(newel) == 2)
def decompose(lhefile, inputXsecs=None, nevts=None, doCompress=False, doInvisible=False, minmassgap=-1. * GeV): """ Perform LHE-based decomposition. :param lhefile: LHE file with e.g. pythia events, may be given as URL (though http and ftp only) :param inputXsecs: xSectionList object with cross sections for the mothers appearing in the LHE file. If None, use information from file. :param nevts: (maximum) number of events used in the decomposition. If None, all events from file are processed. :param doCompress: mass compression option (True/False) :param doInvisible: invisible compression option (True/False) :param minmassgap: minimum mass gap for mass compression (only used if doCompress=True) :returns: list of topologies (TopologyList object) """ if lhefile.startswith("http") or lhefile.startswith("ftp"): logger.info("asked for remote lhefile %s. will fetch it." % lhefile) import requests import os.path r = requests.get(lhefile) if r.status_code != 200: logger.error("could not retrieve remote file %d: %s" % (r.status_code, r.reason)) sys.exit() basename = os.path.basename(lhefile) f = open(basename, "w") f.write(r.text) f.close() lhefile = basename if doCompress and minmassgap < 0. * GeV: logger.error( "Asked for compression without specifying minmassgap. Please set minmassgap." ) raise SModelSError() reader = lheReader.LheReader(lhefile, nevts) smsTopList = topology.TopologyList() # Get cross section from file (= event weight, assuming a common weight for # all events) if not inputXsecs: xSectionList = crossSection.getXsecFromLHEFile(lhefile, addEvents=False) else: xSectionList = inputXsecs # Loop over events and decompose for event in reader: momPDG = tuple(sorted(event.getMom())) # Get mother PDGs eventweight = xSectionList.getXsecsFor(momPDG) # Get event element newElement = elementFromEvent(event, eventweight) if not newElement: continue allElements = [newElement] # Perform compression if doCompress or doInvisible: allElements += newElement.compressElement(doCompress, doInvisible, minmassgap) for el in allElements: el.sortBranches() smsTopList.addElement(el) smsTopList._setElementIds() return smsTopList
def run(self, slhaFile, lhefile=None, unlink=True): """ Run pythia8. :param slhaFile: 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 temporary files after run? :returns: List of cross sections """ #Change pythia configuration file, if defined: if self.pythiacard: pythiacard_default = self.cfgfile self.cfgfile = self.pythiacard self.xsecs = {} logger.debug("wrapper.run()") slha = self.checkFileExists(slhaFile) logger.debug("file check: " + slha) cfg = self.absPath(self.cfgfile) logger.debug("running with cfgfile " + str(cfg)) lhefile = self.tempDirectory() + "/events.lhe" cmd = "%s -n %d -f %s -s %d -c %s -l %s" % \ ( self.executablePath, self.nevents, slha, self.sqrts, cfg, lhefile ) xmldoc = self.executablePath.replace("pythia8.exe", "xml.doc") logger.debug("exe path=%s" % self.executablePath) self.checkInstallation(compile=True) if os.path.exists(xmldoc): logger.debug("xml.doc found at %s." % xmldoc) with open(xmldoc) as f: xmlDir = f.read() toadd = os.path.join(os.path.dirname(xmldoc), xmlDir.strip()) logger.debug("adding -x %s" % toadd) cmd += " -x %s" % toadd logger.debug("Now running ''%s''" % str(cmd)) out = executor.getoutput(cmd) logger.debug("out=%s" % out) if not os.path.isfile(lhefile): raise SModelSError("LHE file %s not found" % lhefile) lheF = open(lhefile, 'r') lhedata = lheF.read() lheF.close() os.remove(lhefile) if not "<LesHouchesEvents" in lhedata: raise SModelSError("No LHE events found in pythia output") if not unlink: tempfile = self.tempDirectory() + "/log" f = open(tempfile, "w") f.write(cmd + "\n\n\n") f.write(out + "\n") f.write(lhedata + "\n") f.close() logger.info("stored everything in %s" % tempfile) # Create memory only file object if sys.version[0] == "2": lhedata = unicode(lhedata) lheFile = io.StringIO(lhedata) ret = getXsecFromLHEFile(lheFile) #Reset pythia card to its default value if self.pythiacard: self.cfgfile = pythiacard_default if unlink: shutil.rmtree(self.tempDirectory()) # print ( "rmtree", self.tempDirectory() ) return ret
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
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: loXsecs.add(xsec) else: if not lhefile or not os.path.isfile(lhefile): lheFile = runPythia(slhafile, nevts, sqrts / TeV, lhefile, unlink=unlink) 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()
def decompose(lhefile, inputXsecs=None, nevts=None, doCompress=False, doInvisible=False, minmassgap=-1. * GeV ): """ Perform LHE-based decomposition. :param lhefile: LHE file with e.g. pythia events, may be given as URL (though http and ftp only) :param inputXsecs: xSectionList object with cross sections for the mothers appearing in the LHE file. If None, use information from file. :param nevts: (maximum) number of events used in the decomposition. If None, all events from file are processed. :param doCompress: mass compression option (True/False) :param doInvisible: invisible compression option (True/False) :param minmassgap: minimum mass gap for mass compression (only used if doCompress=True) :returns: list of topologies (TopologyList object) """ if lhefile.startswith("http") or lhefile.startswith("ftp"): logger.info ( "asked for remote lhefile %s. will fetch it." % lhefile ) import requests import os.path r=requests.get(lhefile) if r.status_code != 200: logger.error ( "could not retrieve remote file %d: %s" % ( r.status_code, r.reason ) ) sys.exit() basename = os.path.basename ( lhefile ) f=open ( basename, "w" ) f.write ( r.text ) f.close() lhefile = basename if doCompress and minmassgap < 0. * GeV: logger.error("Asked for compression without specifying minmassgap. Please set minmassgap.") raise SModelSError() reader = lheReader.LheReader(lhefile, nevts) smsTopList = topology.TopologyList() # Get cross section from file (= event weight, assuming a common weight for # all events) if not inputXsecs: xSectionList = crossSection.getXsecFromLHEFile(lhefile, addEvents=False) else: xSectionList = inputXsecs # Loop over events and decompose for event in reader: momPDG = tuple(sorted(event.getMom())) # Get mother PDGs eventweight = xSectionList.getXsecsFor(momPDG) # Get event element newElement = elementFromEvent(event, eventweight) if not newElement: continue allElements = [newElement] # Perform compression if doCompress or doInvisible: allElements += newElement.compressElement(doCompress, doInvisible, minmassgap) for el in allElements: el.sortBranches() smsTopList.addElement(el) smsTopList._setElementIds() return smsTopList