From 64b386671d82fc2b449ce74fcd0d742c46f4ae01 Mon Sep 17 00:00:00 2001
From: Chris Jones <jonesc@hep.phy.cam.ac.uk>
Date: Mon, 9 Oct 2023 15:30:44 +0100
Subject: [PATCH] Add new algorithm DecodedDataAddMCInfo

---
 Rich/RichFutureMCUtils/CMakeLists.txt         |   1 +
 .../src/component/DecodedDataAddMCInfo.cpp    | 137 ++++++++++++++++++
 2 files changed, 138 insertions(+)
 create mode 100644 Rich/RichFutureMCUtils/src/component/DecodedDataAddMCInfo.cpp

diff --git a/Rich/RichFutureMCUtils/CMakeLists.txt b/Rich/RichFutureMCUtils/CMakeLists.txt
index d683da23616..1b80b497a40 100644
--- a/Rich/RichFutureMCUtils/CMakeLists.txt
+++ b/Rich/RichFutureMCUtils/CMakeLists.txt
@@ -33,6 +33,7 @@ gaudi_add_module(RichFutureMCUtils
     SOURCES
         src/component/TrackToMCParticleRelations.cpp
         src/component/DecodedDataFromMCRichHits.cpp
+        src/component/DecodedDataAddMCInfo.cpp
     LINK
         LHCb::LHCbAlgsLib
         LHCb::LinkerEvent
diff --git a/Rich/RichFutureMCUtils/src/component/DecodedDataAddMCInfo.cpp b/Rich/RichFutureMCUtils/src/component/DecodedDataAddMCInfo.cpp
new file mode 100644
index 00000000000..7a9b9d1b3ab
--- /dev/null
+++ b/Rich/RichFutureMCUtils/src/component/DecodedDataAddMCInfo.cpp
@@ -0,0 +1,137 @@
+/*****************************************************************************\
+* (c) Copyright 2000-2018 CERN for the benefit of the LHCb Collaboration      *
+*                                                                             *
+* This software is distributed under the terms of the GNU General Public      *
+* Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING".   *
+*                                                                             *
+* In applying this licence, CERN does not waive the privileges and immunities *
+* granted to it by virtue of its status as an Intergovernmental Organization  *
+* or submit itself to any jurisdiction.                                       *
+\*****************************************************************************/
+
+// Rich (Future) Kernel
+#include "RichFutureKernel/RichAlgBase.h"
+
+// Gaudi Functional
+#include "LHCbAlgs/Transformer.h"
+
+// Rich Utils
+#include "RichFutureUtils/RichDecodedData.h"
+#include "RichUtils/RichSmartIDSorter.h"
+
+// Event Model
+#include "Event/MCRichHit.h"
+
+#include <map>
+#include <memory>
+#include <tuple>
+
+namespace Rich::Future::MC {
+
+  using namespace Rich::Future::DAQ;
+
+  /** @class DecodedDataFromMCRichHits
+   *
+   *  Update decoded data with MC information (e.g. time)
+   *
+   *  @author Chris Jones
+   *  @date   2016-12-07
+   */
+  class DecodedDataAddMCInfo final
+      : public LHCb::Algorithm::Transformer<DecodedData( DecodedData const&, LHCb::MCRichHits const& ),
+                                            Gaudi::Functional::Traits::BaseClass_t<AlgBase<>>> {
+
+  public:
+    /// Standard constructor
+    DecodedDataAddMCInfo( const std::string& name, ISvcLocator* pSvcLocator )
+        : Transformer( name, pSvcLocator,
+                       // inputs
+                       {KeyValue{"InDecodedDataLocation", DecodedDataLocation::Default},
+                        KeyValue{"MCRichHitsLocation", LHCb::MCRichHitLocation::Default}},
+                       // output
+                       {KeyValue{"OutDecodedDataLocation", DecodedDataLocation::Default}} ) {
+      // setProperty( "OutputLevel", MSG::VERBOSE ).ignore();
+    }
+
+  public:
+    /// Algorithm execution via transform
+    DecodedData operator()( DecodedData const& data, LHCb::MCRichHits const& mchits ) const override {
+
+      // Collect all the (signal) hits in the same pixel
+      std::map<LHCb::RichSmartID, std::vector<LHCb::MCRichHit*>> hitsPerPix;
+      for ( const auto mchit : mchits ) {
+        auto id = mchit->sensDetID().channelDataOnly();
+#ifdef USE_DD4HEP
+        if ( m_detdescMCinput ) {
+          // If built for DD4HEP apply correction to PMT module numbers to account
+          // for different numbering scheme between DD4HEP and DetDesc.
+          // Option needs to be explicitly activated only when input is known to
+          // be DetDesc based MC.
+          // ***** To eventually be removed when DetDesc finally dies completely *****
+          const Rich::DetectorArray<Rich::PanelArray<LHCb::RichSmartID::DataType>> mod_corr{{{0, 0}, {6, 18}}};
+          const auto pdMod      = id.pdMod() + mod_corr[id.rich()][id.panel()];
+          const auto pdNumInMod = id.pdNumInMod();
+          id.setPD( pdMod, pdNumInMod );
+        }
+#endif
+        if ( id.isValid() ) { hitsPerPix[id].push_back( mchit ); }
+      }
+
+      // Clone decoded data
+      DecodedData out_data = data;
+
+      // Loop over data and add MC time info
+      // First, RICH detectors
+      for ( auto& rD : out_data ) {
+        // sides per RICH
+        for ( auto& pD : rD ) {
+          // PD modules per side
+          for ( auto& mD : pD ) {
+            // PDs per module
+            for ( auto& pd : mD ) {
+              // IDs per PD
+              for ( auto& id : pd.smartIDs() ) {
+                // Do we have any MChits for this ID
+                const auto& pix_mchits = hitsPerPix[id];
+                if ( !pix_mchits.empty() ) {
+                  // Find best MCHit to use. Either first labelled as single, otherwise
+                  // just the first in the container
+                  const auto* mch = pix_mchits.front();
+                  for ( const auto* h : pix_mchits ) {
+                    if ( h->isSignal() ) {
+                      mch = h;
+                      break;
+                    }
+                  }
+                  if ( m_useMCTime ) {
+                    // Set time in ID
+                    id.setTime( mch->timeOfFlight() );
+                    _ri_verbo << id << endmsg;
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+
+      // return
+      return out_data;
+    }
+
+  private:
+    // properties
+
+    /** Temporary workaround for processing DetDesc MC as input.
+     *  When active, applies corrections to the data to make compatible
+     *  with the dd4hep builds. */
+    Gaudi::Property<bool> m_detdescMCinput{this, "IsDetDescMC", true};
+
+    /// Enable use of MC time info
+    Gaudi::Property<bool> m_useMCTime{this, "UseMCTime", true};
+  };
+
+  // Declaration of the Algorithm Factory
+  DECLARE_COMPONENT( DecodedDataAddMCInfo )
+
+} // namespace Rich::Future::MC
-- 
GitLab