Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2025-08-05 08:17:41

0001 #! /usr/bin/env perl
0002 
0003 use strict;
0004 use warnings;
0005 use Getopt::Long;
0006 
0007 sub CreateSubsystemInclude;
0008 sub CreateSubsystemImplementation;
0009 
0010 sub CreateDetectorInclude;
0011 sub CreateDetectorImplementation;
0012 
0013 sub CreateSteppingActionInclude;
0014 sub CreateSteppingActionImplementation;
0015 
0016 sub CreateMakefile;
0017 sub CreateAutogen;
0018 sub CreateConfigure;
0019 
0020 if ($#ARGV < 0)
0021 {
0022     print "Repo + Location: coresoftware:simulation/g4simulation/g4detectors\n";
0023     print "Usage:\n";
0024     print "CreateG4Subsystem.pl <Detector Name>\n";
0025     print "options:\n";
0026     print "--all : create also autogen.sh, configure.ac and Makefile.am\n";
0027     print "--overwrite : overwrite existing files\n";
0028     exit(0);
0029 }
0030 
0031 my $createall;
0032 my $overwrite;
0033 GetOptions("all" => \$createall, "overwrite" => \$overwrite);
0034 my $detectorname = sprintf("%s",$ARGV[0]);
0035 if ($detectorname =~ m/[^a-zA-Z0-9]/)
0036 {
0037     print "Detector name contains invalid characters - allowed are alphanumeric (lower and upper caps)\n";
0038     exit(1);
0039 }
0040 if (substr($detectorname,0,1) =~ m/[0-9]/)
0041 {
0042     print "Detector name must start with a letter\n";
0043     exit(1);
0044 }
0045 
0046 my $subsysclassname = sprintf("%sSubsystem",$detectorname);
0047 my $detectorclassname = sprintf("%sDetector",$detectorname);
0048 my $steppingclassname = sprintf("%sSteppingAction",$detectorname);
0049 
0050 my %listoffiles = ();
0051 
0052 my $subsystem_includefile = sprintf("%s.h",$subsysclassname);
0053 my $subsystem_implementfile = sprintf("%s.cc",$subsysclassname );
0054 my $detector_includefile = sprintf("%s.h", $detectorclassname);
0055 my $detector_implementfile = sprintf("%s.cc", $detectorclassname);
0056 my $steppingaction_includefile = sprintf("%s.h", $steppingclassname);
0057 my $steppingaction_implementfile = sprintf("%s.cc", $steppingclassname);
0058 
0059 $listoffiles{$subsystem_includefile} = $detectorname;
0060 $listoffiles{$subsystem_implementfile} = $detectorname;
0061 $listoffiles{$detector_includefile} = $detectorname;
0062 $listoffiles{$detector_implementfile} = $detectorname;
0063 $listoffiles{$steppingaction_includefile} = $detectorname;
0064 $listoffiles{$steppingaction_implementfile} = $detectorname;
0065 
0066 if (defined $createall)
0067 {
0068     $listoffiles{"autogen.sh"} = $detectorname;
0069     $listoffiles{"configure.ac"} = $detectorname;
0070     $listoffiles{"Makefile.am"} = $detectorname;
0071 }
0072 
0073 # check if files exist if overwrite is not set
0074 
0075 if (! defined $overwrite)
0076 {
0077     foreach my $file (keys %listoffiles)
0078     {
0079     if (-f $file)
0080     {
0081         print "$file exists but overwrite option not set\n";
0082         exit(1);
0083     }
0084 
0085     }
0086 }
0087 
0088 CreateSubsystemInclude($subsystem_includefile);
0089 CreateSubsystemImplementation($subsystem_implementfile);
0090 
0091 CreateDetectorInclude($detector_includefile);
0092 CreateDetectorImplementation($detector_implementfile);
0093 
0094 CreateSteppingActionInclude($steppingaction_includefile);
0095 CreateSteppingActionImplementation($steppingaction_implementfile);
0096 
0097 if (defined $createall)
0098 {
0099     CreateAutogen();
0100     CreateMakefile();
0101     CreateConfigure();
0102 }
0103 exit(0);
0104 
0105 sub CreateSteppingActionInclude()
0106 {
0107     my $file = shift;
0108     open(F,">$file");
0109     my $includeguard = uc(sprintf("%s_H",$steppingclassname));
0110     open(F,">$file");
0111     print F "// Tell emacs that this is a C++ source\n";
0112     print F "//  -*- C++ -*-.\n";
0113     print F "#ifndef $includeguard\n";
0114     print F "#define $includeguard\n";
0115     print F "\n";
0116     print F "#include <g4main/PHG4SteppingAction.h>\n";
0117     print F "\n";
0118 
0119     print F "class $detectorclassname;\n";
0120     print F "\n";
0121 
0122     print F "class G4Step;\n";
0123     print F "class G4VPhysicalVolume;\n";
0124     print F "class PHCompositeNode;\n";
0125     print F "class PHG4Hit;\n";
0126     print F "class PHG4HitContainer;\n";
0127     print F "class PHParameters;\n";
0128     print F "\n";
0129 
0130     print F "class $steppingclassname : public PHG4SteppingAction\n";
0131     print F "{\n";
0132     print F " public:\n";
0133     print F "  //! constructor\n";
0134     print F "  $steppingclassname($detectorclassname*, const PHParameters* parameters);\n";
0135     print F "\n";
0136 
0137     print F "  //! destructor\n";
0138     print F "  virtual ~$steppingclassname();\n";
0139     print F "\n";
0140 
0141     print F "  //! stepping action\n";
0142     print F "  virtual bool UserSteppingAction(const G4Step*, bool);\n";
0143     print F "\n";
0144 
0145     print F "  //! reimplemented from base class\n";
0146     print F "  virtual void SetInterfacePointers(PHCompositeNode*);\n";
0147     print F "\n";
0148 
0149     print F " private:\n";
0150     print F "  //! pointer to the detector\n";
0151     print F "  $detectorclassname* m_Detector;\n";
0152     print F "  const PHParameters* m_Params;\n";
0153     print F "  //! pointer to hit container\n";
0154     print F "  PHG4HitContainer* m_HitContainer;\n";
0155     print F "  PHG4Hit* m_Hit;\n";
0156     print F "  PHG4HitContainer* m_SaveHitContainer;\n";
0157     print F "  G4VPhysicalVolume* m_SaveVolPre;\n";
0158     print F "  G4VPhysicalVolume* m_SaveVolPost;\n";
0159     print F "\n";
0160 
0161     print F "  int m_SaveTrackId;\n";
0162     print F "  int m_SavePreStepStatus;\n";
0163     print F "  int m_SavePostStepStatus;\n";
0164     print F "  int m_ActiveFlag;\n";
0165     print F "  int m_BlackHoleFlag;\n";
0166     print F "  double m_EdepSum;\n";
0167     print F "  double m_EionSum;\n";
0168     print F "};\n";
0169     print F "\n";
0170 
0171     print F "#endif // $includeguard\n";
0172     close(F);
0173 }
0174 
0175 sub CreateSteppingActionImplementation()
0176 {
0177     my $file = shift;
0178     open(F,">$file");
0179     print F "//____________________________________________________________________________..\n";
0180     print F "//\n";
0181     print F "// This is a working template for the Stepping Action which needs to be implemented\n";
0182     print F "// for active detectors. Most of the code is error handling and access to the G4 objects\n";
0183     print F "// and our data structures. It does not need any adjustment. The only thing you need to\n";
0184     print F "// do is to add the properties of the G4Hits you want to save for later analysis\n";
0185     print F "// This needs to be done in 2 places, G4Hits are generated when a G4 track enters a new\n";
0186     print F "// volume (or is created). Here you give it an initial value. When the G4 track leaves\n";
0187     print F "// the volume the final value needs to be set.\n";
0188     print F "// The places to do this is marked by //implement your own here//\n";
0189     print F "//\n";
0190 
0191     print F "// As guidance you can look at the total (integrated over all steps in a volume) energy\n";
0192     print F "// deposit which should always be saved.\n";
0193     print F "// Additionally the total ionization energy is saved - this can be removed if you are not\n";
0194     print F "// interested in this. Naturally you may want remove these comments in your version\n";
0195     print F "//\n";
0196     print F "//____________________________________________________________________________..\n";
0197     print F "\n";
0198     print F "#include \"$steppingaction_includefile\"\n";
0199     print F "\n";
0200 
0201     print F "#include \"$detector_includefile\"\n";
0202     print F "\n";
0203 
0204     print F "#include <phparameter/PHParameters.h>\n";
0205     print F "\n";
0206 
0207     print F "#include <g4detectors/PHG4StepStatusDecode.h>\n";
0208     print F "\n";
0209 
0210     print F "#include <g4main/PHG4Hit.h>\n";
0211     print F "#include <g4main/PHG4HitContainer.h>\n";
0212     print F "#include <g4main/PHG4Hitv1.h>\n";
0213     print F "#include <g4main/PHG4Shower.h>\n";
0214     print F "#include <g4main/PHG4SteppingAction.h>\n";
0215     print F "#include <g4main/PHG4TrackUserInfoV1.h>\n";
0216     print F "\n";
0217 
0218     print F "#include <phool/getClass.h>\n";
0219     print F "\n";
0220 
0221     print F "#include <TSystem.h>\n";
0222     print F "\n";
0223 
0224     print F "#include <Geant4/G4ParticleDefinition.hh> \n";
0225     print F "#include <Geant4/G4ReferenceCountedHandle.hh>\n";
0226     print F "#include <Geant4/G4Step.hh>\n";
0227     print F "#include <Geant4/G4StepPoint.hh> \n";
0228     print F "#include <Geant4/G4StepStatus.hh>\n";
0229     print F "#include <Geant4/G4String.hh> \n";
0230     print F "#include <Geant4/G4SystemOfUnits.hh>\n";
0231     print F "#include <Geant4/G4ThreeVector.hh>\n";
0232     print F "#include <Geant4/G4TouchableHandle.hh>\n";
0233     print F "#include <Geant4/G4Track.hh>\n";
0234     print F "#include <Geant4/G4TrackStatus.hh>\n";
0235     print F "#include <Geant4/G4Types.hh>\n";
0236     print F "#include <Geant4/G4VPhysicalVolume.hh>\n";
0237     print F "#include <Geant4/G4VTouchable.hh>\n";
0238     print F "#include <Geant4/G4VUserTrackInformation.hh>\n";
0239     print F "\n";
0240 
0241     print F "#include <cmath>\n";
0242     print F "#include <iostream>\n";
0243     print F "#include <string>\n";
0244     print F "\n";
0245 
0246     print F "class PHCompositeNode;\n";
0247     print F "\n";
0248 
0249     print F "//____________________________________________________________________________..\n";
0250     print F "$steppingclassname\:\:$steppingclassname($detectorclassname *detector, const PHParameters *parameters)\n";
0251     print F "  : PHG4SteppingAction(detector->GetName())\n";
0252     print F "  , m_Detector(detector)\n";
0253     print F "  , m_Params(parameters)\n";
0254     print F "  , m_HitContainer(nullptr)\n";
0255     print F "  , m_Hit(nullptr)\n";
0256     print F "  , m_SaveHitContainer(nullptr)\n";
0257     print F "  , m_SaveVolPre(nullptr)\n";
0258     print F "  , m_SaveVolPost(nullptr)\n";
0259     print F "  , m_SaveTrackId(-1)\n";
0260     print F "  , m_SavePreStepStatus(-1)\n";
0261     print F "  , m_SavePostStepStatus(-1)\n";
0262     print F "  , m_ActiveFlag(m_Params->get_int_param(\"active\"))\n";
0263     print F "  , m_BlackHoleFlag(m_Params->get_int_param(\"blackhole\"))\n";
0264     print F "  , m_EdepSum(0)\n";
0265     print F "  , m_EionSum(0)\n";
0266     print F "{\n";
0267     print F "}\n";
0268     print F "\n";
0269 
0270     print F "//____________________________________________________________________________..\n";
0271     print F "$steppingclassname\:\:~$steppingclassname()\n";
0272     print F "{\n";
0273     print F "  // if the last hit was a zero energie deposit hit, it is just reset\n";
0274     print F "  // and the memory is still allocated, so we need to delete it here\n";
0275     print F "  // if the last hit was saved, hit is a nullptr pointer which are\n";
0276     print F "  // legal to delete (it results in a no operation)\n";
0277     print F "  delete m_Hit;\n";
0278     print F "}\n";
0279     print F "\n";
0280 
0281     print F "//____________________________________________________________________________..\n";
0282     print F "// This is the implementation of the G4 UserSteppingAction\n";
0283     print F "bool $steppingclassname\:\:UserSteppingAction(const G4Step *aStep,bool /*was_used*/)\n";
0284     print F "{\n";
0285     print F "  G4TouchableHandle touch = aStep->GetPreStepPoint()->GetTouchableHandle();\n";
0286     print F "  G4TouchableHandle touchpost = aStep->GetPostStepPoint()->GetTouchableHandle();\n";
0287     print F "  // get volume of the current step\n";
0288     print F "  G4VPhysicalVolume *volume = touch->GetVolume();\n";
0289     print F "  // IsInDetector(volume) returns\n";
0290     print F "  //  == 0 outside of detector\n";
0291     print F "  //   > 0 for hits in active volume\n";
0292     print F "  //  < 0 for hits in passive material\n";
0293     print F "  int whichactive = m_Detector->IsInDetector(volume);\n";
0294     print F "  if (!whichactive)\n";
0295     print F "  {\n";
0296     print F "    return false;\n";
0297     print F "  }\n";
0298 
0299     print F "  // collect energy and track length step by step\n";
0300     print F "  G4double edep = aStep->GetTotalEnergyDeposit() / GeV;\n";
0301     print F "  G4double eion = (aStep->GetTotalEnergyDeposit() - aStep->GetNonIonizingEnergyDeposit()) / GeV;\n";
0302     print F "  const G4Track *aTrack = aStep->GetTrack();\n";
0303 
0304     print F "  // if this detector stops everything, just put all kinetic energy into edep\n";
0305     print F "  if (m_BlackHoleFlag)\n";
0306     print F "  {\n";
0307     print F "    edep = aTrack->GetKineticEnergy() / GeV;\n";
0308     print F "    G4Track *killtrack = const_cast<G4Track *>(aTrack);\n";
0309     print F "    killtrack->SetTrackStatus(fStopAndKill);\n";
0310     print F "  }\n";
0311 
0312     print F "  // we use here only one detector in this simple example\n";
0313     print F "  // if you deal with multiple detectors in this stepping action\n";
0314     print F "  // the detector id can be used to distinguish between them\n";
0315     print F "  // hits can easily be analyzed later according to their detector id\n";
0316     print F "  int detector_id = 0;  // we use here only one detector in this simple example\n";
0317     print F "  bool geantino = false;\n";
0318     print F "  // the check for the pdg code speeds things up, I do not want to make\n";
0319     print F "  // an expensive string compare for every track when we know\n";
0320     print F "  // geantino or chargedgeantino has pid=0\n";
0321     print F "  if (aTrack->GetParticleDefinition()->GetPDGEncoding() == 0 &&\n";
0322     print F "      aTrack->GetParticleDefinition()->GetParticleName().find(\"geantino\") !=\n";
0323     print F "          std::string::npos)  // this also accounts for \"chargedgeantino\"\n";
0324     print F "  {\n";
0325     print F "    geantino = true;\n";
0326     print F "  }\n";
0327     print F "  G4StepPoint *prePoint = aStep->GetPreStepPoint();\n";
0328     print F "  G4StepPoint *postPoint = aStep->GetPostStepPoint();\n";
0329     print F "\n";
0330     print F "// Here we have to decide if we need to create a new hit.  Normally this should \n";
0331     print F "// only be neccessary if a G4 Track enters a new volume or is freshly created\n";
0332     print F "// For this we look at the step status of the prePoint (beginning of the G4 Step).\n";
0333     print F "// This should be either fGeomBoundary (G4 Track crosses into volume) or \n";
0334     print F "// fUndefined (G4 Track newly created)\n";
0335     print F "// Sadly over the years with different G4 versions we have observed cases where\n";
0336     print F "// G4 produces \"impossible hits\" which we try to catch here\n";
0337     print F "// These errors were always rare and it is not clear if they still exist but we\n";
0338     print F "// still check for them for safety. We can reproduce G4 runs identically (if given\n";
0339     print F "// the sequence of random number seeds you find in the log), the printouts help\n";
0340     print F "// us giving the G4 support information about those failures\n";
0341     print F "// \n";
0342     print F "  switch (prePoint->GetStepStatus())\n";
0343     print F "  {\n";
0344     print F "  case fPostStepDoItProc:\n";
0345     print F "    if (m_SavePostStepStatus != fGeomBoundary)\n";
0346     print F "    {\n";
0347     print F "      // this is the okay case, fPostStepDoItProc called in a volume, not first thing inside\n";
0348     print F "      // a new volume, just proceed here\n";
0349     print F "      break;\n";
0350     print F "    }\n";
0351     print F "    else\n";
0352     print F "    {\n";
0353     print F "      // this is an impossible G4 Step print out diagnostic to help debug, not sure if\n";
0354     print F "      // this is still with us\n";
0355     print F "      std::cout << GetName() << \": New Hit for  \" << std::endl;\n";
0356     print F "      std::cout << \"prestep status: \"\n";
0357     print F "           << PHG4StepStatusDecode::GetStepStatus(prePoint->GetStepStatus())\n";
0358     print F "           << \", poststep status: \"\n";
0359     print F "           << PHG4StepStatusDecode::GetStepStatus(postPoint->GetStepStatus())\n";
0360     print F "           << \", last pre step status: \"\n";
0361     print F "           << PHG4StepStatusDecode::GetStepStatus(m_SavePreStepStatus)\n";
0362     print F "           << \", last post step status: \"\n";
0363     print F "           << PHG4StepStatusDecode::GetStepStatus(m_SavePostStepStatus) << std::endl;\n";
0364     print F "      std::cout << \"last track: \" << m_SaveTrackId\n";
0365     print F "           << \", current trackid: \" << aTrack->GetTrackID() << std::endl;\n";
0366     print F "      std::cout << \"phys pre vol: \" << volume->GetName()\n";
0367     print F "           << \" post vol : \" << touchpost->GetVolume()->GetName() << std::endl;\n";
0368     print F "      std::cout << \" previous phys pre vol: \" << m_SaveVolPre->GetName()\n";
0369     print F "           << \" previous phys post vol: \" << m_SaveVolPost->GetName() << std::endl;\n";
0370     print F "    }\n";
0371     print F "    [[fallthrough]];\n";
0372     print F "// These are the normal cases\n";
0373     print F "  case fGeomBoundary:\n";
0374     print F "  case fUndefined:\n";
0375     print F "    if (!m_Hit)\n";
0376     print F "    {\n";
0377     print F "      m_Hit = new PHG4Hitv1();\n";
0378     print F "    }\n";
0379     print F "    m_Hit->set_layer(detector_id);\n";
0380     print F "    // here we set the entrance values in cm\n";
0381     print F "    m_Hit->set_x(0, prePoint->GetPosition().x() / cm);\n";
0382     print F "    m_Hit->set_y(0, prePoint->GetPosition().y() / cm);\n";
0383     print F "    m_Hit->set_z(0, prePoint->GetPosition().z() / cm);\n";
0384     print F "    // time in ns\n";
0385     print F "    m_Hit->set_t(0, prePoint->GetGlobalTime() / nanosecond);\n";
0386     print F "    // set the track ID\n";
0387     print F "    m_Hit->set_trkid(aTrack->GetTrackID());\n";
0388     print F "    m_SaveTrackId = aTrack->GetTrackID();\n";
0389     print F "    // set the initial energy deposit\n";
0390     print F "    m_EdepSum = 0;\n";
0391     print F "    // implement your own here://\n";
0392     print F "    // add the properties you are interested in via set_XXX methods\n";
0393     print F "    // you can find existing set methods in \$OFFLINE_MAIN/include/g4main/PHG4Hit.h\n";
0394     print F "    // this is initialization of your value. This is not needed you can just set the final\n";
0395     print F "    // value at the last step in this volume later one\n";
0396     print F "    if (whichactive > 0)\n";
0397     print F "    {\n";
0398     print F "      m_EionSum = 0;  // assuming the ionization energy is only needed for active\n";
0399     print F "                      // volumes (scintillators)\n";
0400     print F "      m_Hit->set_eion(0);\n";
0401     print F "      m_SaveHitContainer = m_HitContainer;\n";
0402     print F "    }\n";
0403     print F "    else\n";
0404     print F "    {\n";
0405     print F "      std::cout << \"implement stuff for whichactive < 0 (inactive volumes)\" << std::endl;\n";
0406     print F "      gSystem->Exit(1);\n";
0407     print F "    }\n";
0408     print F "    // this is for the tracking of the truth info\n";
0409     print F "    if (G4VUserTrackInformation *p = aTrack->GetUserInformation())\n";
0410     print F "    {\n";
0411     print F "      if (PHG4TrackUserInfoV1 *pp = dynamic_cast<PHG4TrackUserInfoV1 *>(p))\n";
0412     print F "      {\n";
0413     print F "        m_Hit->set_trkid(pp->GetUserTrackId());\n";
0414     print F "        pp->GetShower()->add_g4hit_id(m_SaveHitContainer->GetID(), m_Hit->get_hit_id());\n";
0415     print F "      }\n";
0416     print F "    }\n";
0417 
0418     print F "    break;\n";
0419     print F "  default:\n";
0420     print F "    break;\n";
0421     print F "  }\n";
0422     print F "\n";
0423 
0424     print F "  // This section is called for every step\n";
0425     print F "  // some sanity checks for inconsistencies (aka bugs) we have seen over the years\n";
0426     print F "  // check if this hit was created, if not print out last post step status\n";
0427     print F "  if (!m_Hit || !std::isfinite(m_Hit->get_x(0)))\n";
0428     print F "  {\n";
0429     print F "    std::cout << GetName() << \": hit was not created\" << std::endl;\n";
0430     print F "    std::cout << \"prestep status: \"\n";
0431     print F "         << PHG4StepStatusDecode::GetStepStatus(prePoint->GetStepStatus())\n";
0432     print F "         << \", poststep status: \"\n";
0433     print F "         << PHG4StepStatusDecode::GetStepStatus(postPoint->GetStepStatus())\n";
0434     print F "         << \", last pre step status: \"\n";
0435     print F "         << PHG4StepStatusDecode::GetStepStatus(m_SavePreStepStatus)\n";
0436     print F "         << \", last post step status: \"\n";
0437     print F "         << PHG4StepStatusDecode::GetStepStatus(m_SavePostStepStatus) << std::endl;\n";
0438     print F "    std::cout << \"last track: \" << m_SaveTrackId\n";
0439     print F "         << \", current trackid: \" << aTrack->GetTrackID() << std::endl;\n";
0440     print F "    std::cout << \"phys pre vol: \" << volume->GetName()\n";
0441     print F "         << \" post vol : \" << touchpost->GetVolume()->GetName() << std::endl;\n";
0442     print F "    std::cout << \" previous phys pre vol: \" << m_SaveVolPre->GetName()\n";
0443     print F "         << \" previous phys post vol: \" << m_SaveVolPost->GetName() << std::endl;\n";
0444     print F "    // This is fatal - a hit from nowhere. This needs to be looked at and fixed\n";
0445     print F "    gSystem->Exit(1);\n";
0446     print F "  }\n";
0447     print F "  // check if track id matches the initial one when the hit was created\n";
0448     print F "  if (aTrack->GetTrackID() != m_SaveTrackId)\n";
0449     print F "  {\n";
0450     print F "    std::cout << GetName() << \": hits do not belong to the same track\" << std::endl;\n";
0451     print F "    std::cout << \"saved track: \" << m_SaveTrackId\n";
0452     print F "         << \", current trackid: \" << aTrack->GetTrackID()\n";
0453     print F "         << \", prestep status: \" << prePoint->GetStepStatus()\n";
0454     print F "         << \", previous post step status: \" << m_SavePostStepStatus << std::endl;\n";
0455     print F "    // This is fatal - a hit from nowhere. This needs to be looked at and fixed\n";
0456     print F "    gSystem->Exit(1);\n";
0457     print F "  }\n";
0458     print F "\n";
0459 
0460     print F "// We need to cache a few things from one step to the next\n";
0461     print F "// to identify impossible hits and subsequent debugging printout\n";
0462     print F "  m_SavePreStepStatus = prePoint->GetStepStatus();\n";
0463     print F "  m_SavePostStepStatus = postPoint->GetStepStatus();\n";
0464     print F "  m_SaveVolPre = volume;\n";
0465     print F "  m_SaveVolPost = touchpost->GetVolume();\n";
0466 
0467     print F "  // here we just update the exit values, it will be overwritten\n";
0468     print F "  // for every step until we leave the volume or the particle\n";
0469     print F "  // ceases to exist\n";
0470     print F "  // sum up the energy to get total deposited\n";
0471     print F "  m_EdepSum += edep;\n";
0472     print F "  if (whichactive > 0)\n";
0473     print F "  {\n";
0474     print F "    m_EionSum += eion;\n";
0475     print F "  }\n";
0476     print F "  // if any of these conditions is true this is the last step in\n";
0477     print F "  // this volume and we need to save the hit\n";
0478     print F "  // postPoint->GetStepStatus() == fGeomBoundary: track leaves this volume\n";
0479     print F "  // postPoint->GetStepStatus() == fWorldBoundary: track leaves this world\n";
0480     print F "  // (happens when your detector goes outside world volume)\n";
0481     print F "  // postPoint->GetStepStatus() == fAtRestDoItProc: track stops (typically\n";
0482     print F "  // aTrack->GetTrackStatus() == fStopAndKill is also set)\n";
0483     print F "  // aTrack->GetTrackStatus() == fStopAndKill: track ends\n";
0484     print F "  if (postPoint->GetStepStatus() == fGeomBoundary ||\n";
0485     print F "      postPoint->GetStepStatus() == fWorldBoundary ||\n";
0486     print F "      postPoint->GetStepStatus() == fAtRestDoItProc ||\n";
0487     print F "      aTrack->GetTrackStatus() == fStopAndKill)\n";
0488     print F "  {\n";
0489     print F "    // save only hits with energy deposit (or geantino)\n";
0490     print F "    if (m_EdepSum > 0 || geantino)\n";
0491     print F "    {\n";
0492     print F "      // update values at exit coordinates and set keep flag\n";
0493     print F "      // of track to keep\n";
0494     print F "      m_Hit->set_x(1, postPoint->GetPosition().x() / cm);\n";
0495     print F "      m_Hit->set_y(1, postPoint->GetPosition().y() / cm);\n";
0496     print F "      m_Hit->set_z(1, postPoint->GetPosition().z() / cm);\n";
0497 
0498     print F "      m_Hit->set_t(1, postPoint->GetGlobalTime() / nanosecond);\n";
0499     print F "      if (G4VUserTrackInformation *p = aTrack->GetUserInformation())\n";
0500     print F "      {\n";
0501     print F "        if (PHG4TrackUserInfoV1 *pp = dynamic_cast<PHG4TrackUserInfoV1 *>(p))\n";
0502     print F "        {\n";
0503     print F "          pp->SetKeep(1);  // we want to keep the track\n";
0504     print F "        }\n";
0505     print F "      }\n";
0506     print F "      if (geantino)\n";
0507     print F "      {\n";
0508     print F " //implement your own here://\n";
0509     print F " // if you want to do something special for geantinos (normally you do not)\n";
0510     print F "        m_Hit->set_edep(-1);  // only energy=0 g4hits get dropped, this way\n";
0511     print F "                              // geantinos survive the g4hit compression\n";
0512     print F "        if (whichactive > 0)\n";
0513     print F "        {\n";
0514     print F "          m_Hit->set_eion(-1);\n";
0515     print F "        }\n";
0516     print F "      }\n";
0517     print F "      else\n";
0518     print F "      {\n";
0519     print F "        m_Hit->set_edep(m_EdepSum);\n";
0520     print F "      }\n";
0521     print F " //implement your own here://\n";
0522     print F " // what you set here will be saved in the output\n";
0523     print F "      if (whichactive > 0)\n";
0524     print F "      {\n";
0525     print F "        m_Hit->set_eion(m_EionSum);\n";
0526     print F "      }\n";
0527     print F "      m_SaveHitContainer->AddHit(detector_id, m_Hit);\n";
0528     print F "      // ownership has been transferred to container, set to null\n";
0529     print F "      // so we will create a new hit for the next track\n";
0530     print F "      m_Hit = nullptr;\n";
0531     print F "    }\n";
0532     print F "    else\n";
0533     print F "    {\n";
0534     print F "      // if this hit has no energy deposit, just reset it for reuse\n";
0535     print F "      // this means we have to delete it in the dtor. If this was\n";
0536     print F "      // the last hit we processed the memory is still allocated\n";
0537     print F "      m_Hit->Reset();\n";
0538     print F "    }\n";
0539     print F "  }\n";
0540     print F "  // return true to indicate the hit was used\n";
0541     print F "  return true;\n";
0542     print F "}\n";
0543     print F "\n";
0544 
0545     print F "//____________________________________________________________________________..\n";
0546     print F "void $steppingclassname\:\:SetInterfacePointers(PHCompositeNode *topNode)\n";
0547     print F "{\n";
0548     print F "  std::string hitnodename = \"G4HIT_\" + m_Detector->GetName();\n";
0549 
0550     print F "  // now look for the map and grab a pointer to it.\n";
0551     print F "  m_HitContainer = findNode::getClass<PHG4HitContainer>(topNode, hitnodename);\n";
0552 
0553     print F "  // if we do not find the node we need to make it.\n";
0554     print F "  if (!m_HitContainer)\n";
0555     print F "  {\n";
0556     print F "    std::cout << \"$steppingclassname\:\:SetTopNode - unable to find \"\n";
0557     print F "              << hitnodename << std::endl;\n";
0558     print F "  }\n";
0559     print F "}\n";
0560     close(F);
0561 }
0562 
0563 sub CreateDetectorImplementation()
0564 {
0565     my $file = shift;
0566     open(F,">$file");
0567     print F "//____________________________________________________________________________..\n";
0568     print F "//\n";
0569     print F "// This is a working template for the G4 Construct() method which needs to be implemented\n";
0570     print F "// We wedge a method between the G4 Construct() to enable volume hierarchies on the macro\n";
0571     print F "// so here it is called ConstructMe() but there is no functional difference\n";
0572     print F "// Currently this installs a simple G4Box solid, creates a logical volume from it\n";
0573     print F "// and places it. Put your own detector in place (just make sure all active volumes\n";
0574     print F "// get inserted into the m_PhysicalVolumesSet)\n";
0575     print F "// \n";
0576     print F "// Rather than using hardcoded values you should consider using the parameter class\n";
0577     print F "// Parameter names and defaults are set in $subsysclassname\:\:SetDefaultParameters()\n";
0578     print F "// Only parameters defined there can be used (also to override in the macro)\n";
0579     print F "// to avoids typos.\n";
0580     print F "// IMPORTANT: parameters have no inherent units, there is a convention (cm/deg)\n";
0581     print F "// but in any case you need to multiply them here with the correct CLHEP/G4 unit \n";
0582     print F "// \n";
0583     print F "// The place where you put your own detector is marked with\n";
0584     print F "// //begin implement your own here://\n";
0585     print F "// //end implement your own here://\n";
0586     print F "// Do not forget to include the G4 includes for your volumes\n";
0587     print F "//____________________________________________________________________________..\n";
0588     print F "\n";
0589     print F "#include \"$detector_includefile\"\n";
0590     print F "\n";
0591     print F "#include <phparameter/PHParameters.h>\n";
0592     print F "\n";
0593     print F "#include <g4main/PHG4Detector.h>\n";
0594     print F "\n";
0595 
0596     print F "#include <Geant4/G4Box.hh>\n";
0597     print F "#include <Geant4/G4Color.hh>\n";
0598     print F "#include <Geant4/G4LogicalVolume.hh>\n";
0599     print F "#include <Geant4/G4Material.hh>\n";
0600     print F "#include <Geant4/G4PVPlacement.hh>\n";
0601     print F "#include <Geant4/G4SystemOfUnits.hh>\n";
0602     print F "#include <Geant4/G4VisAttributes.hh>\n";
0603     print F "\n";
0604 
0605     print F "#include <cmath>\n";
0606     print F "#include <iostream>\n";
0607     print F "\n";
0608 
0609     print F "class G4VSolid;\n";
0610     print F "class PHCompositeNode;\n";
0611     print F "\n";
0612 
0613     print F "//____________________________________________________________________________..\n";
0614     print F "$detectorclassname\:\:$detectorclassname(PHG4Subsystem *subsys,\n";
0615     print F "                                         PHCompositeNode *Node,\n";
0616     print F "                                         PHParameters *parameters,\n";
0617     print F "                                         const std::string &dnam)\n";
0618     print F "  : PHG4Detector(subsys, Node, dnam)\n";
0619     print F "  , m_Params(parameters)\n";
0620     print F "{\n";
0621     print F "}\n";
0622     print F "\n";
0623 
0624     print F "//_______________________________________________________________\n";
0625     print F "int $detectorclassname\:\:IsInDetector(G4VPhysicalVolume *volume) const\n";
0626     print F "{\n";
0627     print F "  std::set<G4VPhysicalVolume *>::const_iterator iter = m_PhysicalVolumesSet.find(volume);\n";
0628     print F "  if (iter != m_PhysicalVolumesSet.end())\n";
0629     print F "  {\n";
0630     print F "    return 1;\n";
0631     print F "  }\n";
0632     print F "  return 0;\n";
0633     print F "}\n";
0634     print F "\n";
0635 
0636     print F "//_______________________________________________________________\n";
0637     print F "void $detectorclassname\:\:ConstructMe(G4LogicalVolume *logicWorld)\n";
0638     print F "{\n";
0639     print F " //begin implement your own here://\n";
0640     print F " // Do not forget to multiply the parameters with their respective CLHEP/G4 unit !\n";
0641     print F "  double xdim = m_Params->get_double_param(\"size_x\") * cm;\n";
0642     print F "  double ydim = m_Params->get_double_param(\"size_y\") * cm;\n";
0643     print F "  double zdim = m_Params->get_double_param(\"size_z\") * cm;\n";
0644     print F "  G4VSolid *solidbox = new G4Box(\"${detectorname}Solid\", xdim / 2., ydim / 2., zdim / 2.);\n";
0645     print F "  G4LogicalVolume *logical = new G4LogicalVolume(solidbox, G4Material::GetMaterial(m_Params->get_string_param(\"material\")), \"${detectorname}Logical\");\n";
0646     print F "\n";
0647 
0648     print F "  G4VisAttributes *vis = new G4VisAttributes(G4Color(G4Colour::Grey()));  // grey is good to see the tracks in the display\n";
0649     print F "  vis->SetForceSolid(true);\n";
0650     print F "  logical->SetVisAttributes(vis);\n";
0651     print F "  G4RotationMatrix *rotm = new G4RotationMatrix();\n";
0652     print F "  rotm->rotateX(m_Params->get_double_param(\"rot_x\") * deg);\n";
0653     print F "  rotm->rotateY(m_Params->get_double_param(\"rot_y\") * deg);\n";
0654     print F "  rotm->rotateZ(m_Params->get_double_param(\"rot_z\") * deg);\n";
0655     print F "\n";
0656 
0657     print F "  G4VPhysicalVolume *phy = new G4PVPlacement(\n";
0658     print F "      rotm,\n";
0659     print F "      G4ThreeVector(m_Params->get_double_param(\"place_x\") * cm,\n";
0660     print F "                    m_Params->get_double_param(\"place_y\") * cm,\n";
0661     print F "                    m_Params->get_double_param(\"place_z\") * cm),\n";
0662     print F "      logical, \"$detectorname\", logicWorld, 0, false, OverlapCheck());\n";
0663     print F "  // add it to the list of placed volumes so the IsInDetector method\n";
0664     print F "  // picks them up\n";
0665     print F "  m_PhysicalVolumesSet.insert(phy);\n";
0666     print F " //end implement your own here://\n";
0667     print F "  return;\n";
0668     print F "}\n";
0669     print F "\n";
0670 
0671     print F "//_______________________________________________________________\n";
0672     print F "void $detectorclassname\:\:Print(const std::string &what) const\n";
0673     print F "{\n";
0674     print F "  std::cout << \"$detectorname Detector:\" << std::endl;\n";
0675     print F "  if (what == \"ALL\" || what == \"VOLUME\")\n";
0676     print F "  {\n";
0677     print F "    std::cout << \"Version 0.1\" << std::endl;\n";
0678     print F "    std::cout << \"Parameters:\" << std::endl;\n";
0679     print F "    m_Params->Print();\n";
0680     print F "  }\n";
0681     print F "  return;\n";
0682     print F "}\n";
0683 
0684     close(F);
0685 }
0686 
0687 sub CreateDetectorInclude()
0688 {
0689     my $file = shift;
0690     open(F,">$file");
0691     my $includeguard = uc(sprintf("%s_H",$detectorclassname));
0692     open(F,">$file");
0693     print F "// Tell emacs that this is a C++ source\n";
0694     print F "//  -*- C++ -*-.\n";
0695     print F "#ifndef $includeguard\n";
0696     print F "#define $includeguard\n";
0697     print F "\n";
0698 
0699     print F "#include <g4main/PHG4Detector.h>\n";
0700     print F "\n";
0701 
0702     print F "#include <set>\n";
0703     print F "#include <string>  // for string\n";
0704     print F "\n";
0705 
0706     print F "class G4LogicalVolume;\n";
0707     print F "class G4VPhysicalVolume;\n";
0708     print F "class PHCompositeNode;\n";
0709     print F "class PHG4Subsystem;\n";
0710     print F "class PHParameters;\n";
0711     print F "\n";
0712 
0713     print F "class $detectorclassname : public PHG4Detector\n";
0714     print F "{\n";
0715     print F " public:\n";
0716     print F "  //! constructor\n";
0717     print F "  $detectorclassname(PHG4Subsystem *subsys, PHCompositeNode *Node, PHParameters *parameters, const std::string &dnam);\n";
0718     print F "\n";
0719 
0720     print F "  //! destructor\n";
0721     print F "  virtual ~$detectorclassname() {}\n";
0722     print F "\n";
0723 
0724     print F "  //! construct\n";
0725     print F "  void ConstructMe(G4LogicalVolume *world) override;\n";
0726     print F "\n";
0727 
0728     print F "  void Print(const std::string &what = \"ALL\") const override;\n";
0729     print F "\n";
0730 
0731     print F "  //!\@name volume accessors\n";
0732     print F "  //\@{\n";
0733     print F "  int IsInDetector(G4VPhysicalVolume *) const;\n";
0734     print F "  //\@}\n";
0735     print F "\n";
0736 
0737     print F "  void SuperDetector(const std::string &name) { m_SuperDetector = name; }\n";
0738     print F "  const std::string SuperDetector() const { return m_SuperDetector; }\n";
0739     print F "\n";
0740 
0741     print F " private:\n";
0742     print F "  PHParameters *m_Params;\n";
0743     print F "\n";
0744 
0745     print F "  // active volumes\n";
0746     print F "  std::set<G4VPhysicalVolume *> m_PhysicalVolumesSet;\n";
0747     print F "\n";
0748 
0749     print F "  std::string m_SuperDetector;\n";
0750     print F "};\n";
0751     print F "\n";
0752 
0753     print F "#endif // $includeguard\n";
0754     close(F);
0755 }
0756 
0757 
0758 sub CreateSubsystemInclude()
0759 {
0760     my $includefile = shift;
0761     my $includeguard = uc(sprintf("%s_H",$subsysclassname));
0762     open(F,">$includefile");
0763     print F "// Tell emacs that this is a C++ source\n";
0764     print F "//  -*- C++ -*-.\n";
0765     print F "#ifndef $includeguard\n";
0766     print F "#define $includeguard\n";
0767     print F "\n";
0768 
0769     print F "#include <g4detectors/PHG4DetectorSubsystem.h>\n";
0770     print F "\n";
0771 
0772     print F "class PHCompositeNode;\n";
0773     print F "class PHG4Detector;\n";
0774     print F "class $detectorclassname;\n";
0775     print F "class PHG4SteppingAction;\n";
0776     print F "\n";
0777     print F "/**\n";
0778     print F "   * \\brief Detector Subsystem module\n";
0779     print F "   *\n";
0780     print F "   * The detector is constructed and registered via $detectorclassname\n";
0781     print F "   *\n";
0782     print F "   *\n";
0783     print F "   * \\see $detectorclassname\n";
0784     print F "   * \\see $subsysclassname\n";
0785     print F "   *\n";
0786     print F "   */\n";
0787     print F "class $subsysclassname : public PHG4DetectorSubsystem\n";
0788     print F "{\n";
0789     print F " public:\n";
0790     print F "  //! constructor\n";
0791     print F "  $subsysclassname(const std::string& name = \"$detectorname\");\n";
0792     print F "\n";
0793 
0794     print F "  //! destructor\n";
0795     print F "  virtual ~$subsysclassname() {}\n";
0796     print F "\n";
0797 
0798     print F "  /*!\n";
0799     print F "  creates relevant hit nodes that will be populated by the stepping action and stored in the output DST\n";
0800     print F "  */\n";
0801     print F "  int InitRunSubsystem(PHCompositeNode*) override;\n";
0802     print F "\n";
0803 
0804     print F "  //! event processing\n";
0805     print F "  /*!\n";
0806     print F "  get all relevant nodes from top nodes (namely hit list)\n";
0807     print F "  and pass that to the stepping action\n";
0808     print F "  */\n";
0809     print F "  int process_event(PHCompositeNode*) override;\n";
0810     print F "\n";
0811 
0812     print F "  //! accessors (reimplemented)\n";
0813     print F "  PHG4Detector* GetDetector() const override;\n";
0814     print F "\n";
0815 
0816     print F "  PHG4SteppingAction* GetSteppingAction() const override { return m_SteppingAction; }\n";
0817     print F "  //! Print info (from SubsysReco)\n";
0818     print F "  void Print(const std::string& what = \"ALL\") const override;\n";
0819     print F "\n";
0820 
0821     print F " protected:\n";
0822     print F "  // \\brief Set default parameter values\n";
0823     print F "  void SetDefaultParameters() override;\n";
0824     print F "\n";
0825 
0826     print F " private:\n";
0827     print F "  //! detector construction\n";
0828     print F "  /*! derives from PHG4Detector */\n";
0829     print F "  $detectorclassname  *m_Detector;\n";
0830     print F "\n";
0831 
0832     print F "  //! particle tracking \"stepping\" action\n";
0833     print F "  /*! derives from PHG4SteppingActions */\n";
0834     print F "  PHG4SteppingAction *m_SteppingAction;\n";
0835     print F "};\n";
0836     print F "\n";
0837 
0838     print F "#endif // $includeguard\n";
0839     close(F);
0840 }
0841 
0842 sub CreateSubsystemImplementation()
0843 {
0844     my $file = shift;
0845     open(F,">$file");
0846     print F "//____________________________________________________________________________..\n";
0847     print F "//\n";
0848     print F "// This is the interface to the framework. You only need to define the parameters\n";
0849     print F "// you use for your detector in the SetDefaultParameters() method here\n";
0850     print F "// The place to do this is marked by //implement your own here//\n";
0851     print F "// The parameters have no units, they need to be converted in the\n";
0852     print F "// $detectorclassname\:\:ConstructMe() method\n";
0853     print F "// but the convention is as mentioned cm and deg\n";
0854     print F "//____________________________________________________________________________..\n";
0855     print F "//\n";
0856     print F "#include \"$subsystem_includefile\"\n";
0857     print F "\n";
0858     print F "#include \"$detector_includefile\"\n";
0859     print F "#include \"$steppingaction_includefile\"\n";
0860     print F "\n";
0861 
0862     print F "#include <phparameter/PHParameters.h>\n";
0863     print F "\n";
0864 
0865     print F "#include <g4main/PHG4HitContainer.h>\n";
0866     print F "#include <g4main/PHG4SteppingAction.h> \n";
0867     print F "\n";
0868 
0869     print F "#include <phool/PHCompositeNode.h>\n";
0870     print F "#include <phool/PHIODataNode.h>\n";
0871     print F "#include <phool/PHNode.h> \n";
0872     print F "#include <phool/PHNodeIterator.h>\n";
0873     print F "#include <phool/PHObject.h>\n";
0874     print F "#include <phool/getClass.h>\n";
0875     print F "\n";
0876 
0877     print F "\n";
0878 
0879     print F "//_______________________________________________________________________\n";
0880     print F "$subsysclassname\:\:$subsysclassname(const std::string &name)\n";
0881     print F "  : PHG4DetectorSubsystem(name)\n";
0882     print F "  , m_Detector(nullptr)\n";
0883     print F "  , m_SteppingAction(nullptr)\n";
0884     print F "{\n";
0885     print F "  // call base class method which will set up parameter infrastructure\n";
0886     print F "  // and call our SetDefaultParameters() method\n";
0887     print F "  InitializeParameters();\n";
0888     print F "}\n";
0889 
0890     print F "//_______________________________________________________________________\n";
0891     print F "int $subsysclassname\:\:InitRunSubsystem(PHCompositeNode *topNode)\n";
0892     print F "{\n";
0893     print F "  PHNodeIterator iter(topNode);\n";
0894     print F "  PHCompositeNode *dstNode = dynamic_cast<PHCompositeNode *>(iter.findFirst(\"PHCompositeNode\", \"DST\"));\n";
0895     print F "  PHNodeIterator dstIter(dstNode);\n";
0896     print F "  if (GetParams()->get_int_param(\"active\"))\n";
0897     print F "  {\n";
0898     print F "    PHCompositeNode *DetNode = dynamic_cast<PHCompositeNode *>(dstIter.findFirst(\"PHCompositeNode\", Name()));\n";
0899     print F "    if (!DetNode)\n";
0900     print F "    {\n";
0901     print F "      DetNode = new PHCompositeNode(Name());\n";
0902     print F "      dstNode->addNode(DetNode);\n";
0903     print F "    }\n";
0904     print F "    std::string g4hitnodename = \"G4HIT_\" + Name();\n";
0905     print F "    PHG4HitContainer *g4_hits = findNode::getClass<PHG4HitContainer>(DetNode, g4hitnodename);\n";
0906     print F "    if (!g4_hits)\n";
0907     print F "    {\n";
0908     print F "      g4_hits = new PHG4HitContainer(g4hitnodename);\n";
0909     print F "      DetNode->addNode(new PHIODataNode<PHObject>(g4_hits, g4hitnodename, \"PHObject\"));\n";
0910     print F "    }\n";
0911     print F "  }\n";
0912     print F "  // create detector\n";
0913     print F "  m_Detector = new $detectorclassname(this, topNode, GetParams(), Name());\n";
0914     print F "  m_Detector->OverlapCheck(CheckOverlap());\n";
0915     print F "  // create stepping action if detector is active\n";
0916     print F "  if (GetParams()->get_int_param(\"active\"))\n";
0917     print F "  {\n";
0918     print F "    m_SteppingAction = new $steppingclassname(m_Detector, GetParams());\n";
0919     print F "  }\n";
0920     print F "  return 0;\n";
0921     print F "}\n";
0922 
0923     print F "//_______________________________________________________________________\n";
0924     print F "int $subsysclassname\:\:process_event(PHCompositeNode *topNode)\n";
0925     print F "{\n";
0926     print F "  // pass top node to stepping action so that it gets\n";
0927     print F "  // relevant nodes needed internally\n";
0928     print F "  if (m_SteppingAction)\n";
0929     print F "  {\n";
0930     print F "    m_SteppingAction->SetInterfacePointers(topNode);\n";
0931     print F "  }\n";
0932     print F "  return 0;\n";
0933     print F "}\n";
0934 
0935     print F "//_______________________________________________________________________\n";
0936     print F "void $subsysclassname\:\:Print(const std::string &what) const\n";
0937     print F "{\n";
0938     print F "  if (m_Detector)\n";
0939     print F "  {\n";
0940     print F "    m_Detector->Print(what);\n";
0941     print F "  }\n";
0942     print F "  return;\n";
0943     print F "}\n";
0944     print F "\n";
0945 
0946     print F "//_______________________________________________________________________\n";
0947     print F "PHG4Detector *$subsysclassname\:\:GetDetector(void) const\n";
0948     print F "{\n";
0949     print F "  return m_Detector;\n";
0950     print F "}\n";
0951     print F "\n";
0952 
0953     print F "//_______________________________________________________________________\n";
0954     print F "void $subsysclassname\:\:SetDefaultParameters()\n";
0955     print F "{\n";
0956     print F "  // sizes are in cm\n";
0957     print F "  // angles are in deg\n";
0958     print F "  // units should be converted to G4 units when used\n";
0959     print F "  //implement your own here//\n";
0960     print F "  set_default_double_param(\"place_x\", 0.);\n";
0961     print F "  set_default_double_param(\"place_y\", 0.);\n";
0962     print F "  set_default_double_param(\"place_z\", 0.);\n";
0963     print F "  set_default_double_param(\"rot_x\", 0.);\n";
0964     print F "  set_default_double_param(\"rot_y\", 0.);\n";
0965     print F "  set_default_double_param(\"rot_z\", 0.);\n";
0966     print F "  set_default_double_param(\"size_x\", 20.);\n";
0967     print F "  set_default_double_param(\"size_y\", 20.);\n";
0968     print F "  set_default_double_param(\"size_z\", 20.);\n";
0969     print F "\n";
0970 
0971     print F "  set_default_string_param(\"material\", \"G4_Cu\");\n";
0972     print F "}\n";
0973 
0974     close(F);
0975 }
0976 
0977 sub CreateAutogen()
0978 {
0979     open(F,">autogen.sh");
0980     print F "#!/bin/sh\n";
0981     print F "srcdir=`dirname \$0`\n";
0982     print F "test -z \"\$srcdir\" && srcdir=.\n";
0983     print F "\n";
0984     print F "(cd \$srcdir; aclocal -I \${OFFLINE_MAIN}/share;\\\n";
0985     print F "libtoolize --force; automake -a --add-missing; autoconf)\n";
0986     print F "\n";
0987     print F "\$srcdir/configure  \"\$\@\"\n";
0988     close(F);
0989     chmod 0755, "autogen.sh";
0990 }
0991 
0992 sub CreateConfigure()
0993 {
0994     my $loname = lc($detectorname);
0995     open(F,">configure.ac");
0996     print F "AC_INIT($loname,[1.00])\n";
0997     print F "AC_CONFIG_SRCDIR([configure.ac])\n";
0998     print F "\n";
0999 
1000     print F "AM_INIT_AUTOMAKE\n";
1001     print F "AC_PROG_CXX(CC g++)\n";
1002     print F "\n";
1003 
1004     print F "LT_INIT([disable-static])\n";
1005     print F "\n";
1006 
1007     print F "dnl   no point in suppressing warnings people should \n";
1008     print F "dnl   at least see them, so here we go for g++: -Wall\n";
1009     print F "if test \$ac_cv_prog_gxx = yes; then\n";
1010     print F "   CXXFLAGS=\"\$CXXFLAGS -Wall -Werror\"\n";
1011     print F "fi\n";
1012     print F "\n";
1013 
1014     print F "AC_CONFIG_FILES([Makefile])\n";
1015     print F "AC_OUTPUT\n";
1016     close(F);
1017 }
1018 
1019 sub CreateMakefile()
1020 {
1021     open(F,">Makefile.am");
1022     print F "AUTOMAKE_OPTIONS = foreign\n";
1023     print F "\n";
1024 
1025     print F "AM_CXXFLAGS = `geant4-config --cflags`\n";
1026     print F "\n";
1027 
1028     print F "AM_CPPFLAGS = \\\n";
1029     print F "  -I\$(includedir) \\\n";
1030     print F "  -I\$(OFFLINE_MAIN)/include \\\n";
1031     print F "  -I\$(ROOTSYS)/include \n";
1032     print F "\n";
1033 
1034     print F "AM_LDFLAGS = \\\n";
1035     print F "  -L\$(libdir) \\\n";
1036     print F "  -L\$(OFFLINE_MAIN)/lib \\\n";
1037     print F "  -L\$(OFFLINE_MAIN)/lib64\n";
1038     print F "\n";
1039 
1040     print F "pkginclude_HEADERS = \\\n";
1041     print F "  $subsystem_includefile\n";
1042     print F "\n";
1043 
1044     print F "lib_LTLIBRARIES = \\\n";
1045     print F "  lib$detectorname.la\n";
1046     print F "\n";
1047 
1048     print F "lib${detectorname}_la_SOURCES = \\\n";
1049     print F "  $subsystem_implementfile \\\n";
1050     print F "  $detector_implementfile \\\n";
1051     print F "  $steppingaction_implementfile\n";
1052     print F "\n";
1053 
1054     print F "lib${detectorname}_la_LIBADD = \\\n";
1055     print F "  -lphool \\\n";
1056     print F "  -lSubsysReco \\\n";
1057     print F "  -lg4detectors \\\n";
1058     print F "  -lg4testbench \n";
1059     print F "\n";
1060 
1061     print F "BUILT_SOURCES = testexternals.cc\n";
1062     print F "\n";
1063 
1064     print F "noinst_PROGRAMS = \\\n";
1065     print F "  testexternals\n";
1066     print F "\n";
1067 
1068     print F "testexternals_SOURCES = testexternals.cc\n";
1069     print F "testexternals_LDADD   = lib$detectorname.la\n";
1070     print F "\n";
1071 
1072     print F "testexternals.cc:\n";
1073     print F "\techo \"//*** this is a generated file. Do not commit, do not edit\" > \$\@\n";
1074     print F "\techo \"int main()\" >> \$\@\n";
1075     print F "\techo \"{\" >> \$\@\n";
1076     print F "\techo \"  return 0;\" >> \$\@\n";
1077     print F "\techo \"}\" >> \$\@\n";
1078     print F "\n";
1079 
1080     print F "clean-local:\n";
1081     print F "\trm -f \$(BUILT_SOURCES)\n";
1082     close(F);
1083 }
1084