|
||||
File indexing completed on 2025-01-18 09:57:34
0001 /***********************************************************************************\ 0002 * (c) Copyright 1998-2019 CERN for the benefit of the LHCb and ATLAS collaborations * 0003 * * 0004 * This software is distributed under the terms of the Apache version 2 licence, * 0005 * copied verbatim in the file "LICENSE". * 0006 * * 0007 * In applying this licence, CERN does not waive the privileges and immunities * 0008 * granted to it by virtue of its status as an Intergovernmental Organization * 0009 * or submit itself to any jurisdiction. * 0010 \***********************************************************************************/ 0011 // ============================================================================ 0012 #ifndef GAUDIALG_TUPLEOBJ_H 0013 #define GAUDIALG_TUPLEOBJ_H 1 0014 // ============================================================================ 0015 // Include files 0016 // ============================================================================ 0017 // STD&STL 0018 // ============================================================================ 0019 #include <array> 0020 #include <cstddef> 0021 #include <fmt/format.h> 0022 #include <functional> 0023 #include <limits> 0024 #include <numeric> 0025 #include <set> 0026 #include <sstream> 0027 #include <string> 0028 0029 // ============================================================================ 0030 // GaudiKernel 0031 // ============================================================================ 0032 #include "GaudiKernel/NTuple.h" 0033 #include "GaudiKernel/SerializeSTL.h" 0034 #include "GaudiKernel/VectorMap.h" 0035 // ============================================================================ 0036 // GaudiAlg 0037 // ============================================================================ 0038 #include "GaudiAlg/Maps.h" 0039 #include "GaudiAlg/Tuples.h" 0040 // ============================================================================ 0041 // ROOT 0042 // ============================================================================ 0043 #include "Math/Point3D.h" 0044 #include "Math/SMatrix.h" 0045 #include "Math/SVector.h" 0046 #include "Math/Vector3D.h" 0047 #include "Math/Vector4D.h" 0048 // ============================================================================ 0049 // forward declaration 0050 // ============================================================================ 0051 // GaudiKernel 0052 // ============================================================================ 0053 class IOpaqueAddress; 0054 // ============================================================================ 0055 /** @file TupleObj.h 0056 * 0057 * Header file for class TupleObj 0058 * 0059 * @date 2004-01-23 0060 * @author Vanya BELYAEV Ivan.Belyaev@itep.ru 0061 */ 0062 0063 // ============================================================================ 0064 /** @namespace Tuples 0065 * 0066 * General namespace for Tuple properties 0067 * 0068 * @author Vanya BELYAEV Ivan.Belyaev@itep.ru 0069 * @date 2004-01-23 0070 */ 0071 namespace Tuples { 0072 namespace detail { 0073 template <typename T> 0074 struct to_ { 0075 template <typename Arg> 0076 T operator()( Arg&& i ) const { 0077 return T( std::forward<Arg>( i ) ); 0078 } 0079 }; 0080 constexpr to_<float> to_float{}; 0081 0082 template <typename Iterator> 0083 using const_ref_t = std::add_const_t<typename std::iterator_traits<Iterator>::reference>; 0084 } // namespace detail 0085 // ========================================================================== 0086 /** @enum Type 0087 * the list of available types for ntuples 0088 * @author Vanya BELYAEV Ivan.Belyaev@itep.ru 0089 * @date 2004-01-23 0090 */ 0091 enum Type { 0092 NTUPLE, // Analysis nTuple 0093 EVTCOL // Event Collection 0094 }; 0095 // ========================================================================== 0096 /** @enum ErrorCodes 0097 * 0098 * Tuple error codes 0099 * 0100 * @author Vanya BELYAEV Ivan.Belyaev@itep.ru 0101 * @date 2004-01-23 0102 */ 0103 enum class ErrorCodes : StatusCode::code_t { 0104 InvalidTuple = 100, 0105 InvalidColumn, 0106 InvalidOperation, 0107 InvalidObject, 0108 InvalidItem, 0109 TruncateValue = 200 0110 }; 0111 } // namespace Tuples 0112 0113 STATUSCODE_ENUM_DECL( Tuples::ErrorCodes ) 0114 0115 namespace Tuples { 0116 // ========================================================================== 0117 /** @class TupleObj TupleObj.h GaudiAlg/TupleObj.h 0118 * 0119 * @brief A simple wrapper class over standard 0120 * Gaudi NTuple::Tuple facility 0121 * 0122 * The design and implementation are imported from LoKi package 0123 * 0124 * One should not use lass TupleObj directly. 0125 * The special handler Tuples::Tuple should be used instead, 0126 * which is simultaneously 'proxy' an d'smart pointer' for 0127 * real (and heavy!) TupleObj class. 0128 * 0129 * The main advantages of local ntuples with respect to 'standard' 0130 * Gaudi NTuples ( NTuple::Tuple ) is their "locality". 0131 * For 'standard' ntuples one need 0132 * <ol> 0133 * <li> Define all ntuple columns/items as 0134 * data members of the algorithm </li> 0135 * <li> Book the <tt>NTuple::Tuple</tt> object using 0136 * <tt>INTupleSvc</tt></li> 0137 * <li> Add all defined columns/items to the booked ntuple </li> 0138 * <li> Fill ntuple records 0139 * </ol> 0140 * Usually the first step is done in the header file (separate file!) 0141 * of the algorithm, the second and the third steps are done in 0142 * <tt>initialize()</tt> method of the algorithm and 0143 * the fourth step is done somewhere in <tt>execute()</tt> method of 0144 * the same algorithm. Such approach requires to keep track of the 0145 * tuple structure through different method and event through different 0146 * files. And even minor modification of the structure of the ntuple 0147 * will require the modification of at least 2 methods and 2 files. 0148 * 0149 * The <tt>Tuples::Tuple</tt> wrapper over standard Gaudi 0150 * <tt>NTuple::Tuple</tt> class solves all above listed problems with 0151 * "non-local" nature of Gaudi <tt>NTuple::Tuple</tt> objects. 0152 * 0153 * <tt>Tuples::Tuple</tt> object is booked and used 'locally'. 0154 * One does not need to pre-book the ntuple or its columns/items 0155 * somewhere in different compilation units or other methods different 0156 * from the actual point of using the ntuple. 0157 * 0158 * The simplest example of usage Tuples::Tuple object: 0159 * @code 0160 * Tuple tuple = nTuple( "some more or less unique tuple title "); 0161 * for( Loop D0 = loop( "K- pi+", "D0" ) , D0 , ++D0 ) 0162 * { 0163 * tuple -> column ( "mass" , M ( D0 ) / GeV ) ; 0164 * tuple -> column ( "pt" , PT ( D0 ) / GeV ) ; 0165 * tuple -> column ( "p" , P ( D0 ) / GeV ) ; 0166 * tuple -> write () ; 0167 * } 0168 * @endcode 0169 * 0170 * One could fill some Tuple variables in one go 0171 * @code 0172 * Tuple tuple = nTuple( "some more or less unique tuple title "); 0173 * for( Loop D0 = loop( "K- pi+", "D0" ) , D0 , ++D0 ) 0174 * { 0175 * tuple -> column ( "mass" , M ( D0 ) / GeV ) ; 0176 * tuple -> fill ( "pt , p " , PT ( D0 ) / GeV , P(D0) / GeV ) ; 0177 * tuple -> write () ; 0178 * } 0179 * @endcode 0180 * 0181 * Even ALL variables could be filled in one go: 0182 * @code 0183 * Tuple tuple = nTuple( "some more or less unique tuple title "); 0184 * for( Loop D0 = loop( "K- pi+", "D0" ) , D0 , ++D0 ) 0185 * { 0186 * tuple -> fill ( "mass pt , p ", M(D0)/GeV,PT(D0)/GeV,P(D0)/GeV ) ; 0187 * tuple -> write () ; 0188 * } 0189 * @endcode 0190 * 0191 * The 'array-like' columns are also supported ( see methods 'farray') 0192 * 0193 * All these techniques could be easily combined in arbitrary ways 0194 * 0195 * class TupleObj is an abstract class with 3 pure abstract functions 0196 * Error and Warning , which need to be reimplemented 0197 * in any 'concrete class. 0198 * Helper classes TupleObjImp, ErrorHandler and functions 0199 * createTupleObj and make_handler allows to 0200 * create concrete objects 'on-flight' 0201 * 0202 * @attention 0203 * <c>long long</c> and <c>unsigned long long</c> 0204 * types are not supported. One needs to convert the data 0205 * into some other representation (e.g. as 2 separate fields, 0206 * or perform the explicitly cast to <c>long</c>) 0207 * 0208 * @author Vanya BELYAEV ibelyaev@physics.syr.edu 0209 * @date 2004-01-23 0210 */ 0211 class GAUDI_API TupleObj { 0212 public: 0213 // ======================================================================== 0214 /// basics type for various items 0215 using Bool = NTuple::Item<bool>; 0216 using Char = NTuple::Item<char>; 0217 using UChar = NTuple::Item<unsigned char>; 0218 using Short = NTuple::Item<short>; 0219 using UShort = NTuple::Item<unsigned short>; 0220 using Int = NTuple::Item<int>; 0221 using UInt = NTuple::Item<unsigned int>; 0222 using LongLong = NTuple::Item<long long>; 0223 using ULongLong = NTuple::Item<unsigned long long>; 0224 using Float = NTuple::Item<float>; 0225 using Double = NTuple::Item<double>; 0226 using Address = NTuple::Item<IOpaqueAddress*>; 0227 using FArray = NTuple::Array<float>; 0228 using FMatrix = NTuple::Matrix<float>; 0229 // ======================================================================== 0230 // the actual type for variable size matrix indices 0231 typedef unsigned short MIndex; 0232 // ======================================================================== 0233 // the map of all items 0234 typedef std::map<std::string, std::string, std::less<>> ItemMap; 0235 // ======================================================================== 0236 protected: 0237 // ======================================================================== 0238 /** Standard constructor 0239 * @see NTuple:Tuple 0240 * @param name name of the object 0241 * @param tuple pointer to standard Gaudi NTuple::Tuple object 0242 * @param clid CLID_ColumnWiseTuple or CLID_RowWiseTuple 0243 * @param type the type of the tuple 0244 */ 0245 TupleObj( std::string name, NTuple::Tuple* tuple, const CLID& clid = CLID_ColumnWiseTuple, 0246 const Tuples::Type type = Tuples::NTUPLE ); 0247 // ======================================================================== 0248 public: 0249 // ======================================================================== 0250 virtual ~TupleObj(); 0251 // ======================================================================== 0252 /** Set the value for selected tuple column. 0253 * If column does not exist, it will be automatically created 0254 * and appended to the tuple 0255 * 0256 * @code 0257 * // 0258 * const float mass = ... ; 0259 * tuple->column( "m", mass ); 0260 * // 0261 * @endcode 0262 * 0263 * @param name the name of the column 0264 * @param value the value of the variable 0265 * @return status code 0266 */ 0267 StatusCode column( std::string_view name, float value ); 0268 // ======================================================================== 0269 public: 0270 // ======================================================================== 0271 /** Set the value for the selected tuple column 0272 * If the column does not exist, it will be automatically created 0273 * and appended to the tuple 0274 * 0275 * @code 0276 * // 0277 * const double mass = ... ; 0278 * tuple->column( "m", mass ); 0279 * // 0280 * @endcode 0281 * @warning the value is truncated to float 0282 * 0283 * @param name the name of the column 0284 * @param value the value of the variable 0285 * @return status code 0286 */ 0287 StatusCode column( std::string_view name, double value ); 0288 // ======================================================================== 0289 public: 0290 // ======================================================================== 0291 /** Set the value for selected tuple column. 0292 * If the column does not exist yet, it will be 0293 * automatically created and appended to the tuple 0294 * 0295 * @code 0296 * 0297 * short number = ... ; 0298 * tuple -> column ( "num" , number ); 0299 * 0300 * @endcode 0301 * 0302 * @param name the name of the column 0303 * @param value the value of the variable 0304 * @return status code 0305 */ 0306 StatusCode column( std::string_view name, short value ); 0307 // ======================================================================== 0308 /** Set the value for selected tuple column. 0309 * If the column does not exist yet, it will be 0310 * automatically created and appended to the tuple 0311 * 0312 * @code 0313 * 0314 * short number = ... ; 0315 * tuple->column( "num", number ); 0316 * 0317 * @endcode 0318 * 0319 * @param name name of the column 0320 * @param value value of the variable 0321 * @param minv minimum value of the variable 0322 * @param maxv maximum value of the variable 0323 * @return status code 0324 */ 0325 StatusCode column( std::string_view name, short value, short minv, short maxv ); 0326 // ======================================================================== 0327 public: 0328 // ======================================================================== 0329 /** Set the value for selected tuple column. 0330 * If the column does not exist yet, it will be 0331 * automatically created and appended to the tuple 0332 * 0333 * @code 0334 * 0335 * unsigned short number = ... ; 0336 * tuple -> column ( "num" , number ); 0337 * 0338 * @endcode 0339 * 0340 * @param name the name of the column 0341 * @param value the value of the variable 0342 * @return status code 0343 */ 0344 StatusCode column( std::string_view name, unsigned short value ); 0345 // ======================================================================== 0346 /** Set the value for selected tuple column. 0347 * If the column does not exist yet, it will be 0348 * automatically created and appended to the tuple 0349 * 0350 * @code 0351 * 0352 * unsigned short number = ... ; 0353 * tuple->column( "num", number ); 0354 * 0355 * @endcode 0356 * 0357 * @param name name of the column 0358 * @param value value of the variable 0359 * @param minv minimum value of the variable 0360 * @param maxv maximum value of the variable 0361 * @return status code 0362 */ 0363 StatusCode column( std::string_view name, unsigned short value, unsigned short minv, unsigned short maxv ); 0364 // ======================================================================== 0365 public: 0366 // ======================================================================== 0367 /** Set the value for selected tuple column. 0368 * If the column does not exist yet, it will be 0369 * automatically created and appended to the tuple 0370 * 0371 * @code 0372 * 0373 * char number = ... ; 0374 * tuple -> column ( "num" , number ); 0375 * 0376 * @endcode 0377 * 0378 * @param name the name of the column 0379 * @param value the value of the variable 0380 * @return status code 0381 */ 0382 StatusCode column( std::string_view name, char value ); 0383 // ======================================================================== 0384 /** Set the value for selected tuple column. 0385 * If the column does not exist yet, it will be 0386 * automatically created and appended to the tuple 0387 * 0388 * @code 0389 * 0390 * char number = ... ; 0391 * tuple->column( "num", number ); 0392 * 0393 * @endcode 0394 * 0395 * @param name name of the column 0396 * @param value value of the variable 0397 * @param minv minimum value of the variable 0398 * @param maxv maximum value of the variable 0399 * @return status code 0400 */ 0401 StatusCode column( std::string_view name, char value, char minv, char maxv ); 0402 // ======================================================================== 0403 public: 0404 // ======================================================================== 0405 /** Set the value for selected tuple column. 0406 * If the column does not exist yet, it will be 0407 * automatically created and appended to the tuple 0408 * 0409 * @code 0410 * 0411 * unsigned char number = ... ; 0412 * tuple -> column ( "num" , number ); 0413 * 0414 * @endcode 0415 * 0416 * @param name the name of the column 0417 * @param value the value of the variable 0418 * @return status code 0419 */ 0420 StatusCode column( std::string_view name, unsigned char value ); 0421 // ======================================================================== 0422 /** Set the value for selected tuple column. 0423 * If the column does not exist yet, it will be 0424 * automatically created and appended to the tuple 0425 * 0426 * @code 0427 * 0428 * unsigned char number = ... ; 0429 * tuple->column( "num", number ); 0430 * 0431 * @endcode 0432 * 0433 * @param name name of the column 0434 * @param value value of the variable 0435 * @param minv minimum value of the variable 0436 * @param maxv maximum value of the variable 0437 * @return status code 0438 */ 0439 StatusCode column( std::string_view name, unsigned char value, unsigned char minv, unsigned char maxv ); 0440 // ======================================================================== 0441 public: 0442 // ======================================================================== 0443 /** Set the value for selected tuple column. 0444 * If the column does not exist yet, it will be 0445 * automatically created and appended to the tuple 0446 * 0447 * @code 0448 * 0449 * int number = ... ; 0450 * tuple->column("num", number ); 0451 * 0452 * @endcode 0453 * 0454 * @param name name of the column 0455 * @param value value of the variable 0456 * @return status code 0457 */ 0458 StatusCode column( std::string_view name, int value ); 0459 // ======================================================================== 0460 /** Set the value for selected tuple column. 0461 * If the column does not exist yet, it will be 0462 * automatically created and appended to the tuple 0463 * 0464 * @code 0465 * 0466 * int number = ... ; 0467 * tuple->column( "num", number ); 0468 * 0469 * @endcode 0470 * 0471 * @param name name of the column 0472 * @param value value of the variable 0473 * @param minv minimum value of the variable 0474 * @param maxv maximum value of the variable 0475 * @return status code 0476 */ 0477 StatusCode column( std::string_view name, int value, int minv, int maxv ); 0478 // ======================================================================== 0479 public: 0480 // ======================================================================== 0481 /** Set the value for selected tuple column. 0482 * If the column does not exist yet, it will be 0483 * automatically created and appended to the tuple 0484 * 0485 * @code 0486 * 0487 * unsigned int number = ... ; 0488 * tuple->column("num", number ); 0489 * 0490 * @endcode 0491 * 0492 * @param name name of the column 0493 * @param value value of the variable 0494 * @return status code 0495 */ 0496 StatusCode column( std::string_view name, unsigned int value ); 0497 // ======================================================================== 0498 /** Set the value for selected tuple column. 0499 * If the column does not exist yet, it will be 0500 * automatically created and appended to the tuple 0501 * 0502 * @code 0503 * 0504 * unsigned int number = ... ; 0505 * tuple->column("num", number ); 0506 * 0507 * @endcode 0508 * 0509 * @param name name of the column 0510 * @param value value of the variable 0511 * @param minv minimum value of the variable 0512 * @param maxv maximum value of the variable 0513 * @return status code 0514 */ 0515 StatusCode column( std::string_view name, unsigned int value, unsigned int minv, unsigned int maxv ); 0516 // ======================================================================== 0517 public: 0518 // ======================================================================== 0519 /** Set the value for the selected tuple column. 0520 * If the column does not exist yet, it will be 0521 * automatically created and appended to the tuple 0522 * 0523 * @code 0524 * 0525 * long number = ... ; 0526 * tuple -> column ( "num", number ); 0527 * 0528 * @endcode 0529 * @warning the value could be truncated to int 0530 * 0531 * @param name the name of the column 0532 * @param value the value of the variable 0533 * @return status code 0534 */ 0535 StatusCode column( std::string_view name, long value ); 0536 // ======================================================================== 0537 /** Set the value for selected tuple column. 0538 * If the column does not exist yet, it will be 0539 * automatically created and appended to the tuple 0540 * 0541 * @code 0542 * 0543 * long number = ... ; 0544 * tuple->column("num", number ); 0545 * 0546 * @endcode 0547 * 0548 * @param name name of the column 0549 * @param value value of the variable 0550 * @param minv minimum value of the variable 0551 * @param maxv maximum value of the variable 0552 * @return status code 0553 */ 0554 StatusCode column( std::string_view name, long value, long minv, long maxv ); 0555 // ======================================================================== 0556 public: 0557 // ======================================================================== 0558 /** Set the value for selected tuple column. 0559 * If the column does not exist yet, it will be 0560 * automatically created and appended to the tuple 0561 * 0562 * @code 0563 * 0564 * unsigned long number = ... ; 0565 * tuple -> column ( "num" , number ); 0566 * 0567 * @endcode 0568 * @warning the value could be truncated to int 0569 * 0570 * @param name the name of the column 0571 * @param value the value of the variable 0572 * @return status code 0573 */ 0574 StatusCode column( std::string_view name, unsigned long value ); 0575 // ======================================================================== 0576 /** Set the value for selected tuple column. 0577 * If the column does not exist yet, it will be 0578 * automatically created and appended to the tuple 0579 * 0580 * @code 0581 * 0582 * unsigned long number = ... ; 0583 * tuple->column( "num", number ); 0584 * 0585 * @endcode 0586 * 0587 * @param name name of the column 0588 * @param value value of the variable 0589 * @param minv minimum value of the variable 0590 * @param maxv maximum value of the variable 0591 * @return status code 0592 */ 0593 StatusCode column( std::string_view name, unsigned long value, unsigned long minv, unsigned long maxv ); 0594 // ======================================================================== 0595 public: 0596 // ======================================================================== 0597 /** Set the value for selected tuple column. 0598 * If the column does not exist yet, it will be 0599 * automatically created and appended to the tuple 0600 * 0601 * @code 0602 * 0603 * long long number = ... ; 0604 * tuple->column( "num", number ); 0605 * 0606 * @endcode 0607 * 0608 * @param name name of the column 0609 * @param value value of the variable 0610 * @return status code 0611 */ 0612 StatusCode column( std::string_view name, long long value ); 0613 // ======================================================================== 0614 /** Set the value for selected tuple column. 0615 * If the column does not exist yet, it will be 0616 * automatically created and appended to the tuple 0617 * 0618 * @code 0619 * 0620 * long long number = ... ; 0621 * tuple->column( "num", number ); 0622 * 0623 * @endcode 0624 * 0625 * @param name name of the column 0626 * @param value value of the variable 0627 * @param minv minimum value of the variable 0628 * @param maxv maximum value of the variable 0629 * @return status code 0630 */ 0631 StatusCode column( std::string_view name, long long value, long long minv, long long maxv ); 0632 // ======================================================================== 0633 public: 0634 // ======================================================================== 0635 /** Set the value for selected tuple column. 0636 * If the column does not exist yet, it will be 0637 * automatically created and appended to the tuple 0638 * 0639 * @code 0640 * 0641 * unsigned long long number = ... ; 0642 * tuple->column( "num", number ); 0643 * 0644 * @endcode 0645 * 0646 * @param name name of the column 0647 * @param value value of the variable 0648 * @return status code 0649 */ 0650 StatusCode column( std::string_view name, unsigned long long value ); 0651 // ======================================================================== 0652 /** Set the value for selected tuple column. 0653 * If the column does not exist yet, it will be 0654 * automatically created and appended to the tuple 0655 * 0656 * @code 0657 * 0658 * unsigned long long number = ... ; 0659 * tuple->column( "num", number ); 0660 * 0661 * @endcode 0662 * 0663 * @param name name of the column 0664 * @param value value of the variable 0665 * @param minv minimum value of the variable 0666 * @param maxv maximum value of the variable 0667 * @return status code 0668 */ 0669 StatusCode column( std::string_view name, unsigned long long value, unsigned long long minv, 0670 unsigned long long maxv ); 0671 // ======================================================================== 0672 public: 0673 // ======================================================================== 0674 /** Set the value for the selected tuple column. 0675 * If the column does not exist yet, it will be 0676 * automatically created and appended to the tuple 0677 * 0678 * @code 0679 * 0680 * signed char number = ... ; 0681 * tuple->column("num", number ); 0682 * 0683 * @endcode 0684 * 0685 * @param name the name of the column 0686 * @param value the value of tve variable 0687 * @return status code 0688 */ 0689 StatusCode column( std::string_view name, signed char value ) { 0690 return column( name, value, std::numeric_limits<signed char>::min(), std::numeric_limits<signed char>::max() ); 0691 } 0692 // ======================================================================== 0693 public: 0694 // ======================================================================== 0695 /** Set the value for selected tuple column. 0696 * If the column does not exist yet, it will be 0697 * automatically create and appended to the tuple 0698 * 0699 * @code 0700 * 0701 * tuple->column( "empty" , v.empty() ); 0702 * 0703 * @endcode 0704 * 0705 * @param name the name of the column 0706 * @param value the value of the variable 0707 * @return status code 0708 */ 0709 StatusCode column( std::string_view name, bool value ); 0710 // ======================================================================== 0711 public: 0712 // ======================================================================== 0713 /** Put IOpaqueAddress in POOL-based NTuple. 0714 * If the column does not exist, 0715 * it will be automatically created 0716 * and appended to the tuple. 0717 * 0718 * @code 0719 * 0720 * IOpaqueAddress* address = ... ; 0721 * tuple->column( "Address", address ); 0722 * 0723 * @endcode 0724 * @warning It has sense only for Event tag collection N-Tuples 0725 * 0726 * @param name name of the column 0727 * ("Address" is a recommended convention!) 0728 * @param address IOpaqueAddress 0729 * @return status code 0730 */ 0731 StatusCode column( std::string_view name, IOpaqueAddress* address ); 0732 // ======================================================================== 0733 /** Put IOpaqueAddress in NTuple. 0734 * If the column does not exist, 0735 * it will be automatically created and appended to the tuple. 0736 * The column name is set to be <c>"Address"</c> 0737 * 0738 * @code 0739 * 0740 * IOpaqueAddress* address = ... ; 0741 * tuple->column ( address ); 0742 * 0743 * @endcode 0744 * @warning It has sense only for Event tag collection N-Tuples 0745 * 0746 * @param address IOpaqueAddress 0747 * @return status code 0748 */ 0749 StatusCode column( IOpaqueAddress* address ); 0750 // ======================================================================== 0751 public: 0752 // ======================================================================== 0753 /** Set the values for several columns simultaneously, for the same object 0754 * Non-existing columns will be automatically created 0755 * and appended to the ntuple. 0756 * 0757 * @code 0758 * 0759 * Gaudi::XYZPoint p; 0760 * tuple->columns( p, std::pair{ "X", &Gaudi::XYZPoint::X}, 0761 * std::pair{ "Y", &Gaudi::XYZPoint::Y}, 0762 * std::pair{ "Z", &Gaudi::XYZPoint::Z} ); 0763 * 0764 * @endcode 0765 * 0766 * @warning the type of column is set (implicitly) by the type returned by the 'callable' 0767 * for that column, i.e. in the above the return type of eg. `Gaudi::XYZPoint::X()` 0768 * 0769 * @author Gerhard Raven 0770 */ 0771 0772 template <typename Value, typename... Args> 0773 StatusCode columns( Value&& value, Args&&... args ) { 0774 if ( sizeof...( Args ) == 0 ) return StatusCode::SUCCESS; 0775 std::initializer_list<StatusCode> scs{ 0776 this->column( std::get<0>( args ), std::invoke( std::get<1>( args ), value ) )... }; 0777 return std::accumulate( std::next( begin( scs ) ), end( scs ), *begin( scs ), 0778 []( StatusCode sc, const StatusCode& i ) { 0779 i.ignore(); // make sure there are no unchecked StatusCodes... 0780 return sc.isFailure() ? sc : i; // latch to the first non-success case 0781 } ); 0782 } 0783 // ======================================================================== 0784 public: 0785 // ======================================================================== 0786 /** Set the values for several columns simultaneously. 0787 * Number of columns is arbitrary, but it should match 0788 * the number of blank, or comma, or semi-column separated tags 0789 * in <tt>format</tt> string. 0790 * Non-existing columns will be automatically created 0791 * and appended to the ntuple. 0792 * 0793 * @code 0794 * 0795 * double r1 , r2 , r3 , r4 , mass , length ; 0796 * tuple->fill( "var1 var2, radius rad4 mass len" , 0797 * r1, r2, r3, r4, mass, length); 0798 * 0799 * @endcode 0800 * 0801 * @param format blank-separated list of variables, 0802 * followed by variable number of arguments. 0803 * @author Vanya Belyaev Ivan.Belyaev@itep.ru 0804 * @date 2002-10-30 0805 */ 0806 template <typename Arg, typename... Args> 0807 StatusCode fill( std::string_view fmt, Arg arg, Args... args ) { 0808 constexpr auto separators = " ,;"; 0809 // split into token, and remainder 0810 auto token = fmt.substr( 0, fmt.find_first_of( separators ) ); 0811 fmt.remove_prefix( std::min( token.size() + 1, fmt.size() ) ); 0812 0813 if ( !token.empty() ) { 0814 // check the underlying tuple 0815 if ( invalid() ) return ErrorCodes::InvalidTuple; 0816 return column( token, arg ).andThen( [&] { 0817 if constexpr ( sizeof...( Args ) != 0 ) { return fill( fmt, args... ); } 0818 // no more args to deal with -- so check that there is nothing usefull left in fmt, and if so, call it a 0819 // success... 0820 if ( fmt.find_first_not_of( separators ) != std::string_view::npos ) 0821 throw std::runtime_error{ "TupleObj::fill: bad format -- too few arguments for specified format" }; 0822 return StatusCode{ StatusCode::SUCCESS }; 0823 } ); 0824 } else if ( !fmt.empty() ) { 0825 // got a separator at the front of fmt -- try again now that it is removed from fmt... 0826 return fill( fmt, arg, args... ); 0827 } else { 0828 // empty token, and nothing left in fmt -- but we still where called with (at least) one argument... 0829 throw std::runtime_error{ "TupleObj::fill: bad format -- too many arguments for specified format" }; 0830 return StatusCode::SUCCESS; 0831 } 0832 } 0833 0834 // ======================================================================= 0835 public: 0836 // ======================================================================= 0837 /** Add an indexed array (of type float) to N-tuple. 0838 * The method is not VERY efficient since it copies the data. 0839 * 0840 * @code 0841 * 0842 * std::vector<double> values = ... ; 0843 * 0844 * tuple->farray( "Values" , // item name 0845 * values.begin () , // begin of sequence 0846 * values.end () , // end of sequence 0847 * "Length" , // name of "length" item 0848 * 10000 ) ; 0849 * 0850 * @endcode 0851 * 0852 * The name of "length" item can be reused for several arrays. 0853 * The last assignement "wins" 0854 * 0855 * @code 0856 * 0857 * std::vector<double> val1 = ... ; 0858 * std::vector<double> val2 = ... ; 0859 * 0860 * tuple->farray( "Val1" , // item name 0861 * val1.begin () , // begin of sequence 0862 * val1.end () , // end of sequence 0863 * "Length" , // name of "length" item 0864 * 10000 ) ; // maximal length 0865 * 0866 * tuple->farray( "Val2" , // item name 0867 * val2.begin () , // begin of sequence 0868 * val2.end () , // end of sequence 0869 * "Length" , // name of "length" item 0870 * 10000 ) ; // maximal length 0871 * 0872 * @endcode 0873 * 0874 * Any sequence <tt>[first:last[</tt> of objects 0875 * which can be converted to type <tt>float</tt> can 0876 * be used as input data, e.g. <tt>std::vector<double></tt>, 0877 * <tt>std::vector<float></tt>, plain C-array, or whatever else 0878 * 0879 * @param name name of N-tuple item 0880 * @param first begin of data sequence 0881 * @param last end of data sequence 0882 * @param length name of "length" item 0883 * @param maxv maximal length of array 0884 */ 0885 template <typename ITERATOR1, typename ITERATOR2> 0886 StatusCode farray( std::string_view name, ITERATOR1&& first, ITERATOR2&& last, std::string_view length, 0887 size_t maxv ) { 0888 return farray( name, detail::to_float, std::forward<ITERATOR1>( first ), std::forward<ITERATOR2>( last ), length, 0889 maxv ); 0890 } 0891 // ======================================================================= 0892 /** Add an indexed array (of type float) to N-tuple. 0893 * it is just a small adaptor for the previous method 0894 * 0895 * @code 0896 * 0897 * std::vector<double> values = ... ; 0898 * 0899 * tuple->farray( "Values" , // item name 0900 * values , // sequence 0901 * "Length" , // name of "length" item 0902 * 10000 ) ; 0903 * 0904 * @endcode 0905 * 0906 * The name of "length" item can be reused for several arrays. 0907 * The last assignment "wins" 0908 * 0909 * @code 0910 * 0911 * std::vector<double> val1 = ... ; 0912 * std::vector<double> val2 = ... ; 0913 * 0914 * tuple->farray( "Val1" , // item name 0915 * val1 , // begin of sequence 0916 * "Length" , // name of "length" item 0917 * 10000 ) ; // maximal length 0918 * 0919 * tuple->farray( "Val2" , // item name 0920 * val2 , // begin of sequence 0921 * "Length" , // name of "length" item 0922 * 10000 ) ; // maximal length 0923 * 0924 * @endcode 0925 * 0926 * Any sequence which provides <tt>begin()</tt> and 0927 * <tt>end()</tt> methods can be used. 0928 * 0929 * @param name name of N-tuple item 0930 * @param data data sequence 0931 * @param length name of "length" item 0932 * @param maxv maximal length of array 0933 */ 0934 template <class DATA> 0935 StatusCode farray( std::string_view name, const DATA& data, std::string_view length, const size_t maxv ) { 0936 return farray( name, std::begin( data ), std::end( data ), length, maxv ); 0937 } 0938 // ======================================================================= 0939 /** Put an indexed array into LoKi-style N-Tuple 0940 * 0941 * @code 0942 * 0943 * std::vector<double> data = ... ; 0944 * 0945 * Tuple tuple = ntuple( "My Ntuple" ); 0946 * 0947 * tuple->farray( "data" , // data item name 0948 * sqrt , // "function" to be applied 0949 * data.begin () , // begin of data sequence 0950 * data.end () , // end of data sequence 0951 * "length" , // name of "length" tuple item 0952 * 10000 ) ; // maximal array length 0953 * 0954 * @endcode 0955 * 0956 * Since the method is templated, one can use arbitrary 0957 * combinations of "sequences" and "functions", e.g. one can 0958 * directly manipulate with complex objects. 0959 * The only one thing is required - the result of 0960 * <tt>FUNCTION(*DATA)</tt> formal operation 0961 * MUST be convertible to type <tt>float</tt> 0962 * 0963 * @code 0964 * 0965 * // some container of particles. 0966 * ParticleVector particles = ... ; 0967 * 0968 * Tuple tuple = ntuple( "My Ntuple" ); 0969 * 0970 * // put the transverse momentum of all particles into N-Tuple 0971 * tuple->farray( "pt" , // data item name 0972 * PT , // function object 0973 * particles.begin () , // begin of data sequence 0974 * particles.end () , // end of data sequence 0975 * "num" , // name of "length" tuple item 0976 * 10000 ) ; // maximal array length 0977 * 0978 * 0979 * // create the appropriate function object 0980 * Fun fun = Q / P ; 0981 * 0982 * // put Q/P of all particles into N-Tuple 0983 * tuple->farray( "qp" , // data item name 0984 * fun , // function object 0985 * particles.begin () , // begin of data sequence 0986 * particles.end () , // end of data sequence 0987 * "num" , // name of "length" tuple item 0988 * 10000 ) ; // maximal array length 0989 * 0990 * 0991 * @endcode 0992 * 0993 * @param name tuple item name 0994 * @param function function to be applied 0995 * @param first begin of data sequence 0996 * @param last end of data sequence 0997 * @param length name of "length" tuple name 0998 * @param maxv maximal length of the array 0999 * @return status code 1000 */ 1001 template <class FUNCTION, class ITERATOR> 1002 StatusCode farray( std::string_view name, const FUNCTION& function, ITERATOR first, ITERATOR last, 1003 std::string_view length, size_t maxv ) { 1004 if ( invalid() ) return ErrorCodes::InvalidTuple; 1005 if ( rowWise() ) return ErrorCodes::InvalidOperation; 1006 1007 // adjust the length 1008 if ( std::distance( first, last ) > static_cast<std::ptrdiff_t>( maxv ) ) { 1009 Warning( fmt::format( "farray('{}'): array is overflow, skip extra entries", name ) ) 1010 .ignore( /* AUTOMATICALLY ADDED FOR gaudi/Gaudi!763 */ ); 1011 last = std::next( first, maxv ); 1012 } 1013 1014 // get the length item 1015 Int* len = ints( length, 0, maxv ); 1016 if ( !len ) return ErrorCodes::InvalidColumn; 1017 1018 // adjust the length 1019 *len = std::distance( first, last ); 1020 1021 // get the array itself 1022 FArray* var = fArray( name, len ); 1023 if ( !var ) return ErrorCodes::InvalidColumn; 1024 1025 // fill the array 1026 std::transform( first, last, std::begin( *var ), 1027 [&]( auto&& i ) { return std::invoke( function, std::forward<decltype( i )>( i ) ); } ); 1028 1029 return StatusCode::SUCCESS; 1030 } 1031 // ======================================================================= 1032 /** Put arbitrary number of functions from one data array into LoKi-style N-Tuple 1033 * simultaneously (effective!) 1034 * 1035 * @code 1036 * 1037 * std::vector<double> data = ... ; 1038 * 1039 * Tuple tuple = ntuple( "My Ntuple" ); 1040 * 1041 * tuple->farray( { { "sqrt", sqrt }, // name of 1st column, and function to use for it 1042 * { "sinus", sin } }, // name of the 2nd column, and corresponding function 1043 * data.begin () , // begin of data sequence 1044 * data.end () , // end of data sequence 1045 * "length" , // name of "length" tuple item 1046 * 10000 ) ; // maximal array length 1047 * 1048 * @endcode 1049 * 1050 * 1051 * @param items vector of pairs { name, callable } 1052 * @param first begin of data sequence 1053 * @param last end of data sequence 1054 * @param length name of "length" tuple name 1055 * @param maxv maximal length of the array 1056 * @return status code 1057 */ 1058 1059 template <typename FunIterator, typename DataIterator> 1060 StatusCode farray_impl( FunIterator first_item, FunIterator last_item, DataIterator first, DataIterator last, 1061 std::string_view length, size_t maxv ) { 1062 if ( invalid() ) return ErrorCodes::InvalidTuple; 1063 if ( rowWise() ) return ErrorCodes::InvalidOperation; 1064 1065 // adjust the length 1066 if ( std::distance( first, last ) > static_cast<std::ptrdiff_t>( maxv ) ) { 1067 using GaudiUtils::details::ostream_joiner; 1068 std::ostringstream os; 1069 ostream_joiner( os, first_item, last_item, ",", 1070 []( std::ostream& os, const auto& i ) -> decltype( auto ) { return os << i.first; } ); 1071 Warning( "farray('" + os.str() + "'): array overflow, skipping extra entries" ).ignore(); 1072 last = std::next( first, maxv ); 1073 } 1074 1075 // get the length item 1076 Int* len = ints( length, 0, maxv ); 1077 if ( !len ) return ErrorCodes::InvalidColumn; 1078 1079 // adjust the length 1080 *len = std::distance( first, last ); 1081 1082 // get the arrays themselves 1083 std::vector<FArray*> vars; 1084 vars.reserve( std::distance( first_item, last_item ) ); 1085 std::transform( first_item, last_item, std::back_inserter( vars ), 1086 [&]( const auto& item ) { return this->fArray( item.first, len ); } ); 1087 if ( std::any_of( vars.begin(), vars.end(), []( const FArray* f ) { return !f; } ) ) { 1088 return ErrorCodes::InvalidColumn; 1089 } 1090 1091 // fill the array 1092 for ( size_t index = 0; first != last; ++first, ++index ) { 1093 auto item = first_item; 1094 for ( auto& var : vars ) { ( *var )[index] = std::invoke( ( item++ )->second, *first ); } 1095 } 1096 1097 return StatusCode::SUCCESS; 1098 } 1099 1100 template < 1101 typename DataIterator, template <typename, typename...> class Container = std::initializer_list, 1102 typename NamedFunction = std::pair<std::string_view, std::function<float( detail::const_ref_t<DataIterator> )>>, 1103 typename = std::enable_if_t<!std::is_convertible_v<Container<NamedFunction>, std::string_view>>> 1104 StatusCode farray( const Container<NamedFunction>& funs, DataIterator first, DataIterator last, 1105 std::string_view length, size_t maxv ) { 1106 return farray_impl( funs.begin(), funs.end(), std::forward<DataIterator>( first ), 1107 std::forward<DataIterator>( last ), length, maxv ); 1108 } 1109 1110 template <typename NamedFunctions, typename DataIterator, 1111 typename = std::enable_if_t<!std::is_convertible_v<NamedFunctions, std::string_view>>> 1112 StatusCode farray( const NamedFunctions& funs, DataIterator first, DataIterator last, std::string_view length, 1113 size_t maxv ) { 1114 return farray_impl( funs.begin(), funs.end(), std::forward<DataIterator>( first ), 1115 std::forward<DataIterator>( last ), length, maxv ); 1116 } 1117 // ======================================================================= 1118 /** Put two functions from one data array into LoKi-style N-Tuple 1119 * simultaneously (effective!) 1120 * 1121 * @code 1122 * 1123 * std::vector<double> data = ... ; 1124 * 1125 * Tuple tuple = ntuple( "My Ntuple" ); 1126 * 1127 * tuple->farray( "square_root" , // the first data item name 1128 * sqrt , // "func1" to be used 1129 * "sinus" , // the second data item name 1130 * sin , // "func2" to be used 1131 * data.begin () , // begin of data sequence 1132 * data.end () , // end of data sequence 1133 * "length" , // name of "length" tuple item 1134 * 10000 ) ; // maximal array length 1135 * 1136 * @endcode 1137 * 1138 * 1139 * @param name1 the first tuple item name 1140 * @param func1 the first function to be applied 1141 * @param name2 the second tuple item name 1142 * @param func2 the second function to be applied 1143 * @param first begin of data sequence 1144 * @param last end of data sequence 1145 * @param length name of "length" tuple name 1146 * @param maxv maximal length of the array 1147 * @return status code 1148 */ 1149 template <class FUNC1, class FUNC2, class Iterator> 1150 StatusCode farray( std::string_view name1, const FUNC1& func1, std::string_view name2, const FUNC2& func2, 1151 Iterator&& first, Iterator&& last, std::string_view length, size_t maxv ) { 1152 return farray( { { name1, std::cref( func1 ) }, { name2, std::cref( func2 ) } }, std::forward<Iterator>( first ), 1153 std::forward<Iterator>( last ), length, maxv ); 1154 } 1155 // ======================================================================= 1156 /** Put three functions from one data array into LoKi-style N-Tuple 1157 * simultaneously (effective!) 1158 * 1159 * 1160 * @code 1161 * 1162 * std::vector<double> data = ... ; 1163 * 1164 * Tuple tuple = ntuple( "My Ntuple" ); 1165 * 1166 * tuple->farray( "square_root" , // the first data item name 1167 * sqrt , // "func1" to be used 1168 * "sinus" , // the second data item name 1169 * sin , // "func2" to be used 1170 * "tan" , // the third data item name 1171 * tan , // "func3" to be used 1172 * data.begin () , // begin of data sequence 1173 * data.end () , // end of data sequence 1174 * "length" , // name of "length" tuple item 1175 * 10000 ) ; // maximal array length 1176 * 1177 * @endcode 1178 * 1179 * 1180 * @param name1 the first tuple item name 1181 * @param func1 the first function to be applied 1182 * @param name2 the second tuple item name 1183 * @param func2 the second function to be applied 1184 * @param name3 the third tuple item name 1185 * @param func3 the third function to be applied 1186 * @param first begin of data sequence 1187 * @param last end of data sequence 1188 * @param length name of "length" tuple name 1189 * @param maxv maximal length of the array 1190 * @return status code 1191 */ 1192 template <class FUNC1, class FUNC2, class FUNC3, class Iterator> 1193 StatusCode farray( std::string_view name1, const FUNC1& func1, std::string_view name2, const FUNC2& func2, 1194 std::string_view name3, const FUNC3& func3, Iterator&& first, Iterator&& last, 1195 std::string_view length, size_t maxv ) { 1196 return farray( { { name1, std::cref( func1 ) }, { name2, std::cref( func2 ) }, { name3, std::cref( func3 ) } }, 1197 std::forward<Iterator>( first ), std::forward<Iterator>( last ), length, maxv ); 1198 } 1199 // ======================================================================= 1200 /** Put four functions from one data array into LoKi-style N-Tuple 1201 * simultaneously (effective!) 1202 * 1203 * @code 1204 * 1205 * std::vector<double> data = ... ; 1206 * 1207 * Tuple tuple = ntuple( "My Ntuple" ); 1208 * 1209 * tuple->farray( "square_root" , // the first data item name 1210 * sqrt , // "func1" to be used 1211 * "sinus" , // the second data item name 1212 * sin , // "func2" to be used 1213 * "tan" , // the third data item name 1214 * tan , // "func3" to be used 1215 * "tanh" , // 1216 * tanh , // 1217 * data.begin () , // begin of data sequence 1218 * data.end () , // end of data sequence 1219 * "length" , // name of "length" tuple item 1220 * 10000 ) ; // maximal array length 1221 * 1222 * @endcode 1223 * 1224 * 1225 * @param name1 the first tuple item name 1226 * @param func1 the first function to be applied 1227 * @param name2 the second tuple item name 1228 * @param func2 the second function to be applied 1229 * @param name3 the third tuple item name 1230 * @param func3 the third function to be applied 1231 * @param name4 the fourth tuple item name 1232 * @param func4 the fourth function to be applied 1233 * @param first begin of data sequence 1234 * @param last end of data sequence 1235 * @param length name of "length" tuple name 1236 * @param maxv maximal length of the array 1237 * @return status code 1238 */ 1239 template <class FUNC1, class FUNC2, class FUNC3, class FUNC4, class Iterator> 1240 StatusCode farray( std::string_view name1, const FUNC1& func1, std::string_view name2, const FUNC2& func2, 1241 std::string_view name3, const FUNC3& func3, std::string_view name4, const FUNC4& func4, 1242 Iterator&& first, Iterator&& last, std::string_view length, size_t maxv ) { 1243 return farray( { { name1, std::cref( func1 ) }, 1244 { name2, std::cref( func2 ) }, 1245 { name3, std::cref( func3 ) }, 1246 { name4, std::cref( func4 ) } }, 1247 std::forward<Iterator>( first ), std::forward<Iterator>( last ), length, maxv ); 1248 } 1249 // ======================================================================= 1250 public: 1251 // ======================================================================= 1252 /** Fill N-Tuple with data from variable-size matrix 1253 * 1254 * "Matrix" could be of any type, which supports 1255 * data[iRow][iCol] indexing, e.g. 1256 * - std::vector<std::vector<TYPE> > 1257 * - CLHEP::HepMatrix, etc... 1258 * 1259 * @code 1260 * 1261 * typedef std::vector<double> Row ; 1262 * typedef std::vector<Row> Mtrx ; 1263 * // number of columns (fixed!) 1264 * const size_t numCols = 5 ; 1265 * // maximal number of rows 1266 * const size_t maxRows = 300 ; 1267 * // number of rows (variable) 1268 * size_t numRows = .... ; 1269 * ... 1270 * tuple -> fMatrix ( "mtrx" , // "column" name 1271 * mtrx , // matrix 1272 * numRows , // number of rows (variable!) 1273 * numCols , // number of columns (fixed) 1274 * "Length" , // name for "length" column 1275 * maxRows ) ; // maximal number of columns 1276 * 1277 * @endcode 1278 * 1279 * @code 1280 * 1281 * CLHEP::HepMatrix mtrx = ... ; 1282 * ... 1283 * tuple -> fMatrix ( "mtrx" , // "column" name 1284 * mtrx , // matrix 1285 * mtrx.num_row() , // number of rows (variable!) 1286 * mtrx.num_col() , // number of columns (fixed) 1287 * "Length" , // name for "length" column 1288 * maxRows ) ; // maximal number of columns 1289 * 1290 * @endcode 1291 * 1292 * @param name entry name in N-Tuple 1293 * @param data matrix itself 1294 * @param rows number of rows of matrix (variable) 1295 * @param cols number of columns of matrix (fixed) 1296 * @param length entry name in NTuple for number of matrix column 1297 * @param maxv maximal number of rows in matrix 1298 * 1299 * @author Vanya BELYAEV Ivan.Belyaev@lapp.in2p3.fr 1300 * @date 2005-05-01 1301 */ 1302 template <class MATRIX> 1303 StatusCode fmatrix( std::string_view name, const MATRIX& data, size_t rows, const MIndex& cols, 1304 std::string_view length, size_t maxv ) { 1305 if ( invalid() ) return ErrorCodes::InvalidTuple; 1306 if ( rowWise() ) return ErrorCodes::InvalidOperation; 1307 1308 // adjust the length 1309 if ( rows >= maxv ) { 1310 Warning( fmt::format( "fmatrix('{}'): matrix is overflow, skip extra items", name ) ).ignore(); 1311 rows = ( 0 < maxv ) ? ( maxv - 1 ) : 0; 1312 } 1313 1314 // get the length item 1315 Int* len = ints( length, 0, maxv ); 1316 if ( !len ) return ErrorCodes::InvalidColumn; 1317 1318 // adjust the length item 1319 *len = rows; 1320 1321 // get the array itself 1322 FMatrix* var = fMatrix( name, len, cols ); 1323 if ( !var ) return ErrorCodes::InvalidColumn; 1324 1325 /// fill the matrix 1326 for ( size_t iCol = 0; iCol < cols; ++iCol ) { 1327 for ( MIndex iRow = 0; iRow < rows; ++iRow ) { ( *var )[iRow][iCol] = data[iRow][iCol]; } 1328 } 1329 1330 return StatusCode::SUCCESS; 1331 } 1332 // ======================================================================= 1333 /** Fill N-Tuple with data from variable-size matrix 1334 * 1335 * "Matrix" could be of any type, which supports 1336 * iteration from the first column to the last column 1337 * and for each iterating column supports the indexing: 1338 * (*first)[iCol] 1339 * 1340 * @code 1341 * typedef std::vector<double> Row ; 1342 * typedef std::vector<Row> Mtrx ; 1343 * // number of rows (fixed!) 1344 * const size_t numRows = 5 ; 1345 * // maximal number of columns 1346 * const size_t maxCols = 300 ; 1347 * // number of columns (variable) 1348 * size_t numCols = .... ; 1349 * ... 1350 * tuple -> fMatrix ( "mtrx" , // entry name 1351 * mtrx.begin() , // first row of matrix 1352 * mtrx.end () , // last row of matrix 1353 * numCols , // number of columns (fixed!) 1354 * "Length" , // name for "length" column 1355 * maxRows ) ; // maximal number of rows 1356 * 1357 * @endcode 1358 * 1359 * @param name entry name in N-Tuple 1360 * @param first iterator for the first row of matrix 1361 * @param last iterator for the last row of matrix 1362 * @param cols number of columns for matrix (fixed!) 1363 * @param length entry name in NTuple for number of matrix column 1364 * @param maxv maximal number of rows in matrix 1365 * 1366 * @author Vanya BELYAEV Ivan.Belyaev@lapp.in2p3.fr 1367 * @date 2005-05-01 1368 */ 1369 template <class DATA> 1370 StatusCode fmatrix( std::string_view name, DATA first, DATA last, const MIndex& cols, std::string_view length, 1371 size_t maxv ) { 1372 if ( invalid() ) return ErrorCodes::InvalidTuple; 1373 if ( rowWise() ) return ErrorCodes::InvalidOperation; 1374 1375 // adjust the length 1376 if ( first + maxv < last ) { 1377 Warning( fmt::format( "fmatrix('{}'): matrix is overflow, skip extra items", name ) ).ignore(); 1378 last = first + maxv; 1379 } 1380 1381 // get the length item 1382 Int* len = ints( length, 0, maxv ); 1383 if ( !len ) return ErrorCodes::InvalidColumn; 1384 1385 // adjust the length item 1386 *len = last - first; 1387 1388 // get the array itself 1389 FMatrix* var = fMatrix( name, len, cols ); 1390 if ( !var ) return ErrorCodes::InvalidColumn; 1391 1392 /// fill the matrix 1393 size_t iRow = 0; 1394 for ( ; first != last; ++first ) { 1395 // 1396 for ( MIndex iCol = 0; iCol < cols; ++iCol ) { ( *var )[iRow][iCol] = ( *first )[iCol]; } 1397 // 1398 ++iRow; 1399 } 1400 1401 return StatusCode::SUCCESS; 1402 } 1403 // ======================================================================= 1404 /** fill N-Tuple with matrix of "direct-product" of 1405 * "data-vector" [first,last) and 1406 * "function-vector" [funF, funL) 1407 * 1408 * The elements of effective matrix are: 1409 * 1410 * mtrx[iCol][iRow] = (*(funF+iRow))( *(first+iCol) ) 1411 * 1412 * @attention 1413 * The length of data-vector is variable, while 1414 * the length of "function" vector is fixed! 1415 * 1416 * @code 1417 * 1418 * typedef std::vector<double> Array ; 1419 * Array array = ... ; 1420 * 1421 * typedef double (*fun)( double ) ; 1422 * typedef std::vector<fun> Funs ; 1423 * 1424 * Funs funs ; 1425 * funs.push_back( sin ) ; 1426 * funs.push_back( cos ) ; 1427 * funs.push_back( tan ) ; 1428 * funs.push_back( sinh ) ; 1429 * funs.push_back( cosh ) ; 1430 * funs.push_back( tanh ) ; 1431 * 1432 * tuple->fmatrix ( "mtrx" , // N-Tuple entry name 1433 * funs.begin () , // begin of "function-vector" 1434 * funs.end () , // end of "function-vector" 1435 * array.begin () , // begin of "data-vector" 1436 * array.end () , // end of "data-vector" 1437 * "Length" , 1438 * 100 ) ; 1439 * @endcode 1440 * 1441 * This method is very convenient e.g. for using within LoKi: 1442 * 1443 * @code 1444 * 1445 * typedef std::vector<Fun> VctFun ; 1446 * 1447 * // sequence of Particles 1448 * Range particles = .... ; 1449 * 1450 * // vector of functions: 1451 * VctFun funs ; 1452 * funs.push_back( E / GeV ) ; 1453 * funs.push_back( PX / GeV ) ; 1454 * funs.push_back( PY / GeV ) ; 1455 * funs.push_back( PZ / GeV ) ; 1456 * funs.push_back( PT / GeV ) ; 1457 * funs.push_back( M / GeV ) ; 1458 * funs.push_back( ID ) ; 1459 * 1460 * // fill N-Tuple with information about each particle 1461 * tuple -> fmatrix ( "vars" , 1462 * funs.begin () , 1463 * funs.end () , 1464 * particles.begin () , 1465 * particles.end () , 1466 * "nParts" , 1467 * 200 ) ; 1468 * 1469 * @endcode 1470 * 1471 * @param name entry name in N-Tuple 1472 * @param funF "begin"-iterator for vector of functions 1473 * @param funL "end"-iterator for vector of functions 1474 * @param first "begin"-iterator for vector of data 1475 * @param last "end"-iterator for vector of data 1476 * @param length entry name in NTuple for number of matrix column 1477 * @param maxv maximal number of rows in matrix 1478 * 1479 * @author Vanya BELYAEV Ivan.Belyaev@lapp.in2p3.fr 1480 * @date 2005-05-01 1481 */ 1482 template <class FUN, class DATA> 1483 StatusCode fmatrix( std::string_view name, FUN funF, FUN funL, DATA first, DATA last, std::string_view length, 1484 size_t maxv ) { 1485 if ( invalid() ) return ErrorCodes::InvalidTuple; 1486 if ( rowWise() ) return ErrorCodes::InvalidOperation; 1487 1488 // adjust the length 1489 if ( std::distance( first, last ) > static_cast<std::ptrdiff_t>( maxv ) ) { 1490 Warning( fmt::format( "fmatrix('{}'): matrix is overflow, skip extra items", name ) ).ignore(); 1491 last = std::next( first, maxv ); 1492 } 1493 1494 // get the length item 1495 Int* len = ints( length, 0, maxv ); 1496 1497 if ( !len ) return ErrorCodes::InvalidColumn; 1498 1499 // adjust the length item 1500 *len = std::distance( first, last ); 1501 1502 // get the array itself 1503 auto cols = std::distance( funF, funL ); 1504 FMatrix* var = fMatrix( name, len, cols ); 1505 if ( !var ) return ErrorCodes::InvalidColumn; 1506 1507 /// fill the matrix 1508 size_t iRow = 0; 1509 for ( ; first != last; ++first ) { 1510 // 1511 for ( FUN fun = funF; fun < funL; ++fun ) { ( *var )[iRow][fun - funF] = std::invoke( *fun, *first ); } 1512 // 1513 ++iRow; 1514 } 1515 1516 return StatusCode::SUCCESS; 1517 } 1518 // ======================================================================= 1519 public: 1520 // ======================================================================= 1521 /** fill N-Tuple with fixed-size array 1522 * 1523 * @code 1524 * 1525 * SEQUENCE data( 10 ) ; 1526 * ... 1527 * tuple -> array("data" , 1528 * data.begin () , 1529 * data.end () ) ; 1530 * 1531 * @endcode 1532 * 1533 * Sequence may be of any objects, implicitly 1534 * convertible into "float" 1535 * 1536 * @param name N-Tuple entry name 1537 * @param first begin-iterator for data sequence 1538 * @param last end-iterator for data sequence 1539 * 1540 * @author Vanya BELYAEV Ivan.Belyaev@lapp.in2p3.fr 1541 * @date 2005-05-01 1542 */ 1543 template <class DATA> 1544 StatusCode array( std::string_view name, DATA first, DATA last ) 1545 1546 { 1547 if ( invalid() ) return ErrorCodes::InvalidTuple; 1548 if ( rowWise() ) return ErrorCodes::InvalidOperation; 1549 1550 // get the length (fixed!) 1551 auto length = std::distance( first, last ); 1552 1553 // get the array itself 1554 FArray* var = fArray( name, length ); 1555 if ( !var ) return ErrorCodes::InvalidColumn; 1556 1557 /// fill the array 1558 std::copy( first, last, std::begin( *var ) ); 1559 1560 return StatusCode::SUCCESS; 1561 } 1562 // ======================================================================= 1563 /** fill N-Tuple with fixed-size array 1564 * 1565 * "ARRAY" must support indexing operations: 1566 * e.g it coudl be of type: 1567 * - std::vector<TYPE> 1568 * - CLHEP::HepVector, ... 1569 * - "TYPE"[n] 1570 * 1571 * The content of array should be implicitly 1572 * convertible to "float" 1573 * 1574 * @code 1575 * 1576 * CLHEP::HepVector vct1(10) ; 1577 * ... 1578 * tuple -> array ( "vct1" , vct1 , 10 ) ; 1579 * 1580 * double vct2[40]; 1581 * ... 1582 * tuple -> array ( "vct2" , vct2 , 40 ) ; 1583 * 1584 * long vct3[4]; 1585 * ... 1586 * tuple -> array ( "vct3" , vct4 , 4 ) ; 1587 * 1588 * std::vector<long double> vct4(15) ; 1589 * ... 1590 * tuple -> array ( "vct4" , vct4 , 15 ) ; 1591 * 1592 * @endcode 1593 * 1594 * @param name N-Tuple entry name 1595 * @param data data sequence 1596 * @param length data length (fixed!) 1597 * 1598 * @author Vanya BELYAEV Ivan.Belyaev@lapp.in2p3.fr 1599 * @date 2005-05-01 1600 */ 1601 template <class ARRAY> 1602 StatusCode array( std::string_view name, const ARRAY& data, const MIndex& length ) { 1603 using std::begin; // allow data to be eg. CLHEP::HepVector (which does not define HepVector::begin()!, 1604 // in which case ADL prefers CLHEP::begin (yah! at least they (now) use a namespace) 1605 // so one just to insure double* CLHEP::begin(CLHEP::HepVector& v) { return &v[0]; } 1606 // is visible when this function gets instantiated for CLHEP::HepVector... 1607 auto first = begin( data ); 1608 return array( name, first, std::next( first, length ) ); 1609 } 1610 // ======================================================================= 1611 /** fill N-Tuple with fixed-size array 1612 * 1613 * "ARRAY" is any sequence, which supports 1614 * ARRAY::begin() and ARRAY::end() protocol, e.g. 1615 * 1616 * - std::vector<TYPE> 1617 * - ROOT::Math::SVector<double,15> 1618 * 1619 * The content of array should be implicitly 1620 * convertible to "float" 1621 * 1622 * @code 1623 * 1624 * typedef std::vector<double> Seq ; 1625 * Seq data( 10 ) ; 1626 * for ( int i = 0 ; i < 10 ; ++i ) 1627 * { 1628 * data[i] = ... ; 1629 * } 1630 * 1631 * tuple -> array( "data" , data ) ; 1632 * 1633 * @endcode 1634 * 1635 * @param name N-Tupel entry name 1636 * @param data data sequence 1637 * 1638 * @author Vanya BELYAEV Ivan.Belyaev@lapp.in2p3.fr 1639 * @date 2005-05-01 1640 */ 1641 template <class ARRAY> 1642 StatusCode array( std::string_view name, const ARRAY& data ) { 1643 using std::begin; 1644 using std::end; 1645 return array( name, begin( data ), end( data ) ); 1646 } 1647 // ======================================================================= 1648 public: 1649 // ======================================================================= 1650 /** fill N-Tuple with fixed-size matrix 1651 * 1652 * "MATRIX" must support indexing operations: 1653 * data[iRow][iCol] 1654 * 1655 * e.g it could be of type: 1656 * - std::vector<std::vector<TYPE> > 1657 * - CLHEP::HepMatrix , CLHEP::GenMatrix, etc ... 1658 * - "TYPE"[n][m] 1659 * 1660 * The content of MATRIX should be implicitly convertible 1661 * to "float" 1662 * 1663 * @code 1664 * 1665 * CLHEP::HepMatrix mtrx1(3,20) ; 1666 * ... 1667 * tuple -> matrix ( "m1" , 1668 * mtrx1 , 1669 * mtrx1.num_row() , 1670 * mtrx1.num_col() ) ; 1671 * 1672 * typedef std::vector<double> Row ; 1673 * typedef std:vector<Row> Mtrx ; 1674 * Mtrx mtrx2( 3 , Row(10) ) ; 1675 * ... 1676 * tuple -> matrix ( "m2" , 1677 * mtrx2 , 1678 * 3 , 1679 * 10 ) ; 1680 * 1681 * float mtrx3[3][10] ; 1682 * ... 1683 * tuple -> matrix ( "m3" , 1684 * mtrx3 , 1685 * 3 , 1686 * 10 ) ; 1687 * 1688 * @endcode 1689 * 1690 * @param name N-Tuple entry name 1691 * @param data data source (matrix) 1692 * @param cols number of columns 1693 * @param rows number of rows 1694 * 1695 * @author Vanya BELYAEV Ivan.Belyaev@lapp.in2p3.fr 1696 * @date 2005-05-01 1697 */ 1698 template <class MATRIX> 1699 StatusCode matrix( std::string_view name, const MATRIX& data, const MIndex& rows, const MIndex& cols ) { 1700 if ( invalid() ) return ErrorCodes::InvalidTuple; 1701 if ( rowWise() ) return ErrorCodes::InvalidOperation; 1702 1703 // get the matrix itself 1704 FMatrix* var = fMatrix( name, rows, cols ); 1705 if ( !var ) return ErrorCodes::InvalidColumn; 1706 1707 /// fill the matrix 1708 for ( size_t iCol = 0; iCol < cols; ++iCol ) { 1709 for ( size_t iRow = 0; iRow < rows; ++iRow ) { ( *var )[iRow][iCol] = data[iRow][iCol]; } 1710 }; 1711 return StatusCode::SUCCESS; 1712 } 1713 // ======================================================================= 1714 public: 1715 // ======================================================================= 1716 /** Useful shortcut to put LorentzVector directly into N-Tuple: 1717 * 1718 * @code 1719 * 1720 * const LHCb::Particle* B = ... 1721 * 1722 * Tuple tuple = nTuple("My N-Tuple") ; 1723 * 1724 * // put 4-vector of B-candidate into N-tuple: 1725 * tuple -> column ("B" , B->momentum() ) ; 1726 * 1727 * @endcode 1728 * 1729 * @author Vanya BELYAEV ibelyaev@physics.syr.edu 1730 * @date 2006-11-26 1731 */ 1732 template <class TYPE> 1733 StatusCode column( std::string_view name, const ROOT::Math::LorentzVector<TYPE>& v ) { 1734 return columns( v, std::pair{ fmt::format( "{}E", name ), &ROOT::Math::LorentzVector<TYPE>::E }, 1735 std::pair{ fmt::format( "{}X", name ), &ROOT::Math::LorentzVector<TYPE>::Px }, 1736 std::pair{ fmt::format( "{}Y", name ), &ROOT::Math::LorentzVector<TYPE>::Py }, 1737 std::pair{ fmt::format( "{}Z", name ), &ROOT::Math::LorentzVector<TYPE>::Pz } ); 1738 } 1739 // ======================================================================= 1740 /** Useful shortcut to put 3D-Vector directly into N-Tuple: 1741 * 1742 * @code 1743 * 1744 * const LHCb::Vertex* V = ... 1745 * 1746 * Tuple tuple = nTuple("My N-Tuple") ; 1747 * 1748 * // put vertex position into N-tuple: 1749 * tuple -> column ("B" , B->position() ) ; 1750 * 1751 * @endcode 1752 * 1753 * @author Vanya BELYAEV ibelyaev@physics.syr.edu 1754 * @date 2006-11-26 1755 */ 1756 template <class TYPE, class TAG> 1757 StatusCode column( std::string_view name, const ROOT::Math::DisplacementVector3D<TYPE, TAG>& v ) { 1758 return this->columns( v, std::pair{ fmt::format( "{}X", name ), &ROOT::Math::DisplacementVector3D<TYPE, TAG>::X }, 1759 std::pair{ fmt::format( "{}Y", name ), &ROOT::Math::DisplacementVector3D<TYPE, TAG>::Y }, 1760 std::pair{ fmt::format( "{}Z", name ), &ROOT::Math::DisplacementVector3D<TYPE, TAG>::Z } ); 1761 } 1762 // ======================================================================= 1763 /** Useful shortcut to put 3D-Vector directly into N-Tuple: 1764 * 1765 * @code 1766 * 1767 * const LHCb::Vertex* V = ... 1768 * 1769 * Tuple tuple = nTuple("My N-Tuple") ; 1770 * 1771 * // put vertex position into N-tuple: 1772 * tuple -> column ("B" , B->position() ) ; 1773 * 1774 * @endcode 1775 * 1776 * @author Vanya BELYAEV ibelyaev@physics.syr.edu 1777 * @date 2006-11-26 1778 */ 1779 template <class TYPE, class TAG> 1780 StatusCode column( std::string_view name, const ROOT::Math::PositionVector3D<TYPE, TAG>& v ) { 1781 return this->columns( v, std::pair{ fmt::format( "{}X", name ), &ROOT::Math::PositionVector3D<TYPE, TAG>::X }, 1782 std::pair{ fmt::format( "{}Y", name ), &ROOT::Math::PositionVector3D<TYPE, TAG>::Y }, 1783 std::pair{ fmt::format( "{}Z", name ), &ROOT::Math::PositionVector3D<TYPE, TAG>::Z } ); 1784 } 1785 // ======================================================================= 1786 /** shortcut to put Smatrix into N-tuple: 1787 * 1788 * @code 1789 * @endcode 1790 * 1791 * @author Vanya BELYAEV ibelyaev@physics.syr.edu 1792 * @date 2006-11-26 1793 */ 1794 template <class TYPE, unsigned int D1, unsigned int D2, class REP> 1795 StatusCode matrix( std::string_view name, const ROOT::Math::SMatrix<TYPE, D1, D2, REP>& mtrx ) { 1796 if ( invalid() ) return ErrorCodes::InvalidTuple; 1797 if ( rowWise() ) return ErrorCodes::InvalidOperation; 1798 1799 // get the matrix itself 1800 FMatrix* var = fMatrix( name, (MIndex)D1, (MIndex)D2 ); 1801 if ( !var ) return ErrorCodes::InvalidColumn; 1802 1803 /// fill the matrix 1804 for ( size_t iCol = 0; iCol < D2; ++iCol ) { 1805 for ( size_t iRow = 0; iRow < D1; ++iRow ) { ( *var )[iRow][iCol] = mtrx( iRow, iCol ); } 1806 }; 1807 1808 return StatusCode::SUCCESS; 1809 } 1810 // ======================================================================= 1811 /** shortcut to put "ExtraInfo" fields of major 1812 * into N-Tuple 1813 * 1814 * @code 1815 * 1816 * const LHCb::Particle* B = ... 1817 * 1818 * Tuple tuple = nTuple("My N-Tuple") ; 1819 * 1820 * // put the vector into N-Tuple: 1821 * tuple -> fmatrix ( "Info" , B->extraInfo() , "nInfo" , 100 ) ; 1822 * 1823 * @endcode 1824 * 1825 * @author Vanya BELYAEV ibelyaev@physics.syr.edu 1826 * @date 2006-11-26 1827 */ 1828 template <class KEY, class VALUE> 1829 StatusCode fmatrix( std::string_view name, const GaudiUtils::VectorMap<KEY, VALUE>& info, std::string_view length, 1830 const size_t maxv = 100 ) { 1831 using Info = std::pair<KEY, VALUE>; 1832 static const std::array<float ( * )( const Info& ), 2> fns = { 1833 { []( const Info& i ) -> float { return i.first; }, []( const Info& i ) -> float { return i.second; } } }; 1834 return fmatrix( name, begin( fns ), end( fns ), begin( info ), end( info ), length, maxv ); 1835 } 1836 // ======================================================================= 1837 public: 1838 // ======================================================================= 1839 /** The function allows to add almost arbitrary object into N-tuple 1840 * @attention it requires POOL persistency 1841 * @param name column name 1842 * @param obj pointer to the object 1843 * @author Vanya BELYAEV ibelyaev@physics.syr.edu 1844 * @date 2007-04-08 1845 */ 1846 template <class TYPE> 1847 StatusCode put( std::string_view name, const TYPE* obj ); 1848 // ======================================================================= 1849 public: 1850 // ======================================================================= 1851 /** write a record to NTuple 1852 * @return status code 1853 */ 1854 StatusCode write(); 1855 // ======================================================================= 1856 /// get the name 1857 const std::string& name() const { return m_name; } 1858 // ======================================================================= 1859 /** provide the access to underlying Gaudi N-tuple 1860 * @return pointer to Gaudi N-tuple object 1861 */ 1862 const NTuple::Tuple* tuple() const { return m_tuple; } 1863 // ======================================================================= 1864 /** provide the access to underlying Gaudi N-tuple 1865 * @return pointer to Gaudi N-tuple object 1866 */ 1867 NTuple::Tuple* tuple() { return m_tuple; } 1868 // ======================================================================= 1869 /// accessor to the N-Tuple CLID 1870 const CLID& clid() const { return m_clid; } 1871 // ======================================================================= 1872 /// accessor to the N-Tuple type 1873 Tuples::Type type() const { return m_type; } 1874 // ======================================================================= 1875 /// column wise NTuple ? 1876 bool columnWise() const { return CLID_ColumnWiseTuple == clid(); } 1877 // ======================================================================= 1878 /// row wise NTuple ? 1879 bool rowWise() const { return CLID_RowWiseTuple == clid(); } 1880 // ======================================================================= 1881 /// Event collection ? 1882 bool evtColType() const { return Tuples::EVTCOL == type(); } 1883 // ======================================================================= 1884 /// valid pointer to tuple ? 1885 bool valid() const { return 0 != tuple(); } 1886 // ======================================================================= 1887 /// invalid pointer to tuple ? 1888 bool invalid() const { return !valid(); } 1889 // ======================================================================= 1890 public: 1891 // ======================================================================= 1892 /** add the item name into the list of known items 1893 * @param name the name of the item 1894 * @param type the type of the item 1895 * @return true if the name is indeed added 1896 */ 1897 bool addItem( std::string name, std::string type ) { 1898 return m_items.emplace( std::move( name ), std::move( type ) ).second; 1899 } 1900 // ======================================================================= 1901 /** check the uniqueness of the name 1902 * @param name the name of the item 1903 * @return true if the name is indeed unique 1904 */ 1905 bool goodItem( std::string_view name ) const { return m_items.end() == m_items.find( name ); } 1906 // ======================================================================= 1907 /// get the full list of booked items 1908 const ItemMap& items() const { return m_items; } 1909 // ======================================================================= 1910 public: 1911 // ======================================================================= 1912 virtual StatusCode Error( const std::string& msg, const StatusCode sc = StatusCode::FAILURE ) const = 0; 1913 // ======================================================================= 1914 virtual StatusCode Warning( const std::string& msg, const StatusCode sc = StatusCode::FAILURE ) const = 0; 1915 // ======================================================================= 1916 private: 1917 // ======================================================================= 1918 /// get the column 1919 Int* ints( std::string_view name, int minv, int maxv ); 1920 // ======================================================================= 1921 /// get the column 1922 FArray* fArray( std::string_view name, Int* item ); 1923 // ======================================================================= 1924 /// get the column 1925 FArray* fArray( std::string_view name, const MIndex& rows ); 1926 // ======================================================================= 1927 /// get the column 1928 Address* addresses( std::string_view name ); 1929 // ======================================================================= 1930 /// get the column 1931 FMatrix* fMatrix( std::string_view name, Int* item, const MIndex& cols ); 1932 // ======================================================================= 1933 /// get the column 1934 FMatrix* fMatrix( std::string_view name, const MIndex& rows, const MIndex& cols ); 1935 // ======================================================================= 1936 /// delete the copy constructor and assignment 1937 TupleObj( const TupleObj& ) = delete; 1938 TupleObj& operator=( const TupleObj& ) = delete; 1939 // ======================================================================= 1940 private: 1941 // ======================================================================= 1942 /// name 1943 std::string m_name; 1944 // ======================================================================= 1945 /// tuple itself 1946 NTuple::Tuple* m_tuple; 1947 // ======================================================================= 1948 /// tuple CLID 1949 CLID m_clid; 1950 // ======================================================================= 1951 /// tuple 'type' 1952 Tuples::Type m_type; 1953 // ======================================================================= 1954 /// reference counter 1955 size_t m_refCount = 0; 1956 // ======================================================================= 1957 // helper type to define the actual storage types 1958 template <typename T> 1959 class ColumnStorage { 1960 std::unordered_map<std::string_view, std::pair<T, std::string>> m_map; 1961 1962 public: 1963 using element_type = T; 1964 T* find( std::string_view sv ) { 1965 auto i = m_map.find( sv ); 1966 return i != m_map.end() ? &i->second.first : nullptr; 1967 } 1968 T* end() { return nullptr; } 1969 std::pair<T*, bool> emplace( std::string_view k, T v = T{} ) { 1970 // tricky way to insert a string_view key which points to the 1971 // string contained in the mapped type... all just to make find(string_view) work in C++17... 1972 auto [i, b] = m_map.try_emplace( k, std::move( v ), std::string{ k } ); 1973 if ( !b ) return { static_cast<T*>( nullptr ), false }; 1974 auto nh = m_map.extract( i ); 1975 nh.key() = nh.mapped().second; // "re-point" key to the string contained value_type 1976 auto r = m_map.insert( std::move( nh ) ); 1977 return { &r.position->second.first, r.inserted }; 1978 } 1979 }; 1980 1981 // ======================================================================= 1982 /// the actual storage of all 'bool' columns 1983 mutable ColumnStorage<Bool> m_bools; 1984 // ======================================================================= 1985 /// the actual storage of all 'Int' columns 1986 mutable ColumnStorage<Char> m_chars; 1987 // ======================================================================= 1988 /// the actual storage of all 'unsigned int' columns 1989 mutable ColumnStorage<UChar> m_uchars; 1990 // ======================================================================= 1991 /// the actual storage of all 'Int' columns 1992 mutable ColumnStorage<Short> m_shorts; 1993 // ======================================================================= 1994 /// the actual storage of all 'unsigned int' columns 1995 mutable ColumnStorage<UShort> m_ushorts; 1996 // ======================================================================= 1997 /// the actual storage of all 'Int' columns 1998 mutable ColumnStorage<Int> m_ints; 1999 // ======================================================================= 2000 /// the actual storage of all 'unsigned int' columns 2001 mutable ColumnStorage<UInt> m_uints; 2002 // ======================================================================= 2003 /// the actual storage of all 'long long' columns 2004 mutable ColumnStorage<LongLong> m_longlongs; 2005 // ======================================================================= 2006 /// the actual storage of all 'unsigned long long' columns 2007 mutable ColumnStorage<ULongLong> m_ulonglongs; 2008 // ======================================================================= 2009 /// the actual storage of all 'Float' columns 2010 mutable ColumnStorage<Float> m_floats; 2011 // ======================================================================= 2012 /// the actual storage of all 'Double' columns 2013 mutable ColumnStorage<Double> m_doubles; 2014 // ======================================================================= 2015 /// the actual storage of all 'Address' columns 2016 mutable ColumnStorage<Address> m_addresses; 2017 // ======================================================================= 2018 /// the actual storage of all 'FArray' columns 2019 mutable ColumnStorage<FArray> m_farrays; 2020 // ======================================================================= 2021 /// the actual storage of all 'FArray' columns (fixed) 2022 mutable ColumnStorage<FArray> m_arraysf; 2023 // ======================================================================= 2024 /// the actual storage of all 'FArray' columns 2025 mutable ColumnStorage<FMatrix> m_fmatrices; 2026 // ======================================================================= 2027 /// the actual storage of all 'FMatrix' columns (fixed) 2028 mutable ColumnStorage<FMatrix> m_matricesf; 2029 // ======================================================================= 2030 /// all booked types: 2031 ItemMap m_items; 2032 // ======================================================================= 2033 }; 2034 // ========================================================================== 2035 } // end of namespace Tuples 2036 2037 // ============================================================================ 2038 // GaudiAlg 2039 // ============================================================================ 2040 #include "GaudiAlg/TuplePut.h" 2041 // ============================================================================ 2042 // The END 2043 // ============================================================================ 2044 #endif // GAUDIALG_TUPLEOBJ_H
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |