#!/usr/bin/env python2 # usage = """ %prog [options] arguments Generate a file of events from command line inputs. This is specifically setup so that the calling package doesn't need to depend on SIMG4. Typically, this is called from a tut test-harness. Check the ReconSBCAT test harness for a example. To generate events, give GPS commands (without the '/gps/' prefix), the "beamOn" command, or full geant macro commands. e.g. : SimG4-test-file 'particle mu+' 'position 0 0 0 cm' 'direction 0 0 1' \ 'energy 500 MeV' 'beamOn 10' In C++: std::string cmd("SimG4-test-file"); cmd += " 'particle mu+'"; cmd += " 'position 0 0 0 cm'"; cmd += " 'direction 0 0 1'"; cmd += " 'energy 500 MeV'"; cmd += " 'beamOn 10'"; system(cmd); """ import re import os import commands import optparse #Define the command line options and parse the command line. parser = optparse.OptionParser(usage) parser.add_option("-d","--dry-run",action="store_true", dest="DryRun",default=False, help="Print the commands to run, but do nothing.") parser.add_option("--no-elecsim",action="store_false", dest="UseElecSim", default=True, help="Don't run the electronics simulation.") parser.add_option("--trace",action="store_true", dest="Trace", default=True, help="Print commands before executing them.") parser.add_option("--no-trace",action="store_false", dest="Trace", help="Don't print commands before executing them.") parser.add_option("--output",dest="Output", default="SimG4-test-file", help="Specify the particle type") (options,args) = parser.parse_args() def System(command): """Run a system command after apply the effect of command line options This responds to the --dry-run and --apply options. """ global options if options.Trace: print " System: " + command if not options.DryRun: os.system(command) def CommandOutput(command, forcerun=False): """Run a command if this isn't a dry run.""" if options.Trace: print " Output of: " + command if not options.DryRun or forcerun: return commands.getoutput(command) else: return "dryrun" def CheckCompatibility(parent,root,package,version): """ Verify that a package is compatible with the current package The parent describes the required packages used by the current package. The root, package, and version are check to see if they are compatible with the current package.""" cmd = "(cd " + root + "/" + package + "/" +version + "/cmt ;" cmd += "(cmt show uses | grep '^use'))" v = CommandOutput(cmd,True).splitlines() for line in v: versionRecord = line.split() result = parent.IsCompatible(versionRecord[1],versionRecord[2]) if result == None: continue if not result: return False return True # Summarize the package use information for the current package. This # will be passed to the SIMG4 and SIMDETECTORRESPONSE packages to make sure that # the found versions are compatible. class CurrentPackage: packageUses = [] def __init__(self): v = CommandOutput("(cmt show uses | grep '^use')", True).splitlines() for line in v: current = line.split() self.packageUses.append([current[1], current[2]]) print self.packageUses def IsCompatible(self, package, version): result = None for p in self.packageUses: if p[0] == package: result = False if p[1] == version: result = True return result # Provide a class that will create a pipe to the SIMG4 and let # commands be run one at a time with the ApplyCommand method. class SIMG4: SimG4=None def __init__(self,current): SimG4 = self.FindSIMG4(current) command = "(" command += "source " + SimG4[1] + ";" command += "source " + SimG4[1] + ";" command += SimG4[0] + ")" print command self.SimG4 = os.popen(command,'w') def ApplyCommand(self,command): self.SimG4.write(command + "\n") def Close(self): self.SimG4.close() def FindSIMG4(self,current): """Find the full path for the SIMG4.exe that should be run. """ v = CommandOutput("(cmt show packages | grep SimG4 | sort -r)", True).splitlines() for line in v: versionRecord = line.split(); if CheckCompatibility(current, versionRecord[2], versionRecord[0], versionRecord[1]): result = (versionRecord[2] \ + "/" + versionRecord[0] \ + "/" + versionRecord[1] \ + "/" + os.getenv("CMTCONFIG") \ + "/SIMG4.exe" , \ versionRecord[2] \ + "/" + versionRecord[0] \ + "/" + versionRecord[1] \ + "/cmt/setup.sh") if os.path.exists(result[0]): return result else: print "File doesn't exist: " + result[0] return None def FindElecSim(current): """Find the full path for the SIMDETECTORRESPONSE.exe that should be run. """ v = CommandOutput("(cmt show packages | grep SimDetectorResponse | sort -r)", True).splitlines() for line in v: versionRecord = line.split(); if CheckCompatibility(current, versionRecord[2], versionRecord[0], versionRecord[1]): result = (versionRecord[2] \ + "/" + versionRecord[0] \ + "/" + versionRecord[1] \ + "/" + os.getenv("CMTCONFIG") \ + "/SIMDETECTORRESPONSE.exe" , \ versionRecord[2] \ + "/" + versionRecord[0] \ + "/" + versionRecord[1] \ + "/cmt/setup.sh") if os.path.exists(result[0]): return result else: print "File doesn't exist: " + result[0] return None def RunElecSim(current,esimFile,rawFile): """Run the compatible version of SIMDETECTORRESPONSE.exe on raw MC file.""" version = FindElecSim(current) System("(source " + version[1] + "; " + version[0] + " -o " + esimFile + " " + rawFile + ".root )") # Determine the names of the output files. if options.UseElecSim: rawFile = options.Output + "-raw" esimFile = options.Output + ".root" else: rawFile = options.Output # Check the current package to find out what versions of the packages # it is using. currentPackage = CurrentPackage() # Find a compatible version of COMETmc and start it as a pipe. SimG4 = SIMG4(currentPackage) # Run the commands through the SimG4 if os.path.exists(rawFile+".root"): os.unlink(rawFile + ".root") SimG4.ApplyCommand("/control/verbose 2") SimG4.ApplyCommand("/run/verbose 0") SimG4.ApplyCommand("/event/verbose 0") SimG4.ApplyCommand("/track/verbose 0") SimG4.ApplyCommand("/db/open " + rawFile) SimG4.ApplyCommand("/t2k/update") SimG4.ApplyCommand("/gps/verbose 2") for cmd in args: if (cmd[0:6] == "beamOn"): SimG4.ApplyCommand("/run/" + cmd) elif (cmd[0] == "/"): SimG4.ApplyCommand(cmd) else: SimG4.ApplyCommand("/gps/" + cmd) SimG4.ApplyCommand("exit") SimG4.Close() if options.UseElecSim: if os.path.exists(esimFile): os.unlink(esimFile) RunElecSim(currentPackage,esimFile,rawFile) os.unlink(rawFile + ".root")