Back to home page

EIC code displayed by LXR

 
 

    


Warning, /jana2/docs/jana1to2/developers-transition-guide.md is written in an unsupported language. File is not indexed.

0001 
0002 
0003 # Developers Transition Guide
0004 
0005 ***Key Syntax Changes between JANA1 to JANA2***
0006 
0007 This guide outlines the critical syntax and functional updates between JANA1 and JANA2, helping developers navigate the transition smoothly.
0008 
0009 
0010 
0011 ## Namespace
0012 ##### **JANA1**
0013 Adding following on top of all files was necessary in JANA1:
0014 
0015 ```
0016 using namespace jana;
0017 ```
0018 ##### **JANA2**
0019 This line is no longer required in JANA2.
0020 
0021 
0022 ## Application
0023 
0024 ### JApplication
0025 #### Getting the JApplication
0026 
0027 ##### **JANA1**
0028 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()`.
0029 
0030 ##### **JANA2**
0031 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:
0032 
0033 ```cpp
0034 auto app = GetApplication();
0035 ```
0036 
0037 You can also obtain it from the `JEvent` the same way as you used to from `JEventLoop`, i.e. 
0038 
0039 ```cpp
0040 auto app = event->GetJApplication();
0041 ```
0042 
0043 ### DApplication
0044 ### Getting DApplication
0045 ##### **JANA1**
0046 
0047 ```cpp
0048 #include "DANA/DApplication.h"
0049 dApplication = dynamic_cast<DApplication*>(locEventLoop->GetJApplication
0050 ```
0051 
0052 ##### **JANA2**
0053 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<ServiceT>()`. 
0054 
0055 ```cpp
0056 auto dapp = GetApplication()->GetService<DApplication>();
0057 ```
0058 
0059 
0060 ## Parameter Manager
0061 ### Setting Parameters
0062 
0063 ##### **JANA1**
0064 
0065 ```cpp
0066 gPARMS->GetParameter("OUTPUT_FILENAME", dOutputFileName);
0067 ```
0068 
0069 ##### **JANA2**
0070 You should obtain parameters as shown below. 
0071 
0072 ```cpp
0073 auto app = GetApplication();
0074 app->SetDefaultParameter("component_prefix:value_name", ref_to_member_var);
0075 ```
0076 
0077 We strongly recommend you register all parameters from inside the `Init()` callbacks of your JANA components, or from `InitPlugin()`. This helps JANA:
0078 
0079 - Report back which parameters are available without having to process an input file.
0080 - Emit a warning (or error!) when a user-provided parameter is misspelled
0081 - Emit a warning when two plugins register the same parameter with conflicting default values.
0082 - Inspect the exact parameter values used by a factory
0083 
0084 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.
0085 
0086 ### Getting Parameter Maps
0087 
0088 ##### **JANA1**
0089 To obtain a map of all parameters that share a common prefix:
0090 
0091 ```cpp
0092 //gets all parameters with this filter at the beginning of the key
0093 gPARMS->GetParameters(locParameterMap, "COMBO_DEDXCUT:"); 
0094 ```
0095 
0096 ##### **JANA2**
0097 In JANA2 this has been renamed to `FilterParameters` but the functionality is the same.
0098 Note that this method is not on `JApplication` directly; you have to obtain the parameter manager like so:
0099 
0100 ```cpp
0101 //gets all parameters with this filter at the beginning of the key
0102 GetApplication()->GetJParameterManager()->FilterParameters(locParameterMap, "COMBO_DEDXCUT:");
0103 ```
0104 
0105 
0106 ## DGeometry
0107 #### Getting DGeometry
0108 
0109 ##### **JANA1**
0110 ###### Using japp
0111 ```cpp
0112 #include "DANA/DApplication.h"
0113 #include "HDGEOMETRY/DGeometry.h"
0114 
0115 DApplication* dapp=dynamic_cast<DApplication*>(japp);
0116 const DGeometry *dgeom = dapp->GetDGeometry(runnumber);
0117 ```
0118 
0119 ###### Using eventLoop
0120 
0121 ```cpp
0122 #include "DANA/DApplication.h"
0123 #include "HDGEOMETRY/DGeometry.h"
0124 
0125 DGeometry *locGeom = dApplication ? dApplication->GetDGeometry(eventLoop->GetJEvent().GetRunNumber()) : NULL;
0126 ```
0127 
0128 ##### **JANA2**
0129 In JANA2, you obtain the `DGeometryManager` from the `JApplication` and from there you use the run number to obtain the corresponding `DGeometry`:
0130 
0131 ```cpp
0132 #include "HDGEOMETRY/DGeometry.h"
0133 
0134 auto runnumber = event->GetRunNumber();
0135 auto app = event->GetJApplication();
0136 auto geo_manager = app->GetService<DGeometryManager>();
0137 auto geom = geo_manager->GetDGeometry(runnumber);
0138 ```
0139 
0140 To reduce the boilerplate, we've provided a handy helper function, `DEvent::GetDGeometry()`, that does all of these steps for you:
0141 
0142 ```cpp
0143 #include "DANA/DEvent.h"
0144 
0145 DGeometry *locGeometry = DEvent::GetDGeometry(locEvent);
0146 ```
0147 
0148 You should call `GetDGeometry` from `JFactory::BeginRun` or `JEventProcessor::BeginRun`.
0149 
0150 
0151 ## Calibration
0152 #### Accessing Calibration Data - `GetCalib` 
0153 ##### **JANA1**
0154 
0155 ```cpp
0156 locEventLoop->GetCalib(locTOFParmsTable.c_str(), tofparms);
0157 ```
0158 
0159 ##### **JANA2**
0160 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. 
0161 
0162 ```cpp
0163 #include "DANA/DEvent.h"
0164 
0165 DEvent::GetCalib(event, locTOFParmsTable.c_str(), tofparms);
0166 ```
0167 
0168 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:
0169 
0170 ```cpp
0171 #include <JANA/JEvent.h>
0172 #include <JANA/Calibrations/JCalibrationManager.h>
0173 
0174 auto event_number = event->GetEventNumber();
0175 auto run_number = event->GetRunNumber();
0176 
0177 auto app = GetApplication();
0178 auto calibration = app->GetService<JCalibrationManager>()->GetJCalibration(run_number);
0179 calibration->Get("BCAL/mc_parms", bcalparms, event_number)
0180 ```
0181 
0182 
0183 ## Status Bit
0184 #### Accessing Status Bit - `GetStatusBit`
0185 
0186 ##### **JANA1**
0187 
0188 ```cpp
0189 locEventLoop->GetJEvent().GetStatusBit(kSTATUS_PHYSICS_EVENT)
0190 ```
0191 
0192 ##### **JANA2**
0193 Status bits are no longer an event member variable. Instead, they are inserted and retrieved just like the other collections:
0194 
0195 ```cpp
0196 #include "DANA/DStatusBits.h"
0197 
0198 
0199 locEvent->GetSingle<DStatusBits>()->GetStatusBit(kSTATUS_PHYSICS_EVENT)
0200 
0201 // or, for a little bit more safety:
0202 
0203 locEvent->GetSingleStrict<DStatusBits>()->GetStatusBit(kSTATUS_REST);
0204 ```
0205 
0206 
0207 ## Magnetic Field
0208 #### Getting Magnetic Field - `GetBField`
0209 
0210 ##### **JANA1**
0211 
0212 ```cpp
0213 #include "DANA/DApplication.h"
0214 
0215 dApplication = dynamic_cast<DApplication*>(locEventLoop->GetJApplication());
0216 dMagFMap= dApplication->GetBfield(locEventLoop->GetJEvent().GetRunNumber());
0217 
0218 ```
0219 ##### **JANA2**
0220 In JANA2, the magnetic field map is a resource handled analogously to `DGeometry` and `JCalibrationManager`. Thus, we recommend obtaining the 
0221 field map by calling `DEvent::GetBField(event)` from inside `BeginRun`:
0222 
0223 ```cpp
0224 #include "DANA/DEvent.h"
0225 
0226 dMagneticFieldMap = DEvent::GetBfield(locEvent);
0227 ```
0228 
0229 
0230 ## Get Functions
0231 ### JObject Getters
0232 
0233 #### 1. `GetSingleT`
0234 
0235 `GetSingleT` has been replaced with `GetSingle`. Templated methods no longer have a `T` suffix; templated classes (such as `JFactoryT`) still do.
0236 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 
0237 `nullptr`.
0238 
0239 ##### **JANA1**
0240 
0241 Was present in JANA1
0242 
0243 
0244 ##### **JANA2**
0245 
0246 No longer available in JANA2; use ```GetSingle()``` instead
0247 
0248 
0249 #### 2. `GetSingle`
0250 ##### **JANA1**
0251 
0252 ```cpp
0253 // Pass by reference
0254 // Set passed param equal to pointer to object
0255 const Df250PulsePedestal* PPobj = NULL;
0256 digihit->GetSingle(PPobj);
0257 ```
0258 
0259 ##### **JANA2**
0260 ```cpp
0261 // Template function
0262 // Return pointer to object
0263 auto PPobj = digihit->GetSingle<Df250PulsePedestal>();
0264 ```
0265 
0266 
0267 #### 3. `Get`
0268 
0269 Similarly to `GetSingle`, `Get` returns a vector rather than updating an out parameter.
0270 ##### **JANA1**
0271 
0272 ```cpp
0273 // Pass by Reference
0274 vector<const DBCALUnifiedHit*> assoc_hits;
0275 point.Get(assoc_hits);
0276 ```
0277 
0278 ##### **JANA2**
0279 ```cpp
0280 // Templated Function
0281 // Return value
0282 vector<const DBCALUnifiedHit*> assoc_hits = point.Get<DBCALUnifiedHit>();
0283 ```
0284 ### JEvent Getters
0285 
0286 
0287 #### 1. `GetSingle`
0288 ##### **JANA1**
0289 
0290 ```cpp
0291 // Pass by Reference, 
0292 // passed param got assigned pointer to object
0293 
0294 const DTTabUtilities* locTTabUtilities = NULL;
0295 loop->GetSingle(locTTabUtilities); 
0296 ```
0297 
0298 ##### **JANA2**
0299 ```cpp
0300 // Return the pointer to object based on template type
0301 
0302 const DTTabUtilities* locTTabUtilities = event->GetSingle<DTTabUtilities>();
0303 ```
0304 
0305 #### 2. `Get`
0306 ##### **JANA1**
0307 
0308 ```cpp
0309 // Pass by Reference
0310 vector<const DBCALShower*> showers;
0311 loop->Get(showers, "IU");
0312 ```
0313 
0314 ##### **JANA2**
0315 ```cpp
0316 // JANA1 Get is still available but will be deprecated soon
0317 // So better to use the one given below
0318 
0319 // Templated function
0320 // Return value
0321 auto showers = event->Get<DBCALShower>("IU");
0322 ```
0323 
0324 ## **JEventSource**
0325 ### Key Differences
0326 #### **1. Type name and Resource name
0327 
0328 JEventSources are identified by both a type name, e.g. "JEventSource_EVIO", and a resource name, e.g. "./hd_rawdata_123456_000.evio". JANA2 handles both of these differently than JANA1.
0329 
0330 In JANA1, the user was required to provide the type name manually by providing two callbacks:
0331 ```c++
0332 virtual const char* className();
0333 static const char* static_className();
0334 ```
0335 
0336 In JANA2, the class name is simply a member variable on the `JEventSource` base class, which the user may access via getters and setters:
0337 ```c++
0338 void SetTypeName(std::string type_name);
0339 std::string GetTypeName() const;
0340 ```
0341 Note that `JEventSourceGeneratorT` will automatically populate the type name. If a custom generator is being used, or no generator is used at all (e.g. for test cases), `SetTypeName()` should be called from inside the `JEventSource` constructor, just like with the other components.
0342 
0343 The resource name has similarly evolved.
0344 In JANA1, the resource name was always passed as a constructor argument and later accessed using `inline const char* GetSourceName()`. In JANA2, the resource name is a member variable accessed by `SetResourceName(std::string)` and `std::string GetResourceName() const`. While JANA2 still optionally accepts the resource name as a constructor argument for backwards compatibility, this is no longer preferred and will eventually be deprecated in favor of having `JEventSources` be default-constructible. `JEventSourceGeneratorT` already supports both constructor styles, and will automatically populate the resource name just like the type name, so the user shouldn't need to manually call `SetResourceName()`.
0345 
0346 
0347 #### **2. Event Retrieval (`GetEvent` & `Emit`)**
0348 
0349 In JANA1, populating and emitting a fresh event into the stream was done using `GetEvent`, which returned a `jerror_t` code to indicate success or failure. 
0350 
0351 In JANA2, `jerror_t` has been removed completely, and the `GetEvent` callback has been replaced. JANA2 supports two new callback signatures, with different error-handling approaches. JANA2 will choose which callback to use based off the `callbackStyle` flag. For JEventSources, the available callback styles are `ExpertMode` and `LegacyMode`.
0352 The purpose of the callback style flag is to enable smooth, gradual migrations in the future: components can opt-in to using new features on their own timetable without
0353 having to update everything everywhere.
0354 
0355 1. **`JEventSource::Result Emit(JEvent &event)`** – This is the preferred replacement for `GetEvent()`. It returns a `Result` enum with the following values: `Success` (indicating that a fresh event was successfully read), `FailureTryAgain` (indicating that no event was found, but more may be coming later), or `FailureFinished` (indicating that the file has or stream has run out of events and is ready to close). To tell JANA2 to use `Emit`, set the callback style to `ExpertMode` by calling `SetCallbackStyle(CallbackStyle::ExpertMode)` in the constructor.
0356 
0357 2. `GetEvent(std::shared_ptr<JEvent> event)` – This callback signature will be deprecated in the near future, and so should not be used for new code. However, we are including it here for completeness. This method returns `void` and signals different statuses by throwing exceptions instead of returning an error code. It throws a `RETURN_STATUS` enum value, which includes `kNO_MORE_EVENTS`, `kBUSY`, `kTRY_AGAIN`, `kERROR`, or `kUNKNOWN`. This callback will be called by default, or if you set `SetCallbackStyle(CallbackStyle::LegacyMode)` in the `JEventSource` constructor.
0358 
0359 | **Aspect**               | **JANA1**                                                                                                | **JANA2**                                                                                                                                                      |
0360 | ------------------------ | -------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
0361 | **`GetEvent`**           | `GetEvent(JEvent &event)` returns a `jerror_t` error code (e.g., `NOERROR`, `NO_MORE_EVENTS_IN_SOURCE`). | `GetEvent(std::shared_ptr<JEvent> event)` returns `void` and signals different statuses by throwing `RETURN_STATUS` enum values as exceptions.                 |
0362 | **Recommended - `Emit`** | _Not available._                                                                                         | `Emit(JEvent &event)` provides an alternative way to retrieve events. Instead of throwing an exception, it returns one of `Result` enum values to show status. |
0363 
0364 #### **3. `GetObjects` Implementation**
0365 JANA1’s `GetObjects` returned a `jerror_t`.  
0366 JANA2 replaces this with a `bool` return type. Never return a `jerror_t`, as the compiler may mistakenly perceive it as `true` when the intended meaning is `false`. Always return `true` if objects are found and `false` otherwise.
0367 
0368 | **Aspect**                    | **JANA1**                                                                 | **JANA2**                                                                                                                                              |
0369 | ----------------------------- | ------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
0370 | **GetObjects Implementation** | `jerror_t GetObjects(jana::JEvent &event, jana::JFactory_base *factory);` | `bool GetObjects(const std::shared_ptr<const JEvent> &event, JFactory* factory) override;` `bool` (return `true` if objects found, otherwise `false`). |
0371 
0372 #### **4. Enabling `GetObjects` Call**
0373 In **JANA1**, `GetObjects` was always called, leading to unnecessary performance overhead.  
0374 In **JANA2**, `GetObjects` is **disabled by default**. If the source file contains objects that should be used instead of being generated by factories, enable it in the event source constructor:
0375 
0376 ```cpp
0377 EnableGetObjects(true);
0378 ```
0379 
0380 |**Aspect**|**JANA1**|**JANA2**|
0381 |---|---|---|
0382 |**Enabling `GetObjects` Call**|Called by default for every event.|Disabled by default. Must be enabled with `EnableGetObjects(true)`.|
0383 
0384 #### **5. Calling `FinishEvent`**
0385 In **JANA1**, `FreeEvent` was always called automatically after an event was processed, but this required acquiring/releasing locks, adding performance overhead. In **JANA2**, `FinishEvent` replaces `FreeEvent` and is **disabled by default** for efficiency. If additional logic should run at the end of each event, enable it manually in the event source constructor:
0386 
0387 ```cpp
0388 EnableFinishEvent(true);
0389 ```
0390 
0391 |**Aspect**|**JANA1**|**JANA2**|
0392 |---|---|---|
0393 |**Calling `FinishEvent`**|`FreeEvent` was always called automatically.|`FinishEvent` is disabled by default to improve performance.|
0394 
0395 #### 6. Resource lifetimes (`Open()` and `Close()`)
0396 
0397 In **JANA1**, the initialization of parameters and opening of the file or socket was done inside the constructor, and the closing of the file or socket was done inside the destructor. In **JANA2**, the lifecycle is **explicitly managed** using the `Init()`, `Open()` and `Close()` callbacks:
0398 
0399 | **Aspect**           | **JANA1**                   | **JANA2**                                                                    |
0400 | -------------------- | --------------------------- | ---------------------------------------------------------------------------- |
0401 | **Initialization**   | Handled in the constructor. | `Init()` should be used for obtaining parameters and services. |
0402 | **Opening a Source** | Handled in the constructor. | `Open()` is called when JANA is ready to accept events from the event source |
0403 | **Closing a Source** | Handled in the destructor.  | `Close()` is called when the source is done processing events.               |
0404 
0405 These methods allow better resource management by ensuring that the event source is properly opened before processing events and properly cleaned up afterwards.
0406 
0407 ##### **Example Usage in JANA2**
0408 ```cpp
0409 void JEventSource_Sample::Open() {
0410 // Initialize resources (e.g., open files, set up connections)
0411 }
0412 
0413 void JEventSource_Sample::Close() {
0414  // Release resources (e.g., close files, disconnect)
0415 }
0416 ```
0417 
0418 
0419 ### **JEventSource Header Files**
0420 ##### **JANA1**
0421 ```cpp
0422 #ifndef _JEventSource_Sample_
0423 #define _JEventSource_Sample_
0424 
0425 #include <JANA/jerror.h>
0426 #include <JANA/JApplication.h>
0427 #include <JANA/JEventSource.h>
0428 #include <JANA/JEvent.h>
0429 #include <JANA/JFactory.h>
0430 #include <JANA/JStreamLog.h>
0431 
0432 class JEventSource_Sample: public jana::JEventSource {
0433 public:
0434     JEventSource_Sample(const char* source_name);
0435     virtual ~JEventSource_Sample();
0436 
0437     virtual const char* className(void) { return static_className(); }
0438     static const char* static_className(void) { return "JEventSource_Sample"; }
0439 
0440     jerror_t GetEvent(JEvent &event);
0441     void FreeEvent(JEvent &event);
0442     jerror_t GetObjects(JEvent &event, jana::JFactory_base *factory);
0443 };
0444 
0445 #endif // _JEventSource_Sample_
0446 ```
0447 ##### **JANA2**
0448 ```cpp
0449 #pragma once
0450 
0451 #include <JANA/JApplication.h>
0452 #include <JANA/JEventSource.h>
0453 #include <JANA/JEvent.h>
0454 #include <JANA/JFactory.h>
0455 #include <JANA/Compatibility/JStreamLog.h>
0456 
0457 class JEventSource_Sample : public JEventSource {
0458 public:
0459     JEventSource_Sample(std::string resource_name) {
0460             SetTypeName(NAME_OF_THIS);
0461             SetCallbackStyle(CallbackStyle::ExpertMode);
0462             EnableGetObjects(true); 
0463             EnableFinishEvent(true); 
0464     }
0465     virtual ~JEventSource_Sample();
0466 
0467     void Init() override;
0468     void Open() override;
0469     void Close() override;
0470     void FinishEvent(JEvent& event) override;
0471     Result Emit(JEvent& event) override;
0472     bool GetObjects(const std::shared_ptr<const JEvent>& event, JFactory* factory) override;
0473 };
0474 ```
0475 
0476 ## JEventProcessor
0477 ### JEventProcessor Header File
0478 
0479 `JEventProcessors` in JANA2 have a similar feel to JANA1. The key differences are:
0480 
0481 1. The names and type signatures of the callbacks have changed
0482 2. The event number and run number now live on the JEvent object rather than as separate arguments
0483 3. JANA2 doesn't use `jerror_t` anywhere for several reasons: there's too many options to exhaustively check, most 
0484 error codes don't apply to JEventProcessors, there's no clear indication which error codes represent failure conditions,
0485 and no reasonable strategy JANA can take if a failure is reached other than a premature exit. Thus the callbacks return
0486 void. 
0487 4. If a failure condition is reached in user code, the user should throw a `JException` with a detailed message. JANA will
0488 add additional context information (such as the component name, callback, plugin, and backtrace), log everything, and shut
0489 down cleanly.
0490 5. The user no longer provides a `className` callback. Instead, they call `SetTypeName(NAME_OF_THIS);` from the constructor.
0491 
0492 ##### JANA1
0493 
0494 ```cpp
0495 #ifndef _JEventProcessor_myplugin_
0496 #define _JEventProcessor_myplugin_
0497 
0498 #include <JANA/JApplication.h>
0499 #include <JANA/JFactory.h>
0500 #include <JANA/JEventProcessor.h>
0501 using namespace jana;
0502   
0503 
0504 class JEventProcessor_myplugin : public jana::JEventProcessor{
0505 public:
0506         JEventProcessor_myplugin();
0507         ~JEventProcessor_myplugin();
0508         const char* className(void){return "JEventProcessor_myplugin";}
0509 
0510 private:
0511         jerror_t init(void); 
0512         jerror_t brun(jana::JEventLoop *eventLoop, int32_t runnumber); 
0513         jerror_t evnt(jana::JEventLoop *eventLoop, uint64_t eventnumber); 
0514         jerror_t erun(void); 
0515         jerror_t fini(void); 
0516 
0517 };
0518 
0519 #endif // _JEventProcessor_myplugin_
0520 ```
0521 
0522 ##### JANA2
0523 
0524 ```cpp
0525 #ifndef _JEventProcessor_myplugin_
0526 #define _JEventProcessor_myplugin_
0527 #include <JANA/JEventProcessor.h>
0528 
0529 class JEventProcessor_myplugin : public JEventProcessor {
0530 
0531 public:
0532         JEventProcessor_myplugin() { 
0533         SetTypeName(NAME_OF_THIS);
0534     }
0535         ~JEventProcessor_myplugin() = default;
0536 
0537 private:
0538         void Init() override;
0539         void BeginRun(const std::shared_ptr<const JEvent>& event) override; 
0540         void Process(const std::shared_ptr<const JEvent>& event) override; 
0541         void EndRun() override; 
0542         void Finish() override; 
0543 };
0544 
0545 #endif // _JEventProcessor_myplugin_
0546 ```
0547 
0548 ## JObject
0549 ### JObject Header File
0550 
0551 
0552 `JObjects` in JANA2 are also conceptually similar to their JANA1 counterparts, with a
0553 syntax refresh aimed at future extensibility. The `toStrings` callback has been
0554 replaced with a `Summarize` callback as shown below. Note that in JANA2, data model classes
0555 do not need to inherit from `JObject` anymore - `JObject` merely provides clean, user-specified formatting, 
0556 and convenient simple tracking of object associations. JANA2 also supports using [PODIO](https://github.com/AIDASoft/podio)
0557 based data models, which provide free serialization/deserialization, a first-class Python interface, automatic
0558 memory management and immutability guarantees, and relational object associations.
0559 
0560 ##### JANA1
0561 ```cpp
0562 #include <JANA/JObject.h>
0563 #include <JANA/JFactory.h>
0564 
0565 using namespace jana;
0566 
0567 class DCereHit: public JObject {
0568 public:
0569 
0570     JOBJECT_PUBLIC(DCereHit);
0571     int sector; 
0572     float pe; 
0573     float t;
0574 
0575     void toStrings(vector<pair<string, string> >&items) const { 
0576         AddString(items, "sector", "%d", sector);
0577         AddString(items, "pe", "%1.3f", pe);
0578         AddString(items, "t", "%1.3f", t);
0579     }
0580 };
0581 ```
0582 
0583 ##### JANA2
0584 
0585 ```cpp
0586 #include <JANA/JObject.h>
0587 
0588 class DCereHit: public JObject {
0589 public:
0590 
0591     JOBJECT_PUBLIC(DCereHit);
0592     int sector;
0593     float pe;
0594     float t;
0595 
0596     void Summarize(JObjectSummary& summary) const override {
0597         summary.add(sector, "sector", "%d");
0598         summary.add(pe, "pe", "%1.3f");
0599         summary.add(t, "t", "%1.3f");
0600     }
0601 };
0602 ```
0603 ### JObject ID Handling
0604 
0605 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
0606 that it is set reliably or consistently, it is fundamentally part of the data model and not part of the framework. Thus, JANA2 
0607 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
0608 establish a convention for how and when it gets set. For reliable, automatic object IDs for all data model classes, consider using PODIO.
0609 
0610 
0611 ##### **JANA1**
0612 ```cpp
0613 // JANA1 JObject had a data member id
0614 
0615 DBCALShower *shower = new DBCALShower;
0616 shower->id = id++;
0617 ```
0618 ##### **JANA2**
0619 
0620 ```cpp
0621 // id data member does not exist in JObject anymore in JANA2
0622 
0623 DBCALShower *shower = new DBCALShower;
0624 shower->id = id++; // Compiler error
0625 ```
0626 
0627 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:
0628 
0629 ```cpp
0630 #include "DANA/DObjectID.h"
0631 
0632 oid_t // Not inside JObject anymore!
0633 ```
0634 
0635 ## JFactory
0636 ### Transition from JFactory to JFactoryT
0637 ##### **JANA1**
0638 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.
0639 ##### **JANA2**
0640 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. 
0641 
0642 The syntax differences between JANA1 and JANA2 `JFactory`s' are consistent with those for `JEventProcessor`s. 
0643 
0644 1. The names and type signatures of the callbacks have changed
0645 2. The event number and run number now live on the JEvent object rather than as separate arguments
0646 3. JANA2 doesn't use `jerror_t` anywhere for several reasons: there's too many options to exhaustively check, most 
0647 error codes don't apply to JEventProcessors, there's no clear indication which error codes represent failure conditions,
0648 and no reasonable strategy JANA can take if a failure is reached other than a premature exit. Thus the callbacks return
0649 void. 
0650 4. If a failure condition is reached in user code, the user should throw a `JException` with a detailed message. JANA will
0651 add additional context information (such as the component name, callback, plugin, and backtrace), log everything, and shut
0652 down cleanly.
0653 5. The user no longer provides a `className` callback. Instead, they call `SetTypeName(NAME_OF_THIS);` from the constructor.
0654 
0655 Another important difference is how factory tags are set. In JANA1, the user provides a `Tag()` callback, whereas in JANA2,
0656 the user sets the tag by calling `SetTag()` from the constructor. The user can retrieve the factory tag by calling `GetTag()`.
0657 
0658 One important semantic difference is that in JANA1, there is always one factory set assigned to each thread, whereas in JANA2, 
0659 there is one factory set for each event in flight. The number of in-flight events is a parameter controlled separately 
0660 from the thread count. This is important for ensuring that there is always work for threads to do when running 
0661 multi-level processing topologies. Another consequence of this design is that factories don't belong to just one thread and hence 
0662 shouldn't reference thread-local variables - instead, one thread can pop an event from a queue, process it, and push it to a 
0663 different queue, where it could later be picked up by a different thread. Importantly, however, only one thread has access to any 
0664 given JEvent and its corresponding factory set at any time, so you don't need to worry about thread safety in JFactories.
0665 
0666 ### Factory Header File
0667 
0668 ##### JANA1
0669 
0670 ```cpp
0671 #ifndef _myfactory_factory_
0672 #define _myfactory_factory_
0673 
0674 #include <JANA/JFactory.h>
0675 #include "myobject.h"
0676 
0677 class myfactory_factory : public jana::JFactory<myobject> {
0678 
0679 public:
0680     myfactory_factory() = default;
0681     ~myfactory_factory() = default;
0682 
0683     const char* Tag() { return "MyTag"; }
0684 
0685 private:
0686     jerror_t init(void); 
0687     jerror_t brun(jana::JEventLoop *eventLoop, int32_t runnumber); 
0688     jerror_t evnt(jana::JEventLoop *eventLoop, uint64_t eventnumber); 
0689     jerror_t erun(void); 
0690     jerror_t fini(void); 
0691 };
0692 
0693 #endif
0694 ```
0695 
0696 ##### JANA2
0697 
0698 ```cpp
0699 #ifndef _thirdFacTest_factory_
0700 #define _thirdFacTest_factory_
0701 
0702 #include <JANA/JFactoryT.h>
0703 #include "myobject.h"
0704 
0705 class thirdFacTest_factory : public JFactoryT<myobject> {
0706 public:
0707     thirdFacTest_factory() { 
0708         SetTag("MyTag");
0709     }
0710     ~thirdFacTest_factory() = default;
0711 
0712 private:
0713     void Init() override;
0714     void BeginRun(const std::shared_ptr<const JEvent>& event) override; 
0715     void Process(const std::shared_ptr<const JEvent>& event) override; 
0716     void EndRun() override; 
0717     void Finish() override; 
0718 };
0719 
0720 #endif
0721 ```
0722 
0723 ### Registering a New Factory
0724 
0725 In JANA1, the user creates a `JFactoryGenerator` with a `GenerateFactories()` callback. Within this callback, 
0726 the user instantiates new factories and adds them to a `JEventLoop`. (In `halld_recon`, there is a `DFactoryGenerator`
0727 which instantiates factories for all fundamental detector plugins, calling each plugin's corresponding 
0728 `$DETECTOR_init()` function.)
0729 
0730 In JANA2, the user is still free to create their own `JFactoryGenerator`. It's syntax has been modified (notably, 
0731 `GenerateFactories()` provides a `JFactorySet` argument that the user adds the factories to), but the core concepts
0732 are the same. However, there is now also a `JFactoryGeneratorT` utility which reduces the boilerplate. As long
0733 as the factory is default constructible, the user merely needs to pass the factory class as a template argument to
0734 `JFactoryGeneratorT`, and JANA will do the rest of the work. JANA2 is perfectly fine with users passing a single 
0735 `JFactoryGenerator` that instantiates every single factory in the system, but there are future benefits if users
0736 pass separate `JFactoryGeneratorT`s for each factory instead.
0737 
0738 
0739 ##### **JANA1**
0740 
0741 ```cpp
0742 #include <JANA/JApplication.h>
0743 #include "JFactoryGenerator_myfactory.h"
0744 #include "myfactory.h"
0745 
0746 using namespace jana;
0747 
0748 extern "C" {
0749 void InitPlugin(JApplication *app) {
0750         InitJANAPlugin(app);
0751         app->AddFactoryGenerator(new JFactoryGenerator_myfactory());
0752 }
0753 } // "C"
0754 ```
0755 
0756 ##### **JANA2**
0757 
0758 ```cpp
0759 #include <JANA/JApplication.h>
0760 #include <JANA/JFactoryGenerator.h>
0761 #include "myfactory.h"
0762 
0763 extern "C" {
0764 void InitPlugin(JApplication *app) {
0765         InitJANAPlugin(app);
0766         app->Add(new JFactoryGeneratorT<my_factory>());
0767 }
0768 } // "C"
0769 ```
0770 
0771 ### Getting All Factories
0772 
0773 Sometimes it is necessary to retrieve all factories that produce objects of a given type. In
0774 JANA1 this was done by retrieving all factories and doing a `dynamic_cast`. In JANA2 there's a
0775 dedicated method for this, `GetFactoryAll`. (Note that this will retrieve the factories without
0776 automatically running them!). JANA2 also supports retrieving all objects of type `T` from all
0777 factories using `GetAll()` and retrieving all objects descended from parent type `T` 
0778 (e.g. `JObject` or `TObject`) using `GetAlllChildren()`.
0779 
0780 ##### **JANA1**
0781 
0782 ```cpp
0783 vector<JFactory_base*> locFactories = locEventLoop->GetFactories();
0784 // Cast JFactory_base to particular factory type
0785 JFactory<DReaction>* locFactory = dynamic_cast<JFactory<DReaction>*>(locFactories[0]);
0786 ```
0787 
0788 ##### **JANA2**
0789 
0790 ```cpp
0791 // Retrieve all factories producing T directly
0792 vector<JFactoryT<DReaction>*> locFacs = locEvent->GetFactoryAll<DReaction>();
0793 ```
0794 
0795 ### Saving Created Object(s) to Factory
0796 
0797 When writing a factory, the user creates some data objects inside `Process()` and
0798 then needs to pass them back to JANA. In JANA1, this was done by modifying the
0799 `_data` member variable directly. In JANA2, we prefer using a dedicated setter method.
0800 For the sake of porting GlueX without having to rewrite certain complex factories, 
0801 we've left the member variable `protected`, though the member variable has been 
0802 renamed to `mData`.
0803 
0804 ##### _Single Object_
0805 ###### **JANA1**
0806 
0807 ```cpp
0808 _data.push_back(locAnalysisResults);
0809 ```
0810 
0811 ###### **JANA2**
0812 
0813 ```cpp
0814 Insert(locAnalysisResults);
0815 
0816 // Or (less preferred)
0817 mData.push_back(locAnalysisResults);
0818 ```
0819 
0820 ##### _Array of Objects_
0821 
0822 ```cpp
0823 std::vector<Hit*> results;
0824 results.push_back(new Hit(...));
0825 ```
0826 
0827 ###### **JANA1**
0828 
0829 ```cpp
0830 for (auto hit: results){
0831         _data.push_back(hit); 
0832 }
0833 ```
0834 
0835 ###### **JANA2**
0836 
0837 ```cpp
0838 Set(results)
0839 ```
0840 
0841 ### **Setting Factory Flag**
0842 In JANA1, factory flag was set by calling `SetFactoryFlag(FLAG_NAME)` inside the factory constructor. The available flags were:
0843 
0844 ```cpp
0845 enum JFactory_Flags_t {
0846     JFACTORY_NULL      = 0x00,
0847     PERSISTANT         = 0x01,  // Misspelling of "PERSISTENT"
0848     WRITE_TO_OUTPUT    = 0x02,
0849     NOT_OBJECT_OWNER   = 0x04
0850 };
0851 ```
0852 
0853 JANA2 retains the same approach but introduces an additional flag while correcting the spelling of `PERSISTANT`:
0854 
0855 ```cpp
0856 enum JFactory_Flags_t {
0857     JFACTORY_NULL     = 0x00,
0858     PERSISTENT        = 0x01,  // Corrected spelling
0859     WRITE_TO_OUTPUT   = 0x02,
0860     NOT_OBJECT_OWNER  = 0x04,
0861     REGENERATE        = 0x08   // New flag
0862 };
0863 ```
0864 #### **Key Differences**
0865 ##### **1. `REGENERATE` – Forcing the Factory to Regenerate Objects**
0866 In JANA2, the `REGENERATE` flag prevents JANA from searching for objects in the input file, replicating the behavior of `use_factory = 1` in JANA1.
0867 ###### **JANA1:**
0868 ```cpp
0869 DEventWriterROOT_factory_ReactionEfficiency() {
0870     use_factory = 1; 
0871 };
0872 ```
0873  ###### **JANA2:**
0874 ```cpp
0875 DEventWriterROOT_factory_ReactionEfficiency() {
0876     SetRegenerateFlag(REGENERATE);
0877 };
0878 ```
0879 
0880 Alternatively, you can enable the `REGENERATE` flag using a boolean value:
0881 
0882 ```cpp
0883 DEventWriterROOT_factory_ReactionEfficiency() {
0884     SetRegenerateFlag(true);
0885 };
0886 ```
0887 
0888 ##### **2. `PERSISTENT` – Making Factory-Generated Objects Persistent**
0889 In JANA1, objects were made persistent by calling `SetFactoryFlag(PERSISTANT)`. JANA2 corrects the spelling mistake, renaming it to `PERSISTENT`, while maintaining the same core functionality. However, there is a key difference in how persistent objects are handled:
0890 - **JANA1:** The destructors of persistent objects are called automatically when the process terminates.
0891 - **JANA2:** The destructors of persistent objects are never called automatically, meaning any logic inside them will not execute unless the objects are explicitly deleted by the user. Therefore, if you set the `PERSISTENT` flag, you must manually delete these objects inside the factory’s `Finish()` method to prevent memory leaks.
0892 &nbsp;
0893     ```cpp
0894     void Finish() {
0895         for (auto locInfo : mData) {
0896             delete locInfo;
0897         }
0898         mData.clear();
0899     }
0900     ```
0901 
0902 ## JEvent
0903 ### Transition from JEventLoop to JEvent
0904 ##### **JANA1**
0905 In JANA1, all processing operated on a `JEventLoop` object. In JANA2, this has been changed to `JEvent`.
0906 Conceptually, a `JEvent` is just a container for data that can be processed as a discrete unit, indepedently from the rest
0907 of the stream (this usually correspondings to a physics event, but also potentially a timeslice, block, subevent, etc). This includes the 
0908 event number, run number, all data read from the event source, all data created by factories so far, and all of
0909 the factory state necessary to generate additional data belonging to the same context. The factories themselves are managed by a `JFactorySet`
0910 which is one-to-one with and owned by the JEvent.
0911 
0912 ### Getting the Run Number
0913 ##### **JANA1**
0914 ```cpp
0915 run_number = locEventLoop->GetJEvent().GetRunNumber());
0916 ```
0917 ##### **JANA2**
0918 ```cpp
0919 locEvent->GetRunNumber()
0920 ```
0921 
0922 #### Getting the Event Number
0923 ##### **JANA1**
0924 
0925 ```cpp
0926 run_number = locEventLoop->GetJEvent().GetEventNumber());
0927 ```
0928 ##### **JANA2**
0929 
0930 ```cpp
0931 locEvent->GetEventNumber()
0932 ```
0933 
0934 ## Acquiring Locks
0935 
0936 JANA1 required the user to manually acquire and hold locks when accessing to shared resources in a JEventProcessor.
0937 JANA2 offers a different interface which handles all locks internally. However, using this new callback interface
0938 would require restructuring the existing `JEventProcessor` code. When migrating from JANA1 to JANA2 it 
0939 is much safer to avoid making such deep changes, at least initially. The old-style user-managed locks can be migrated
0940 to JANA2 as-is with one minor change: the various lock helper methods have been moved from `JApplication` to `JLockService`.
0941 
0942 
0943 ### ROOT Read/Write locks
0944 ##### JANA1
0945 
0946 ```cpp
0947 dActionLock = japp->RootReadLock(); 
0948 // ...
0949 japp->RootUnLock(locLockName);
0950 ```
0951 ##### JANA2
0952 
0953 ```cpp
0954 auto app = GetApplication(); // or event->GetJApplication()
0955 auto lock_svc = app->GetService<JLockService>();
0956 
0957 lock_svc->RootReadLock(); 
0958 // ...
0959 lock_svc->RootUnLock();
0960 ```
0961 
0962 To reduce boilerplate, we've added a helper function:
0963 
0964 ```cpp
0965 #include "DANA/DEvent.h"
0966 
0967 DEvent::GetLockService(locEvent)->RootWriteLock(); 
0968 DEvent::GetLockService(locEvent)->RootUnLock();
0969 ```
0970 
0971 ### Named locks
0972 
0973 ##### JANA1
0974 
0975 ```cpp
0976 dActionLock = japp->ReadLock(locLockName); 
0977 // ...
0978 pthread_rwlock_unlock(dActionLock);
0979 // Or: japp->Unlock(locLockName);
0980 ```
0981 
0982 ##### JANA2
0983 
0984 ```cpp
0985 auto app = GetApplication(); // or event->GetJApplication()
0986 auto lock_svc = app->GetService<JLockService>();
0987 
0988 dActionLock = lock_svc->ReadLock(locLockName); 
0989 // ...
0990 pthread_rwlock_unlock(dActionLock);
0991 // Or: lock_svc->Unlock(locLockName);
0992 ```
0993 
0994 To reduce boilerplate:
0995 
0996 ```cpp
0997 DEvent::GetLockService(locEvent)->ReadLock("app"); 
0998 DEvent::GetLockService(locEvent)->Unlock("app");
0999 ```
1000 ## Deprecated Headers & Functions
1001 
1002 ### Why Do These Warnings Appear?
1003 When building a plugin ported to JANA2, you may see deprecation warnings (deprecated headers etc.). These headers and functions exist in JANA2 only for backward compatibility with JANA1 and are marked as deprecated to discourage their use, as they may be removed in the future.
1004 
1005 ### Can These Warnings Be Ignored?
1006 Yes, as long as your plugin compiles without crashes. They don't have any immediate impact on functionality. However, it’s better to update to the latest headers and functions because:
1007 - Deprecated headers and functions may be removed completely in future JANA2 versions.
1008 - Using them can slightly slow down compilation.
1009 ### How to Remove These Warnings?
1010 Replace deprecated headers and functions in your plugin code with alternatives provided in following table:
1011 
1012 | **Deprecated** | **Use Instead** |  
1013 |--------------------------|---------------------------|  
1014 | `#include <JANA/Compatibility/JLockService.h>` | `#include <JANA/Services/JLockService.h>` |  
1015 | `#include <JANA/Compatibility/JGeometry.h>` | `#include <JANA/Geometry/JGeometry.h>` |  
1016 | `#include <JANA/Calibrations/JLargeCalibration.h>` | `#include <JANA/Calibrations/JResource.h>` |  
1017 | `auto *jlargecalib = DEvent::GetJLargeCalibration(event);` | `auto *res = DEvent::GetJResource(event);` |  
1018 | `jlargecalib->GetResource(dedx_i_theta_file_name["file_name"]);` | `res->GetResource(dedx_i_theta_file_name["file_name"]);` |  
1019 | `JLargeCalibration *jresman;` | `JResource *jresman;` |  
1020 | `jresman = calib_svc->GetLargeCalibration(runnumber);` | `jresman = calib_svc->GetResource(runnumber);` |  
1021 | `#include <JANA/Compatibility/JGeometryXML.h>` | `#include <JANA/Geometry/JGeometryXML.h>` |  
1022 | `#include <JANA/Compatibility/JGeometryManager.h>` | `#include <JANA/Geometry/JGeometryManager.h>` |  
1023 | `#include <JANA/Compatibility/JStatusBits.h>` | `#include <JANA/Utils/JStatusBits.h>` |  
1024 | `#include <JANA/Compatibility/jerror.h>` | `#include <DANA/jerror.h>` |  
1025 
1026 
1027 ## Rarely Used Features
1028 
1029 ### `Unknown` Handling
1030 
1031 The enum in `particleType.h` was experiencing a name conflict with a JANA2 enum, so it has been changed
1032 to an enum class.
1033 
1034 ##### **JANA1**
1035 
1036 ```cpp
1037 //Was a plain enum so could be accessed without any scope resolution operator
1038 
1039 #include "particleType.h"
1040 
1041 return ((locFirstStep->Get_TargetPID() != Unknown) || (locFirstStep->Get_SecondBeamPID() != Unknown));
1042 ```
1043 
1044 ##### **JANA2**
1045 ```cpp
1046 // Is Enum class now so could be accessed like this `Particle_t::Unknown` only
1047 
1048 #include "particleType.h"
1049 
1050 return ((locFirstStep->Get_TargetPID() != Particle_t::Unknown) || (locFirstStep->Get_SecondBeamPID() != Particle_t::Unknown));
1051 ```