diff --git a/cmake/AddJanaLibrary.cmake b/cmake/AddJanaLibrary.cmake index 86038ab9c..9e372b063 100644 --- a/cmake/AddJanaLibrary.cmake +++ b/cmake/AddJanaLibrary.cmake @@ -37,7 +37,9 @@ macro(add_jana_library library_name) if (${PROJECT_NAME} STREQUAL "jana2") # This is an internal plugin - set(INSTALL_NAMESPACE "JANA") + if (NOT DEFINED INSTALL_NAMESPACE) + set(INSTALL_NAMESPACE "JANA") + endif() set(JANA_NAMESPACE "") if (NOT LIBRARY_EXPORT) set(LIBRARY_EXPORT "jana2_targets") @@ -66,20 +68,24 @@ macro(add_jana_library library_name) # Handle public headers if (LIBRARY_PUBLIC_HEADER) + # Include files get installed to $CMAKE_PREFIX_PATH/$INSTALL_NAMESPACE/$CWD_NAME + # First we extract $CWD_NAME + get_filename_component(CWD_NAME "${CMAKE_CURRENT_SOURCE_DIR}" NAME) + set_target_properties(${library_name} PROPERTIES PUBLIC_HEADER "${LIBRARY_PUBLIC_HEADER}" ) target_include_directories(${library_name} PUBLIC $ - $ + $ ) endif() # Install target install(TARGETS ${library_name} EXPORT ${LIBRARY_EXPORT} - PUBLIC_HEADER DESTINATION include/${INSTALL_NAMESPACE}/${library_name} + PUBLIC_HEADER DESTINATION include/${INSTALL_NAMESPACE}/${CWD_NAME} LIBRARY DESTINATION lib ) diff --git a/cmake/AddJanaPlugin.cmake b/cmake/AddJanaPlugin.cmake index 713da5ef5..c50d2c7b4 100644 --- a/cmake/AddJanaPlugin.cmake +++ b/cmake/AddJanaPlugin.cmake @@ -43,7 +43,9 @@ macro(add_jana_plugin plugin_name) if (${PROJECT_NAME} STREQUAL "jana2") # This is an internal plugin - set(INSTALL_NAMESPACE "JANA") + if (NOT DEFINED INSTALL_NAMESPACE) + set(INSTALL_NAMESPACE "JANA") + endif() set(JANA_NAMESPACE "") if (NOT PLUGIN_EXPORT) set(PLUGIN_EXPORT "jana2_targets") diff --git a/src/examples/misc/CMakeLists.txt b/src/examples/misc/CMakeLists.txt index 441291772..ed5d20249 100644 --- a/src/examples/misc/CMakeLists.txt +++ b/src/examples/misc/CMakeLists.txt @@ -1,5 +1,4 @@ -add_subdirectory(CsvWriter) add_subdirectory(DstExample) add_subdirectory(Tutorial) add_subdirectory(EventGroupExample) diff --git a/src/examples/misc/CsvWriter/CMakeLists.txt b/src/examples/misc/CsvWriter/CMakeLists.txt deleted file mode 100644 index 057a08739..000000000 --- a/src/examples/misc/CsvWriter/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ - - -add_jana_plugin(CsvWriter) - -add_test( - NAME jana-example-csv-writer - COMMAND jana -Pjana:nevents=5 -Pplugins=JTest,CsvWriter -Pcsv:collection_names=JTestTrackData) diff --git a/src/examples/misc/CsvWriter/CsvWriter.cc b/src/examples/misc/CsvWriter/CsvWriter.cc deleted file mode 100644 index 202f406ec..000000000 --- a/src/examples/misc/CsvWriter/CsvWriter.cc +++ /dev/null @@ -1,139 +0,0 @@ - -// Copyright 2020, Jefferson Science Associates, LLC. -// Subject to the terms in the LICENSE file found in the top-level directory. - - -#include -#include - -#include -#include - -class CsvWriter : public JEventProcessor { -private: - - // Define the parameters that our processor is going to request - - Parameter> m_collection_names {this, "csv:collection_names", {}, - "Comma-separated list of collection names (Type:Tag) to write to CSV"}; - - Parameter m_dest_path{this, "csv:dest_file", "./output.csv", - "Location where CSV files get written"}; - - // Other internal member variables that our EventProcessor needs - - std::vector> m_collection_types_and_tags; - - std::fstream m_dest_file; - -public: - - CsvWriter() { - SetTypeName(NAME_OF_THIS); - SetCallbackStyle(CallbackStyle::ExpertMode); - }; - - void Init() override { - - m_dest_file.open(*m_dest_path, std::fstream::out); - - // For historical reasons, our JEvent interface requires types and tags to be separated - // for non-Podio types. Ideally we could deprecate this in favor of a unified concept of - // collection name that includes both type and tag information. However this takes some finesse. - // So for now, we do the separation here in order to minimize runtime costs. - for (auto collection_name : *m_collection_names) { - auto pos = collection_name.find(":"); - std::string type_name = collection_name.substr(0, pos); - std::string tag = (pos==std::string::npos ? "":collection_name.substr(pos+1)); - // Note that we do this exact same thing in JControlEventProcessor.cc:158. This should be refactored in both - // places once the JStorage mechanism is fully implemented and merged. - - m_collection_types_and_tags.push_back({type_name, tag}); - LOG_INFO(GetLogger()) << "Requesting collection with type=" << type_name << ", tag=" << tag << LOG_END; - } - } - - void ProcessParallel(const JEvent& event) override { - - // In parallel, trigger construction of the collections we need. - for (const auto& [type_name, tag] : m_collection_types_and_tags) { - auto databundle = event.GetFactorySet()->GetDatabundle(type_name, tag); - if (databundle == nullptr || databundle->GetFactory() == nullptr) { - // If the factory is not found, throw an exception immediately and exit - throw JException("Factory not found! typename=%s, tag=%s", type_name.c_str(), tag.c_str()); - } - databundle->GetFactory()->Create(event); - } - } - - void ProcessSequential(const JEvent& event) override { - - // Sequentially, read the collections we requested earlier, and write them to file. - // Everything inside this callback happens inside a lock; unlike earlier versions - // of JANA, users do not need to manipulate locks at all. To get this behavior, - // set the callback style to "ExpertMode" in the constructor. - - m_dest_file - << "########################################" << std::endl - << "event_number,run_number" << std::endl - << event.GetEventNumber() << "," << event.GetRunNumber() << std::endl; - - for (const auto& [type_name, tag] : m_collection_types_and_tags) { - - // Retrieve the collections we triggered earlier - auto databundle = event.GetFactorySet()->GetDatabundle(type_name, tag); - std::vector objects = databundle->GetAs(); - size_t obj_count = objects.size(); - if (obj_count != databundle->GetSize()) { - throw JException("Collection does not appear to contain JObjects!"); - // Right now, there's no foolproof way to distinguish between - // JFactory::GetAs() returning empty because the collection is simply empty, - // or because the objects don't inherit from JObject. This is another thing - // to address once JStorage is in place. - } - - // Print collection information - m_dest_file - << "========================================" << std::endl - << "type_name,tag,object_count" << std::endl - << type_name << "," << tag << "," << obj_count << std::endl - << "----------------------------------------" << std::endl; - - JObjectSummary summary; - - // Print header - if (obj_count > 0) { - objects[0]->Summarize(summary); - for (auto& field : summary.get_fields()) { - m_dest_file << field.name << ","; - } - m_dest_file << std::endl; - } - - // Print each row in the table - for (auto obj : objects) { - obj->Summarize(summary); - for (auto& field : summary.get_fields()) { - m_dest_file << field.value << ","; - } - m_dest_file << std::endl; - } - } - } - - void Finish() override { - //m_dest_file.close(); - } - -}; - -extern "C" { -void InitPlugin(JApplication* app) { - InitJANAPlugin(app); - app->Add(new CsvWriter); -} -} - - - - diff --git a/src/examples/misc/CsvWriter/README.md b/src/examples/misc/CsvWriter/README.md deleted file mode 100644 index 40cb21868..000000000 --- a/src/examples/misc/CsvWriter/README.md +++ /dev/null @@ -1,12 +0,0 @@ - -CsvWriter -========= - -CsvWriter demonstrates how to write an event processor that writes a number of output collections to a file. -For simplicity, each collection is represented as CSV with a little extra outer structure. Specifically, `####` lines separate events, `====` lines separate collections, and `----` lines separate headers from table bodies. - -This example demonstrates how to generically work with JObjects without committing to a particular data model. Specifically, it uses `JFactory::GetAs()` and `JFactory::Summarize()` together in order to manipulate collections without having their concrete type. JANA does something similar internally for its `janacontrol` plugin and its interactive `JInspector`. It is useful to compare this to `TutorialProcessor`, which does know the exact types of its output collections. - -This example requires that the data model classes inherit from `JObject`. If they don't, an exception will be thrown. - - diff --git a/src/examples/misc/JObjectDatamodel/CMakeLists.txt b/src/examples/misc/JObjectDatamodel/CMakeLists.txt deleted file mode 100644 index 9c4f51b45..000000000 --- a/src/examples/misc/JObjectDatamodel/CMakeLists.txt +++ /dev/null @@ -1,21 +0,0 @@ - - -# This is a "header-only" CMake target. Use it to include any of the headers -# via `target_link_libraries(SOMETHING PUBLIC JObjectDatamodel)`. It works both -# in-tree and externally. - -add_library(Examples::JObjectDatamodel INTERFACE) - -target_include_directories(Examples::JObjectDatamodel INTERFACE - $ - $ - -/// JObjects are plain-old data containers for inputs, intermediate results, and outputs. -/// They have member functions for introspection and maintaining associations with other JObjects, but -/// all of the numerical code which goes into their creation should live in a JFactory instead. -/// You are allowed to include STL containers and pointers to non-POD datatypes inside your JObjects, -/// however, it is highly encouraged to keep them flat and include only primitive datatypes if possible. -/// Think of a JObject as being a row in a database table, with event number as an implicit foreign key. - -struct CalorimeterCluster : public JObject { - - JOBJECT_PUBLIC(CalorimeterCluster) - - double x_center; // Pixel coordinates centered around 0,0 - double y_center; // Pixel coordinates centered around 0,0 - double E_tot; // Energy loss in GeV - double t_begin; // Time in us - double t_end; // Time in us - - - /// Override Summarize to tell JANA how to produce a convenient string representation for our JObject. - /// This can be used called from user code, but also lets JANA automatically inspect its own data. For instance, - /// adding JCsvWriter will automatically generate a CSV file containing each hit. Warning: This is obviously - /// slow, so use this for debugging and monitoring but not inside the performance critical code paths. - - void Summarize(JObjectSummary& summary) const override { - summary.add(x_center, NAME_OF(x_center), "%f", "Pixel coords <- [0,80)"); - summary.add(y_center, NAME_OF(y_center), "%f", "Pixel coords <- [0,24)"); - summary.add(E_tot, NAME_OF(E_tot), "%f", "Energy loss in GeV"); - summary.add(t_begin, NAME_OF(t_begin), "%f", "Earliest observed time in us"); - summary.add(t_end, NAME_OF(t_end), "%f", "Latest observed time in us"); - } - -}; - - diff --git a/src/examples/misc/JObjectDatamodel/CalorimeterHit.h b/src/examples/misc/JObjectDatamodel/CalorimeterHit.h deleted file mode 100644 index debc6c8c8..000000000 --- a/src/examples/misc/JObjectDatamodel/CalorimeterHit.h +++ /dev/null @@ -1,38 +0,0 @@ - -// Copyright 2020, Jefferson Science Associates, LLC. -// Subject to the terms in the LICENSE file found in the top-level directory. - -#pragma once -#include - -/// JObjects are plain-old data containers for inputs, intermediate results, and outputs. -/// They have member functions for introspection and maintaining associations with other JObjects, but -/// all of the numerical code which goes into their creation should live in a JFactory instead. -/// You are allowed to include STL containers and pointers to non-POD datatypes inside your JObjects, -/// however, it is highly encouraged to keep them flat and include only primitive datatypes if possible. -/// Think of a JObject as being a row in a database table, with event number as an implicit foreign key. - -struct CalorimeterHit : public JObject { - - JOBJECT_PUBLIC(CalorimeterHit) - - int x; // Pixel coordinates centered around 0,0 - int y; // Pixel coordinates centered around 0,0 - double E; // Energy loss in GeV - double t; // Time in ms - - - /// Override Summarize to tell JANA how to produce a convenient string representation for our JObject. - /// This can be used called from user code, but also lets JANA automatically inspect its own data. For instance, - /// adding JCsvWriter will automatically generate a CSV file containing each hit. Warning: This is obviously - /// slow, so use this for debugging and monitoring but not inside the performance critical code paths. - - void Summarize(JObjectSummary& summary) const override { - summary.add(x, NAME_OF(x), "%d", "Pixel coordinates centered around 0,0"); - summary.add(y, NAME_OF(y), "%d", "Pixel coordinates centered around 0,0"); - summary.add(E, NAME_OF(E), "%f", "Energy loss in GeV"); - summary.add(t, NAME_OF(t), "%f", "Time in ms"); - } -}; - - diff --git a/src/examples/misc/JObjectDatamodel/F250Hit.h b/src/examples/misc/JObjectDatamodel/F250Hit.h deleted file mode 100644 index 2af235349..000000000 --- a/src/examples/misc/JObjectDatamodel/F250Hit.h +++ /dev/null @@ -1,41 +0,0 @@ - -// Copyright 2020, Jefferson Science Associates, LLC. -// Subject to the terms in the LICENSE file found in the top-level directory. - -#pragma once -#include -#include - -/// JObjects are plain-old data containers for inputs, intermediate results, and outputs. -/// They have member functions for introspection and maintaining associations with other JObjects, but -/// all of the numerical code which goes into their creation should live in a JFactory instead. -/// You are allowed to include STL containers and pointers to non-POD datatypes inside your JObjects, -/// however, it is highly encouraged to keep them flat and include only primitive datatypes if possible. -/// Think of a JObject as being a row in a database table, with event number as an implicit foreign key. - -struct F250Hit : public JObject { - - JOBJECT_PUBLIC(F250Hit) - - uint32_t crate; - uint32_t slot; - uint32_t channel; - uint32_t E; - uint32_t t; - - - /// Override Summarize to tell JANA how to produce a convenient string representation for our JObject. - /// This can be used called from user code, but also lets JANA automatically inspect its own data. For instance, - /// adding JCsvWriter will automatically generate a CSV file containing each hit. Warning: This is obviously - /// slow, so use this for debugging and monitoring but not inside the performance critical code paths. - - void Summarize(JObjectSummary& summary) const override { - summary.add(crate, NAME_OF(crate), "%f"); - summary.add(slot, NAME_OF(slot), "%f"); - summary.add(channel, NAME_OF(channel), "%f"); - summary.add(E, NAME_OF(E), "%f", "Energy in GeV"); - summary.add(t, NAME_OF(t), "%f", "Time in ms"); - } -}; - - diff --git a/src/examples/tutorial_with_lightweight_datamodel/01_datamodel/CMakeLists.txt b/src/examples/tutorial_with_lightweight_datamodel/01_datamodel/CMakeLists.txt index 499f09569..967de9812 100644 --- a/src/examples/tutorial_with_lightweight_datamodel/01_datamodel/CMakeLists.txt +++ b/src/examples/tutorial_with_lightweight_datamodel/01_datamodel/CMakeLists.txt @@ -3,13 +3,13 @@ add_library(lw_datamodel INTERFACE) target_include_directories(lw_datamodel INTERFACE $ - $ + $ ) file(GLOB lw_datamodel_headers "*.h") install(FILES ${lw_datamodel_headers} - DESTINATION include/jana2_tutorial_lightweight/datamodel) + DESTINATION include/jana2_tutorial_lightweight/01_datamodel) install(TARGETS lw_datamodel EXPORT jana2_targets) diff --git a/src/examples/tutorial_with_lightweight_datamodel/02_random_hit_source/CMakeLists.txt b/src/examples/tutorial_with_lightweight_datamodel/02_random_hit_source/CMakeLists.txt index fc08bc4be..55fd56983 100644 --- a/src/examples/tutorial_with_lightweight_datamodel/02_random_hit_source/CMakeLists.txt +++ b/src/examples/tutorial_with_lightweight_datamodel/02_random_hit_source/CMakeLists.txt @@ -1,7 +1,15 @@ +add_jana_library(lw_random_hit_source_common + SOURCES RandomHitSource.cc + PUBLIC_HEADER RandomHitSource.h +) +target_link_libraries(lw_random_hit_source_common PUBLIC lw_datamodel) -add_jana_plugin(lw_random_hit_source) -target_link_libraries(lw_random_hit_source PUBLIC lw_datamodel) +add_jana_plugin(lw_random_hit_source + SOURCES random_hit_source.cc +) +target_link_libraries(lw_random_hit_source PUBLIC lw_random_hit_source_common) add_test(NAME examples-lw-00-smoketest COMMAND jana -Pplugins=lw_random_hit_source -Pjana:nevents=10) + set_tests_properties(examples-lw-00-smoketest PROPERTIES LABELS "examples") diff --git a/src/examples/tutorial_with_lightweight_datamodel/05_csv_file_writer/CMakeLists.txt b/src/examples/tutorial_with_lightweight_datamodel/05_csv_file_writer/CMakeLists.txt index 8d66d1244..f42a991ef 100644 --- a/src/examples/tutorial_with_lightweight_datamodel/05_csv_file_writer/CMakeLists.txt +++ b/src/examples/tutorial_with_lightweight_datamodel/05_csv_file_writer/CMakeLists.txt @@ -1,7 +1,19 @@ -add_jana_plugin(lw_csv_file_writer) -target_link_libraries(lw_csv_file_writer PUBLIC lw_datamodel) +add_jana_library(lw_csv_file_writer_common + SOURCES CsvWriter.cc + PUBLIC_HEADER CsvWriter.h +) + +target_link_libraries(lw_csv_file_writer_common PUBLIC lw_datamodel) + +add_jana_plugin(lw_csv_file_writer + SOURCES csv_file_writer_plugin.cc +) + +target_link_libraries(lw_csv_file_writer PUBLIC lw_csv_file_writer_common) add_test(NAME examples-lw-05-smoketest COMMAND jana -Pplugins=lw_random_hit_source,lw_csv_file_writer -Pjana:nevents=10) set_tests_properties(examples-lw-05-smoketest PROPERTIES LABELS "examples") + + diff --git a/src/examples/tutorial_with_lightweight_datamodel/05_csv_file_writer/plugin.cc b/src/examples/tutorial_with_lightweight_datamodel/05_csv_file_writer/csv_file_writer_plugin.cc similarity index 100% rename from src/examples/tutorial_with_lightweight_datamodel/05_csv_file_writer/plugin.cc rename to src/examples/tutorial_with_lightweight_datamodel/05_csv_file_writer/csv_file_writer_plugin.cc diff --git a/src/examples/tutorial_with_lightweight_datamodel/19_wrapper_program/CMakeLists.txt b/src/examples/tutorial_with_lightweight_datamodel/19_wrapper_program/CMakeLists.txt index bd4d3147d..ac74de407 100644 --- a/src/examples/tutorial_with_lightweight_datamodel/19_wrapper_program/CMakeLists.txt +++ b/src/examples/tutorial_with_lightweight_datamodel/19_wrapper_program/CMakeLists.txt @@ -1,2 +1,13 @@ -#add_jana_executable(lw-wrapper-program) +add_executable(lw-tutorial-recon tutorial_recon_main.cc) + +target_link_libraries(lw-tutorial-recon PRIVATE + jana2_shared_lib + lw_protocluster_common + lw_random_hit_source_common + lw_ascii_heatmap_writer_common +) +# Note that if you are outside the JANA2 source tree, you need to target_link_libraries against JANA::jana2_shared_lib instead + +install(TARGETS lw-tutorial-recon DESTINATION bin) + diff --git a/src/examples/tutorial_with_lightweight_datamodel/19_wrapper_program/tutorial_recon_main.cc b/src/examples/tutorial_with_lightweight_datamodel/19_wrapper_program/tutorial_recon_main.cc new file mode 100644 index 000000000..b3faae6a8 --- /dev/null +++ b/src/examples/tutorial_with_lightweight_datamodel/19_wrapper_program/tutorial_recon_main.cc @@ -0,0 +1,44 @@ + +#include + +#include +#include +#include +#include + +#include +#include +#include + + +int main(int argc, char* argv[]) { + + std::cout << "Welcome to lw-tutorial-recon" << std::endl; + + auto options = jana::ParseCommandLineOptions(argc, argv); + auto params = new JParameterManager(); + + for(auto pair: options.params) { + params->SetParameter(pair.first, pair.second); + } + // Instantiate the JApplication with the parameter manager + JApplication app(params); + + // Add the event source filenames from command line + for(auto event_source : options.eventSources) { + app.Add(event_source); + } + + // Register components + app.Add(new JEventSourceGeneratorT()); + app.Add(new JFactoryGeneratorT()); + app.Add(new AsciiHeatmap_writer); + + // Initialize and run the application + app.Initialize(); + app.Run(); + + // Retrieve and return the exit code + return app.GetExitCode(); +} + diff --git a/src/examples/tutorial_with_lightweight_datamodel/CMakeLists.txt b/src/examples/tutorial_with_lightweight_datamodel/CMakeLists.txt index b841ad125..40072c78a 100644 --- a/src/examples/tutorial_with_lightweight_datamodel/CMakeLists.txt +++ b/src/examples/tutorial_with_lightweight_datamodel/CMakeLists.txt @@ -1,4 +1,6 @@ +set(INSTALL_NAMESPACE jana2_tutorial_lightweight) + add_subdirectory(01_datamodel) add_subdirectory(02_random_hit_source) add_subdirectory(03_protocluster_factory) @@ -20,4 +22,4 @@ add_subdirectory(18_subevent_splitter_merger_cuda) add_subdirectory(19_wrapper_program) add_subdirectory(20_streaming_actor) - +set(INSTALL_NAMESPACE JANA)