From 0107dd3cce20f96dbbd1d6f04da22d62ef75a31f Mon Sep 17 00:00:00 2001 From: raiqarasool Date: Fri, 16 Aug 2024 15:15:10 -0400 Subject: [PATCH 1/7] Added Doc Mentioning Syntax Changes betweeen JANA1 and JANA2 --- docs/syntaxChangesJANA1ToJANA2.md | 759 ++++++++++++++++++++++++++++++ 1 file changed, 759 insertions(+) create mode 100644 docs/syntaxChangesJANA1ToJANA2.md diff --git a/docs/syntaxChangesJANA1ToJANA2.md b/docs/syntaxChangesJANA1ToJANA2.md new file mode 100644 index 000000000..b29f04c62 --- /dev/null +++ b/docs/syntaxChangesJANA1ToJANA2.md @@ -0,0 +1,759 @@ + +**** +## Common Functions + +### JANA Namespace +##### **JANA1** +Adding following on top of all files was necessary in JANA1 + +``` +using namespace jana; +``` +##### **JANA2** +No more required to add that line in JANA2 + +### Application +#### Getting application +##### **JANA1** +There was just a japp that could be used directly, am I right?? +##### **JANA2** +###### _Within a particular context_ +``` +// Figure out what context, don't know yet ?? +auto app = GetApplication(); +``` +###### _Out of that particular context, you can get it from event_, don't know which?? +``` +auto app = locEvent->GetJApplication(); +``` +### Parameters +#### Setting Parameter +##### **JANA1** +``` +gPARMS->GetParameter("OUTPUT_FILENAME", dOutputFileName); +``` +##### **JANA2** +###### _Inside Init_ ????? Is this right? +``` +auto app = GetApplication(); +app->SetDefaultParameter("OUTPUT_FILENAME", dOutputFileName); +``` +###### _Inside Constructor_ ??? +``` +japp->SetDefaultParameter(locFullParamName, locKeyValue); +``` +#### Getting Parameter +##### **JANA1** +``` +//gets all parameters with this filter at the beginning of the key +gPARMS->GetParameters(locParameterMap, "COMBO_DEDXCUT:"); +``` +##### **JANA2** +###### _Inside Constructor_ ??? Is this right?? +``` +//gets all parameters with this filter at the beginning of the key +japp->GetJParameterManager()->FilterParameters(locParameterMap, "COMBO_DEDXCUT:"); +``` + +### DApplication +#### Getting DApplication +##### **JANA1** + +``` +#include "DANA/DApplication.h" +dApplication = dynamic_cast(locEventLoop->GetJApplication +``` + +##### **JANA2** +There is no DApplication anymore in JANA2 + +### DGeometry +#### Getting DGeometry +##### **JANA1** +###### Using japp +``` +#include "DANA/DApplication.h" +#include "HDGEOMETRY/DGeometry.h" + +DApplication* dapp=dynamic_cast(japp); +const DGeometry *dgeom = dapp->GetDGeometry(runnumber); +``` +###### Using eventLoop +``` +#include "DANA/DApplication.h" +#include "HDGEOMETRY/DGeometry.h" + +dApplication = dynamic_cast(eventLoop->GetJApplication +DGeometry *locGeom = dApplication ? dApplication->GetDGeometry(eventLoop->GetJEvent().GetRunNumber()) : NULL; + +``` +##### **JANA2** +###### Using japp +``` +#include "HDGEOMETRY/DGeometry.h" + +auto dgeoman = japp->GetService(); +const DGeometry *dgeom = dgeoman->GetDGeometry(event->GetRunNumber()); +``` +###### Using DEvent +``` +#include "DANA/DEvent.h" +#include "HDGEOMETRY/DGeometry.h" + +DGeometry *locGeometry = DEvent::GetDGeometry(locEvent); +``` +###### Using app +``` +#include "HDGEOMETRY/DGeometry.h" + +auto runnumber = event->GetRunNumber(); +auto app = event->GetJApplication(); +auto geo_manager = app->GetService(); +auto geom = geo_manager->GetDGeometry(runnumber); +``` + +### Calibration +#### GetCalib +##### **JANA1** +``` +locEventLoop->GetCalib(locTOFParmsTable.c_str(), tofparms); +``` +##### **JANA2** +###### 1. Using DEvent +``` +#include "DANA/DEvent.h" + +DEvent::GetCalib(locEvent, locTOFParmsTable.c_str(), tofparms); +``` +###### 2. Using GetApplication +Requires you to be inside a particular context. What context exactly??? +``` +#include +#include + +auto event_number = event->GetEventNumber(); +auto run_number = event->GetRunNumber + +auto app = GetApplication(); + +auto calibration = app->GetService()->GetJCalibration(run_number); +calibration->Get("BCAL/mc_parms", bcalparms, event_number) + + +``` + +### Status Bit +#### GetStatusBit +##### **JANA1** +``` +locEventLoop->GetJEvent().GetStatusBit(kSTATUS_PHYSICS_EVENT) +``` +##### **JANA2** +``` +#include "DANA/DStatusBits.h" + + +locEvent->GetSingle()->GetStatusBit(kSTATUS_PHYSICS_EVENT) + +// or + +locEvent->GetSingleStrict()->GetStatusBit(kSTATUS_REST); +``` + +### BField +#### GetBField +##### **JANA1** +``` +#include "DANA/DApplication.h" + +dApplication = dynamic_cast(locEventLoop->GetJApplication +dMagFMap= dApplication->GetBfield(locEventLoop->GetJEvent().GetRunNumber()); + +``` +##### **JANA2** +``` +#include "DANA/DEvent.h" + +dMagneticFieldMap = DEvent::GetBfield(locEvent); +``` + + + +## Modified Gets + +### JObject +#### 1. GetSingleT +##### **JANA1** +``` +Was present in JANA1 +``` +##### **JANA2** +``` +No more available in JANA2, use GetSingle instead +``` +#### 2. Get Single +##### **JANA1** +``` +// Pass by reference +// Set passed param equal to pointer to object +const Df250PulsePedestal* PPobj = NULL; +digihit->GetSingle(PPobj); +``` +##### **JANA2** +``` +// Template function +// Return pointer to object +auto PPobj = digihit->GetSingle(); +``` +#### 3. Get +##### **JANA1** +``` +// Pass by Reference +vector assoc_hits; +point.Get(assoc_hits); +``` +##### **JANA2** +``` +// Templated Function +// Return value +vector assoc_hits = point.Get(); +``` + +### JEvent +#### 1. GetSingle +##### **JANA1** +``` +// Pass by Reference, +// passed param got assigned pointer to object + +const DTTabUtilities* locTTabUtilities = NULL; +loop->GetSingle(locTTabUtilities); +``` +##### **JANA2** +``` +// Return the pointer to object based on template type + +const DTTabUtilities* locTTabUtilities = event->GetSingle(); +``` +#### 2. Get +##### **JANA1** +``` +// Pass by Reference +vector showers; +loop->Get(showers, "IU"); +``` +##### **JANA2** +``` +// JANA1 Get is still available but will be deprecated soon +// So better to use the one given below + +// Templated function +// Return value +auto showers = event->Get("IU"); +``` + +## JEventProcessor +### Child JEventProcessor Basic Header File +##### JANA1 +``` + + +#ifndef _JEventProcessor_myplugin_ +#define _JEventProcessor_myplugin_ + +#include +#include +#include +using namespace jana; + + +class JEventProcessor_myplugin:public jana::JEventProcessor{ +public: + JEventProcessor_myplugin(); + ~JEventProcessor_myplugin(); + const char* className(void){return "JEventProcessor_myplugin";} + +private: + jerror_t init(void); + jerror_t brun(jana::JEventLoop *eventLoop, int32_t runnumber); + jerror_t evnt(jana::JEventLoop *eventLoop, uint64_t eventnumber); + jerror_t erun(void); + jerror_t fini(void); + +}; + +#endif // _JEventProcessor_myplugin_ +``` +##### JANA2 +``` + +#ifndef _JEventProcessor_secondTest_ +#define _JEventProcessor_secondTest_ +#include + +class JEventProcessor_secondTest:public JEventProcessor{ + +public: + JEventProcessor_secondTest(); + ~JEventProcessor_secondTest(); + const char* className(void){return "JEventProcessor_secondTest";} + + + +private: + + void Init() override; + void BeginRun(const std::shared_ptr& event) override; + void Process(const std::shared_ptr& event) override; + void EndRun() override; + void Finish() override; +}; + + + +#endif // _JEventProcessor_secondTest_ +``` + + +## JObject +### Child JObject Basic Header File +##### JANA1 +``` +#include +#include // No more required in JANA2 + +using namespace jana; // No more required in JANA2 + +class DCereHit: public JObject { + +public: + +JOBJECT_PUBLIC (DCereHit); +int sector; +float pe; +float t; + +//Changed to Summarize in JANA2 +void toStrings(vector >&items) const { +AddString(items, "sector", "%d", sector); +AddString(items, "pe", "%1.3f", pe); +AddString(items, "t", "%1.3f", t); +} + +}; +``` +##### JANA2 +``` +#include + +class DCereHit: public JObject { + +public: + +JOBJECT_PUBLIC (DCereHit); +int sector; +float pe; +float t; + +// This function was called toStrings in JANA1 +void Summarize(JObjectSummary& summary) const override { +summary.add(sector, "sector", "%d"); +summary.add(pe, "pe", "%1.3f"); +summary.add(t, "t", "%1.3f"); +} + +}; +``` +### id +##### **JANA1** +``` +// JANA1 JObject had a data member id + +DBCALShower *shower = new DBCALShower; +shower->id = id++; +``` +##### **JANA2** +``` +// id data member does not exist in JObject anymore in JANA2 + +DBCALShower *shower = new DBCALShower; +shower->id = id++; // Throw Error: no id member +``` +### oid_t +##### **JANA1** +``` +JObject::oid_t +``` +##### **JANA2** +``` +#include "DANA/DObjectID.h" + +oid_t //Not inside JObject anymore? +``` + + +## JFactory + + +### JFactory to JFactoryT +##### **JANA1** +``` +Was existing and getting used in JANA1, write what for +``` + +##### **JANA2** +``` +Now JFactoryT is getting used everywhere instead of JFactory, I think but not sure if their functionality is same. Write how it is same and different from previous one? Also apparently JFactory still exist in JANA2 why so? and how is it different compared to one in JANA1? +``` + +### Child Factory Basic Header File +##### JANA1 +``` +#ifndef _myfactory_factory_ +#define _myfactory_factory_ + +#include +#include "myfactory.h" + +class myfactory_factory:public jana::JFactory{ + +public: +myfactory_factory(){}; +~myfactory_factory(){}; + +private: + +jerror_t init(void); +jerror_t brun(jana::JEventLoop *eventLoop, int32_t runnumber); +jerror_t evnt(jana::JEventLoop *eventLoop, uint64_t eventnumber); +jerror_t erun(void); +jerror_t fini(void); + +}; + +#endif +``` +##### JANA2 +``` +#ifndef _thirdFacTest_factory_ +#define _thirdFacTest_factory_ + +#include +#include "thirdFacTest.h" + +class thirdFacTest_factory:public JFactoryT{ +public: +thirdFacTest_factory(){ +SetTag(""); +} +~thirdFacTest_factory(){} + + +private: +void Init() override; +void BeginRun(const std::shared_ptr& event) override; +void Process(const std::shared_ptr& event) override; +void EndRun() override; +void Finish() override; + +}; + +#endif +``` +### Registering a New Factory + +This section require some explanation like how factory was getting added before and how it is now with complete explanation +##### **JANA1** +###### Using EventLoop +``` +jerror_t BCAL_init(JEventLoop *loop) +{ +/// Create and register BCAL data factories +loop->AddFactory(new JFactory()); +loop->AddFactory(new JFactory()); +loop->AddFactory(new DBCALHit_factory()); + +} +``` +###### Using Factory Generator +``` +#include "myfactory_factory.h" +#include "JFactoryGenerator_myfactory.h" +#include +using namespace jana; + + + +extern "C"{ + void InitPlugin(JApplication *app){ + InitJANAPlugin(app); + app->AddFactoryGenerator(new JFactoryGenerator_myfactory()); + } +} // "C" +``` +##### **JANA2** +###### Using Factory Set +``` +#include +#include + +void BCAL_init(JFactorySet *factorySet) + +{ + +/// Create and register BCAL data factories +factorySet->Add(new JGetObjectsFactory()); +factorySet->Add(new JGetObjectsFactory()); +factorySet->Add(new DBCALHit_factory()); + +} +``` +###### Using Factory Generator +``` +#include "thirdFacTest_factory.h" +#include +#include + +extern "C"{ + void InitPlugin(JApplication *app){ + InitJANAPlugin(app); + app->Add(new JFactoryGeneratorT()); + } +} // "C" +``` + +### Getting All factories +##### **JANA1** +``` +vector locFactories = locEventLoop->GetFactories(); +//JFactory_base to particular factory type +JFactory* locFactory = dynamic_cast*>(locFactories[0]); +``` +##### **JANA2** +``` +// Directly give particular factory type +vector*> locFacs = locEvent->GetFactoryAll(); +``` + +### Saving Created Object(s) to Factory +##### _Single Object_ +###### **JANA1** +``` +_data.push_back(locAnalysisResults); +``` +###### **JANA2** +``` +Insert(locAnalysisResults); +``` + +##### _Array of Objects_ +``` +std::vector results; +results.push_back(new fac1(...)); +``` +###### **JANA1** +``` +for (auto obj: results){ + _data.push_back(obj); +} +``` +###### **JANA2** +``` +Set(results) +``` + +### Getting Created Objects from Factory +##### **JANA1** +``` +vector locReactionsSubset; +locFactory->Get(locReactionsSubset); +locReactions.insert(locReactions.end(), locReactionsSubset.begin(), locReactionsSubset.end()); +``` +##### **JANA2** +``` +vector locReactionsSubset; +auto iters = locFactory->GetOrCreate(locEvent, locEvent->GetJApplication(), locEvent->GetRunNumber()); +locReactions.insert(locReactions.end(), iters.first, iters.second); +``` + +### Factory Tag +#### 1. SetTag +##### **JANA1** +``` +//Inside factory class definition this was required to be added +const char* Tag(void){return "Combo";} +``` +##### **JANA2** +``` +// Have to set inside factory constructor now +DChargedTrack_factory_Combo(){ + SetTag("Combo"); +} +``` +#### 2. GetTag +##### **JANA1** +``` +locFactory->Tag() +``` +##### **JANA2** +``` +locFactory->GetTag() +``` + + +### Factory ObjectName +#### 1. SetObjectName + +##### **JANA1** +``` +// Was not present in JANA1 + +DReaction_factory_Thrown(){ +//prevents JANA from searching the input file for these objects +use_factory = 1; +} +``` +##### **JANA2** +``` +// Present in JANA2 and is set inside constructor. Write what it mainly do? + +DReaction_factory_Thrown(){ +SetObjectName("DReaction"); +SetTag("Thrown"); +} +``` + + +## JEvent +### JEventLoop to JEvent +##### **JANA1** +``` +JEventLoop is JANA1 thing, write what it was doing mainly +#include -- you have to import this header file in factory and where else? +``` +##### **JANA2** +``` +JANA2 has replaced JEventLoop with JEvent, + +#include --- you have to import it in factory, need to include anywhere else too?? + +write how it is different that JEventLoop? I think mainly now factoryies are inside factory set instead of having them inside JEvent as it was for JEventLoop. +``` +### Getting Run Number +##### **JANA1** +``` +run_number = locEventLoop->GetJEvent().GetRunNumber()); +``` +##### **JANA2** +``` +locEvent->GetRunNumber() +``` +#### Getting Event Number +##### **JANA1** +``` +run_number = locEventLoop->GetJEvent().GetEventNumber()); +``` +##### **JANA2** +``` +locEvent->GetEventNumber() +``` + + +## Acquiring Locks +### Pre Steps +##### **JANA1** +``` +#include "DANA/DApplication.h" + + +dApplication = dynamic_cast(locEventLoop->GetJApplication +``` +##### **JANA2** +``` +#include + + +auto app = locEvent->GetJApplication(); +jLockService = app->GetService(); +// or +jLockService = japp->GetService() +``` +### Locks +#### 1. ReadLock + +##### **JANA1** +``` +dActionLock = japp->ReadLock(locLockName); +pthread_rwlock_unlock(dActionLock); //unlock +``` +##### **JANA2** +``` +dActionLock = app->GetService()->ReadLock(locLockName); +pthread_rwlock_unlock(dActionLock); //unlock +``` + +#### 2. WriteLock + +##### **JANA1** +``` +japp->WriteLock("DAnalysisResults +japp->Unlock("DAnalysisResults"); +``` +##### **JANA2** +``` +jLockService->WriteLock("DAnalysisResults"); +jLockService->Unlock("DAnalysisResults"); +``` + +#### 3.RootWriteLock + +##### **JANA1** +``` +dApplication->RootWriteLock(); //lock +dApplication->RootUnLock(); //unlock +``` +##### **JANA2** +###### Using JLockService +``` +jLockService->RootWriteLock(); //lock +jLockService->RootUnLock(); //unlock +``` +###### Using DEvent +``` +#include "DANA/DEvent.h" +DEvent::GetLockService(locEvent)->RootWriteLock(); +DEvent::GetLockService(locEvent)->RootUnLock(); +``` + +## Rarely used +### use_factory +##### **JANA1** +``` +Could be used in JANA1 + + +//prevents JANA from searching the input file for these objects +DEventWriterROOT_factory(){use_factory = 1;}; +``` +##### **JANA2** +``` +No more available in JANA2, how is the functionality that it was providing is getting used? +DEventWriterROOT_factory() = default; +``` +### Unknown Enum +##### **JANA1** +``` +//Was a plain enum so could be accessed without any scope resolution operator + +#include "particleType.h" + +return ((locFirstStep->Get_TargetPID() != Unknown) || (locFirstStep->Get_SecondBeamPID() != Unknown)); +``` +##### **JANA2** +``` +// Is Enum class now so could be accessed like this `Particle_t::Unknown` only + +#include "particleType.h" + +return ((locFirstStep->Get_TargetPID() != Particle_t::Unknown) || (locFirstStep->Get_SecondBeamPID() != Particle_t::Unknown)); +``` From c942ea8450a99fe0b99d2fa412fd1a2888e72f1a Mon Sep 17 00:00:00 2001 From: Nathan Brei Date: Mon, 19 Aug 2024 16:28:05 -0400 Subject: [PATCH 2/7] Edited 2/3 of the document --- docs/syntaxChangesJANA1ToJANA2.md | 239 +++++++++++++++--------------- 1 file changed, 123 insertions(+), 116 deletions(-) diff --git a/docs/syntaxChangesJANA1ToJANA2.md b/docs/syntaxChangesJANA1ToJANA2.md index b29f04c62..7f4de11cd 100644 --- a/docs/syntaxChangesJANA1ToJANA2.md +++ b/docs/syntaxChangesJANA1ToJANA2.md @@ -4,55 +4,72 @@ ### JANA Namespace ##### **JANA1** -Adding following on top of all files was necessary in JANA1 +Adding following on top of all files was necessary in JANA1: ``` using namespace jana; ``` ##### **JANA2** -No more required to add that line in JANA2 +This line is no longer required in JANA2. ### Application -#### Getting application +#### Getting the JApplication ##### **JANA1** -There was just a japp that could be used directly, am I right?? +In JANA1 there is a global variable `japp` which is a pointer to the project's `JApplication`. You can also obtain it from `JEventLoop::GetJApplication()`. ##### **JANA2** -###### _Within a particular context_ +In JANA2, `japp` is still around but we are strongly discouraging its future use. If you are within any JANA component (for instance: JFactory, JEventProcessor, JEventSource, JService) you can obtain the `JApplication` pointer from `this`, like so: ``` -// Figure out what context, don't know yet ?? auto app = GetApplication(); ``` -###### _Out of that particular context, you can get it from event_, don't know which?? -``` -auto app = locEvent->GetJApplication(); + +You can also obtain it from the `JEvent` the same way as you used to from `JEventLoop`, i.e. +```c++ +auto app = event->GetJApplication(); ``` + + ### Parameters -#### Setting Parameter +#### Setting Parameters ##### **JANA1** ``` gPARMS->GetParameter("OUTPUT_FILENAME", dOutputFileName); ``` ##### **JANA2** -###### _Inside Init_ ????? Is this right? + +You should obtain parameters as shown below. + ``` auto app = GetApplication(); -app->SetDefaultParameter("OUTPUT_FILENAME", dOutputFileName); -``` -###### _Inside Constructor_ ??? -``` -japp->SetDefaultParameter(locFullParamName, locKeyValue); +app->SetDefaultParameter("component_prefix:value_name", ref_to_member_var); ``` -#### Getting Parameter + +We strongly recommend you register all parameters from inside the `Init()` callbacks of your JANA components, or from `InitPlugin()`. This helps JANA: + +- Report back which parameters are available without having to process an input file. +- Emit a warning (or error!) when a user-provided parameter is misspelled +- Emit a warning when two plugins register the same parameter with conflicting default values. +- Inspect the exact parameter values used by a factory + +If you register parameters in other contexts, this machinery might not work and you might get incomplete parameter lists and missing or spurious error messages. Worse, your code might not see the parameter values you expect it to see. Registering parameters from inside component constructors is less problematic but still discouraged because it won't work with some upcoming new features. + + +#### Getting parameter maps ##### **JANA1** + +To obtain a map of all parameters that share a common prefix: + ``` //gets all parameters with this filter at the beginning of the key gPARMS->GetParameters(locParameterMap, "COMBO_DEDXCUT:"); ``` ##### **JANA2** -###### _Inside Constructor_ ??? Is this right?? + +In JANA2 this has been renamed to `FilterParameters` but the functionality is the same. +Note that this method is not on `JApplication` directly; you have to obtain the parameter manager like so: + ``` //gets all parameters with this filter at the beginning of the key -japp->GetJParameterManager()->FilterParameters(locParameterMap, "COMBO_DEDXCUT:"); +GetApplication()->GetJParameterManager()->FilterParameters(locParameterMap, "COMBO_DEDXCUT:"); ``` ### DApplication @@ -65,7 +82,7 @@ dApplication = dynamic_cast(locEventLoop->GetJApplication ``` ##### **JANA2** -There is no DApplication anymore in JANA2 +There is no `DApplication` anymore in JANA2. `JApplication` is `final`, which means you can't inherit from it. The functionality on `DApplication` has been moved into `JService`s, which can be accessed via `JApplication::GetService()`. ### DGeometry #### Getting DGeometry @@ -83,34 +100,28 @@ const DGeometry *dgeom = dapp->GetDGeometry(runnumber); #include "DANA/DApplication.h" #include "HDGEOMETRY/DGeometry.h" -dApplication = dynamic_cast(eventLoop->GetJApplication DGeometry *locGeom = dApplication ? dApplication->GetDGeometry(eventLoop->GetJEvent().GetRunNumber()) : NULL; - ``` ##### **JANA2** -###### Using japp +In JANA2, you obtain the `DGeometryManager` from the `JApplication` and from there you use the run number to obtain the corresponding `DGeometry`: ``` #include "HDGEOMETRY/DGeometry.h" -auto dgeoman = japp->GetService(); -const DGeometry *dgeom = dgeoman->GetDGeometry(event->GetRunNumber()); +auto runnumber = event->GetRunNumber(); +auto app = event->GetJApplication(); +auto geo_manager = app->GetService(); +auto geom = geo_manager->GetDGeometry(runnumber); ``` -###### Using DEvent + +To reduce the boilerplate, we've provided a handy helper function, `DEvent::GetDGeometry()`, that does all of these steps for you: + ``` #include "DANA/DEvent.h" -#include "HDGEOMETRY/DGeometry.h" DGeometry *locGeometry = DEvent::GetDGeometry(locEvent); ``` -###### Using app -``` -#include "HDGEOMETRY/DGeometry.h" -auto runnumber = event->GetRunNumber(); -auto app = event->GetJApplication(); -auto geo_manager = app->GetService(); -auto geom = geo_manager->GetDGeometry(runnumber); -``` +You should call `GetDGeometry` from `JFactory::BeginRun` or `JEventProcessor::BeginRun`. ### Calibration #### GetCalib @@ -119,23 +130,25 @@ auto geom = geo_manager->GetDGeometry(runnumber); locEventLoop->GetCalib(locTOFParmsTable.c_str(), tofparms); ``` ##### **JANA2** -###### 1. Using DEvent + +Analogously to `DGeometry`, you obtain the calibrations by obtaining the `JCalibrationManager` from `JApplication::GetService<>()` and then loading the calibration object corresponding to the event's run number. We recommend you use `DEvent::GetCalib` to avoid this boilerplate. You should call this from your `BeginRun` callback. + ``` #include "DANA/DEvent.h" -DEvent::GetCalib(locEvent, locTOFParmsTable.c_str(), tofparms); +DEvent::GetCalib(event, locTOFParmsTable.c_str(), tofparms); ``` -###### 2. Using GetApplication -Requires you to be inside a particular context. What context exactly??? + +In principle, the calibrations could also be keyed off of event number intervals, in which case you should call it from `Process` and pass the event number as well: + ``` #include #include auto event_number = event->GetEventNumber(); -auto run_number = event->GetRunNumber +auto run_number = event->GetRunNumber(); auto app = GetApplication(); - auto calibration = app->GetService()->GetJCalibration(run_number); calibration->Get("BCAL/mc_parms", bcalparms, event_number) @@ -149,13 +162,16 @@ calibration->Get("BCAL/mc_parms", bcalparms, event_number) locEventLoop->GetJEvent().GetStatusBit(kSTATUS_PHYSICS_EVENT) ``` ##### **JANA2** + +Status bits are no longer an event member variable. Instead, they are inserted and retrieved just like the other collections: + ``` #include "DANA/DStatusBits.h" locEvent->GetSingle()->GetStatusBit(kSTATUS_PHYSICS_EVENT) -// or +// or, for a little bit more safety: locEvent->GetSingleStrict()->GetStatusBit(kSTATUS_REST); ``` @@ -166,11 +182,15 @@ locEvent->GetSingleStrict()->GetStatusBit(kSTATUS_REST); ``` #include "DANA/DApplication.h" -dApplication = dynamic_cast(locEventLoop->GetJApplication +dApplication = dynamic_cast(locEventLoop->GetJApplication()); dMagFMap= dApplication->GetBfield(locEventLoop->GetJEvent().GetRunNumber()); ``` ##### **JANA2** + +In JANA2, the magnetic field map is a resource handled analogously to `DGeometry` and `JCalibrationManager`. Thus, we recommend obtaining the +field map by calling `DEvent::GetBField(event)` from inside `BeginRun`: + ``` #include "DANA/DEvent.h" @@ -179,7 +199,7 @@ dMagneticFieldMap = DEvent::GetBfield(locEvent); -## Modified Gets +## Modified Getters ### JObject #### 1. GetSingleT @@ -189,9 +209,9 @@ Was present in JANA1 ``` ##### **JANA2** ``` -No more available in JANA2, use GetSingle instead +No longer available in JANA2; use GetSingle() instead ``` -#### 2. Get Single +#### 2. GetSingle ##### **JANA1** ``` // Pass by reference @@ -291,17 +311,15 @@ private: #define _JEventProcessor_secondTest_ #include -class JEventProcessor_secondTest:public JEventProcessor{ +class JEventProcessor_secondTest : public JEventProcessor { public: - JEventProcessor_secondTest(); - ~JEventProcessor_secondTest(); - const char* className(void){return "JEventProcessor_secondTest";} - - + JEventProcessor_secondTest() { + SetTypeName(NAME_OF_THIS); + } + ~JEventProcessor_secondTest() = default; private: - void Init() override; void BeginRun(const std::shared_ptr& event) override; void Process(const std::shared_ptr& event) override; @@ -309,37 +327,32 @@ private: void Finish() override; }; - - #endif // _JEventProcessor_secondTest_ ``` ## JObject -### Child JObject Basic Header File +### JObject Header File ##### JANA1 ``` #include -#include // No more required in JANA2 +#include -using namespace jana; // No more required in JANA2 +using namespace jana; class DCereHit: public JObject { - public: -JOBJECT_PUBLIC (DCereHit); -int sector; -float pe; -float t; - -//Changed to Summarize in JANA2 -void toStrings(vector >&items) const { -AddString(items, "sector", "%d", sector); -AddString(items, "pe", "%1.3f", pe); -AddString(items, "t", "%1.3f", t); -} + JOBJECT_PUBLIC(DCereHit); + int sector; + float pe; + float t; + void toStrings(vector >&items) const { + AddString(items, "sector", "%d", sector); + AddString(items, "pe", "%1.3f", pe); + AddString(items, "t", "%1.3f", t); + } }; ``` ##### JANA2 @@ -347,21 +360,18 @@ AddString(items, "t", "%1.3f", t); #include class DCereHit: public JObject { - public: -JOBJECT_PUBLIC (DCereHit); -int sector; -float pe; -float t; - -// This function was called toStrings in JANA1 -void Summarize(JObjectSummary& summary) const override { -summary.add(sector, "sector", "%d"); -summary.add(pe, "pe", "%1.3f"); -summary.add(t, "t", "%1.3f"); -} + JOBJECT_PUBLIC(DCereHit); + int sector; + float pe; + float t; + void Summarize(JObjectSummary& summary) const override { + summary.add(sector, "sector", "%d"); + summary.add(pe, "pe", "%1.3f"); + summary.add(t, "t", "%1.3f"); + } }; ``` ### id @@ -373,22 +383,23 @@ DBCALShower *shower = new DBCALShower; shower->id = id++; ``` ##### **JANA2** + + +JANA2 no longer provides a built-in object id. However, you can always add one as a field to your `JObject` and set it yourself. + ``` // id data member does not exist in JObject anymore in JANA2 DBCALShower *shower = new DBCALShower; shower->id = id++; // Throw Error: no id member ``` -### oid_t -##### **JANA1** -``` -JObject::oid_t -``` -##### **JANA2** + +Similarly, the `JObject::oid_t` type has been removed from JANA2 as well. If you need it, it lives on in the halld_recon codebase: + ``` #include "DANA/DObjectID.h" -oid_t //Not inside JObject anymore? +oid_t // Not inside JObject anymore! ``` @@ -398,37 +409,35 @@ oid_t //Not inside JObject anymore? ### JFactory to JFactoryT ##### **JANA1** ``` -Was existing and getting used in JANA1, write what for +In JANA1, `JFactory_base` was a common factory base class, and `JFactory` was a template that inherits from `JFactory_base` and adds functionality specific to the type of the factory's output collection. ``` ##### **JANA2** ``` -Now JFactoryT is getting used everywhere instead of JFactory, I think but not sure if their functionality is same. Write how it is same and different from previous one? Also apparently JFactory still exist in JANA2 why so? and how is it different compared to one in JANA1? +In JANA2, the base class was renamed to `JFactory`, and the template was renamed to `JFactoryT`. JANA2 adds some new functionality, but the old functionality is largely consistent with JANA1. One important difference is that in JANA1, there is always one factory set assigned to each thread, whereas in JANA2, there is one factory set for each event in flight. The number of in-flight events is a parameter controlled separately from the thread count. ``` -### Child Factory Basic Header File +### Factory header file ##### JANA1 ``` #ifndef _myfactory_factory_ #define _myfactory_factory_ #include -#include "myfactory.h" +#include "myobject.h" -class myfactory_factory:public jana::JFactory{ +class myfactory_factory : public jana::JFactory { public: -myfactory_factory(){}; -~myfactory_factory(){}; + myfactory_factory() = default; + ~myfactory_factory() = default; private: - -jerror_t init(void); -jerror_t brun(jana::JEventLoop *eventLoop, int32_t runnumber); -jerror_t evnt(jana::JEventLoop *eventLoop, uint64_t eventnumber); -jerror_t erun(void); -jerror_t fini(void); - + jerror_t init(void); + jerror_t brun(jana::JEventLoop *eventLoop, int32_t runnumber); + jerror_t evnt(jana::JEventLoop *eventLoop, uint64_t eventnumber); + jerror_t erun(void); + jerror_t fini(void); }; #endif @@ -439,23 +448,21 @@ jerror_t fini(void); #define _thirdFacTest_factory_ #include -#include "thirdFacTest.h" +#include "myobject.h" -class thirdFacTest_factory:public JFactoryT{ +class thirdFacTest_factory : public JFactoryT { public: -thirdFacTest_factory(){ -SetTag(""); -} -~thirdFacTest_factory(){} - + thirdFacTest_factory() { + SetTag("MyTag"); + } + ~thirdFacTest_factory() = default; private: -void Init() override; -void BeginRun(const std::shared_ptr& event) override; -void Process(const std::shared_ptr& event) override; -void EndRun() override; -void Finish() override; - + void Init() override; + void BeginRun(const std::shared_ptr& event) override; + void Process(const std::shared_ptr& event) override; + void EndRun() override; + void Finish() override; }; #endif From 93187f8c683f02864f60735d5c11ab4ba691c2d2 Mon Sep 17 00:00:00 2001 From: raiqarasool Date: Sun, 1 Sep 2024 21:58:19 -0400 Subject: [PATCH 3/7] Divided Syntax Changes Doc to Parameter and Developer guide --- docs/developers-transition-guide.md | 766 ++++++++++++++++++++++++ docs/parameter-changes-guide.md | 25 + docs/transition-guide-jana1-to-jana2.md | 16 + 3 files changed, 807 insertions(+) create mode 100644 docs/developers-transition-guide.md create mode 100644 docs/parameter-changes-guide.md create mode 100644 docs/transition-guide-jana1-to-jana2.md diff --git a/docs/developers-transition-guide.md b/docs/developers-transition-guide.md new file mode 100644 index 000000000..7f4de11cd --- /dev/null +++ b/docs/developers-transition-guide.md @@ -0,0 +1,766 @@ + +**** +## Common Functions + +### JANA Namespace +##### **JANA1** +Adding following on top of all files was necessary in JANA1: + +``` +using namespace jana; +``` +##### **JANA2** +This line is no longer required in JANA2. + +### Application +#### Getting the JApplication +##### **JANA1** +In JANA1 there is a global variable `japp` which is a pointer to the project's `JApplication`. You can also obtain it from `JEventLoop::GetJApplication()`. +##### **JANA2** +In JANA2, `japp` is still around but we are strongly discouraging its future use. If you are within any JANA component (for instance: JFactory, JEventProcessor, JEventSource, JService) you can obtain the `JApplication` pointer from `this`, like so: +``` +auto app = GetApplication(); +``` + +You can also obtain it from the `JEvent` the same way as you used to from `JEventLoop`, i.e. +```c++ +auto app = event->GetJApplication(); +``` + + +### Parameters +#### Setting Parameters +##### **JANA1** +``` +gPARMS->GetParameter("OUTPUT_FILENAME", dOutputFileName); +``` +##### **JANA2** + +You should obtain parameters as shown below. + +``` +auto app = GetApplication(); +app->SetDefaultParameter("component_prefix:value_name", ref_to_member_var); +``` + +We strongly recommend you register all parameters from inside the `Init()` callbacks of your JANA components, or from `InitPlugin()`. This helps JANA: + +- Report back which parameters are available without having to process an input file. +- Emit a warning (or error!) when a user-provided parameter is misspelled +- Emit a warning when two plugins register the same parameter with conflicting default values. +- Inspect the exact parameter values used by a factory + +If you register parameters in other contexts, this machinery might not work and you might get incomplete parameter lists and missing or spurious error messages. Worse, your code might not see the parameter values you expect it to see. Registering parameters from inside component constructors is less problematic but still discouraged because it won't work with some upcoming new features. + + +#### Getting parameter maps +##### **JANA1** + +To obtain a map of all parameters that share a common prefix: + +``` +//gets all parameters with this filter at the beginning of the key +gPARMS->GetParameters(locParameterMap, "COMBO_DEDXCUT:"); +``` +##### **JANA2** + +In JANA2 this has been renamed to `FilterParameters` but the functionality is the same. +Note that this method is not on `JApplication` directly; you have to obtain the parameter manager like so: + +``` +//gets all parameters with this filter at the beginning of the key +GetApplication()->GetJParameterManager()->FilterParameters(locParameterMap, "COMBO_DEDXCUT:"); +``` + +### DApplication +#### Getting DApplication +##### **JANA1** + +``` +#include "DANA/DApplication.h" +dApplication = dynamic_cast(locEventLoop->GetJApplication +``` + +##### **JANA2** +There is no `DApplication` anymore in JANA2. `JApplication` is `final`, which means you can't inherit from it. The functionality on `DApplication` has been moved into `JService`s, which can be accessed via `JApplication::GetService()`. + +### DGeometry +#### Getting DGeometry +##### **JANA1** +###### Using japp +``` +#include "DANA/DApplication.h" +#include "HDGEOMETRY/DGeometry.h" + +DApplication* dapp=dynamic_cast(japp); +const DGeometry *dgeom = dapp->GetDGeometry(runnumber); +``` +###### Using eventLoop +``` +#include "DANA/DApplication.h" +#include "HDGEOMETRY/DGeometry.h" + +DGeometry *locGeom = dApplication ? dApplication->GetDGeometry(eventLoop->GetJEvent().GetRunNumber()) : NULL; +``` +##### **JANA2** +In JANA2, you obtain the `DGeometryManager` from the `JApplication` and from there you use the run number to obtain the corresponding `DGeometry`: +``` +#include "HDGEOMETRY/DGeometry.h" + +auto runnumber = event->GetRunNumber(); +auto app = event->GetJApplication(); +auto geo_manager = app->GetService(); +auto geom = geo_manager->GetDGeometry(runnumber); +``` + +To reduce the boilerplate, we've provided a handy helper function, `DEvent::GetDGeometry()`, that does all of these steps for you: + +``` +#include "DANA/DEvent.h" + +DGeometry *locGeometry = DEvent::GetDGeometry(locEvent); +``` + +You should call `GetDGeometry` from `JFactory::BeginRun` or `JEventProcessor::BeginRun`. + +### Calibration +#### GetCalib +##### **JANA1** +``` +locEventLoop->GetCalib(locTOFParmsTable.c_str(), tofparms); +``` +##### **JANA2** + +Analogously to `DGeometry`, you obtain the calibrations by obtaining the `JCalibrationManager` from `JApplication::GetService<>()` and then loading the calibration object corresponding to the event's run number. We recommend you use `DEvent::GetCalib` to avoid this boilerplate. You should call this from your `BeginRun` callback. + +``` +#include "DANA/DEvent.h" + +DEvent::GetCalib(event, locTOFParmsTable.c_str(), tofparms); +``` + +In principle, the calibrations could also be keyed off of event number intervals, in which case you should call it from `Process` and pass the event number as well: + +``` +#include +#include + +auto event_number = event->GetEventNumber(); +auto run_number = event->GetRunNumber(); + +auto app = GetApplication(); +auto calibration = app->GetService()->GetJCalibration(run_number); +calibration->Get("BCAL/mc_parms", bcalparms, event_number) + + +``` + +### Status Bit +#### GetStatusBit +##### **JANA1** +``` +locEventLoop->GetJEvent().GetStatusBit(kSTATUS_PHYSICS_EVENT) +``` +##### **JANA2** + +Status bits are no longer an event member variable. Instead, they are inserted and retrieved just like the other collections: + +``` +#include "DANA/DStatusBits.h" + + +locEvent->GetSingle()->GetStatusBit(kSTATUS_PHYSICS_EVENT) + +// or, for a little bit more safety: + +locEvent->GetSingleStrict()->GetStatusBit(kSTATUS_REST); +``` + +### BField +#### GetBField +##### **JANA1** +``` +#include "DANA/DApplication.h" + +dApplication = dynamic_cast(locEventLoop->GetJApplication()); +dMagFMap= dApplication->GetBfield(locEventLoop->GetJEvent().GetRunNumber()); + +``` +##### **JANA2** + +In JANA2, the magnetic field map is a resource handled analogously to `DGeometry` and `JCalibrationManager`. Thus, we recommend obtaining the +field map by calling `DEvent::GetBField(event)` from inside `BeginRun`: + +``` +#include "DANA/DEvent.h" + +dMagneticFieldMap = DEvent::GetBfield(locEvent); +``` + + + +## Modified Getters + +### JObject +#### 1. GetSingleT +##### **JANA1** +``` +Was present in JANA1 +``` +##### **JANA2** +``` +No longer available in JANA2; use GetSingle() instead +``` +#### 2. GetSingle +##### **JANA1** +``` +// Pass by reference +// Set passed param equal to pointer to object +const Df250PulsePedestal* PPobj = NULL; +digihit->GetSingle(PPobj); +``` +##### **JANA2** +``` +// Template function +// Return pointer to object +auto PPobj = digihit->GetSingle(); +``` +#### 3. Get +##### **JANA1** +``` +// Pass by Reference +vector assoc_hits; +point.Get(assoc_hits); +``` +##### **JANA2** +``` +// Templated Function +// Return value +vector assoc_hits = point.Get(); +``` + +### JEvent +#### 1. GetSingle +##### **JANA1** +``` +// Pass by Reference, +// passed param got assigned pointer to object + +const DTTabUtilities* locTTabUtilities = NULL; +loop->GetSingle(locTTabUtilities); +``` +##### **JANA2** +``` +// Return the pointer to object based on template type + +const DTTabUtilities* locTTabUtilities = event->GetSingle(); +``` +#### 2. Get +##### **JANA1** +``` +// Pass by Reference +vector showers; +loop->Get(showers, "IU"); +``` +##### **JANA2** +``` +// JANA1 Get is still available but will be deprecated soon +// So better to use the one given below + +// Templated function +// Return value +auto showers = event->Get("IU"); +``` + +## JEventProcessor +### Child JEventProcessor Basic Header File +##### JANA1 +``` + + +#ifndef _JEventProcessor_myplugin_ +#define _JEventProcessor_myplugin_ + +#include +#include +#include +using namespace jana; + + +class JEventProcessor_myplugin:public jana::JEventProcessor{ +public: + JEventProcessor_myplugin(); + ~JEventProcessor_myplugin(); + const char* className(void){return "JEventProcessor_myplugin";} + +private: + jerror_t init(void); + jerror_t brun(jana::JEventLoop *eventLoop, int32_t runnumber); + jerror_t evnt(jana::JEventLoop *eventLoop, uint64_t eventnumber); + jerror_t erun(void); + jerror_t fini(void); + +}; + +#endif // _JEventProcessor_myplugin_ +``` +##### JANA2 +``` + +#ifndef _JEventProcessor_secondTest_ +#define _JEventProcessor_secondTest_ +#include + +class JEventProcessor_secondTest : public JEventProcessor { + +public: + JEventProcessor_secondTest() { + SetTypeName(NAME_OF_THIS); + } + ~JEventProcessor_secondTest() = default; + +private: + void Init() override; + void BeginRun(const std::shared_ptr& event) override; + void Process(const std::shared_ptr& event) override; + void EndRun() override; + void Finish() override; +}; + +#endif // _JEventProcessor_secondTest_ +``` + + +## JObject +### JObject Header File +##### JANA1 +``` +#include +#include + +using namespace jana; + +class DCereHit: public JObject { +public: + + JOBJECT_PUBLIC(DCereHit); + int sector; + float pe; + float t; + + void toStrings(vector >&items) const { + AddString(items, "sector", "%d", sector); + AddString(items, "pe", "%1.3f", pe); + AddString(items, "t", "%1.3f", t); + } +}; +``` +##### JANA2 +``` +#include + +class DCereHit: public JObject { +public: + + JOBJECT_PUBLIC(DCereHit); + int sector; + float pe; + float t; + + void Summarize(JObjectSummary& summary) const override { + summary.add(sector, "sector", "%d"); + summary.add(pe, "pe", "%1.3f"); + summary.add(t, "t", "%1.3f"); + } +}; +``` +### id +##### **JANA1** +``` +// JANA1 JObject had a data member id + +DBCALShower *shower = new DBCALShower; +shower->id = id++; +``` +##### **JANA2** + + +JANA2 no longer provides a built-in object id. However, you can always add one as a field to your `JObject` and set it yourself. + +``` +// id data member does not exist in JObject anymore in JANA2 + +DBCALShower *shower = new DBCALShower; +shower->id = id++; // Throw Error: no id member +``` + +Similarly, the `JObject::oid_t` type has been removed from JANA2 as well. If you need it, it lives on in the halld_recon codebase: + +``` +#include "DANA/DObjectID.h" + +oid_t // Not inside JObject anymore! +``` + + +## JFactory + + +### JFactory to JFactoryT +##### **JANA1** +``` +In JANA1, `JFactory_base` was a common factory base class, and `JFactory` was a template that inherits from `JFactory_base` and adds functionality specific to the type of the factory's output collection. +``` + +##### **JANA2** +``` +In JANA2, the base class was renamed to `JFactory`, and the template was renamed to `JFactoryT`. JANA2 adds some new functionality, but the old functionality is largely consistent with JANA1. One important difference is that in JANA1, there is always one factory set assigned to each thread, whereas in JANA2, there is one factory set for each event in flight. The number of in-flight events is a parameter controlled separately from the thread count. +``` + +### Factory header file +##### JANA1 +``` +#ifndef _myfactory_factory_ +#define _myfactory_factory_ + +#include +#include "myobject.h" + +class myfactory_factory : public jana::JFactory { + +public: + myfactory_factory() = default; + ~myfactory_factory() = default; + +private: + jerror_t init(void); + jerror_t brun(jana::JEventLoop *eventLoop, int32_t runnumber); + jerror_t evnt(jana::JEventLoop *eventLoop, uint64_t eventnumber); + jerror_t erun(void); + jerror_t fini(void); +}; + +#endif +``` +##### JANA2 +``` +#ifndef _thirdFacTest_factory_ +#define _thirdFacTest_factory_ + +#include +#include "myobject.h" + +class thirdFacTest_factory : public JFactoryT { +public: + thirdFacTest_factory() { + SetTag("MyTag"); + } + ~thirdFacTest_factory() = default; + +private: + void Init() override; + void BeginRun(const std::shared_ptr& event) override; + void Process(const std::shared_ptr& event) override; + void EndRun() override; + void Finish() override; +}; + +#endif +``` +### Registering a New Factory + +This section require some explanation like how factory was getting added before and how it is now with complete explanation +##### **JANA1** +###### Using EventLoop +``` +jerror_t BCAL_init(JEventLoop *loop) +{ +/// Create and register BCAL data factories +loop->AddFactory(new JFactory()); +loop->AddFactory(new JFactory()); +loop->AddFactory(new DBCALHit_factory()); + +} +``` +###### Using Factory Generator +``` +#include "myfactory_factory.h" +#include "JFactoryGenerator_myfactory.h" +#include +using namespace jana; + + + +extern "C"{ + void InitPlugin(JApplication *app){ + InitJANAPlugin(app); + app->AddFactoryGenerator(new JFactoryGenerator_myfactory()); + } +} // "C" +``` +##### **JANA2** +###### Using Factory Set +``` +#include +#include + +void BCAL_init(JFactorySet *factorySet) + +{ + +/// Create and register BCAL data factories +factorySet->Add(new JGetObjectsFactory()); +factorySet->Add(new JGetObjectsFactory()); +factorySet->Add(new DBCALHit_factory()); + +} +``` +###### Using Factory Generator +``` +#include "thirdFacTest_factory.h" +#include +#include + +extern "C"{ + void InitPlugin(JApplication *app){ + InitJANAPlugin(app); + app->Add(new JFactoryGeneratorT()); + } +} // "C" +``` + +### Getting All factories +##### **JANA1** +``` +vector locFactories = locEventLoop->GetFactories(); +//JFactory_base to particular factory type +JFactory* locFactory = dynamic_cast*>(locFactories[0]); +``` +##### **JANA2** +``` +// Directly give particular factory type +vector*> locFacs = locEvent->GetFactoryAll(); +``` + +### Saving Created Object(s) to Factory +##### _Single Object_ +###### **JANA1** +``` +_data.push_back(locAnalysisResults); +``` +###### **JANA2** +``` +Insert(locAnalysisResults); +``` + +##### _Array of Objects_ +``` +std::vector results; +results.push_back(new fac1(...)); +``` +###### **JANA1** +``` +for (auto obj: results){ + _data.push_back(obj); +} +``` +###### **JANA2** +``` +Set(results) +``` + +### Getting Created Objects from Factory +##### **JANA1** +``` +vector locReactionsSubset; +locFactory->Get(locReactionsSubset); +locReactions.insert(locReactions.end(), locReactionsSubset.begin(), locReactionsSubset.end()); +``` +##### **JANA2** +``` +vector locReactionsSubset; +auto iters = locFactory->GetOrCreate(locEvent, locEvent->GetJApplication(), locEvent->GetRunNumber()); +locReactions.insert(locReactions.end(), iters.first, iters.second); +``` + +### Factory Tag +#### 1. SetTag +##### **JANA1** +``` +//Inside factory class definition this was required to be added +const char* Tag(void){return "Combo";} +``` +##### **JANA2** +``` +// Have to set inside factory constructor now +DChargedTrack_factory_Combo(){ + SetTag("Combo"); +} +``` +#### 2. GetTag +##### **JANA1** +``` +locFactory->Tag() +``` +##### **JANA2** +``` +locFactory->GetTag() +``` + + +### Factory ObjectName +#### 1. SetObjectName + +##### **JANA1** +``` +// Was not present in JANA1 + +DReaction_factory_Thrown(){ +//prevents JANA from searching the input file for these objects +use_factory = 1; +} +``` +##### **JANA2** +``` +// Present in JANA2 and is set inside constructor. Write what it mainly do? + +DReaction_factory_Thrown(){ +SetObjectName("DReaction"); +SetTag("Thrown"); +} +``` + + +## JEvent +### JEventLoop to JEvent +##### **JANA1** +``` +JEventLoop is JANA1 thing, write what it was doing mainly +#include -- you have to import this header file in factory and where else? +``` +##### **JANA2** +``` +JANA2 has replaced JEventLoop with JEvent, + +#include --- you have to import it in factory, need to include anywhere else too?? + +write how it is different that JEventLoop? I think mainly now factoryies are inside factory set instead of having them inside JEvent as it was for JEventLoop. +``` +### Getting Run Number +##### **JANA1** +``` +run_number = locEventLoop->GetJEvent().GetRunNumber()); +``` +##### **JANA2** +``` +locEvent->GetRunNumber() +``` +#### Getting Event Number +##### **JANA1** +``` +run_number = locEventLoop->GetJEvent().GetEventNumber()); +``` +##### **JANA2** +``` +locEvent->GetEventNumber() +``` + + +## Acquiring Locks +### Pre Steps +##### **JANA1** +``` +#include "DANA/DApplication.h" + + +dApplication = dynamic_cast(locEventLoop->GetJApplication +``` +##### **JANA2** +``` +#include + + +auto app = locEvent->GetJApplication(); +jLockService = app->GetService(); +// or +jLockService = japp->GetService() +``` +### Locks +#### 1. ReadLock + +##### **JANA1** +``` +dActionLock = japp->ReadLock(locLockName); +pthread_rwlock_unlock(dActionLock); //unlock +``` +##### **JANA2** +``` +dActionLock = app->GetService()->ReadLock(locLockName); +pthread_rwlock_unlock(dActionLock); //unlock +``` + +#### 2. WriteLock + +##### **JANA1** +``` +japp->WriteLock("DAnalysisResults +japp->Unlock("DAnalysisResults"); +``` +##### **JANA2** +``` +jLockService->WriteLock("DAnalysisResults"); +jLockService->Unlock("DAnalysisResults"); +``` + +#### 3.RootWriteLock + +##### **JANA1** +``` +dApplication->RootWriteLock(); //lock +dApplication->RootUnLock(); //unlock +``` +##### **JANA2** +###### Using JLockService +``` +jLockService->RootWriteLock(); //lock +jLockService->RootUnLock(); //unlock +``` +###### Using DEvent +``` +#include "DANA/DEvent.h" +DEvent::GetLockService(locEvent)->RootWriteLock(); +DEvent::GetLockService(locEvent)->RootUnLock(); +``` + +## Rarely used +### use_factory +##### **JANA1** +``` +Could be used in JANA1 + + +//prevents JANA from searching the input file for these objects +DEventWriterROOT_factory(){use_factory = 1;}; +``` +##### **JANA2** +``` +No more available in JANA2, how is the functionality that it was providing is getting used? +DEventWriterROOT_factory() = default; +``` +### Unknown Enum +##### **JANA1** +``` +//Was a plain enum so could be accessed without any scope resolution operator + +#include "particleType.h" + +return ((locFirstStep->Get_TargetPID() != Unknown) || (locFirstStep->Get_SecondBeamPID() != Unknown)); +``` +##### **JANA2** +``` +// Is Enum class now so could be accessed like this `Particle_t::Unknown` only + +#include "particleType.h" + +return ((locFirstStep->Get_TargetPID() != Particle_t::Unknown) || (locFirstStep->Get_SecondBeamPID() != Particle_t::Unknown)); +``` diff --git a/docs/parameter-changes-guide.md b/docs/parameter-changes-guide.md new file mode 100644 index 000000000..9d65eae7e --- /dev/null +++ b/docs/parameter-changes-guide.md @@ -0,0 +1,25 @@ + +# JANA1 to JANA2 Parameter Changes Guide + +As part of the transition from JANA1 to JANA2, a few parameters have been updated. This guide provides a comparison of these parameters to help you adjust your configurations and usage. + +## JANA Parameter Changes + +| **Parameter** | **JANA1** | **JANA2** | +|-----------------------|---------------------------------|---------------------------------| +| **PLUGINS** | Configured with `PLUGINS` | Updated configuration method | +| **EVENTS_TO_KEEP** | Previous value or syntax | New value or syntax | +| **EVENTS_TO_SKIP** | Previous value or syntax | New value or syntax | +| **NTHREADS** | Number of threads | Updated usage or default value | +| **JANA:BATCH_MODE** | `1` | Updated value or usage | +| **JANA_CALIB_CONTEXT**| Previous setting | Updated setting or method | + +## Changes in `halld_recon` Parameters + +All parameters in `halld_recon` other than the `-b` option of `hd_dump` remain the same. + +- **`hd_dump` Option Change:** + - **JANA1:** The `-b` option was used for printing event status bits. + - **JANA2:** The `-b` option is now used for benchmarking in JANA2. To avoid conflicts, the `hd_dump` parameter is changed to `-B`. Make sure to update your usage accordingly. + +For additional assistance or if you have any questions, contact [rasool@jlab.org](mailto:rasool@jlab.org). diff --git a/docs/transition-guide-jana1-to-jana2.md b/docs/transition-guide-jana1-to-jana2.md new file mode 100644 index 000000000..991b513aa --- /dev/null +++ b/docs/transition-guide-jana1-to-jana2.md @@ -0,0 +1,16 @@ +# Transition Guides for JANA1 to JANA2 + +Welcome to the transition guides for JANA1 to JANA2! This page provides an overview of the changes and directs you to detailed documentation to help you navigate the updates effectively. + +## Overview + +As JANA transitions from version 1 (JANA1) to version 2 (JANA2), several important changes have been made. To assist you in adapting to these changes, we have created two comprehensive guides: + +1. **Developers Transition Guide:** This guide focuses on key syntax and structural changes between JANA1 and JANA2. It is intended for developers who need to understand and update their codebase according to the new standards. + - [Developers Transition Guide: Key Syntax Changes](developers-transition-guide.md) + +2. **Parameter Changes Guide:** This guide details the changes in parameters between JANA1 and JANA2. It provides user-focused information on how these changes impact configurations and usage. + - [Parameter Changes Guide](parameter-changes-guide.md) + + +These resources are designed to help you understand the modifications and adapt your workflow accordingly. For additional assistance or if you have any questions, contact [rasool@jlab.org](mailto:rasool@jlab.org). \ No newline at end of file From 46733a93164049414b12127551b0ef2aaa864c10 Mon Sep 17 00:00:00 2001 From: raiqarasool Date: Fri, 6 Sep 2024 10:37:04 -0400 Subject: [PATCH 4/7] Developers Transition Guide Headings Improved --- docs/developers-transition-guide.md | 146 +++++++++------------------- 1 file changed, 48 insertions(+), 98 deletions(-) diff --git a/docs/developers-transition-guide.md b/docs/developers-transition-guide.md index 7f4de11cd..d43a39ed6 100644 --- a/docs/developers-transition-guide.md +++ b/docs/developers-transition-guide.md @@ -1,8 +1,11 @@ **** -## Common Functions +# Developers Transition Guide: Key Syntax Changes between JANA1 to JANA2 -### JANA Namespace +This guide outlines the critical syntax and functional updates between JANA1 and JANA2, helping developers navigate the transition smoothly. + +## Commonly Used Features +### JANA Namespace Handling ##### **JANA1** Adding following on top of all files was necessary in JANA1: @@ -11,8 +14,7 @@ using namespace jana; ``` ##### **JANA2** This line is no longer required in JANA2. - -### Application +### Application Handling #### Getting the JApplication ##### **JANA1** In JANA1 there is a global variable `japp` which is a pointer to the project's `JApplication`. You can also obtain it from `JEventLoop::GetJApplication()`. @@ -26,16 +28,13 @@ You can also obtain it from the `JEvent` the same way as you used to from `JEven ```c++ auto app = event->GetJApplication(); ``` - - -### Parameters +### Parameter Management #### Setting Parameters ##### **JANA1** ``` gPARMS->GetParameter("OUTPUT_FILENAME", dOutputFileName); ``` ##### **JANA2** - You should obtain parameters as shown below. ``` @@ -51,11 +50,8 @@ We strongly recommend you register all parameters from inside the `Init()` callb - Inspect the exact parameter values used by a factory If you register parameters in other contexts, this machinery might not work and you might get incomplete parameter lists and missing or spurious error messages. Worse, your code might not see the parameter values you expect it to see. Registering parameters from inside component constructors is less problematic but still discouraged because it won't work with some upcoming new features. - - -#### Getting parameter maps +#### Getting Parameter Maps ##### **JANA1** - To obtain a map of all parameters that share a common prefix: ``` @@ -63,7 +59,6 @@ To obtain a map of all parameters that share a common prefix: gPARMS->GetParameters(locParameterMap, "COMBO_DEDXCUT:"); ``` ##### **JANA2** - In JANA2 this has been renamed to `FilterParameters` but the functionality is the same. Note that this method is not on `JApplication` directly; you have to obtain the parameter manager like so: @@ -71,20 +66,16 @@ Note that this method is not on `JApplication` directly; you have to obtain the //gets all parameters with this filter at the beginning of the key GetApplication()->GetJParameterManager()->FilterParameters(locParameterMap, "COMBO_DEDXCUT:"); ``` - -### DApplication +### DApplication Handling #### Getting DApplication ##### **JANA1** - ``` #include "DANA/DApplication.h" dApplication = dynamic_cast(locEventLoop->GetJApplication ``` - ##### **JANA2** There is no `DApplication` anymore in JANA2. `JApplication` is `final`, which means you can't inherit from it. The functionality on `DApplication` has been moved into `JService`s, which can be accessed via `JApplication::GetService()`. - -### DGeometry +### DGeometry Handling #### Getting DGeometry ##### **JANA1** ###### Using japp @@ -122,15 +113,13 @@ DGeometry *locGeometry = DEvent::GetDGeometry(locEvent); ``` You should call `GetDGeometry` from `JFactory::BeginRun` or `JEventProcessor::BeginRun`. - -### Calibration -#### GetCalib +### Calibration Handling +#### Accessing Calibration Data - `GetCalib` ##### **JANA1** ``` locEventLoop->GetCalib(locTOFParmsTable.c_str(), tofparms); ``` ##### **JANA2** - Analogously to `DGeometry`, you obtain the calibrations by obtaining the `JCalibrationManager` from `JApplication::GetService<>()` and then loading the calibration object corresponding to the event's run number. We recommend you use `DEvent::GetCalib` to avoid this boilerplate. You should call this from your `BeginRun` callback. ``` @@ -154,15 +143,13 @@ calibration->Get("BCAL/mc_parms", bcalparms, event_number) ``` - -### Status Bit -#### GetStatusBit +### Status Bit Handling +#### Accessing Status Bit - `GetStatusBit` ##### **JANA1** ``` locEventLoop->GetJEvent().GetStatusBit(kSTATUS_PHYSICS_EVENT) ``` ##### **JANA2** - Status bits are no longer an event member variable. Instead, they are inserted and retrieved just like the other collections: ``` @@ -175,9 +162,8 @@ locEvent->GetSingle()->GetStatusBit(kSTATUS_PHYSICS_EVENT) locEvent->GetSingleStrict()->GetStatusBit(kSTATUS_REST); ``` - -### BField -#### GetBField +### Magnetic Field Handling +#### Getting Magnetic Field - `GetBField` ##### **JANA1** ``` #include "DANA/DApplication.h" @@ -187,7 +173,6 @@ dMagFMap= dApplication->GetBfield(locEventLoop->GetJEvent().GetRunNumber()); ``` ##### **JANA2** - In JANA2, the magnetic field map is a resource handled analogously to `DGeometry` and `JCalibrationManager`. Thus, we recommend obtaining the field map by calling `DEvent::GetBField(event)` from inside `BeginRun`: @@ -197,12 +182,9 @@ field map by calling `DEvent::GetBField(event)` from inside `BeginRun`: dMagneticFieldMap = DEvent::GetBfield(locEvent); ``` - - -## Modified Getters - -### JObject -#### 1. GetSingleT +## Updated Get Functions +### JObject Getters +#### 1. `GetSingleT` ##### **JANA1** ``` Was present in JANA1 @@ -211,7 +193,7 @@ Was present in JANA1 ``` No longer available in JANA2; use GetSingle() instead ``` -#### 2. GetSingle +#### 2. `GetSingle` ##### **JANA1** ``` // Pass by reference @@ -225,7 +207,7 @@ digihit->GetSingle(PPobj); // Return pointer to object auto PPobj = digihit->GetSingle(); ``` -#### 3. Get +#### 3. `Get` ##### **JANA1** ``` // Pass by Reference @@ -238,9 +220,8 @@ point.Get(assoc_hits); // Return value vector assoc_hits = point.Get(); ``` - -### JEvent -#### 1. GetSingle +### JEvent Getters +#### 1. `GetSingle` ##### **JANA1** ``` // Pass by Reference, @@ -255,7 +236,7 @@ loop->GetSingle(locTTabUtilities); const DTTabUtilities* locTTabUtilities = event->GetSingle(); ``` -#### 2. Get +#### 2. `Get` ##### **JANA1** ``` // Pass by Reference @@ -273,11 +254,9 @@ auto showers = event->Get("IU"); ``` ## JEventProcessor -### Child JEventProcessor Basic Header File +### JEventProcessor Header File ##### JANA1 ``` - - #ifndef _JEventProcessor_myplugin_ #define _JEventProcessor_myplugin_ @@ -287,7 +266,7 @@ auto showers = event->Get("IU"); using namespace jana; -class JEventProcessor_myplugin:public jana::JEventProcessor{ +class JEventProcessor_myplugin : public jana::JEventProcessor{ public: JEventProcessor_myplugin(); ~JEventProcessor_myplugin(); @@ -306,18 +285,17 @@ private: ``` ##### JANA2 ``` - -#ifndef _JEventProcessor_secondTest_ -#define _JEventProcessor_secondTest_ +#ifndef _JEventProcessor_myplugin_ +#define _JEventProcessor_myplugin_ #include -class JEventProcessor_secondTest : public JEventProcessor { +class JEventProcessor_myplugin : public JEventProcessor { public: - JEventProcessor_secondTest() { + JEventProcessor_myplugin() { SetTypeName(NAME_OF_THIS); } - ~JEventProcessor_secondTest() = default; + ~JEventProcessor_myplugin() = default; private: void Init() override; @@ -327,10 +305,9 @@ private: void Finish() override; }; -#endif // _JEventProcessor_secondTest_ +#endif // _JEventProcessor_myplugin_ ``` - ## JObject ### JObject Header File ##### JANA1 @@ -374,7 +351,7 @@ public: } }; ``` -### id +### JObject ID Handling ##### **JANA1** ``` // JANA1 JObject had a data member id @@ -383,8 +360,6 @@ DBCALShower *shower = new DBCALShower; shower->id = id++; ``` ##### **JANA2** - - JANA2 no longer provides a built-in object id. However, you can always add one as a field to your `JObject` and set it yourself. ``` @@ -402,22 +377,13 @@ Similarly, the `JObject::oid_t` type has been removed from JANA2 as well. If you oid_t // Not inside JObject anymore! ``` - ## JFactory - - -### JFactory to JFactoryT +### Transition from JFactory to JFactoryT ##### **JANA1** -``` In JANA1, `JFactory_base` was a common factory base class, and `JFactory` was a template that inherits from `JFactory_base` and adds functionality specific to the type of the factory's output collection. -``` - ##### **JANA2** -``` In JANA2, the base class was renamed to `JFactory`, and the template was renamed to `JFactoryT`. JANA2 adds some new functionality, but the old functionality is largely consistent with JANA1. One important difference is that in JANA1, there is always one factory set assigned to each thread, whereas in JANA2, there is one factory set for each event in flight. The number of in-flight events is a parameter controlled separately from the thread count. -``` - -### Factory header file +### Factory Header File ##### JANA1 ``` #ifndef _myfactory_factory_ @@ -468,7 +434,6 @@ private: #endif ``` ### Registering a New Factory - This section require some explanation like how factory was getting added before and how it is now with complete explanation ##### **JANA1** ###### Using EventLoop @@ -528,8 +493,7 @@ extern "C"{ } } // "C" ``` - -### Getting All factories +### Getting All Factories ##### **JANA1** ``` vector locFactories = locEventLoop->GetFactories(); @@ -541,7 +505,6 @@ JFactory* locFactory = dynamic_cast*>(locFactorie // Directly give particular factory type vector*> locFacs = locEvent->GetFactoryAll(); ``` - ### Saving Created Object(s) to Factory ##### _Single Object_ ###### **JANA1** @@ -552,7 +515,6 @@ _data.push_back(locAnalysisResults); ``` Insert(locAnalysisResults); ``` - ##### _Array of Objects_ ``` std::vector results; @@ -568,7 +530,6 @@ for (auto obj: results){ ``` Set(results) ``` - ### Getting Created Objects from Factory ##### **JANA1** ``` @@ -582,9 +543,8 @@ vector locReactionsSubset; auto iters = locFactory->GetOrCreate(locEvent, locEvent->GetJApplication(), locEvent->GetRunNumber()); locReactions.insert(locReactions.end(), iters.first, iters.second); ``` - -### Factory Tag -#### 1. SetTag +### Factory Tag Handling +#### 1. Setting Tag ##### **JANA1** ``` //Inside factory class definition this was required to be added @@ -597,7 +557,7 @@ DChargedTrack_factory_Combo(){ SetTag("Combo"); } ``` -#### 2. GetTag +#### 2. Getting Tag ##### **JANA1** ``` locFactory->Tag() @@ -606,11 +566,8 @@ locFactory->Tag() ``` locFactory->GetTag() ``` - - -### Factory ObjectName -#### 1. SetObjectName - +### Factory Object Name Handling +#### 1. Setting Object Name ##### **JANA1** ``` // Was not present in JANA1 @@ -630,9 +587,8 @@ SetTag("Thrown"); } ``` - ## JEvent -### JEventLoop to JEvent +### Transition from JEventLoop to JEvent ##### **JANA1** ``` JEventLoop is JANA1 thing, write what it was doing mainly @@ -665,9 +621,8 @@ run_number = locEventLoop->GetJEvent().GetEventNumber()); locEvent->GetEventNumber() ``` - ## Acquiring Locks -### Pre Steps +### Initialization ##### **JANA1** ``` #include "DANA/DApplication.h" @@ -685,9 +640,8 @@ jLockService = app->GetService(); // or jLockService = japp->GetService() ``` -### Locks +### Available Locks & Their Acquiring #### 1. ReadLock - ##### **JANA1** ``` dActionLock = japp->ReadLock(locLockName); @@ -698,9 +652,7 @@ pthread_rwlock_unlock(dActionLock); //unlock dActionLock = app->GetService()->ReadLock(locLockName); pthread_rwlock_unlock(dActionLock); //unlock ``` - #### 2. WriteLock - ##### **JANA1** ``` japp->WriteLock("DAnalysisResults @@ -711,9 +663,7 @@ japp->Unlock("DAnalysisResults"); jLockService->WriteLock("DAnalysisResults"); jLockService->Unlock("DAnalysisResults"); ``` - #### 3.RootWriteLock - ##### **JANA1** ``` dApplication->RootWriteLock(); //lock @@ -732,8 +682,8 @@ DEvent::GetLockService(locEvent)->RootWriteLock(); DEvent::GetLockService(locEvent)->RootUnLock(); ``` -## Rarely used -### use_factory +## Rarely Used Features +### `use_factory` ##### **JANA1** ``` Could be used in JANA1 @@ -747,7 +697,7 @@ DEventWriterROOT_factory(){use_factory = 1;}; No more available in JANA2, how is the functionality that it was providing is getting used? DEventWriterROOT_factory() = default; ``` -### Unknown Enum +### `Unknown` Handling ##### **JANA1** ``` //Was a plain enum so could be accessed without any scope resolution operator @@ -763,4 +713,4 @@ return ((locFirstStep->Get_TargetPID() != Unknown) || (locFirstStep->Get_SecondB #include "particleType.h" return ((locFirstStep->Get_TargetPID() != Particle_t::Unknown) || (locFirstStep->Get_SecondBeamPID() != Particle_t::Unknown)); -``` +``` \ No newline at end of file From a7d4e018b7eb1e1b6d2613ea7cc2638603cf016e Mon Sep 17 00:00:00 2001 From: raiqarasool Date: Tue, 10 Sep 2024 08:39:14 -0400 Subject: [PATCH 5/7] Completed parameter changes table --- docs/parameter-changes-guide.md | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/docs/parameter-changes-guide.md b/docs/parameter-changes-guide.md index 9d65eae7e..dfbea798f 100644 --- a/docs/parameter-changes-guide.md +++ b/docs/parameter-changes-guide.md @@ -1,25 +1,25 @@ - # JANA1 to JANA2 Parameter Changes Guide -As part of the transition from JANA1 to JANA2, a few parameters have been updated. This guide provides a comparison of these parameters to help you adjust your configurations and usage. +This guide outlines the key parameter changes from JANA1 to JANA2, helping you adjust your configurations and usage as needed. + +### Commonly Used JANA Parameters -## JANA Parameter Changes +The following table compares commonly used JANA parameters between JANA1 and JANA2. Parameters that remain unchanged in JANA2 are marked with `-`. In the "Possible Input" column, `-` means that they are the same as in JANA1. Changes are listed where applicable. -| **Parameter** | **JANA1** | **JANA2** | -|-----------------------|---------------------------------|---------------------------------| -| **PLUGINS** | Configured with `PLUGINS` | Updated configuration method | -| **EVENTS_TO_KEEP** | Previous value or syntax | New value or syntax | -| **EVENTS_TO_SKIP** | Previous value or syntax | New value or syntax | -| **NTHREADS** | Number of threads | Updated usage or default value | -| **JANA:BATCH_MODE** | `1` | Updated value or usage | -| **JANA_CALIB_CONTEXT**| Previous setting | Updated setting or method | +| **Parameter** | **JANA1** | **JANA2** | **Possible Inputs** | +|-----------------------|------------------------|------------------------------|--------------------------------------------------| +| **PLUGINS** | `- ` | `-` | `-` | +| **EVENTS_TO_KEEP** | `EVENTS_TO_KEEP` | `jana:nevents` | `-` | +| **EVENTS_TO_SKIP** | `EVENTS_TO_SKIP` | `jana:nskips` | `-` | +| **NTHREADS** | `-` | `-` | `-` | +| **JANA:BATCH_MODE** | `JANA:BATCH_MODE` | `log:global` | `TRACE`, `DEBUG`, `INFO`, `WARN`, `FATAL`, `OFF` | +| **JANA_CALIB_CONTEXT**| `JANA_CALIB_CONTEXT` | `jana:calib_context` | `-` | ## Changes in `halld_recon` Parameters -All parameters in `halld_recon` other than the `-b` option of `hd_dump` remain the same. +### `hd_dump` Option Update -- **`hd_dump` Option Change:** - - **JANA1:** The `-b` option was used for printing event status bits. - - **JANA2:** The `-b` option is now used for benchmarking in JANA2. To avoid conflicts, the `hd_dump` parameter is changed to `-B`. Make sure to update your usage accordingly. +- **JANA1:** The `-b` option was used for printing event status bits in `hd_dump`. +- **JANA2:** The `-b` option is used for benchmarking in JANA2. Thus, `hd_dump` parameter for event status bits (`-b`) has been changed to `-B`. Update your usage accordingly. -For additional assistance or if you have any questions, contact [rasool@jlab.org](mailto:rasool@jlab.org). +For additional assistance or questions, please contact [rasool@jlab.org](mailto:rasool@jlab.org). \ No newline at end of file From 94815a1ac203f59aa639db2675721b3b8c522d4f Mon Sep 17 00:00:00 2001 From: raiqarasool Date: Tue, 10 Sep 2024 08:41:25 -0400 Subject: [PATCH 6/7] Moved jana1to2 transition guides to docs/jana1to2 folder --- docs/{ => jana1to2}/developers-transition-guide.md | 0 docs/{ => jana1to2}/parameter-changes-guide.md | 0 docs/{ => jana1to2}/transition-guide-jana1-to-jana2.md | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename docs/{ => jana1to2}/developers-transition-guide.md (100%) rename docs/{ => jana1to2}/parameter-changes-guide.md (100%) rename docs/{ => jana1to2}/transition-guide-jana1-to-jana2.md (100%) diff --git a/docs/developers-transition-guide.md b/docs/jana1to2/developers-transition-guide.md similarity index 100% rename from docs/developers-transition-guide.md rename to docs/jana1to2/developers-transition-guide.md diff --git a/docs/parameter-changes-guide.md b/docs/jana1to2/parameter-changes-guide.md similarity index 100% rename from docs/parameter-changes-guide.md rename to docs/jana1to2/parameter-changes-guide.md diff --git a/docs/transition-guide-jana1-to-jana2.md b/docs/jana1to2/transition-guide-jana1-to-jana2.md similarity index 100% rename from docs/transition-guide-jana1-to-jana2.md rename to docs/jana1to2/transition-guide-jana1-to-jana2.md From 4b6f083c6e08a5c99011d4bfc9db380575142e72 Mon Sep 17 00:00:00 2001 From: Nathan Brei Date: Wed, 11 Sep 2024 12:46:38 -0400 Subject: [PATCH 7/7] Finish updating migration guide --- docs/jana1to2/developers-transition-guide.md | 360 ++++++++++--------- 1 file changed, 184 insertions(+), 176 deletions(-) diff --git a/docs/jana1to2/developers-transition-guide.md b/docs/jana1to2/developers-transition-guide.md index d43a39ed6..26cc99262 100644 --- a/docs/jana1to2/developers-transition-guide.md +++ b/docs/jana1to2/developers-transition-guide.md @@ -49,7 +49,8 @@ We strongly recommend you register all parameters from inside the `Init()` callb - Emit a warning when two plugins register the same parameter with conflicting default values. - Inspect the exact parameter values used by a factory -If you register parameters in other contexts, this machinery might not work and you might get incomplete parameter lists and missing or spurious error messages. Worse, your code might not see the parameter values you expect it to see. Registering parameters from inside component constructors is less problematic but still discouraged because it won't work with some upcoming new features. +If you register parameters in other contexts, this machinery might not work and you might get incomplete parameter lists and missing or spurious error messages. Worse, your code might not see the parameter values you expect it to see. Registering parameters from inside constructors is less problematic but still discouraged because it won't work with some upcoming new features. + #### Getting Parameter Maps ##### **JANA1** To obtain a map of all parameters that share a common prefix: @@ -184,7 +185,13 @@ dMagneticFieldMap = DEvent::GetBfield(locEvent); ## Updated Get Functions ### JObject Getters + #### 1. `GetSingleT` + +`GetSingleT` has been replaced with `GetSingle`. Templated methods no longer have a `T` suffix; templated classes (such as `JFactoryT`) still do. +The new `GetSingle` returns a pointer rather than updating an out parameter. If there isn't exactly one associated item of that type, it will return +`nullptr`. + ##### **JANA1** ``` Was present in JANA1 @@ -208,6 +215,8 @@ digihit->GetSingle(PPobj); auto PPobj = digihit->GetSingle(); ``` #### 3. `Get` + +Similarly to `GetSingle`, `Get` returns a vector rather than updating an out parameter. ##### **JANA1** ``` // Pass by Reference @@ -221,6 +230,8 @@ point.Get(assoc_hits); vector assoc_hits = point.Get(); ``` ### JEvent Getters + + #### 1. `GetSingle` ##### **JANA1** ``` @@ -255,6 +266,20 @@ auto showers = event->Get("IU"); ## JEventProcessor ### JEventProcessor Header File + +`JEventProcessors` in JANA2 have a similar feel to JANA1. The key differences are: + +1. The names and type signatures of the callbacks have changed +2. The event number and run number now live on the JEvent object rather than as separate arguments +3. JANA2 doesn't use `jerror_t` anywhere for several reasons: there's too many options to exhaustively check, most +error codes don't apply to JEventProcessors, there's no clear indication which error codes represent failure conditions, +and no reasonable strategy JANA can take if a failure is reached other than a premature exit. Thus the callbacks return +void. +4. If a failure condition is reached in user code, the user should throw a `JException` with a detailed message. JANA will +add additional context information (such as the component name, callback, plugin, and backtrace), log everything, and shut +down cleanly. +5. The user no longer provides a `className` callback. Instead, they call `SetTypeName(NAME_OF_THIS);` from the constructor. + ##### JANA1 ``` #ifndef _JEventProcessor_myplugin_ @@ -310,6 +335,16 @@ private: ## JObject ### JObject Header File + + +`JObjects` in JANA2 are also conceptually similar to their JANA1 counterparts, with a +syntax refresh aimed at future extensibility. The `toStrings` callback has been +replaced with a `Summarize` callback as shown below. Note that in JANA2, data model classes +do not need to inherit from `JObject` anymore - `JObject` merely provides clean, user-specified formatting, +and convenient simple tracking of object associations. JANA2 also supports using [PODIO](https://github.com/AIDASoft/podio) +based data models, which provide free serialization/deserialization, a first-class Python interface, automatic +memory management and immutability guarantees, and relational object associations. + ##### JANA1 ``` #include @@ -352,6 +387,13 @@ public: }; ``` ### JObject ID Handling + +In JANA1, JObjects provided an `id` field. However it was left up to the user how to set and use it. Because JANA can't guarantee +that it is set reliably or consistently, it is fundamentally part of the data model and not part of the framework. Thus, JANA2 +no longer provides a built-in object id. If needed, users are welcome to add their own `id` field to their data model classes and +establish a convention for how and when it gets set. For reliable, automatic object IDs for all data model classes, consider using PODIO. + + ##### **JANA1** ``` // JANA1 JObject had a data member id @@ -360,17 +402,15 @@ DBCALShower *shower = new DBCALShower; shower->id = id++; ``` ##### **JANA2** -JANA2 no longer provides a built-in object id. However, you can always add one as a field to your `JObject` and set it yourself. ``` // id data member does not exist in JObject anymore in JANA2 DBCALShower *shower = new DBCALShower; -shower->id = id++; // Throw Error: no id member +shower->id = id++; // Compiler error ``` Similarly, the `JObject::oid_t` type has been removed from JANA2 as well. If you need it, it lives on in the halld_recon codebase: - ``` #include "DANA/DObjectID.h" @@ -382,7 +422,32 @@ oid_t // Not inside JObject anymore! ##### **JANA1** In JANA1, `JFactory_base` was a common factory base class, and `JFactory` was a template that inherits from `JFactory_base` and adds functionality specific to the type of the factory's output collection. ##### **JANA2** -In JANA2, the base class was renamed to `JFactory`, and the template was renamed to `JFactoryT`. JANA2 adds some new functionality, but the old functionality is largely consistent with JANA1. One important difference is that in JANA1, there is always one factory set assigned to each thread, whereas in JANA2, there is one factory set for each event in flight. The number of in-flight events is a parameter controlled separately from the thread count. +In JANA2, the base class was renamed to `JFactory`, and the template was renamed to `JFactoryT`. JANA2 adds some new functionality, but the old functionality is largely consistent with JANA1. + +The syntax differences between JANA1 and JANA2 `JFactory`s' are consistent with those for `JEventProcessor`s. + +1. The names and type signatures of the callbacks have changed +2. The event number and run number now live on the JEvent object rather than as separate arguments +3. JANA2 doesn't use `jerror_t` anywhere for several reasons: there's too many options to exhaustively check, most +error codes don't apply to JEventProcessors, there's no clear indication which error codes represent failure conditions, +and no reasonable strategy JANA can take if a failure is reached other than a premature exit. Thus the callbacks return +void. +4. If a failure condition is reached in user code, the user should throw a `JException` with a detailed message. JANA will +add additional context information (such as the component name, callback, plugin, and backtrace), log everything, and shut +down cleanly. +5. The user no longer provides a `className` callback. Instead, they call `SetTypeName(NAME_OF_THIS);` from the constructor. + +Another important difference is how factory tags are set. In JANA1, the user provides a `Tag()` callback, whereas in JANA2, +the user sets the tag by calling `SetTag()` from the constructor. The user can retrieve the factory tag by calling `GetTag()`. + +One important semantic difference is that in JANA1, there is always one factory set assigned to each thread, whereas in JANA2, +there is one factory set for each event in flight. The number of in-flight events is a parameter controlled separately +from the thread count. This is important for ensuring that there is always work for threads to do when running +multi-level processing topologies. Another consequence of this design is that factories don't belong to just one thread and hence +shouldn't reference thread-local variables - instead, one thread can pop an event from a queue, process it, and push it to a +different queue, where it could later be picked up by a different thread. Importantly, however, only one thread has access to any +given JEvent and its corresponding factory set at any time, so you don't need to worry about thread safety in JFactories. + ### Factory Header File ##### JANA1 ``` @@ -398,6 +463,8 @@ public: myfactory_factory() = default; ~myfactory_factory() = default; + const char* Tag() { return "MyTag"; } + private: jerror_t init(void); jerror_t brun(jana::JEventLoop *eventLoop, int32_t runnumber); @@ -434,78 +501,83 @@ private: #endif ``` ### Registering a New Factory -This section require some explanation like how factory was getting added before and how it is now with complete explanation + +In JANA1, the user creates a `JFactoryGenerator` with a `GenerateFactories()` callback. Within this callback, +the user instantiates new factories and adds them to a `JEventLoop`. (In `halld_recon`, there is a `DFactoryGenerator` +which instantiates factories for all fundamental detector plugins, calling each plugin's corresponding +`$DETECTOR_init()` function.) + +In JANA2, the user is still free to create their own `JFactoryGenerator`. It's syntax has been modified (notably, +`GenerateFactories()` provides a `JFactorySet` argument that the user adds the factories to), but the core concepts +are the same. However, there is now also a `JFactoryGeneratorT` utility which reduces the boilerplate. As long +as the factory is default constructible, the user merely needs to pass the factory class as a template argument to +`JFactoryGeneratorT`, and JANA will do the rest of the work. JANA2 is perfectly fine with users passing a single +`JFactoryGenerator` that instantiates every single factory in the system, but there are future benefits if users +pass separate `JFactoryGeneratorT`s for each factory instead. + + ##### **JANA1** -###### Using EventLoop -``` -jerror_t BCAL_init(JEventLoop *loop) -{ -/// Create and register BCAL data factories -loop->AddFactory(new JFactory()); -loop->AddFactory(new JFactory()); -loop->AddFactory(new DBCALHit_factory()); -} -``` -###### Using Factory Generator ``` -#include "myfactory_factory.h" -#include "JFactoryGenerator_myfactory.h" #include -using namespace jana; - +#include "JFactoryGenerator_myfactory.h" +#include "myfactory.h" +using namespace jana; -extern "C"{ - void InitPlugin(JApplication *app){ +extern "C" { +void InitPlugin(JApplication *app) { InitJANAPlugin(app); app->AddFactoryGenerator(new JFactoryGenerator_myfactory()); - } +} } // "C" ``` ##### **JANA2** -###### Using Factory Set -``` -#include -#include - -void BCAL_init(JFactorySet *factorySet) - -{ - -/// Create and register BCAL data factories -factorySet->Add(new JGetObjectsFactory()); -factorySet->Add(new JGetObjectsFactory()); -factorySet->Add(new DBCALHit_factory()); -} -``` -###### Using Factory Generator ``` -#include "thirdFacTest_factory.h" #include #include +#include "myfactory.h" -extern "C"{ - void InitPlugin(JApplication *app){ +extern "C" { +void InitPlugin(JApplication *app) { InitJANAPlugin(app); - app->Add(new JFactoryGeneratorT()); - } + app->Add(new JFactoryGeneratorT()); +} } // "C" ``` + ### Getting All Factories + +Sometimes it is necessary to retrieve all factories that produce objects of a given type. In +JANA1 this was done by retrieving all factories and doing a `dynamic_cast`. In JANA2 there's a +dedicated method for this, `GetFactoryAll`. (Note that this will retrieve the factories without +automatically running them!). JANA2 also supports retrieving all objects of type `T` from all +factories using `GetAll()` and retrieving all objects descended from parent type `T` +(e.g. `JObject` or `TObject`) using `GetAlllChildren()`. + ##### **JANA1** + ``` vector locFactories = locEventLoop->GetFactories(); -//JFactory_base to particular factory type +// Cast JFactory_base to particular factory type JFactory* locFactory = dynamic_cast*>(locFactories[0]); ``` ##### **JANA2** ``` -// Directly give particular factory type +// Retrieve all factories producing T directly vector*> locFacs = locEvent->GetFactoryAll(); ``` + ### Saving Created Object(s) to Factory + +When writing a factory, the user creates some data objects inside `Process()` and +then needs to pass them back to JANA. In JANA1, this was done by modifying the +`_data` member variable directly. In JANA2, we prefer using a dedicated setter method. +For the sake of porting GlueX without having to rewrite certain complex factories, +we've left the member variable `protected`, though the member variable has been +renamed to `mData`. + ##### _Single Object_ ###### **JANA1** ``` @@ -514,95 +586,38 @@ _data.push_back(locAnalysisResults); ###### **JANA2** ``` Insert(locAnalysisResults); + +// Or (less preferred) +mData.push_back(locAnalysisResults); ``` ##### _Array of Objects_ ``` -std::vector results; -results.push_back(new fac1(...)); +std::vector results; +results.push_back(new Hit(...)); ``` ###### **JANA1** ``` -for (auto obj: results){ - _data.push_back(obj); +for (auto hit: results){ + _data.push_back(hit); } ``` ###### **JANA2** ``` Set(results) ``` -### Getting Created Objects from Factory -##### **JANA1** -``` -vector locReactionsSubset; -locFactory->Get(locReactionsSubset); -locReactions.insert(locReactions.end(), locReactionsSubset.begin(), locReactionsSubset.end()); -``` -##### **JANA2** -``` -vector locReactionsSubset; -auto iters = locFactory->GetOrCreate(locEvent, locEvent->GetJApplication(), locEvent->GetRunNumber()); -locReactions.insert(locReactions.end(), iters.first, iters.second); -``` -### Factory Tag Handling -#### 1. Setting Tag -##### **JANA1** -``` -//Inside factory class definition this was required to be added -const char* Tag(void){return "Combo";} -``` -##### **JANA2** -``` -// Have to set inside factory constructor now -DChargedTrack_factory_Combo(){ - SetTag("Combo"); -} -``` -#### 2. Getting Tag -##### **JANA1** -``` -locFactory->Tag() -``` -##### **JANA2** -``` -locFactory->GetTag() -``` -### Factory Object Name Handling -#### 1. Setting Object Name -##### **JANA1** -``` -// Was not present in JANA1 - -DReaction_factory_Thrown(){ -//prevents JANA from searching the input file for these objects -use_factory = 1; -} -``` -##### **JANA2** -``` -// Present in JANA2 and is set inside constructor. Write what it mainly do? - -DReaction_factory_Thrown(){ -SetObjectName("DReaction"); -SetTag("Thrown"); -} -``` ## JEvent ### Transition from JEventLoop to JEvent ##### **JANA1** ``` -JEventLoop is JANA1 thing, write what it was doing mainly -#include -- you have to import this header file in factory and where else? -``` -##### **JANA2** -``` -JANA2 has replaced JEventLoop with JEvent, - -#include --- you have to import it in factory, need to include anywhere else too?? - -write how it is different that JEventLoop? I think mainly now factoryies are inside factory set instead of having them inside JEvent as it was for JEventLoop. +In JANA1, all processing operated on a `JEventLoop` object. In JANA2, this has been changed to `JEvent`. +Conceptually, a `JEvent` is just a container for data that can be processed as a discrete unit, indepedently from the rest +of the stream (this usually correspondings to a physics event, but also potentially a timeslice, block, subevent, etc). This includes the +event number, run number, all data read from the event source, all data created by factories so far, and all of +the factory state necessary to generate additional data belonging to the same context. The factories themselves are managed by a `JFactorySet` +which is one-to-one with and owned by the JEvent. ``` -### Getting Run Number +### Getting the Run Number ##### **JANA1** ``` run_number = locEventLoop->GetJEvent().GetRunNumber()); @@ -611,7 +626,8 @@ run_number = locEventLoop->GetJEvent().GetRunNumber()); ``` locEvent->GetRunNumber() ``` -#### Getting Event Number + +#### Getting the Event Number ##### **JANA1** ``` run_number = locEventLoop->GetJEvent().GetEventNumber()); @@ -622,82 +638,74 @@ locEvent->GetEventNumber() ``` ## Acquiring Locks -### Initialization -##### **JANA1** -``` -#include "DANA/DApplication.h" - -dApplication = dynamic_cast(locEventLoop->GetJApplication -``` -##### **JANA2** -``` -#include +JANA1 required the user to manually acquire and hold locks when accessing to shared resources in a JEventProcessor. +JANA2 offers a different interface which handles all locks internally. However, using this new callback interface +would require restructuring the existing `JEventProcessor` code. When migrating from JANA1 to JANA2 it +is much safer to avoid making such deep changes, at least initially. The old-style user-managed locks can be migrated +to JANA2 as-is with one minor change: the various lock helper methods have been moved from `JApplication` to `JLockService`. -auto app = locEvent->GetJApplication(); -jLockService = app->GetService(); -// or -jLockService = japp->GetService() -``` -### Available Locks & Their Acquiring -#### 1. ReadLock -##### **JANA1** -``` -dActionLock = japp->ReadLock(locLockName); -pthread_rwlock_unlock(dActionLock); //unlock -``` -##### **JANA2** -``` -dActionLock = app->GetService()->ReadLock(locLockName); -pthread_rwlock_unlock(dActionLock); //unlock -``` -#### 2. WriteLock -##### **JANA1** -``` -japp->WriteLock("DAnalysisResults -japp->Unlock("DAnalysisResults"); -``` -##### **JANA2** -``` -jLockService->WriteLock("DAnalysisResults"); -jLockService->Unlock("DAnalysisResults"); -``` -#### 3.RootWriteLock -##### **JANA1** +### ROOT Read/Write locks +##### JANA1 ``` -dApplication->RootWriteLock(); //lock -dApplication->RootUnLock(); //unlock +dActionLock = japp->RootReadLock(); +// ... +japp->RootUnLock(locLockName); ``` -##### **JANA2** -###### Using JLockService +##### JANA2 ``` -jLockService->RootWriteLock(); //lock -jLockService->RootUnLock(); //unlock +auto app = GetApplication(); // or event->GetJApplication() +auto lock_svc = app->GetService(); + +lock_svc->RootReadLock(); +// ... +lock_svc->RootUnLock(); ``` -###### Using DEvent + +To reduce boilerplate, we've added a helper function: ``` #include "DANA/DEvent.h" + DEvent::GetLockService(locEvent)->RootWriteLock(); DEvent::GetLockService(locEvent)->RootUnLock(); ``` -## Rarely Used Features -### `use_factory` -##### **JANA1** +### Named locks + +##### JANA1 +``` +dActionLock = japp->ReadLock(locLockName); +// ... +pthread_rwlock_unlock(dActionLock); +// Or: japp->Unlock(locLockName); ``` -Could be used in JANA1 +##### JANA2 +``` +auto app = GetApplication(); // or event->GetJApplication() +auto lock_svc = app->GetService(); -//prevents JANA from searching the input file for these objects -DEventWriterROOT_factory(){use_factory = 1;}; +dActionLock = lock_svc->ReadLock(locLockName); +// ... +pthread_rwlock_unlock(dActionLock); +// Or: lock_svc->Unlock(locLockName); ``` -##### **JANA2** + +To reduce boilerplate: ``` -No more available in JANA2, how is the functionality that it was providing is getting used? -DEventWriterROOT_factory() = default; +DEvent::GetLockService(locEvent)->ReadLock("app"); +DEvent::GetLockService(locEvent)->Unlock("app"); ``` + + +## Rarely Used Features + ### `Unknown` Handling + +The enum in `particleType.h` was experiencing a name conflict with a JANA2 enum, so it has been changed +to an enum class. + ##### **JANA1** ``` //Was a plain enum so could be accessed without any scope resolution operator @@ -713,4 +721,4 @@ return ((locFirstStep->Get_TargetPID() != Unknown) || (locFirstStep->Get_SecondB #include "particleType.h" return ((locFirstStep->Get_TargetPID() != Particle_t::Unknown) || (locFirstStep->Get_SecondBeamPID() != Particle_t::Unknown)); -``` \ No newline at end of file +```