diff --git a/corsika/detail/modules/ObservationPlane.inl b/corsika/detail/modules/ObservationPlane.inl index eb42521a0b10052c7b8cb2e07ff12b5816445cee..acdcc4461e9376c6737d3a39d1772716eb65efe3 100644 --- a/corsika/detail/modules/ObservationPlane.inl +++ b/corsika/detail/modules/ObservationPlane.inl @@ -24,8 +24,8 @@ namespace corsika { template <typename TOutput> inline ProcessReturn ObservationPlane<TOutput>::doContinuous( - corsika::setup::Stack::particle_type& particle, - corsika::setup::Trajectory&, bool const stepLimit) { + corsika::setup::Stack::particle_type& particle, corsika::setup::Trajectory&, + bool const stepLimit) { /* The current step did not yet reach the ObservationPlane, do nothing now and wait: */ diff --git a/corsika/detail/modules/writers/ObservationPlaneWriterParquet.inl b/corsika/detail/modules/writers/ObservationPlaneWriterParquet.inl index a2e0e722006d87c52bb442bd34b9b786dd1b6ed3..0c9e15442c96fa695e91a761f70e3900a7b12aa7 100644 --- a/corsika/detail/modules/writers/ObservationPlaneWriterParquet.inl +++ b/corsika/detail/modules/writers/ObservationPlaneWriterParquet.inl @@ -34,17 +34,23 @@ namespace corsika { // and build the streamer output_.buildStreamer(); + + setInit(true); } void ObservationPlaneWriterParquet::endOfShower() { ++shower_; } void ObservationPlaneWriterParquet::endOfLibrary() { output_.closeStreamer(); } - void ObservationPlaneWriterParquet::write(Code const& pid, - units::si::HEPEnergyType const& energy, - units::si::LengthType const& x, - units::si::LengthType const& y) { - using namespace units::si; + void ObservationPlaneWriterParquet::write(Code const& pid, HEPEnergyType const& energy, + LengthType const& x, LengthType const& y) { + if (!isInit()) { + std::runtime_error( + "ObservationPlaneWriterParquet not initialized. Either 1) add the " + "corresponding module to " + "the OutputManager, or 2) declare the module to write no output using " + "NoOutput."); + } // write the next row - we must write `shower_` first. *(output_.getWriter()) << shower_ << static_cast<int>(get_PDG(pid)) diff --git a/corsika/detail/modules/writers/TrackWriterParquet.inl b/corsika/detail/modules/writers/TrackWriterParquet.inl index 089dfa600e5e6a411077e11c56985831d9392bf1..71e3c64e71dd71f1e933c5216d301b665bfcbc2e 100644 --- a/corsika/detail/modules/writers/TrackWriterParquet.inl +++ b/corsika/detail/modules/writers/TrackWriterParquet.inl @@ -38,16 +38,24 @@ namespace corsika { // and build the streamer output_.buildStreamer(); + + setInit(true); } void TrackWriterParquet::endOfShower() { ++shower_; } void TrackWriterParquet::endOfLibrary() { output_.closeStreamer(); } - void TrackWriterParquet::write(Code const& pid, units::si::HEPEnergyType const& energy, + void TrackWriterParquet::write(Code const& pid, HEPEnergyType const& energy, QuantityVector<length_d> const& start, QuantityVector<length_d> const& end) { - using namespace units::si; + + if (!isInit()) { + std::runtime_error( + "TrackWriterParquet not initialized. Either 1) add the corresponding module to " + "the OutputManager, or 2) declare the module to write no output using " + "NoOutput."); + } // write the next row - we must write `shower_` first. // clang-format off diff --git a/corsika/output/BaseOutput.hpp b/corsika/output/BaseOutput.hpp index db998f336c8b445c3a8466fb9f6059bb8c5378ec..7c5351463335a67bb7993a4429d39f71a9b2a41c 100644 --- a/corsika/output/BaseOutput.hpp +++ b/corsika/output/BaseOutput.hpp @@ -20,8 +20,6 @@ namespace corsika { class BaseOutput { protected: - int shower_{0}; ///< The current event number. - BaseOutput(); public: @@ -54,6 +52,21 @@ namespace corsika { * Get any summary information for the entire library. */ virtual YAML::Node getSummary() { return YAML::Node(); }; + + /** + * Flag to indicate readiness. + */ + bool isInit() const { return is_init_; } + + /** + * Set init flag. + */ + void setInit(bool const v) { is_init_ = v; } + + protected: + int shower_{0}; ///< The current event number. + private: + bool is_init_{false}; ///< flag to indicate readiness }; } // namespace corsika diff --git a/examples/boundary_example.cpp b/examples/boundary_example.cpp index 161b875ae3a2bae69e773c33a7b3fdc7160ce9f6..ebb202597bc8f7d09e88b815e89e5f55cf5a3225 100644 --- a/examples/boundary_example.cpp +++ b/examples/boundary_example.cpp @@ -13,7 +13,8 @@ #include <corsika/framework/random/RNGManager.hpp> #include <corsika/framework/utility/CorsikaFenv.hpp> #include <corsika/framework/core/Logging.hpp> -#include <corsika/output/DummyOutputManager.hpp> + +#include <corsika/output/OutputManager.hpp> #include <corsika/setup/SetupEnvironment.hpp> #include <corsika/setup/SetupStack.hpp> @@ -114,6 +115,8 @@ int main() { world->addChild(std::move(target)); universe.addChild(std::move(world)); + OutputManager output("boundary_outputs"); + // setup processes, decays and interactions setup::Tracking tracking; @@ -124,6 +127,8 @@ int main() { ParticleCut cut(50_GeV, true, true); TrackWriter trackWriter; + output.add("tracks", trackWriter); // register TrackWriter + MyBoundaryCrossingProcess<true> boundaryCrossing("crossings.dat"); // assemble all processes into an ordered process list @@ -166,7 +171,6 @@ int main() { } // define air shower object, run simulation - DummyOutputManager output; Cascade EAS(env, tracking, sequence, output, stack); EAS.run(); @@ -177,4 +181,6 @@ int main() { (cut.getCutEnergy() + cut.getInvEnergy() + cut.getEmEnergy()); CORSIKA_LOG_INFO("Total energy (GeV): {} relative difference (%): {}", Efinal / 1_GeV, (Efinal / E0 - 1.) * 100); + + output.endOfLibrary(); } diff --git a/examples/cascade_example.cpp b/examples/cascade_example.cpp index bee5869abfc43e7d938e2c34d94b7d6f508383fb..61d0c545dd96507dc2a2a65c75174a537a0ac683 100644 --- a/examples/cascade_example.cpp +++ b/examples/cascade_example.cpp @@ -11,10 +11,10 @@ #include <corsika/framework/core/PhysicalUnits.hpp> #include <corsika/framework/random/RNGManager.hpp> #include <corsika/framework/geometry/Sphere.hpp> - #include <corsika/framework/utility/CorsikaFenv.hpp> #include <corsika/framework/core/Logging.hpp> -#include <corsika/output/DummyOutputManager.hpp> + +#include <corsika/output/OutputManager.hpp> #include <corsika/media/Environment.hpp> #include <corsika/media/HomogeneousMedium.hpp> @@ -55,8 +55,7 @@ using namespace std; // int main() { - corsika_logger->set_pattern("[%n:%^%-8l%$] custom pattern: %v"); - logging::set_level(logging::level::trace); + logging::set_level(logging::level::info); std::cout << "cascade_example" << std::endl; @@ -108,6 +107,8 @@ int main() { rootCS, 0_m, 0_m, height_atmosphere); // this is the CORSIKA 7 start of atmosphere/universe + OutputManager output("cascade_outputs"); + ShowerAxis const showerAxis{injectionPos, Vector{rootCS, 0_m, 0_m, -100_km}, env}; { @@ -142,6 +143,8 @@ int main() { ParticleCut cut(80_GeV, true, true); TrackWriter trackWriter; + output.add("tracks", trackWriter); // register TrackWriter + BetheBlochPDG eLoss{showerAxis}; // assemble all processes into an ordered process list @@ -149,7 +152,6 @@ int main() { make_sequence(stackInspect, sibyll, sibyllNuc, decay, eLoss, cut, trackWriter); // define air shower object, run simulation - DummyOutputManager output; Cascade EAS(env, tracking, sequence, output, stack); EAS.run(); @@ -164,4 +166,6 @@ int main() { cout << "total dEdX energy (GeV): " << eLoss.getTotal() / 1_GeV << endl << "relative difference (%): " << eLoss.getTotal() / E0 * 100 << endl; cut.reset(); + + output.endOfLibrary(); } diff --git a/examples/cascade_proton_example.cpp b/examples/cascade_proton_example.cpp index 4b0b25f53cda1d8c3662c108f7f84d4ad26e302b..a02c914e4ad1d554160d36745e5d00a2ee6d981e 100644 --- a/examples/cascade_proton_example.cpp +++ b/examples/cascade_proton_example.cpp @@ -11,10 +11,10 @@ #include <corsika/framework/core/PhysicalUnits.hpp> #include <corsika/framework/random/RNGManager.hpp> #include <corsika/framework/geometry/Sphere.hpp> - #include <corsika/framework/utility/CorsikaFenv.hpp> #include <corsika/framework/core/Logging.hpp> -#include <corsika/output/DummyOutputManager.hpp> + +#include <corsika/output/OutputManager.hpp> #include <corsika/media/Environment.hpp> #include <corsika/media/HomogeneousMedium.hpp> @@ -67,6 +67,8 @@ int main() { // initialize random number sequence(s) RNGManager::getInstance().registerRandomStream("cascade"); + OutputManager output("cascade_proton_outputs"); + // setup environment, geometry using EnvType = setup::Environment; EnvType env; @@ -116,7 +118,7 @@ int main() { // setup processes, decays and interactions setup::Tracking tracking; - StackInspector<setup::Stack> stackInspect(1, true, E0); + StackInspector<setup::Stack> stackInspect(1000, true, E0); RNGManager::getInstance().registerRandomStream("sibyll"); RNGManager::getInstance().registerRandomStream("pythia"); @@ -132,6 +134,8 @@ int main() { // hadronicElastic(env); TrackWriter trackWriter; + output.add("tracks", trackWriter); // register TrackWriter + ShowerAxis const showerAxis{injectionPos, Vector{rootCS, 0_m, 0_m, -100_km}, env}; BetheBlochPDG eLoss{showerAxis}; @@ -142,7 +146,6 @@ int main() { auto sequence = make_sequence(pythia, decay, eLoss, cut, trackWriter, stackInspect); // define air shower object, run simulation - DummyOutputManager output; Cascade EAS(env, tracking, sequence, output, stack); EAS.run(); @@ -152,4 +155,6 @@ int main() { cut.getCutEnergy() + cut.getInvEnergy() + cut.getEmEnergy(); cout << "total energy (GeV): " << Efinal / 1_GeV << endl << "relative difference (%): " << (Efinal / E0 - 1.) * 100 << endl; + + output.endOfLibrary(); } diff --git a/examples/em_shower.cpp b/examples/em_shower.cpp index 8de0de39d4f249227741f323ddc91f4752c1eb0e..9634b18703905b104b7c882139972d36125cc0f4 100644 --- a/examples/em_shower.cpp +++ b/examples/em_shower.cpp @@ -17,7 +17,8 @@ #include <corsika/framework/utility/CorsikaFenv.hpp> #include <corsika/framework/process/InteractionCounter.hpp> #include <corsika/framework/core/Logging.hpp> -#include <corsika/output/DummyOutputManager.hpp> + +#include <corsika/output/OutputManager.hpp> #include <corsika/media/Environment.hpp> #include <corsika/media/LayeredSphericalAtmosphereBuilder.hpp> @@ -67,7 +68,6 @@ using MyExtraEnv = MediumPropertyModel<UniformMagneticField<T>>; int main(int argc, char** argv) { logging::set_level(logging::level::info); - corsika_logger->set_pattern("[%n:%^%-8l%$] custom pattern: %v"); if (argc != 2) { std::cerr << "usage: em_shower <energy/GeV>" << std::endl; @@ -138,6 +138,7 @@ int main(int argc, char** argv) { std::cout << "shower axis length: " << (showerCore - injectionPos).getNorm() * 1.02 << std::endl; + OutputManager output("em_shower_outputs"); ShowerAxis const showerAxis{injectionPos, (showerCore - injectionPos) * 1.02, env}; // setup processes, decays and interactions @@ -148,6 +149,7 @@ int main(int argc, char** argv) { InteractionCounter emCascadeCounted(emCascade); TrackWriter trackWriter; + output.add("tracks", trackWriter); // register TrackWriter // long. profile; columns for gamma, e+, e- still need to be added LongitudinalProfile longprof{showerAxis}; @@ -155,12 +157,12 @@ int main(int argc, char** argv) { Plane const obsPlane(showerCore, DirectionVector(rootCS, {0., 0., 1.})); ObservationPlane observationLevel(obsPlane, DirectionVector(rootCS, {1., 0., 0.}), "particles.dat"); + output.add("obsplane", observationLevel); auto sequence = make_sequence(emCascadeCounted, emContinuous, longprof, cut, observationLevel, trackWriter); // define air shower object, run simulation setup::Tracking tracking; - DummyOutputManager output; Cascade EAS(env, tracking, sequence, output, stack); // to fix the point of first interaction, uncomment the following two lines: @@ -185,4 +187,6 @@ int main(int argc, char** argv) { save_hist(hists.labHist(), "inthist_lab_emShower.npz", true); save_hist(hists.CMSHist(), "inthist_cms_emShower.npz", true); longprof.save("longprof_emShower.txt"); + + output.endOfLibrary(); } diff --git a/examples/geometry_example.cpp b/examples/geometry_example.cpp index 7a25708a8d434b8b35e89a8cd23b1e4ad35e0f1f..596e6c1842011d56d8db27dc6e02fe81ab8bdbb9 100644 --- a/examples/geometry_example.cpp +++ b/examples/geometry_example.cpp @@ -21,7 +21,6 @@ using namespace corsika; int main() { logging::set_level(logging::level::info); - corsika_logger->set_pattern("[%n:%^%-8l%$] custom pattern: %v"); CORSIKA_LOG_INFO("geometry_example"); diff --git a/examples/helix_example.cpp b/examples/helix_example.cpp index cf58531b4170aa5b74a3693033b71c700cde102e..e980931b74ace074bf6d0459cf69e6d158f32b91 100644 --- a/examples/helix_example.cpp +++ b/examples/helix_example.cpp @@ -21,7 +21,6 @@ using namespace corsika; int main() { logging::set_level(logging::level::info); - corsika_logger->set_pattern("[%n:%^%-8l%$] custom pattern: %v"); CORSIKA_LOG_INFO("helix_example"); diff --git a/examples/hybrid_MC.cpp b/examples/hybrid_MC.cpp index ed4324b3e066d69d0ffd75c34d91da4908b14da7..8026586cb2f119821c0ed5c77c16159f09f611cf 100644 --- a/examples/hybrid_MC.cpp +++ b/examples/hybrid_MC.cpp @@ -23,9 +23,10 @@ #include <corsika/framework/core/PhysicalUnits.hpp> #include <corsika/framework/utility/CorsikaFenv.hpp> #include <corsika/framework/core/Cascade.hpp> -#include <corsika/output/DummyOutputManager.hpp> #include <corsika/framework/geometry/PhysicalGeometry.hpp> +#include <corsika/output/OutputManager.hpp> + #include <corsika/media/Environment.hpp> #include <corsika/media/FlatExponential.hpp> #include <corsika/media/LayeredSphericalAtmosphereBuilder.hpp> @@ -87,7 +88,6 @@ using MyExtraEnv = MediumPropertyModel<UniformMagneticField<T>>; int main(int argc, char** argv) { logging::set_level(logging::level::info); - corsika_logger->set_pattern("[%n:%^%-8l%$] custom pattern: %v"); CORSIKA_LOG_INFO("hybrid_MC"); @@ -172,6 +172,7 @@ int main(int argc, char** argv) { std::cout << "shower axis length: " << (showerCore - injectionPos).getNorm() * 1.02 << std::endl; + OutputManager output("hybrid_MC_outputs"); ShowerAxis const showerAxis{injectionPos, (showerCore - injectionPos) * 1.02, env}; // setup processes, decays and interactions @@ -220,7 +221,8 @@ int main(int argc, char** argv) { Plane const obsPlane(showerCore, DirectionVector(rootCS, {0., 0., 1.})); ObservationPlane observationLevel(obsPlane, DirectionVector(rootCS, {1., 0., 0.}), "particles.dat"); - + output.add("obsplane", observationLevel); + corsika::urqmd::UrQMD urqmd_model; InteractionCounter urqmdCounted{urqmd_model}; @@ -241,7 +243,6 @@ int main(int argc, char** argv) { // define air shower object, run simulation setup::Tracking tracking; - DummyOutputManager output; Cascade EAS(env, tracking, sequence, output, stack); // to fix the point of first interaction, uncomment the following two lines: @@ -274,4 +275,6 @@ int main(int argc, char** argv) { std::ofstream finish("finished"); finish << "run completed without error" << std::endl; + + output.endOfLibrary(); } diff --git a/examples/vertical_EAS.cpp b/examples/vertical_EAS.cpp index fa08acc5ebec5ac06574998c75b58ac8bdb23e0e..928197970e8c27f08b93d561f33aab1defea5796 100644 --- a/examples/vertical_EAS.cpp +++ b/examples/vertical_EAS.cpp @@ -99,7 +99,6 @@ using MyExtraEnv = MediumPropertyModel<UniformMagneticField<T>>; int main(int argc, char** argv) { - corsika_logger->set_pattern("[%n:%^%-8l%$] %s:%#: %v"); logging::set_level(logging::level::info); CORSIKA_LOG_INFO("vertical_EAS");