File indexing completed on 2025-08-05 08:17:41
0001
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 =~ )
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) =~ )
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
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