Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:13:24

0001 //==========================================================================
0002 //  AIDA Detector description implementation 
0003 //--------------------------------------------------------------------------
0004 // Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
0005 // All rights reserved.
0006 //
0007 // For the licensing terms see $DD4hepINSTALL/LICENSE.
0008 // For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
0009 //
0010 // Author     : M.Frank
0011 //
0012 //==========================================================================
0013 
0014 // Framework includes
0015 #include <DDAlign/AlignmentsCalib.h>
0016 
0017 #include <DD4hep/Memory.h>
0018 #include <DD4hep/Printout.h>
0019 #include <DD4hep/DetectorTools.h>
0020 #include <DD4hep/detail/AlignmentsInterna.h>
0021 
0022 using namespace dd4hep::align;
0023 
0024 /// Helper class to store information about alignment calibration items
0025 /**  Implementation details: Alignment context entry
0026  *
0027  *   \author  M.Frank
0028  *   \version 1.0
0029  *   \date    31/01/2017
0030  *   \ingroup DD4HEP_DDALIGN
0031  */
0032 class AlignmentsCalib::Entry   {
0033 public:
0034   dd4hep::Delta                  delta;
0035   dd4hep::Delta                  original;
0036   dd4hep::Condition              source;
0037   dd4hep::DetElement             detector;
0038   dd4hep::Condition::key_type    target = 0;
0039   int                            dirty  = 0;
0040   Entry() = default;
0041   Entry(const Entry& c) = delete;
0042   Entry& operator=(const Entry& c) = delete;
0043 };
0044  
0045 /// Initializing constructor
0046 AlignmentsCalib::AlignmentsCalib(Detector& det, ConditionsMap& cond_map)
0047   : description(det), slice(cond_map)
0048 {
0049 }
0050 
0051 /// Default destructor
0052 AlignmentsCalib::~AlignmentsCalib()   noexcept(false)  {
0053   clear();
0054 }
0055 
0056 /// Convenience only: Access detector element by path
0057 dd4hep::DetElement AlignmentsCalib::detector(const std::string& path)  const   {
0058   DetElement det(detail::tools::findElement(description,path));
0059   return det;
0060 }
0061 
0062 /// Implementation: Add a new entry to the transaction stack.
0063 std::pair<dd4hep::Condition::key_type,AlignmentsCalib::Entry*>
0064 AlignmentsCalib::_set(DetElement detector, const Delta& delta)   {
0065   ConditionKey tar_key(detector.key(),Keys::alignmentKey);
0066   UsedConditions::iterator i = used.find(tar_key.hash);
0067   if ( i != used.end() )   {
0068     (*i).second->delta = delta;
0069     return (*i);
0070   }
0071 
0072   Condition src_cond  = slice.get(detector,Keys::deltaKey);
0073   if ( !src_cond.isValid() )   {
0074     // Try to create a new condition and register it to the
0075     // conditions manager from the delta value.
0076     ConditionKey key(detector, Keys::deltaKey);
0077     src_cond = Condition(detector.path()+"#"+Keys::deltaName,Keys::deltaName);
0078     src_cond.bind<Delta>();
0079     src_cond->setFlag(Condition::ALIGNMENT_DELTA);
0080     src_cond->hash = key.hash;
0081     if ( !slice.insert(detector, Keys::deltaKey, src_cond) )   {
0082       detail::destroyHandle(src_cond);
0083     }
0084     /// Now check again if we succeeded.
0085     if ( !src_cond.isValid() )   {
0086       except("AlignmentsCalib",
0087              "++ The SOURCE alignment condition [%016llX]: %s#%s is invalid.",
0088              key.hash, detector.path().c_str(), Keys::deltaName.c_str());
0089     }
0090   }
0091   // Add the entry the usual way. This should also check everything again.
0092   dd4hep_ptr<Entry>  entry(new Entry());
0093   entry->original = src_cond.get<Delta>();
0094   entry->delta    = delta;
0095   entry->detector = detector;
0096   entry->source   = src_cond;
0097   entry->target   = tar_key.hash;
0098   entry->dirty    = 1;
0099   return *(used.emplace(tar_key,entry.release()).first);
0100 }
0101 
0102 /// (1) Add a new entry to an existing DetElement structure.
0103 dd4hep::Condition::key_type
0104 AlignmentsCalib::set(DetElement det, const Delta& delta)   {
0105   return _set(det.access(), delta).first;
0106 }
0107 
0108 /// (2) Add a new entry to an existing DetElement structure.
0109 dd4hep::Condition::key_type
0110 AlignmentsCalib::set(const std::string& path, const Delta& delta)   {
0111   return _set(detector(path).access(), delta).first;
0112 }
0113 
0114 /// Clear all delta data in the caches transaction stack.
0115 void AlignmentsCalib::clearDeltas()   {
0116   if ( !used.empty() )  {
0117     for ( auto& e : used )  {
0118       e.second->delta.clear();
0119       e.second->dirty = 0;
0120     }
0121   }
0122 }
0123 
0124 /// Clear all pending entries in the working cache
0125 void AlignmentsCalib::clear()   noexcept(false)  {
0126   for(auto& e : used)   {
0127     e.second->source.get<Delta>() = e.second->delta;
0128     detail::deletePtr(e.second);
0129   }
0130   used.clear();
0131 }
0132 
0133 /// Commit all pending transactions. Returns number of altered entries
0134 AlignmentsCalculator::Result AlignmentsCalib::commit()   {
0135   std::map<DetElement, Delta> deltas;
0136   AlignmentsCalculator        calculator;
0137 
0138   /// Propagate the Delta values to the source conditions
0139   for ( auto& entry : used )  {
0140     Entry* e = entry.second;
0141     if ( e->dirty )  {
0142       /// Update the source condition with the new delta value
0143       deltas[e->detector]    = e->delta;
0144       e->source.get<Delta>() = e->delta;
0145       e->dirty = 0;
0146     }
0147   }
0148   return calculator.compute(deltas, slice);
0149 }