Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-11-09 09:33:00

0001 #include <cstdlib>
0002 #include <future>
0003 #include <stdexcept>
0004 #include <vector>
0005 
0006 #include "G4DynamicParticle.hh"
0007 #include "G4Electron.hh"
0008 #include "G4Material.hh"
0009 #include "G4Step.hh"
0010 #include "G4SystemOfUnits.hh"
0011 #include "G4Track.hh"
0012 #include "OpticksGenstep.h"
0013 #include "SEvt.hh"
0014 #include "U4.hh"
0015 #include "squad.h"
0016 
0017 namespace
0018 {
0019 void Require(bool condition, const char* message)
0020 {
0021     if (!condition)
0022         throw std::runtime_error(message);
0023 }
0024 
0025 std::vector<quad6> Collect(const G4Material* material, int photons)
0026 {
0027     G4Track track(new G4DynamicParticle(G4Electron::Definition(), {0., 0., 1.}, 1. * MeV),
0028                   0., {1., 2., 3.});
0029     G4Step  step;
0030     step.SetTrack(&track);
0031     track.SetStep(&step);
0032     track.SetTrackID(17);
0033     step.SetStepLength(2. * mm);
0034     step.GetPreStepPoint()->SetMaterial(const_cast<G4Material*>(material));
0035     step.GetPreStepPoint()->SetPosition({1., 2., 3.});
0036     step.GetPostStepPoint()->SetPosition({1., 2., 5.});
0037     step.GetPreStepPoint()->SetVelocity(200. * mm / ns);
0038     step.GetPostStepPoint()->SetVelocity(150. * mm / ns);
0039     std::vector<quad6> buffer;
0040     for (int i = 0; i < 32; ++i)
0041     {
0042         U4::CollectGenstep_G4Cerenkov_modified(
0043             &track, &step, photons, 1.1, 2. * eV, 3. * eV, 0.9, 0.19, 10., 12., &buffer);
0044         U4::CollectGenstep_Scintillation(&track, &step, photons + 1, 0, 12. * ns, &buffer);
0045     }
0046     return buffer;
0047 }
0048 } // namespace
0049 
0050 int main()
0051 {
0052     Require(!SEvt::Exists(SEvt::EGPU) && !SEvt::Exists(SEvt::ECPU), "Unexpected global event");
0053     G4Electron::Definition();
0054     G4Material                                   material("buffer_test", 1., 1. * g / mole, 1. * g / cm3);
0055     std::vector<std::future<std::vector<quad6>>> workers;
0056 #ifdef G4MULTITHREADED
0057     constexpr auto launch_policy = std::launch::async;
0058 #else
0059     // Serial Geant4 allocators are shared: construct and destroy tracks on this thread.
0060     constexpr auto launch_policy = std::launch::deferred;
0061 #endif
0062     for (int worker = 0; worker < 4; ++worker)
0063         workers.push_back(std::async(launch_policy, [&material, worker] {
0064             return Collect(&material, 3 + worker);
0065         }));
0066     for (int worker = 0; worker < 4; ++worker)
0067     {
0068         const auto buffer = workers[worker].get();
0069         Require(buffer.size() == 64, "A worker lost or shared gensteps");
0070         for (int i = 0; i < 64; ++i)
0071         {
0072             const auto& genstep = buffer[i];
0073             Require(genstep.gentype() == (i % 2 == 0 ? OpticksGenstep_G4Cerenkov_modified
0074                                                      : OpticksGenstep_SCINTILLATION),
0075                     "Incorrect genstep process");
0076             Require(genstep.numphoton() == 3 + worker + i % 2, "Worker photon counts were mixed");
0077             Require(genstep.matline() == material.GetIndex() + SEvt::G4_INDEX_OFFSET,
0078                     "Material mapping must wait until GPU submission");
0079             Require(genstep.q0.i.y == 17, "Track identity was lost");
0080             Require(genstep.q1.f.x == 1.f && genstep.q2.f.z == 2.f, "Step geometry was lost");
0081         }
0082     }
0083     Require(!SEvt::Exists(SEvt::EGPU) && !SEvt::Exists(SEvt::ECPU), "Collection created global events");
0084     setenv(U4::CollectGenstep_G4Cerenkov_modified_DISABLE, "1", 1);
0085     setenv(U4::CollectGenstep_Scintillation_DISABLE, "1", 1);
0086     Require(Collect(&material, 3).empty(), "Disabled processes still collected gensteps");
0087     unsetenv(U4::CollectGenstep_G4Cerenkov_modified_DISABLE);
0088     unsetenv(U4::CollectGenstep_Scintillation_DISABLE);
0089     return 0;
0090 }