| Report problems to ATLAS LXR Team (with time and IP address indicated) |
|
[ source navigation ] [ diff markup ] [ identifier search ] [ general search ] |
||||
|
||||||
| Links to LXR source navigation pages for stable releases | [ 12.*.* ] [ 13.*.* ] [ 14.*.* ] [ 15.*.* ] | |||||
001 // $Id: TupleObj.h,v 1.23 2008/10/27 19:22:20 marcocle Exp $ 002 // ============================================================================ 003 // CVS tag $Name: $, version $Revision: 1.23 $ 004 // ============================================================================ 005 #ifndef GAUDIALG_TUPLEOBJ_H 006 #define GAUDIALG_TUPLEOBJ_H 1 007 // ============================================================================ 008 // Include files 009 // ============================================================================ 010 // STD&STL 011 // ============================================================================ 012 #include <set> 013 #include <string> 014 #include <limits> 015 // ============================================================================ 016 // GaudiKernel 017 // ============================================================================ 018 #include "GaudiKernel/NTuple.h" 019 #include "GaudiKernel/VectorMap.h" 020 // ============================================================================ 021 // GaudiAlg 022 // ============================================================================ 023 #include "GaudiAlg/Tuples.h" 024 #include "GaudiAlg/Maps.h" 025 // ============================================================================ 026 // ROOT 027 // ============================================================================ 028 #include "Math/Point3D.h" 029 #include "Math/Vector3D.h" 030 #include "Math/Vector4D.h" 031 #include "Math/SVector.h" 032 #include "Math/SMatrix.h" 033 // ============================================================================ 034 // forward declaration 035 // ============================================================================ 036 // GaudiKernel 037 // ============================================================================ 038 class IOpaqueAddress ; 039 // ============================================================================ 040 /** @file TupleObj.h 041 * 042 * Header file for class TupleObj 043 * 044 * @date 2004-01-23 045 * @author Vanya BELYAEV Ivan.Belyaev@itep.ru 046 */ 047 // ============================================================================ 048 /** @namespace Tuples 049 * 050 * General namespace for Tuple properties 051 * 052 * @author Vanya BELYAEV Ivan.Belyaev@itep.ru 053 * @date 2004-01-23 054 */ 055 namespace Tuples 056 { 057 // ========================================================================== 058 /** @enum Type 059 * the list of availabe types for ntuples 060 * @author Vanya BELYAEV Ivan.Belyaev@itep.ru 061 * @date 2004-01-23 062 */ 063 enum Type 064 { 065 NTUPLE , // Analysis nTuple 066 EVTCOL // Event Collection 067 }; 068 // ========================================================================== 069 /** @enum ErrorCodes 070 * 071 * Tuple error codes 072 * 073 * @author Vanya BELYAEV Ivan.Belyaev@itep.ru 074 * @date 2004-01-23 075 */ 076 enum ErrorCodes 077 { 078 InvalidTuple = 100 , 079 InvalidColumn , 080 InvalidOperation , 081 InvalidObject , 082 InvalidItem , 083 TruncateValue = 200 084 }; 085 // ========================================================================== 086 /** @class TupleObj TupleObj.h GaudiAlg/TupleObj.h 087 * 088 * @brief A simple wrapper class over standard 089 * Gaudi NTuple::Tuple facility 090 * 091 * The design and implementation are imported from LoKi package 092 * 093 * One should not use lass TupleObj directly. 094 * The specaial handler Tuples::Tuple shoudl be used instead, 095 * which is simultaneously 'proxy' an d'smart pointer' for 096 * real (and heavy!) TupleObj class. 097 * 098 * The main advantages of local ntuples with respect to 'standard' 099 * Gaudi NTuples ( NTuple::Tuple ) is their "locality". 100 * For 'standard' ntuples one need 101 * <ol> 102 * <li> Define all ntuple columns/items as 103 * data members of the algorithm </li> 104 * <li> Book the <tt>NTuple::Tuple</tt> object using 105 * <tt>INTupleSvc</tt></li> 106 * <li> Add all defined columns/items to the booked ntuple </li> 107 * <li> Fill ntuple records 108 * </ol> 109 * Usially the first step is done in the header file (separate file!) 110 * of the algorithm, the second and the third steps are done in 111 * <tt>initialize()</tt> method of the algorithm and 112 * the fourth step is done somewhere in <tt>execute()</tt> method of 113 * the same algorithm. Such approach requires to keep track of the 114 * tuple structure through different method and event throught different 115 * files. And even minor modification of the structure of teh ntuple 116 * will reqire the modification of at least 2 methods and 2 files. 117 * 118 * The <tt>Tuples::Tuple</tt> wrapper over standard Gaudi 119 * <tt>NTuple::Tuple</tt> class solves all abouve listed problems with 120 * "non-local" nature of Gaudi <tt>NTuple::Tuple</tt> objects. 121 * 122 * <tt>Tuples::Tuple</tt> object is booked and used 'locally'. 123 * One does not need to pre-book the ntuple or its columns/items 124 * somewhere in different compilation units or other methods different 125 * from the actual point of using the ntuple. 126 * 127 * The simplest example of usage Tuples::Tuple object: 128 * @code 129 * Tuple tuple = nTuple( "some more or less uniqe tuple title "); 130 * for( Loop D0 = loop( "K- pi+", "D0" ) , D0 , ++D0 ) 131 * { 132 * tuple -> column ( "mass" , M ( D0 ) / GeV ) ; 133 * tuple -> column ( "pt" , PT ( D0 ) / GeV ) ; 134 * tuple -> column ( "p" , P ( D0 ) / GeV ) ; 135 * tuple -> write () ; 136 * } 137 * @endcode 138 * 139 * One could fill some Tuple variables in one go 140 * @code 141 * Tuple tuple = nTuple( "some more or less uniqe tuple title "); 142 * for( Loop D0 = loop( "K- pi+", "D0" ) , D0 , ++D0 ) 143 * { 144 * tuple -> column ( "mass" , M ( D0 ) / GeV ) ; 145 * tuple -> fill ( "pt , p " , PT ( D0 ) / GeV , P(D0) / GeV ) ; 146 * tuple -> write () ; 147 * } 148 * @endcode 149 * 150 * Even ALL variables could be filled in one go: 151 * @code 152 * Tuple tuple = nTuple( "some more or less uniqe tuple title "); 153 * for( Loop D0 = loop( "K- pi+", "D0" ) , D0 , ++D0 ) 154 * { 155 * tuple -> fill ( "mass pt , p ", M(D0)/GeV,PT(D0)/GeV,P(D0)/GeV ) ; 156 * tuple -> write () ; 157 * } 158 * @endcode 159 * 160 * The 'array-like' columns are also supported ( see methods 'farray') 161 * 162 * All these techniques could be easily combined in arbitrary ways 163 * 164 * class TupleObj is an abstract class with 3 pure abstract functions 165 * Error and Warning , which need to be reimplemented 166 * in any 'concrete class. 167 * Helper classes TupleObjImp, ErrorHandler and functions 168 * createTupleObj and make_handler alllows to 169 * create concrete objects 'on-fligh' 170 * 171 * @attention 172 * <c>long long</c> and <c>unsigned long long</c> 173 * types are not supported. One needs to convert the data 174 * into some other representation (e.g. as 2 separate fields, 175 * or perform the explicitely cast to <c>long</c>) 176 * 177 * @author Vanya BELYAEV ibelyaev@physics.syr.edu 178 * @date 2004-01-23 179 */ 180 class TupleObj 181 { 182 public: 183 // ======================================================================== 184 /** basic type for 'integer' items 185 * It has the fixed bit-length (32) for all platforms (?) 186 */ 187 typedef NTuple::Item<int> Int ; 188 // ======================================================================== 189 /** basic type for 'float/double' items 190 * It has the fixed bit-length (32) for all platforms (?) 191 */ 192 typedef NTuple::Item<float> Float ; 193 // ======================================================================== 194 /// basic type for address items 195 typedef NTuple::Item<IOpaqueAddress*> Address ; 196 // ======================================================================== 197 /// basic type for array of floats 198 typedef NTuple::Array<float> FArray ; 199 // ======================================================================== 200 /// basic type for matrix of floats 201 typedef NTuple::Matrix<float> FMatrix ; 202 // ======================================================================== 203 // the actual type for variable size matrix indices 204 typedef unsigned short MIndex ; 205 // ======================================================================== 206 // the map of items 207 typedef std::map<std::string,std::string> ItemMap ; 208 // ======================================================================== 209 protected: 210 // ======================================================================== 211 /** Standard constructor 212 * @see NTuple:Tuple 213 * @param name name of the object 214 * @param tuple pointer to standard Gaudi NTuple::Tuple object 215 * @param clid CLID_ColumnWiseTuple or CLID_RowWiseTuple 216 * @param type the type of the tuple 217 */ 218 TupleObj 219 ( const std::string& name , 220 NTuple::Tuple* tuple , 221 const CLID& clid = CLID_ColumnWiseTuple , 222 const Tuples::Type type = Tuples::NTUPLE ) ; 223 // ======================================================================== 224 protected: 225 // ======================================================================== 226 /// destructor is protected 227 virtual ~TupleObj(); 228 // ======================================================================== 229 public: 230 // ======================================================================== 231 /** Set the value for selected tuple column. 232 * If the column does not exist yet, it will be 233 * automatically created and appended to the tuple 234 * 235 * @code 236 * 237 * int number = ... ; 238 * tuple->column("num", number ); 239 * 240 * @endcode 241 * 242 * @param name name of the column 243 * @param value value of tve variable 244 * @return status code 245 */ 246 StatusCode column ( const std::string& name , 247 const int value ) 248 { 249 if ( invalid() ) { return InvalidTuple ; } 250 Int* item = ints( name ) ; 251 if ( 0 == item ) { return InvalidColumn ; } 252 *item = value ; 253 return StatusCode::SUCCESS ; 254 } 255 // ======================================================================== 256 /** Set the value for selected tuple column. 257 * If the column does not exist yet, it will be 258 * automatically created and appended to the tuple 259 * 260 * @code 261 * 262 * long number = ... ; 263 * tuple->column("num", number ); 264 * 265 * @endcode 266 * 267 * @param name name of the column 268 * @param value value of tve variable 269 * @param minv minimum value of the variable 270 * @param maxv maximum value of the variable 271 * @return status code 272 */ 273 StatusCode column ( const std::string& name , 274 const int value , 275 const int minv , 276 const int maxv ) 277 { 278 if ( invalid() ) { return InvalidTuple ; } 279 Int* item = ints ( name , minv , maxv ) ; 280 if ( 0 == item ) { return InvalidColumn ; } 281 *item = value ; 282 return StatusCode::SUCCESS ; 283 } 284 // ======================================================================== 285 public: 286 // ======================================================================== 287 /** Set the value for selected tuple column. 288 * If the column does not exist yet, it will be 289 * automatically created and appended to the tuple 290 * 291 * @code 292 * 293 * int number = ... ; 294 * tuple->column("num", number ); 295 * 296 * @endcode 297 * 298 * @param name name of the column 299 * @param value value of tve variable 300 * @return status code 301 */ 302 StatusCode column ( const std::string& name , 303 const unsigned int value ) 304 { 305 StatusCode sc1 = StatusCode::SUCCESS ; 306 static const unsigned int s_max = std::numeric_limits<int>::max() ; 307 if ( s_max < value ) 308 { sc1 = Warning 309 (" column('" + name + "'): truncate unsigned int" , TruncateValue ) ; } 310 const int val = (int) value ; 311 StatusCode sc2 = column ( name , val ) ; 312 return sc2.isFailure() ? sc2 : sc1 ; 313 } 314 // ======================================================================== 315 /** Set the value for the selected tuple column. 316 * If the column does not exist yet, it will be 317 * automatically created and appended to the tuple 318 * 319 * @code 320 * 321 * int number = ... ; 322 * tuple -> column ( "num", number ); 323 * 324 * @endcode 325 * @warning the value could be truncated to int 326 * 327 * @param name the name of the column 328 * @param value the value of the variable 329 * @return status code 330 */ 331 StatusCode column ( const std::string& name , 332 const long value ) 333 { 334 StatusCode sc1 = StatusCode::SUCCESS ; 335 if ( sizeof(int) != sizeof(long) 336 && ( std::numeric_limits<int>::max() < value || 337 std::numeric_limits<int>::min() > value ) ) 338 { sc1 = Warning (" column('" + name + "'): truncate long value" , 339 TruncateValue ) ; } 340 const int val = (int) value ; 341 StatusCode sc2 = column ( name , val ) ; 342 return sc2.isFailure() ? sc2 : sc1 ; 343 } 344 // ======================================================================== 345 /** Set the value for selected tuple column. 346 * If the column does not exist yet, it will be 347 * automatically created and appended to the tuple 348 * 349 * @code 350 * 351 * int number = ... ; 352 * tuple -> column ( "num" , number ); 353 * 354 * @endcode 355 * @warning the value could be truncated to int 356 * 357 * @param name the name of the column 358 * @param value the value of the variable 359 * @return status code 360 */ 361 StatusCode column ( const std::string& name , 362 const unsigned long value ) 363 { 364 StatusCode sc1 = StatusCode::SUCCESS ; 365 static const unsigned long s_max = std::numeric_limits<int>::max() ; 366 if ( sizeof (int) != sizeof (unsigned long) && s_max < value ) 367 { sc1 = Warning (" column('" + name + "'): truncate unsigned long value" , 368 TruncateValue ) ; } 369 const int val = (int) value ; 370 StatusCode sc2 = column ( name , val ) ; 371 return sc2.isFailure() ? sc2 : sc1 ; 372 } 373 // ======================================================================== 374 /** Set the value for selected tuple column. 375 * If the column does not exist yet, it will be 376 * automatically created and appended to the tuple 377 * 378 * @code 379 * 380 * short number = ... ; 381 * tuple -> column ( "num" , number ); 382 * 383 * @endcode 384 * 385 * @param name the name of the column 386 * @param value the value of the variable 387 * @return status code 388 */ 389 StatusCode column ( const std::string& name , 390 const short value ) 391 { 392 return column 393 ( name , 394 value , 395 std::numeric_limits<short>::min() , 396 std::numeric_limits<short>::max() ) ; 397 } 398 // ======================================================================== 399 /** Set the value for selected tuple column. 400 * If the column does not exist yet, it will be 401 * automatically created and appended to the tuple 402 * 403 * @code 404 * 405 * unsigned short number = ... ; 406 * tuple -> column ( "num" , number ); 407 * 408 * @endcode 409 * 410 * @param name the name of the column 411 * @param value the value of the variable 412 * @return status code 413 */ 414 StatusCode column ( const std::string& name , 415 const unsigned short value ) 416 { 417 return column 418 ( name , 419 value , 420 std::numeric_limits<unsigned short>::min() , 421 std::numeric_limits<unsigned short>::max() ) ; 422 } 423 // ======================================================================== 424 /** Set the value for selected tuple column. 425 * If the column does not exist yet, it will be 426 * automatically created and appended to the tuple 427 * 428 * @code 429 * 430 * char number = ... ; 431 * tuple -> column ( "num" , number ); 432 * 433 * @endcode 434 * 435 * @param name the name of the column 436 * @param value the value of tve variable 437 * @return status code 438 */ 439 StatusCode column ( const std::string& name , 440 const char value ) 441 { 442 return column 443 ( name , 444 value , 445 std::numeric_limits<char>::min() , 446 std::numeric_limits<char>::max() ) ; 447 } 448 // ======================================================================== 449 /** Set the value for the selected tuple column. 450 * If the column does not exist yet, it will be 451 * automatically created and appended to the tuple 452 * 453 * @code 454 * 455 * unsigned char number = ... ; 456 * tuple->column("num", number ); 457 * 458 * @endcode 459 * 460 * @param name the name of the column 461 * @param value the value of tve variable 462 * @return status code 463 */ 464 StatusCode column ( const std::string& name , 465 const unsigned char value ) 466 { 467 return column 468 ( name , 469 value , 470 std::numeric_limits<unsigned char>::min() , 471 std::numeric_limits<unsigned char>::max() ) ; 472 } 473 // ======================================================================== 474 /** Set the value for the selected tuple column. 475 * If the column does not exist yet, it will be 476 * automatically created and appended to the tuple 477 * 478 * @code 479 * 480 * signed char number = ... ; 481 * tuple->column("num", number ); 482 * 483 * @endcode 484 * 485 * @param name the name of the column 486 * @param value the value of tve variable 487 * @return status code 488 */ 489 StatusCode column ( const std::string& name , 490 const signed char value ) 491 { 492 return column 493 ( name , 494 value , 495 std::numeric_limits<signed char>::min() , 496 std::numeric_limits<signed char>::max() ) ; 497 } 498 // ======================================================================== 499 public: 500 // ======================================================================== 501 /** Set the value for selected tuple column. 502 * If column does not exist, it will be automatically created 503 * and appended to the tuple 504 * 505 * @code 506 * // 507 * const float mass = ... ; 508 * tuple->column("m", mass ); 509 * // 510 * @endcode 511 * 512 * @param name the name of the column 513 * @param value the value of the variable 514 * @return status code 515 */ 516 StatusCode column ( const std::string& name , 517 const float value ) 518 { 519 if ( invalid() ) { return InvalidTuple ; } 520 Float* item = floats ( name ) ; 521 if ( 0 == item ) { return InvalidColumn ; } 522 *item = value ; 523 return StatusCode::SUCCESS ; 524 } 525 // ======================================================================== 526 /** Set the value for the selected tuple column 527 * If the column does not exist, it will be automatically created 528 * and appended to the tuple 529 * 530 * @code 531 * // 532 * const double mass = ... ; 533 * tuple->column("m", mass ); 534 * // 535 * @endcode 536 * @warning the value is truncated to float 537 * 538 * @param name the name of the column 539 * @param value the value of the variable 540 * @return status code 541 */ 542 StatusCode column ( const std::string& name , 543 const double value ) 544 { 545 StatusCode sc1 = StatusCode::SUCCESS ; 546 static const double s_max = std::numeric_limits<float>::max() ; 547 static const double s_min = -1 * std::numeric_limits<float>::max() ; 548 if ( s_max < value || s_min > value ) 549 { sc1 = Warning (" column('" + name + "'): truncate double value " , 550 TruncateValue ) ; } 551 const float val = (float) value ; 552 StatusCode sc2 = column ( name , val ) ; 553 return sc2.isFailure() ? sc2 : sc1 ; 554 } 555 // ======================================================================== 556 /** Set the value for selected tuple column. 557 * If the column does not exist yet, it will be 558 * automatically create and appended to the tuple 559 * 560 * @code 561 * 562 * tuple->column( "empty" , v.empty() ); 563 * 564 * @endcode 565 * 566 * @param name the name of the column 567 * @param value the value of the variable 568 * @return status code 569 */ 570 StatusCode column ( const std::string& name , 571 const bool value ) 572 { 573 const int val = value ; 574 return column ( name , val , 0 , 1 ) ; 575 } 576 // ======================================================================== 577 public: 578 // ======================================================================== 579 /** Put IOpaqueAddress in POOL-based NTuple. 580 * If the column does not exist, 581 * it will be automatically created 582 * and appended to the tuple. 583 * 584 * @code 585 * 586 * IOpaqueAddress* address = ... ; 587 * tuple->column( "Address", address ); 588 * 589 * @endcode 590 * @warning It has sense only for Event tag collection N-Tuples 591 * 592 * @param name name of the column 593 * ("Address" is a recommended convention!) 594 * @param address IOpaqueAddress 595 * @return status code 596 */ 597 StatusCode column ( const std::string& name , 598 IOpaqueAddress* address ) ; 599 // ======================================================================== 600 /** Put IOpaqueAddress in NTuple. 601 * If the column does not exist, 602 * it will be automatically created and appended to the tuple. 603 * The column name is set to be <c>"Address"</c> 604 * 605 * @code 606 * 607 * IOpaqueAddress* address = ... ; 608 * tuple->column ( address ); 609 * 610 * @endcode 611 * @warning It has sense only for Event tag collection N-Tuples 612 * 613 * @param address IOpaqueAddress 614 * @return status code 615 */ 616 StatusCode column ( IOpaqueAddress* address ) ; 617 // ======================================================================== 618 public: 619 // ======================================================================== 620 /** Set the values for several columns simultaneously. 621 * Number of columns is arbitrary, but it should not 622 * be less than number of blank or comma separated tags 623 * in <tt>format</tt> string. 624 * Non-existing columns will be automatically created 625 * and appended to the ntuple. 626 * 627 * @code 628 * 629 * double r1 , r2 , r3 , r4 , mass , length ; 630 * tuple->fill( "var1 var2, radius rad4 mass len" , 631 * r1, r2, r3, r4, mass, length); 632 * 633 * @endcode 634 * 635 * @warning *ALL* columns are assumed to be of type <tt>double</tt> 636 * 637 * @param format blank-separated list of variables, 638 * followed by variable number of arguments. 639 * @attention All variables are assumed to be <c>double</c> numbers 640 * @author Vanya Belyaev Ivan.Belyaev@itep.ru 641 * @date 2002-10-30 642 */ 643 StatusCode fill( const char* format ... ) ; 644 // ======================================================================= 645 public: 646 // ======================================================================= 647 /** Add an indexed array (of type float) to N-tuple. 648 * The method is not VERY efficient since it copies the data. 649 * 650 * @code 651 * 652 * std::vector<double> values = ... ; 653 * 654 * tuple->farray( "Values" , // item name 655 * values.begin () , // begin of sequence 656 * values.end () , // end of sequence 657 * "Length" , // name of "length" item 658 * 10000 ) ; 659 * 660 * @endcode 661 * 662 * The name of "length" item can be reused for several arrays. 663 * The last assignement "wins" 664 * 665 * @code 666 * 667 * std::vector<double> val1 = ... ; 668 * std::vector<double> val2 = ... ; 669 * 670 * tuple->farray( "Val1" , // item name 671 * val1.begin () , // begin of sequence 672 * val1.end () , // end of sequence 673 * "Length" , // name of "length" item 674 * 10000 ) ; // maximal length 675 * 676 * tuple->farray( "Val2" , // item name 677 * val2.begin () , // begin of sequence 678 * val2.end () , // end of sequence 679 * "Length" , // name of "length" item 680 * 10000 ) ; // maximal length 681 * 682 * @endcode 683 * 684 * Any sequence <tt>[first:last[</tt> of objects 685 * which can be converted to type <tt>float</tt> can 686 * be used as input data, e.g. <tt>std::vector<double></tt>, 687 * <tt>std::vector<float></tt>, plain C-array, or whatever else 688 * 689 * @param name name of N-tuple item 690 * @param first begin of data sequence 691 * @param last end of data sequence 692 * @param length name of "length" item 693 * @param maxv maximal length of array 694 */ 695 template <class DATA> 696 StatusCode farray ( const std::string& name , 697 DATA first , 698 DATA last , 699 const std::string& length , 700 const size_t maxv ) 701 { 702 if ( invalid () ) { return InvalidTuple ; } 703 if ( rowWise () ) { return InvalidOperation ; } 704 705 // adjust the length 706 if( first + maxv < last ) 707 { 708 Warning(" farray('"+name+"'): array is overflow, skip extra items") ; 709 last = first + maxv ; 710 }; 711 712 // get the length item 713 Int* len = ints( length , 0 , maxv ) ; 714 if( 0 == len ) { return InvalidColumn; } 715 716 // adjust the length item 717 *len = last - first ; 718 719 // get the array itself 720 FArray* var = fArray ( name , len ) ; 721 if( 0 == var ) { return InvalidColumn ; } 722 723 /// fill the array 724 size_t index = 0 ; 725 for( ; first != last ; ++first ) 726 { (*var)[ index ] = (float)(*first) ; ++index ; } 727 728 return StatusCode::SUCCESS ; 729 } 730 // ======================================================================= 731 /** Add an indexed array (of type float) to N-tuple. 732 * it is just a small adaptor for the previous method 733 * 734 * @code 735 * 736 * std::vector<double> values = ... ; 737 * 738 * tuple->farray( "Values" , // item name 739 * values , // sequence 740 * "Length" , // name of "length" item 741 * 10000 ) ; 742 * 743 * @endcode 744 * 745 * The name of "length" item can be reused for several arrays. 746 * The last assignement "wins" 747 * 748 * @code 749 * 750 * std::vector<double> val1 = ... ; 751 * std::vector<double> val2 = ... ; 752 * 753 * tuple->farray( "Val1" , // item name 754 * val1 , // begin of sequence 755 * "Length" , // name of "length" item 756 * 10000 ) ; // maximal length 757 * 758 * tuple->farray( "Val2" , // item name 759 * val2 , // begin of sequence 760 * "Length" , // name of "length" item 761 * 10000 ) ; // maximal length 762 * 763 * @endcode 764 * 765 * Any sequence which provides <tt>begin()</tt> and 766 * <tt>end()</tt> methods can be used. 767 * 768 * @param name name of N-tuple item 769 * @param data data sequence 770 * @param length name of "length" item 771 * @param maxv maximal length of array 772 */ 773 template <class DATA> 774 StatusCode farray ( const std::string& name , 775 const DATA& data , 776 const std::string& length , 777 const size_t maxv ) 778 { return farray ( name , data.begin() , data.end() , length , maxv ) ; } 779 // ======================================================================= 780 /** Put an indexed array into LoKi-style N-Tuple 781 * 782 * @code 783 * 784 * std::vector<double> data = ... ; 785 * 786 * Tuple tuple = ntuple( "My Ntuple" ); 787 * 788 * tuple->farray( "data" , // data item name 789 * sqrt , // "function" to be applied 790 * data.begin () , // begin of data sequence 791 * data.end () , // end of data sequence 792 * "length" , // name of "length" tuple item 793 * 10000 ) ; // maximal array length 794 * 795 * @endcode 796 * 797 * Since the method is templated, one can use arbitrary 798 * combinations of "sequences" and "functions", e.g. one can 799 * directly manipulate with complex objects. 800 * The only on ething is required - the result of 801 * <tt>FUNCTION(*DATA)</tt> formal operation 802 * MUST be convertible to type <tt>float</tt> 803 * 804 * @code 805 * 806 * // some container of particles. 807 * ParticleVector particles = ... ; 808 * 809 * Tuple tuple = ntuple( "My Ntuple" ); 810 * 811 * // put the transverse momentum of all particles into N-Tuple 812 * tuple->farray( "pt" , // data item name 813 * PT , // function object 814 * particles.begin () , // begin of data sequence 815 * particles.end () , // end of data sequence 816 * "num" , // name of "length" tuple item 817 * 10000 ) ; // maximal array length 818 * 819 * 820 * // create the appropriate function object 821 * Fun fun = Q / P ; 822 * 823 * // put Q/P of all particles into N-Tuple 824 * tuple->farray( "qp" , // data item name 825 * fun , // function object 826 * particles.begin () , // begin of data sequence 827 * particles.end () , // end of data sequence 828 * "num" , // name of "length" tuple item 829 * 10000 ) ; // maximal array length 830 * 831 * 832 * @endcode 833 * 834 * @param name tuple item name 835 * @param function function to be applied 836 * @param first begin of data sequence 837 * @param last end of data sequence 838 * @param length name of "length" tupel name 839 * @param maxv maximal length of the array 840 * @return status code 841 */ 842 template <class FUNCTION, class DATA> 843 StatusCode farray ( const std::string& name , 844 const FUNCTION& function , 845 DATA first , 846 DATA last , 847 const std::string& length , 848 const size_t maxv ) 849 { 850 if ( invalid () ) { return InvalidTuple ; } 851 if ( rowWise () ) { return InvalidOperation ; } 852 853 // adjust the length 854 if( first + maxv < last ) 855 { 856 Warning(" farray('" 857 + name + "'): array is overflow, skip extra entries") ; 858 last = first + maxv ; 859 }; 860 861 // get the length item 862 Int* len = ints( length , 0 , maxv ) ; 863 if( 0 == len ) { return InvalidColumn ; } 864 865 // adjust the length 866 *len = last - first ; 867 868 // get the array itself 869 FArray* var = fArray ( name , len ) ; 870 if( 0 == var ) { return InvalidColumn ; } 871 872 // fill the array 873 size_t index = 0 ; 874 for( ; first != last ; ++first ) 875 { (*var)[ index ] = function( *first ) ; ++index ; } 876 877 return StatusCode::SUCCESS ; 878 } 879 // ======================================================================= 880 /** Put two functions from one data array into LoKi-style N-Tuple 881 * simultaneously (effective!) 882 * 883 * @code 884 * 885 * std::vector<double> data = ... ; 886 * 887 * Tuple tuple = ntuple( "My Ntuple" ); 888 * 889 * tuple->farray( "sqr" , // the first data item name 890 * sqrt , // "func1" to be used 891 * "sinus" , // the second data item name 892 * sin , // "func2" to be used 893 * data.begin () , // begin of data sequence 894 * data.end () , // end of data sequence 895 * "length" , // name of "length" tuple item 896 * 10000 ) ; // maximal array length 897 * 898 * @endcode 899 * 900 * 901 * @param name1 the first tuple item name 902 * @param func1 the first function to be applied 903 * @param name2 the second tuple item name 904 * @param func2 the second function to be applied 905 * @param first begin of data sequence 906 * @param last end of data sequence 907 * @param length name of "length" tupel name 908 * @param maxv maximal length of the array 909 * @return status code 910 */ 911 template <class FUNC1, class FUNC2, class DATA> 912 StatusCode farray ( const std::string& name1 , 913 const FUNC1& func1 , 914 const std::string& name2 , 915 const FUNC2& func2 , 916 DATA first , 917 DATA last , 918 const std::string& length , 919 const size_t maxv ) 920 { 921 if ( invalid () ) { return InvalidTuple ; } 922 if ( rowWise () ) { return InvalidOperation ; } 923 924 // adjust the lenfth 925 if( first + maxv < last ) 926 { 927 Warning(" farray('" 928 + name1 + "," 929 + name2 + "'): array is overflow, skip extra entries") ; 930 Warning(" farray('"+name1+"'): array is overflow, skip extra items") ; 931 last = first + maxv ; 932 }; 933 934 // get the length item 935 Int* len = ints ( length , 0 , maxv ) ; 936 if ( 0 == len ) { return InvalidColumn ; } 937 938 // adjust the length 939 *len = last - first ; 940 941 // get the array itself 942 FArray* var1 = fArray ( name1 , len ) ; 943 if ( 0 == var1 ) { return InvalidColumn ; } 944 945 // get the array itself 946 FArray* var2 = fArray ( name2 , len ) ; 947 if ( 0 == var2 ) { return InvalidColumn ; } 948 949 // fill the array 950 size_t index = 0 ; 951 for( ; first != last ; ++first ) 952 { 953 ( *var1 ) [ index ] = func1 ( *first ) ; 954 ( *var2 ) [ index ] = func2 ( *first ) ; 955 ++index ; 956 } 957 958 return StatusCode::SUCCESS ; 959 } 960 // ======================================================================= 961 /** Put three functions from one data array into LoKi-style N-Tuple 962 * simultaneously (effective!) 963 * 964 * 965 * @code 966 * 967 * std::vector<double> data = ... ; 968 * 969 * Tuple tuple = ntuple( "My Ntuple" ); 970 * 971 * tuple->farray( "sqr" , // the first data item name 972 * sqrt , // "func1" to be used 973 * "sinus" , // the second data item name 974 * sin , // "func2" to be used 975 * "tan" , // the third data item name 976 * tan , // "func3" to be used 977 * data.begin () , // begin of data sequence 978 * data.end () , // end of data sequence 979 * "length" , // name of "length" tuple item 980 * 10000 ) ; // maximal array length 981 * 982 * @endcode 983 * 984 * 985 * @param name1 the first tuple item name 986 * @param func1 the first function to be applied 987 * @param name2 the second tuple item name 988 * @param func2 the second function to be applied 989 * @param name3 the third tuple item name 990 * @param func3 the third function to be applied 991 * @param first begin of data sequence 992 * @param last end of data sequence 993 * @param length name of "length" tupel name 994 * @param maxv maximal length of the array 995 * @return status code 996 */ 997 template <class FUNC1, class FUNC2, class FUNC3, class DATA> 998 StatusCode farray ( const std::string& name1 , 999 const FUNC1& func1 , 1000 const std::string& name2 , 1001 const FUNC2& func2 , 1002 const std::string& name3 , 1003 const FUNC3& func3 , 1004 DATA first , 1005 DATA last , 1006 const std::string& length , 1007 const size_t maxv ) 1008 { 1009 if ( invalid () ) { return InvalidTuple ; } 1010 if ( rowWise () ) { return InvalidOperation ; } 1011 1012 // adjust the lenfth 1013 if( first + maxv < last ) 1014 { 1015 Warning(" farray('" 1016 + name1 + "," 1017 + name2 + "," 1018 + name3 + "'): array is overflow, skip extra entries") ; 1019 last = first + maxv ; 1020 }; 1021 1022 // get the length item 1023 Int* len = ints ( length , 0 , maxv ) ; 1024 if( 0 == len ) { return InvalidColumn ; } 1025 1026 // adjust the length 1027 *len = last - first ; 1028 1029 // get the array itself 1030 FArray* var1 = fArray ( name1 , len ) ; 1031 if( 0 == var1 ) { return InvalidColumn ; } 1032 1033 // get the array itself 1034 FArray* var2 = fArray ( name2 , len ) ; 1035 if( 0 == var2 ) { return InvalidColumn ; } 1036 1037 // get the array itself 1038 FArray* var3 = fArray ( name3 , len ) ; 1039 if( 0 == var3 ) { return InvalidColumn ; } 1040 1041 // fill the array 1042 size_t index = 0 ; 1043 for( ; first != last ; ++first ) 1044 { 1045 ( *var1 ) [ index ] = (float)func1 ( *first ) ; 1046 ( *var2 ) [ index ] = (float)func2 ( *first ) ; 1047 ( *var3 ) [ index ] = (float)func3 ( *first ) ; 1048 ++index ; 1049 } 1050 return StatusCode::SUCCESS ; 1051 } 1052 // ======================================================================= 1053 /** Put four functions from one data array into LoKi-style N-Tuple 1054 * simultaneously (effective!) 1055 * 1056 * @code 1057 * 1058 * std::vector<double> data = ... ; 1059 * 1060 * Tuple tuple = ntuple( "My Ntuple" ); 1061 * 1062 * tuple->farray( "sqr" , // the first data item name 1063 * sqrt , // "func1" to be used 1064 * "sinus" , // the second data item name 1065 * sin , // "func2" to be used 1066 * "tan" , // the third data item name 1067 * tan , // "func3" to be used 1068 * "tanh" , // 1069 * tanh , // 1070 * data.begin () , // begin of data sequence 1071 * data.end () , // end of data sequence 1072 * "length" , // name of "length" tuple item 1073 * 10000 ) ; // maximal array length 1074 * 1075 * @endcode 1076 * 1077 * 1078 * @param name1 the first tuple item name 1079 * @param func1 the first function to be applied 1080 * @param name2 the second tuple item name 1081 * @param func2 the second function to be applied 1082 * @param name3 the third tuple item name 1083 * @param func3 the third function to be applied 1084 * @param name4 the fourthtuple item name 1085 * @param func4 the fourth function to be applied 1086 * @param first begin of data sequence 1087 * @param last end of data sequence 1088 * @param length name of "length" tuple name 1089 * @param maxv maximal length of the array 1090 * @return status code 1091 */ 1092 template <class FUNC1, class FUNC2, class FUNC3, class FUNC4, class DATA> 1093 StatusCode farray ( const std::string& name1 , 1094 const FUNC1& func1 , 1095 const std::string& name2 , 1096 const FUNC2& func2 , 1097 const std::string& name3 , 1098 const FUNC3& func3 , 1099 const std::string& name4 , 1100 const FUNC4& func4 , 1101 DATA first , 1102 DATA last , 1103 const std::string& length , 1104 const size_t maxv ) 1105 { 1106 if ( invalid () ) { return InvalidTuple ; } 1107 if ( rowWise () ) { return InvalidOperation ; } 1108 1109 // adjust the lenfth 1110 if( first + maxv < last ) 1111 { 1112 Warning(" farray('" 1113 + name1 + "," 1114 + name2 + "," 1115 + name3 + "," 1116 + name4 + "'): array is overflow, skip extra entries") ; 1117 last = first + maxv ; 1118 }; 1119 1120 // get the length item 1121 Int* len = ints ( length , 0 , maxv ) ; 1122 if( 0 == len ) { return InvalidColumn ; } 1123 1124 // adjust the length 1125 *len = last - first ; 1126 1127 // get the array itself 1128 FArray* var1 = fArray ( name1 , len ) ; 1129 if( 0 == var1 ) { return InvalidColumn ; } 1130 1131 // get the array itself 1132 FArray* var2 = fArray ( name2 , len ) ; 1133 if( 0 == var2 ) { return InvalidColumn ; } 1134 1135 // get the array itself 1136 FArray* var3 = fArray ( name3 , len ) ; 1137 if( 0 == var3 ) { return InvalidColumn ; } 1138 1139 // get the array itself 1140 FArray* var4 = fArray ( name4 , len ) ; 1141 if( 0 == var4 ) { return InvalidColumn ; } 1142 1143 // fill the array 1144 size_t index = 0 ; 1145 for( ; first != last ; ++first ) 1146 { 1147 ( *var1 ) [ index ] = static_cast<float> ( func1 ( *first ) ); 1148 ( *var2 ) [ index ] = static_cast<float> ( func2 ( *first ) ); 1149 ( *var3 ) [ index ] = static_cast<float> ( func3 ( *first ) ); 1150 ( *var4 ) [ index ] = static_cast<float> ( func4 ( *first ) ); 1151 ++index ; 1152 } 1153 1154 return StatusCode::SUCCESS ; 1155 } 1156 // ======================================================================= 1157 public: 1158 // ======================================================================= 1159 /** Fill N-Tuple with data from variable-size matrix 1160 * 1161 * "Matrix" could be of any type, which supports 1162 * data[iRow][iCol] indexing, e.g. 1163 * - std::vector<std::vector<TYPE> > 1164 * - CLHEP::HepMatrix, etc... 1165 * 1166 * @code 1167 * 1168 * typedef std::vector<double> Row ; 1169 * typedef std::vector<Row> Mtrx ; 1170 * // number of columns (fixed!) 1171 * const size_t numCols = 5 ; 1172 * // maximal number of rows 1173 * const size_t maxRows = 300 ; 1174 * // number of rows (variable) 1175 * size_t numRows = .... ; 1176 * ... 1177 * tuple -> fMatrix ( "mtrx" , // "column" name 1178 * mtrx , // matrix 1179 * numRows , // number of rows (variable!) 1180 * numCols , // number of columns (fixed) 1181 * "Length" , // name for "lenghth" column 1182 * maxRows ) ; // maximal number of columns 1183 * 1184 * @endcode 1185 * 1186 * @code 1187 * 1188 * CLHEP::HepMatrix mtrx = ... ; 1189 * ... 1190 * tuple -> fMatrix ( "mtrx" , // "column" name 1191 * mtrx , // matrix 1192 * mtrx.num_row() , // number of rows (variable!) 1193 * mtrx.num_col() , // number of columns (fixed) 1194 * "Length" , // name for "lenghth" column 1195 * maxRows ) ; // maximal number of columns 1196 * 1197 * @endcode 1198 * 1199 * @param name entry name in N-Tuple 1200 * @param data matrix itself 1201 * @param rows number of rows of matrix (variable) 1202 * @param cols number of columns of matrix (fixed) 1203 * @param length entry name in NTuple for number of matrix column 1204 * @param maxv maximal number of rows in matrix 1205 * 1206 * @author Vanya BELYAEV Ivan.Belyaev@lapp.in2p3.fr 1207 * @date 2005-05-01 1208 */ 1209 template <class MATRIX> 1210 StatusCode fmatrix ( const std::string& name , 1211 const MATRIX& data , 1212 size_t rows , 1213 const MIndex& cols , 1214 const std::string& length , 1215 const size_t maxv ) 1216 { 1217 if ( invalid () ) { return InvalidTuple ; } 1218 if ( rowWise () ) { return InvalidOperation ; } 1219 1220 // adjust the length 1221 if ( rows >= maxv ) 1222 { 1223 Warning ( " fmatrix('"+name+"'): matrix is overflow, skip extra items") ; 1224 rows = ( 0 < maxv ) ? ( maxv - 1 ) : 0 ; 1225 }; 1226 1227 // get the length item 1228 Int* len = ints( length , 0 , maxv ) ; 1229 if ( 0 == len ) { return InvalidColumn; } 1230 1231 // adjust the length item 1232 *len = rows ; 1233 1234 // get the array itself 1235 FMatrix* var = fMatrix ( name , len , cols ) ; 1236 if ( 0 == var ) { return InvalidColumn ; } 1237 1238 /// fill the matrix 1239 for ( size_t iCol = 0 ; iCol < cols ; ++iCol ) 1240 { 1241 for ( MIndex iRow = 0 ; iRow < rows ; ++iRow ) 1242 { (*var)[ iRow ] [ iCol ] = (float)(data[ iRow ][ iCol ]) ; } 1243 }; 1244 1245 return StatusCode::SUCCESS ; 1246 } 1247 // ======================================================================= 1248 /** Fill N-Tuple with data from variable-size matrix 1249 * 1250 * "Matrix" could be of any type, which supports 1251 * iteration from the first column to the last column 1252 * and for each iterating column supports the indexing: 1253 * (*first)[iCol] 1254 * 1255 * @code 1256 * typedef std::vector<double> Row ; 1257 * typedef std::vector<Row> Mtrx ; 1258 * // number of rows (fixed!) 1259 * const size_t numRows = 5 ; 1260 * // maximal number of columns 1261 * const size_t maxCols = 300 ; 1262 * // number of columns (variable) 1263 * size_t numCols = .... ; 1264 * ... 1265 * tuple -> fMatrix ( "mtrx" , // entry name 1266 * mtrx.begin() , // first row of matrix 1267 * mtrx.end () , // last row of matrix 1268 * numCols , // number of columns (fixed!) 1269 * "Length" , // name for "lenght" column 1270 * maxRows ) ; // maximal number of rows 1271 * 1272 * @endcode 1273 * 1274 * @param name entry name in N-Tuple 1275 * @param first iterator for the first row of matrix 1276 * @param last iterator for the last row of matrix 1277 * @param cols number of columns for matrix (fixed!) 1278 * @param length entry name in NTuple for number of matrix column 1279 * @param maxv maximal number of rows in matrix 1280 * 1281 * @author Vanya BELYAEV Ivan.Belyaev@lapp.in2p3.fr 1282 * @date 2005-05-01 1283 */ 1284 template <class DATA> 1285 StatusCode fmatrix ( const std::string& name , 1286 DATA first , 1287 DATA last , 1288 const MIndex& cols , 1289 const std::string& length , 1290 const size_t maxv ) 1291 { 1292 if ( invalid () ) { return InvalidTuple ; } 1293 if ( rowWise () ) { return InvalidOperation ; } 1294 1295 // adjust the length 1296 if ( first + maxv < last ) 1297 { 1298 Warning(" fmatrix('"+name+"'): matrix is overflow, skip extra items") ; 1299 last = first + maxv ; 1300 }; 1301 1302 // get the length item 1303 Int* len = ints( length , 0 , maxv ) ; 1304 if ( 0 == len ) { return InvalidColumn; } 1305 1306 // adjust the length item 1307 *len = last - first ; 1308 1309 // get the array itself 1310 FMatrix* var = fMatrix ( name , len , cols ) ; 1311 if ( 0 == var ) { return InvalidColumn ; } 1312 1313 /// fill the matrix 1314 size_t iRow = 0 ; 1315 for ( ; first != last ; ++first ) 1316 { 1317 // 1318 for ( MIndex iCol = 0 ; iCol < cols ; ++iCol ) 1319 { (*var)[ iRow ] [ iCol ] = (float)((*first)[ iCol ]) ; } 1320 // 1321 ++iRow ; 1322 }; 1323 1324 return StatusCode::SUCCESS ; 1325 } 1326 // ======================================================================= 1327 /** fill N-Tuple with matrix of "direct-product" of 1328 * "data-vector" [first,last) and 1329 * "function-vector" [funF, funL) 1330 * 1331 * The elements of effective matrix are: 1332 * 1333 * mtrx[iCol][iRow] = (*(funF+iRow))( *(first+iCol) ) 1334 * 1335 * @attention 1336 * The length of data-vector is variable, while 1337 * the length of "function" vector is fixed! 1338 * 1339 * @code 1340 * 1341 * typedef std::vector<double> Array ; 1342 * Array array = ... ; 1343 * 1344 * typedef double (*fun)( double ) ; 1345 * typedef std::vector<fun> Funs ; 1346 * 1347 * Funs funs ; 1348 * funs.push_back( sin ) ; 1349 * funs.push_back( cos ) ; 1350 * funs.push_back( tan ) ; 1351 * funs.push_back( sinh ) ; 1352 * funs.push_back( cosh ) ; 1353 * funs.push_back( tanh ) ; 1354 * 1355 * tuple->fmatrix ( "mtrx" , // N-Tuple entry name 1356 * funs.begin () , // begin of "function-vector" 1357 * funs.end () , // end of "function-vector" 1358 * array.begin () , // begin of "data-vector" 1359 * array.end () , // end of "data-vector" 1360 * "Length" , 1361 * 100 ) ; 1362 * @endcode 1363 * 1364 * This method is very convinient e.g. for using within LoKi: 1365 * 1366 * @code 1367 * 1368 * typedef std::vector<Fun> VctFun ; 1369 * 1370 * // sequence of Particles 1371 * Range particles = .... ; 1372 * 1373 * // vector of functions: 1374 * VctFun funs ; 1375 * funs.push_back( E / GeV ) ; 1376 * funs.push_back( PX / GeV ) ; 1377 * funs.push_back( PY / GeV ) ; 1378 * funs.push_back( PZ / GeV ) ; 1379 * funs.push_back( PT / GeV ) ; 1380 * funs.push_back( M / GeV ) ; 1381 * funs.push_back( ID ) ; 1382 * 1383 * // fill N-Tuple with information abvout each particle 1384 * tuple -> fmatrix ( "vars" , 1385 * funs.begin () , 1386 * funs.end () , 1387 * particles.begin () , 1388 * particles.end () , 1389 * "nParts" , 1390 * 200 ) ; 1391 * 1392 * @endcode 1393 * 1394 * @param name entry name in N-Tuple 1395 * @param funF "begin"-iterator for vector of functions 1396 * @param funL "end"-iterator for vector of functions 1397 * @param first "begin"-iterator for vector of data 1398 * @param last "end"-iterator for vector of data 1399 * @param length entry name in NTuple for number of matrix column 1400 * @param maxv maximal number of rows in matrix 1401 * 1402 * @author Vanya BELYAEV Ivan.Belyaev@lapp.in2p3.fr 1403 * @date 2005-05-01 1404 */ 1405 template <class FUN,class DATA> 1406 StatusCode fmatrix ( const std::string& name , 1407 FUN funF , 1408 FUN funL , 1409 DATA first , 1410 DATA last , 1411 const std::string& length , 1412 const size_t maxv ) 1413 { 1414 if ( invalid () ) { return InvalidTuple ; } 1415 if ( rowWise () ) { return InvalidOperation ; } 1416 1417 // adjust the length 1418 if ( first + maxv < last ) 1419 { 1420 Warning(" fmatrix('"+name+"'): matrix is overflow, skip extra items") ; 1421 last = first + maxv ; 1422 }; 1423 1424 // get the length item 1425 Int* len = ints( length , 0 , maxv ) ; 1426 if ( 0 == len ) { return InvalidColumn; } 1427 1428 // adjust the length item 1429 *len = last - first ; 1430 1431 // get the array itself 1432 const size_t cols = funL - funF ; 1433 FMatrix* var = fMatrix ( name , len , cols ) ; 1434 if ( 0 == var ) { return InvalidColumn ; } 1435 1436 /// fill the matrix 1437 size_t iRow = 0 ; 1438 for ( ; first != last ; ++first ) 1439 { 1440 // 1441 for ( FUN fun = funF ; fun < funL ; ++fun ) 1442 { (*var)[ iRow ] [ fun - funF ] = (float)((*fun) ( *first )) ; } 1443 // 1444 ++iRow; 1445 }; 1446 1447 return StatusCode::SUCCESS ; 1448 } 1449 // ======================================================================= 1450 public: 1451 // ======================================================================= 1452 /** fill N-Tuple with fixed-size array 1453 * 1454 * @code 1455 * 1456 * SEQUENCE data( 10 ) ; 1457 * ... 1458 * tuple -> array("data" , 1459 * data.begin () , 1460 * data.end () ) ; 1461 * 1462 * @endcode 1463 * 1464 * Sequence may be of any onkects, implicitey 1465 * convertibel iuto "float" 1466 * 1467 * @param name N-Tuple entry name 1468 * @param first begin-iterator for data sequence 1469 * @param last end-iterator for data sequence 1470 * 1471 * @author Vanya BELYAEV Ivan.Belyaev@lapp.in2p3.fr 1472 * @date 2005-05-01 1473 */ 1474 template <class DATA> 1475 StatusCode array ( const std::string& name , 1476 DATA first , 1477 DATA last ) 1478 1479 { 1480 if ( invalid () ) { return InvalidTuple ; } 1481 if ( rowWise () ) { return InvalidOperation ; } 1482 1483 // get the length (fixed!) 1484 const size_t length = last - first ; 1485 1486 // get the array itself 1487 FArray* var = fArray ( name , length ) ; 1488 if ( 0 == var ) { return InvalidColumn ; } 1489 1490 /// fill the array 1491 size_t iCol = 0 ; 1492 for ( ; first != last ; ++first ) 1493 { (*var)[ iCol ] = (float)(*first) ; ++iCol ; } 1494 1495 return StatusCode::SUCCESS ; 1496 } 1497 // ======================================================================= 1498 /** fill N-Tuple with fixed-size array 1499 * 1500 * "ARRAY" must support indexing operations: 1501 * e.g it coudl be of type: 1502 * - std::vector<TYPE> 1503 * - CLHEP::HepVector, ... 1504 * - "TYPE"[n] 1505 * 1506 * The content of array shodul be implicitely 1507 * convertible to "float" 1508 * 1509 * @code 1510 * 1511 * CLHEP::HepVector vct1(10) ; 1512 * ... 1513 * tuple -> array ( "vct1" , vct1 , 10 ) ; 1514 * 1515 * double vct2[40]; 1516 * ... 1517 * tuple -> array ( "vct2" , vct2 , 40 ) ; 1518 * 1519 * long vct3[4]; 1520 * ... 1521 * tuple -> array ( "vct3" , vct4 , 4 ) ; 1522 * 1523 * std::vector<long double> vct4(15) ; 1524 * ... 1525 * tuple -> array ( "vct4" , vct4 , 15 ) ; 1526 * 1527 * @endcode 1528 * 1529 * @param name N-Tuple entry name 1530 * @param data data sequence 1531 * @param length data length (fixed!) 1532 * 1533 * @author Vanya BELYAEV Ivan.Belyaev@lapp.in2p3.fr 1534 * @date 2005-05-01 1535 */ 1536 template <class ARRAY> 1537 StatusCode array ( const std::string& name , 1538 const ARRAY& data , 1539 const MIndex& length ) 1540 { 1541 if ( invalid () ) { return InvalidTuple ; } 1542 if ( rowWise () ) { return InvalidOperation ; } 1543 1544 // get the array itself 1545 FArray* var = fArray ( name , length ) ; 1546 if ( 0 == var ) { return InvalidColumn ; } 1547 1548 /// fill the array 1549 for ( size_t index = 0 ; index < length ; ++index ) 1550 { (*var)[ index ] = (float) data[index] ; } 1551 1552 return StatusCode::SUCCESS ; 1553 } 1554 // ======================================================================= 1555 /** fill N-Tuple with fixed-size array 1556 * 1557 * "ARRAY" is any sequence, which supports 1558 * ARRAY::begin() and ARRAY::end() protocol, e.g. 1559 * 1560 * - std::vector<TYPE> 1561 * 1562 * The content of array shodul be implicitely 1563 * convertible to "float" 1564 * 1565 * @code 1566 * 1567 * typedef std::vector<double> Seq ; 1568 * Seq data( 10 ) ; 1569 * for ( int i = 0 ; i < 10 ; ++i ) 1570 * { 1571 * data[i] = ... ; 1572 * } 1573 * 1574 * tuple -> array( "data" , data ) ; 1575 * 1576 * @endcode 1577 * 1578 * @param name N-Tupel entry name 1579 * @param data data sequence 1580 * 1581 * @author Vanya BELYAEV Ivan.Belyaev@lapp.in2p3.fr 1582 * @date 2005-05-01 1583 */ 1584 template <class ARRAY> 1585 StatusCode array ( const std::string& name , 1586 const ARRAY& data ) 1587 { return array ( name , data.begin() , data.end() ) ; } 1588 // ======================================================================= 1589 public: 1590 // ======================================================================= 1591 /** fill N-Tuple with fixed-size matrix 1592 * 1593 * "MATRIX" must support indexing operations: 1594 * data[iRow][iCol] 1595 * 1596 * e.g it could be of type: 1597 * - std::vector<std::vector<TYPE> > 1598 * - CLHEP::HepMatrix , CLHEP::GenMatrix, etc ... 1599 * - "TYPE"[n][m] 1600 * 1601 * The content of MATRIX shoudl be implicitely convertible 1602 * to "float" 1603 * 1604 * @code 1605 * 1606 * CLHEP::HepMatrix mtrx1(3,20) ; 1607 * ... 1608 * tuple -> matrix ( "m1" , 1609 * mtrx1 , 1610 * mtrx1.num_row() , 1611 * mtrx1.num_col() ) ; 1612 * 1613 * typedef std::vector<double> Row ; 1614 * typedef std:vector<Row> Mtrx ; 1615 * Mtrx mtrx2( 3 , Row(10) ) ; 1616 * ... 1617 * tuple -> matrix ( "m2" , 1618 * mtrx2 , 1619 * 3 , 1620 * 10 ) ; 1621 * 1622 * float mtrx3[3][10] ; 1623 * ... 1624 * tuple -> matrix ( "m3" , 1625 * mtrx3 , 1626 * 3 , 1627 * 10 ) ; 1628 * 1629 * @endcode 1630 * 1631 * @param name N-Tuple entry name 1632 * @param data data source (matrix) 1633 * @param cols number of columns 1634 * @param rows number of rows 1635 * 1636 * @author Vanya BELYAEV Ivan.Belyaev@lapp.in2p3.fr 1637 * @date 2005-05-01 1638 */ 1639 template <class MATRIX> 1640 StatusCode matrix ( const std::string& name , 1641 const MATRIX& data , 1642 const MIndex& rows , 1643 const MIndex& cols ) 1644 { 1645 if ( invalid () ) { return InvalidTuple ; } 1646 if ( rowWise () ) { return InvalidOperation ; } 1647 1648 // get the matrix itself 1649 FMatrix* var = fMatrix ( name , rows , cols ) ; 1650 if ( 0 == var ) { return InvalidColumn ; } 1651 1652 /// fill the matrix 1653 for ( size_t iCol = 0 ; iCol < cols ; ++iCol ) 1654 { 1655 for ( size_t iRow = 0 ; iRow < rows ; ++iRow ) 1656 { (*var)[iRow][iCol] = (float)(data[iRow][iCol]) ; } 1657 }; 1658 return StatusCode::SUCCESS ; 1659 } 1660 // ======================================================================= 1661 public: 1662 // ======================================================================= 1663 /** Useful shortcut to put LorentzVector directly into N-Tuple: 1664 * 1665 * @code 1666 * 1667 * const LHCb::Particle* B = ... 1668 * 1669 * Tuple tuple = nTuple("My N-Tuple") ; 1670 * 1671 * // put 4-vector of B-candidate into N-tuple: 1672 * tuple -> column ("B" , B->momentum() ) ; 1673 * 1674 * @endcode 1675 * 1676 * @author Vanya BELYAEV ibelyaev@physics.syr.edu 1677 * @date 2006-11-26 1678 */ 1679 template <class TYPE> 1680 StatusCode column 1681 ( const std::string& name , 1682 const ROOT::Math::LorentzVector<TYPE>& v ) 1683 { 1684 if ( invalid() ) { return InvalidTuple ; } 1685 // fill all separate columns: 1686 StatusCode sc1 = this -> column ( name + "E" , v.E () ) ; 1687 StatusCode sc2 = this -> column ( name + "X" , v.Px () ) ; 1688 StatusCode sc3 = this -> column ( name + "Y" , v.Py () ) ; 1689 StatusCode sc4 = this -> column ( name + "Z" , v.Pz () ) ; 1690 return 1691 sc1.isFailure () ? sc1 : 1692 sc2.isFailure () ? sc2 : 1693 sc3.isFailure () ? sc3 : 1694 sc4.isFailure () ? sc4 : StatusCode(StatusCode::SUCCESS) ; 1695 } 1696 // ======================================================================= 1697 /** Useful shortcut to put 3D-Vector directly into N-Tuple: 1698 * 1699 * @code 1700 * 1701 * const LHCb::Vertex* V = ... 1702 * 1703 * Tuple tuple = nTuple("My N-Tuple") ; 1704 * 1705 * // put vertex position into N-tuple: 1706 * tuple -> column ("B" , B->position() ) ; 1707 * 1708 * @endcode 1709 * 1710 * @author Vanya BELYAEV ibelyaev@physics.syr.edu 1711 * @date 2006-11-26 1712 */ 1713 template <class TYPE,class TAG> 1714 StatusCode column 1715 ( const std::string& name , 1716 const ROOT::Math::DisplacementVector3D<TYPE,TAG>& v ) 1717 { 1718 if ( invalid() ) { return InvalidTuple ; } 1719 /// fill separate columns 1720 StatusCode sc1 = this -> column ( name + "X" , v.X () ) ; 1721 StatusCode sc2 = this -> column ( name + "Y" , v.Y () ) ; 1722 StatusCode sc3 = this -> column ( name + "Z" , v.Z () ) ; 1723 return 1724 sc1.isFailure () ? sc1 : 1725 sc2.isFailure () ? sc2 : 1726 sc3.isFailure () ? sc3 : StatusCode(StatusCode::SUCCESS) ; 1727 } 1728 // ======================================================================= 1729 /** Useful shortcut to put 3D-Vector directly into N-Tuple: 1730 * 1731 * @code 1732 * 1733 * const LHCb::Vertex* V = ... 1734 * 1735 * Tuple tuple = nTuple("My N-Tuple") ; 1736 * 1737 * // put vertex position into N-tuple: 1738 * tuple -> column ("B" , B->position() ) ; 1739 * 1740 * @endcode 1741 * 1742 * @author Vanya BELYAEV ibelyaev@physics.syr.edu 1743 * @date 2006-11-26 1744 */ 1745 template <class TYPE,class TAG> 1746 StatusCode column 1747 ( const std::string& name , 1748 const ROOT::Math::PositionVector3D<TYPE,TAG>& v ) 1749 { 1750 if ( invalid() ) { return InvalidTuple ; } 1751 /// fill separate columns 1752 StatusCode sc1 = this -> column ( name + "X" , v.X () ) ; 1753 StatusCode sc2 = this -> column ( name + "Y" , v.Y () ) ; 1754 StatusCode sc3 = this -> column ( name + "Z" , v.Z () ) ; 1755 return 1756 sc1.isFailure () ? sc1 : 1757 sc2.isFailure () ? sc2 : 1758 sc3.isFailure () ? sc3 : StatusCode(StatusCode::SUCCESS) ; 1759 } 1760 // ======================================================================= 1761 /** shortcut to put SVector into N-tuple: 1762 * 1763 * @code 1764 * 1765 * ROOT::Math::SVector<double,15> vct = ... ; 1766 * 1767 * Tuple tuple = nTuple("My N-Tuple") ; 1768 * 1769 * // put the vector into N-Tuple: 1770 * tuple -> array ( "v" , vct ) ; 1771 * 1772 * @endcode 1773 * 1774 * @author Vanya BELYAEV ibelyaev@physics.syr.edu 1775 * @date 2006-11-26 1776 */ 1777 template <class TYPE,unsigned int DIM> 1778 StatusCode array 1779 ( const std::string& name , 1780 const ROOT::Math::SVector<TYPE,DIM>& vect ) 1781 { 1782 return this->array( name , vect.begin() , vect.end() ) ; 1783 } 1784 // ======================================================================= 1785 /** shortcut to put Smatrix into N-tuple: 1786 * 1787 * @code 1788 * @endcode 1789 * 1790 * @author Vanya BELYAEV ibelyaev@physics.syr.edu 1791 * @date 2006-11-26 1792 */ 1793 template <class TYPE,unsigned int D1,unsigned int D2,class REP> 1794 StatusCode matrix 1795 ( const std::string& name , 1796 const ROOT::Math::SMatrix<TYPE,D1,D2,REP>& mtrx ) 1797 { 1798 if ( invalid () ) { return InvalidTuple ; } 1799 if ( rowWise () ) { return InvalidOperation ; } 1800 1801 // get the matrix itself 1802 FMatrix* var = fMatrix ( name , D1 , D2 ) ; 1803 if ( 0 == var ) { return InvalidColumn ; } 1804 1805 /// fill the matrix 1806 for ( size_t iCol = 0 ; iCol < D2 ; ++iCol ) 1807 { 1808 for ( size_t iRow = 0 ; iRow < D1 ; ++iRow ) 1809 { (*var)[iRow][iCol] = (float) mtrx(iRow,iCol) ; } 1810 }; 1811 1812 return StatusCode::SUCCESS ; 1813 } 1814 // ======================================================================= 1815 /** shortcut to put "ExtraInfo" fields of major 1816 * into N-Tuple 1817 * 1818 * @code 1819 * 1820 * const LHCb::Particle* B = ... 1821 * 1822 * Tuple tuple = nTuple("My N-Tuple") ; 1823 * 1824 * // put the vector into N-Tuple: 1825 * tuple -> fmatrix ( "Info" , B->extraInfo() , "nInfo" , 100 ) ; 1826 * 1827 * @endcode 1828 * 1829 * @author Vanya BELYAEV ibelyaev@physics.syr.edu 1830 * @date 2006-11-26 1831 */ 1832 template <class KEY, class VALUE> 1833 StatusCode fmatrix 1834 ( const std::string& name , 1835 const GaudiUtils::VectorMap<KEY,VALUE>& info , 1836 const std::string& length , 1837 const size_t maxv = 100 ) 1838 { 1839 1840 if ( invalid () ) { return InvalidTuple ; } 1841 if ( rowWise () ) { return InvalidOperation ; } 1842 1843 typename GaudiUtils::VectorMap<KEY,VALUE>::const_iterator begin = info.begin () ; 1844 typename GaudiUtils::VectorMap<KEY,VALUE>::const_iterator end = info.end () ; 1845 1846 // adjust the length 1847 if ( maxv < info.size() ) 1848 { 1849 Warning(" fmatrix('"+name+"'): matrix is overflow, skip extra items") ; 1850 end = begin + maxv ; 1851 } ; 1852 1853 // get the length item 1854 Int* len = ints( length , 0 , maxv ) ; 1855 if ( 0 == len ) { return InvalidColumn; } 1856 1857 // adjust the length item 1858 *len = end - begin ; 1859 1860 // get the array itself 1861 FMatrix* var = fMatrix ( name , len , 2 ) ; 1862 if ( 0 == var ) { return InvalidColumn ; } 1863 1864 /// fill the matrix 1865 size_t iRow = 0 ; 1866 for ( ; begin != end ; ++begin) 1867 { 1868 // 1869 (*var)[iRow][0] = (float) begin->first ; 1870 (*var)[iRow][1] = (float) begin->second ; 1871 // 1872 ++iRow ; 1873 } ; 1874 1875 return StatusCode::SUCCESS ; 1876 } 1877 // ======================================================================= 1878 public: 1879 // ======================================================================= 1880 /** The function allows to add almost arbitrary object into N-tuple 1881 * @attention it requires POOL persistency 1882 * @param name column name 1883 * @param obj pointer to the object 1884 * @author Vanya BELYAEV ibelyaev@physics.syr.edu 1885 * @date 2007-04-08 1886 */ 1887 template <class TYPE> 1888 StatusCode put 1889 ( const std::string& name , const TYPE* obj ) ; 1890 // ======================================================================= 1891 public: 1892 // ======================================================================= 1893 /** write a record to NTuple 1894 * @return status code 1895 */ 1896 StatusCode write () ; 1897 // ======================================================================= 1898 /// get the name 1899 const std::string& name() const { return m_name ; } 1900 // ======================================================================= 1901 /** provide the access to underlying Gaudi N-tuple 1902 * @return pointer to Gaudi N-tuple object 1903 */ 1904 NTuple::Tuple* tuple() const { return m_tuple ; } 1905 // ======================================================================= 1906 /** return the reference counter 1907 * @return current reference counter 1908 */ 1909 unsigned long refCount() const { return m_refCount ; } 1910 // ======================================================================= 1911 /** add the reference to TupleObj 1912 * @return current reference counter 1913 */ 1914 unsigned long addRef () { return ++m_refCount ; } 1915 // ======================================================================= 1916 /** release the reference to TupleObj 1917 * if reference counter becomes zero, 1918 * object will be automatically deleted 1919 */ 1920 void release () ; 1921 // ======================================================================= 1922 /// accessor to the N-Tuple CLID 1923 const CLID& clid() const { return m_clid ; } 1924 // ======================================================================= 1925 /// accessor to the N-Tuple type 1926 Tuples::Type type() const { return m_type ; } 1927 // ======================================================================= 1928 /// column wise NTuple ? 1929 bool columnWise() const { return CLID_ColumnWiseTuple == clid() ; } 1930 // ======================================================================= 1931 /// row wise NTuple ? 1932 bool rowWise () const { return CLID_RowWiseTuple == clid() ; } 1933 // ======================================================================= 1934 /// Event collection ? 1935 bool evtColType() const { return Tuples::EVTCOL == type() ; } 1936 // ======================================================================= 1937 /// valid pointer to tuple ? 1938 bool valid () const { return 0 != tuple() ; } 1939 // ======================================================================= 1940 /// invalid pointer to tuple ? 1941 bool invalid () const { return 0 == tuple() ; } 1942 // ======================================================================= 1943 public: 1944 // ======================================================================= 1945 /** add the item name into the list of known items 1946 * @param name the name of the item 1947 * @param type the type of the item 1948 * @return true if the name is indeed added 1949 */ 1950 bool addItem ( const std::string& name , 1951 const std::string& type ) 1952 { return m_items.insert ( std::make_pair ( name , type ) ).second ; } 1953 // ======================================================================= 1954 /** check the uniquness of the name 1955 * @param name the name of the item 1956 * @return true if the name is indeed unique 1957 */ 1958 bool goodItem ( const std::string& name ) const 1959 { return m_items.end() == m_items.find ( name ) ; } 1960 // ======================================================================= 1961 /// get the full list of booked items 1962 const ItemMap& items() const { return m_items ; } 1963 // ======================================================================= 1964 public: 1965 // ======================================================================= 1966 virtual StatusCode Error 1967 ( const std::string& msg , 1968 const StatusCode sc = StatusCode::FAILURE ) const = 0 ; 1969 // ======================================================================= 1970 virtual StatusCode Warning 1971 ( const std::string& msg , 1972 const StatusCode sc = StatusCode::FAILURE ) const = 0 ; 1973 // ======================================================================= 1974 private: 1975 // ======================================================================= 1976 /// get the column 1977 Float* floats ( const std::string& name ); 1978 // ======================================================================= 1979 /// get the column 1980 Int* ints ( const std::string& name ); 1981 // ======================================================================= 1982 /// get the column 1983 Int* ints ( const std::string& name , 1984 const int minv , 1985 const int maxv ) ; 1986 // ======================================================================= 1987 /// get the column 1988 FArray* fArray ( const std::string& name , 1989 Int* item ) ; 1990 // ======================================================================= 1991 /// get the column 1992 FArray* fArray ( const std::string& name , 1993 const MIndex& rows ) ; 1994 // ======================================================================= 1995 /// get the column 1996 Address* addresses ( const std::string& name ) ; 1997 // ======================================================================= 1998 /// get the column 1999 FMatrix* fMatrix ( const std::string& name , 2000 Int* item , 2001 const MIndex& cols ) ; 2002 // ======================================================================= 2003 /// get the column 2004 FMatrix* fMatrix ( const std::string& name , 2005 const MIndex& rows , 2006 const MIndex& cols ) ; 2007 // ======================================================================= 2008 private: 2009 // ======================================================================= 2010 /// the default constructor is disabled 2011 TupleObj () ; 2012 // ======================================================================= 2013 /// copy constructor is disabled 2014 TupleObj ( const TupleObj& ) ; 2015 // ======================================================================= 2016 /// assigement is disabled 2017 TupleObj& operator= ( const TupleObj& ) ; 2018 // ======================================================================= 2019 private: 2020 // ======================================================================= 2021 /// the actual storage type for integer columns 2022 typedef GaudiUtils::HashMap<std::string,Int*> Ints; 2023 // ======================================================================= 2024 /// the actual storage type for float columns 2025 typedef GaudiUtils::HashMap<std::string,Float*> Floats; 2026 // ======================================================================= 2027 /// the actual storage type for address columns 2028 typedef GaudiUtils::HashMap<std::string,Address*> Addresses; 2029 // ======================================================================= 2030 /// the actual storage type for array columns 2031 typedef GaudiUtils::HashMap<std::string,FArray*> FArrays; 2032 // ======================================================================= 2033 /// the actual storage type for matrix columns 2034 typedef GaudiUtils::HashMap<std::string,FMatrix*> FMatrices; 2035 // ======================================================================= 2036 private: 2037 // ======================================================================= 2038 // name 2039 std::string m_name ; ///< the name 2040 // ======================================================================= 2041 // tuple itself 2042 NTuple::Tuple* m_tuple ; ///< tuple itself 2043 // ======================================================================= 2044 // tuple CLID 2045 CLID m_clid ; ///< tuple CLID 2046 // ======================================================================= 2047 // tuple 'type' 2048 Tuples::Type m_type ; ///< tuple 'type' 2049 // ======================================================================= 2050 // reference counter 2051 size_t m_refCount ; ///< reference counter 2052 // ======================================================================= 2053 // the actual storage of all 'Int' columns 2054 mutable Ints m_ints ; ///< the actual storage of columns 2055 // ======================================================================= 2056 // the actual storage of all 'Float' columns 2057 mutable Floats m_floats ; ///< the actual storage of columns 2058 // ======================================================================= 2059 // the actual storage of all 'Address' columns 2060 mutable Addresses m_addresses ; ///< the actual storage of columns 2061 // ======================================================================= 2062 // the actual storage of all 'FArray' columns 2063 mutable FArrays m_farrays ; ///< the actual storage of columns 2064 // ======================================================================= 2065 // the actual storage of all 'FArray' columns (fixed) 2066 mutable FArrays m_arraysf ; ///< the actual storage of columns 2067 // ======================================================================= 2068 // the actual storage of all 'FArray' columns 2069 mutable FMatrices m_fmatrices ; ///< the actual storage of columns 2070 // ======================================================================= 2071 // the actual storage of all 'FMatrix' columns (fixed) 2072 mutable FMatrices m_matricesf ; ///< the actual storage of columns 2073 // ======================================================================= 2074 // all booked types: 2075 ItemMap m_items ; ///< all booked types: 2076 // ======================================================================= 2077 } ; 2078 // ========================================================================== 2079 } // end of namespace Tuples 2080 // ============================================================================ 2081 // GaudiAlg 2082 // ============================================================================ 2083 #include "GaudiAlg/TuplePut.h" 2084 // ============================================================================ 2085 // The END 2086 // ============================================================================ 2087 #endif // GAUDIALG_TUPLEOBJ_H 2088 // ============================================================================ 2089
| [ source navigation ] | [ diff markup ] | [ identifier search ] | [ general search ] |
| Due to the LXR bug, the updates fail sometimes to remove references to deleted files. The Saturday's full rebuilds fix these problems | |
| This page was automatically generated by the LXR engine. |
|