Report problems to ATLAS LXR Team (with time and IP address indicated)

The LXR Cross Referencer

source navigation ]
diff markup ]
identifier search ]
general search ]
 
 
Architecture: linux ]
Version: head ] [ nightly ] [ GaudiDev ]
  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. Valid HTML 4.01!