CDF II
CDF KITS
source navigation ]
diff markup ]
identifier search ]
freetext search ]
file search ]
 
Architecture: i386 ]
Version: 4.10.4 ] [ 4.10.5 ] [ 4.8.4 ] [ 4.8.4l3s ] [ 4.8.5 ] [ 4.9.0 ] [ 4.9.1 ] [ 4.9.1.hpt3 ] [ 4.9.1hpt3 ] [ 4.9.1top1 ] [ 5.0.0 ] [ 5.1.0 ] [ 5.1.0beamonly ] [ 5.1.1 ] [ 5.2.0 ] [ 5.3.0 ] [ 5.3.1 ] [ 5.3.1dsp ] [ 5.3.3 ] [ 5.3.3_nt ] [ 5.3.4 ] [ 6.1.1 ] [ 6.1.1b ] [ 6.1.2 ] [ 6.1.3 ] [ 6.1.4 ] [ 6.1.4int3 ] [ 6.1.4mc ] [ 6.1.4mc_a ] [ 6.1.6 ] [ development ]

001 #ifndef HEPNTUPLE_H
002 #define HEPNTUPLE_H
003 
004 // ----------------------------------------------------------------------
005 //
006 // HepNtuple.h - class declaration for NTuple,
007 
008 
009 // To use:
010 //   create a HepTuple manager* M
011 //   create the HepNtuple by M->newHepNtuple(title, id=0)
012 //   Attach to an existing one by M->oldHepNtuple(title) or
013 //                                M->oldHepNtuple(id)
014 
015 // Open Issues:
016 
017 //   In the HepNtuple Manager should we call the HepNtuple ''constructor''
018 //   newHepNtuple or newNtuple or ntuple.
019 
020 // We must comment oldHepNtuple (and oldHist1D etc) as follows:
021 //      Make a new pointer to an **existing HepNtuple (or Hist1D...) in
022 //      the manager that has this supplied title.  The user will be
023 //      responsible for deleting this HepNtuple* when through with it,
024 //      or the memory assignment will persist till the end of the job.
025 
026 // There are ways of finding out which Ntuples the manager has in this
027 // directory.  So it is right to make a clash (new with same name or id, old
028 // based on one we can't find) either an error or return null pointer.  We
029 // have no way to prevent constructs like
030 //              HepNtuple* h1 = M->newHepNtuple(title, id=0).
031 //              HepNtuple* h2 = h1
032 // but we don't encourage that.  We DON'T allow attaching to an Ntuple where
033 // you already have attached to it.  Our manager WILL track pointers it knows
034 // about and, if the user deletes the manager, they will be marked as
035 // Unmanaged so that attempts to use them will fail in a predictable way.
036 // Copying pointers defeats this safety feature.
037 //
038 // To get around this difficulties we will actually return a reference to the
039 // current HepNtuple.  In addition the function isValid() will return false
040 // as soon as an exception arise during an heptuple operation.  When the
041 // HepNtuple is invalid, no actual usefull operation will be done (like capture
042 // and booking or adding new column.)
043 
044 
045 #ifdef COMMENT
046 
047 Mods in development:
048 
049 7/11/97   mf    Codeguard name is HEPTUPLE_H:  Rule is if a file name starts
050                 with the package''s name-guard because the class it represents
051                 does, we don''t repeat that name-guard twice: 
052                 not HEPHEPTUPLE_H.
053 
054                 Added clearDataColumn(), and changed name for clearDataBlock().
055                 Changed name of capture for a block to captureBlock().
056 
057                 Added lockOutNewColumns() and allowNewColumns().
058 
059                 Added private variables and methods area.
060 
061                 Added to private area:  unspecifiedBlock
062                                         unspecifiedBlockNumber
063                                         formUnspecifiedBlock()
064                                         lockNoNewColumns
065 
066 7/14/97   mf    Added declarations of ZMx classes.  These are temporary, and
067                 will need to be fleshed out even before full ZM exception
068                 mechanism is done.
069 
070 7/22/97   pc    added isLockedNewColumns() returns whether the addition of new
071                 columns is blocked.
072 
073 7/28/97   web   Granted friendship to HepFileManager
074 
075 7/30/97   web   Made use of new base class HepObj for consistency in naming
076 1/20/98   pc    Change all pertinent char* and char[] to std::string
077 2/21/00   web   Improved C++ standard compliance
078 
079 
080 #endif // COMMENT
081 
082 
083 #ifdef COMMENT
084 
085 In this preliminary version of the header for HepNtuple we
086 don''t know yet how we will want to handle colums of characters (in
087 HBOOK they have 8 types, CHAR4 thru CHAR32).  This decision won''t seriously
088 affect the rest of the interface.
089 
090 #endif /* COMMENT */
091 
092 #ifndef ZMENVIRONMENT_H
093   #include "ZMutility/ZMenvironment.h"
094 #endif
095 
096 #include <string>
097 
098 #include "ZMutility/map"
099 #include <vector>
100 
101 
102 #ifndef HEPOBJ_H
103   #include "HepTuple/HepObj.h"
104 #endif
105 
106 #ifndef FIXEDTYPES_H
107   #include "ZMutility/FixedTypes.h"
108 #endif
109 ZM_USING_NAMESPACE( zmfxt )
110 
111 #include "HepTuple/ColumnAttribs.h"
112 #include <HepTuple/useMethod.h>
113 
114 
115 ZM_BEGIN_NAMESPACE( zmht )      /*  namespace zmht  {  */
116 
117 class HepFileManager;
118 
119 class Block;
120 class Column;
121 template <class T> class ColumnT;
122 
123 class TupleNameTag;
124 
125 class HepNtuple  :  public HepObj  {
126 
127   friend class HepFileManager;
128 
129 
130         // --- Original HepNtuple form of column definition/filling
131         // --- Other ways of defining columns
132         // --- Refining column properties
133         // --- Defining blocks
134         // --- Storage Strategy
135         // --- How to fill the histogram
136         // --- Clearing captured data
137         // --- Retrieving Ntuple data
138         // --- Establishing destination variables
139         // --- Accessing information about the HepNtuple structure
140         // --- Data types other than float
141 
142 
143 #ifdef COMMENT
144                 Methods summary
145 
146 (Only the float forms of Tuple data are shown in this summary)
147 
148   bool column (const std::string& nametag, float value, float defval=0);  /*H*/
149   bool newColumn (const std::string& nametag, float val, float defval=0); /*H*/
150   HepNtuple& columnAt (const std::string& nametag, float* address, 
151                                                    float defval=0);
152   HepNtuple& columnVia (const std::string& nametag, ZMuseMethod<float>* method,
153                                                     float defval=0);
154   HepNtuple& columnVia (const std::string& nametag, float(*function)(),
155                                                     float defval=0);
156   HepNtuple& columnArray (const std::string& nametag, int ncolumns, 
157                                                       float defval=0);
158   HepNtuple& columnDirect (const std::string& nametag, float defval=0);
159   HepNtuple& pack (                           float min, float max, int nbits);
160   HepNtuple& pack (const std::string& nametag,float min, float max, int nbits);
161   HepNtuple& span (                           int min, int max);
162   HepNtuple& span (const std::string& nametag,int min, int max);
163   HepNtuple& dimension (const std::string& nametag, int dim);
164   HepNtuple& dimension (                            int dim);
165   HepNtuple& dimension (const std::string& nametag, int dim1, int dim2,
166                         int dim3=0, int dim4=0, int dim5=0, int dim6=0,
167                         int dim7=0, int dim8=0, int dim9=0, int dim10=0);
168   HepNtuple& dimension (                int dim1, int dim2,
169                         int dim3=0, int dim4=0, int dim5=0, int dim6=0,
170                         int dim7=0, int dim8=0, int dim9=0, int dim10=0);
171   HepNtuple& index (const std::string& nametag, const std::string& indextag);
172   HepNtuple& index (                            const std::string& indextag);
173   HepNtuple& characters (const std::string& nametag, int length);
174   HepNtuple& characters (                            int length);
175   bool block (const std::string& blockName, const std::string& format, 
176               std::vector<void*> addresses);
177 
178   bool lockOutNewColumns ();
179   bool allowNewColumns ();
180   bool isLockNewColumns();
181 
182   bool setRowWise ();
183   bool setColumnWise ();
184   bool setBlockWise ();
185   bool setDiskResident ();
186   bool setMemResident ();
187   bool setSharedMemory (char sharedMemoryArea[]);
188   bool setNwbuff    (int nwbuff);
189   bool setBuffLimit (int nbytes);
190   bool setCircularBuffer (int nwbuff);
191   bool setDemandBuffers  (int nbytes);
192 
193   bool captureThenStore ( );
194   bool capture (const std::string& nametag, float value);
195   int setExistingColumn (const std::string& lbl, float val);  /*H*/
196   bool capture (const std::string& nametag, float value[]);
197   bool capture (const std::string& nametag, float value[], int indexval);
198   bool captureColumn (const std::string& nametag);
199   bool captureBlock (const std::string& blockName);
200   bool capture ( );
201   bool storeCapturedData ( );
202 
203   bool clearData ( );  \*H*\
204   bool clearDataBlock (const std::string& blockName);
205   bool clearDataColumn(const std::string& nametag);
206 
207   bool readColumn (int irow, const std::string& nametag, float* value);
208   int readColumnArray (int irow, const std::string& nametag, float values[]);
209   int readBlock (int irow, const std::string& blockName);
210   int readRow (int irow);
211   int bulkReadColumn (const int irow, const int nrows,
212                       const std::string& nametag, float destination[]);
213 
214   HepNtuple destinationAt (const std::string& nametag, 
215                            float* address);
216   HepNtuple destinationVia (const std::string& nametag, 
217                             void (* setMethod) (float));
218   HepNtuple destinationVia (const std::string& nametag, 
219                             void (* setMethod) (float[]));
220   bool blockDestinations (const std::string& blockName, 
221                           const std::string& format,
222                           std::vector<void*> addresses);
223   std::string title ( ); // provided by HepObj
224   std::string dir ( );   // provided by HepObj
225   HepFileManager* manager ( ); // provided by HepObj
226   int id ( );       // provided by HepObj
227   bool isRowWise ( );
228   bool isColumnWise ( );
229   bool isBlockWise ( );
230   char resident ( );
231   Std::String sharedAreaName ( );
232   int nwbuff ( );
233   int buffLimit ( );
234   bool isCircularBuffer ( );
235   bool isDemandBuffers ( );
236 
237   int nBlocks ( );
238   std::string blockName (int blockNumber);
239   std::string blockFormat (int blockNumber);
240   std::string blockFormat (const std::string& blockName);
241 
242   int nColumns ( );
243   int nColumns (const std::string& blockName);
244   std::string nametag (int columnNumber);
245   std::string nametag (int columnNumber, const std::string& blockName);
246   std::string tag (int columnNumber);
247   std::string tag (int columnNumber, const std::string& blockName);
248 
249   std::string columnBlock (const std::string& tag);
250   std::string columnNametag (const std::string& tag);
251   type_info columnType_info (const std::string& nametag);
252   ColumnData_t columnDataType (const std::string& nametag);
253   int columnDimensions (const std::string& nametag, int dims[] );
254   std::string columnIndex (const std::string& nametag);
255   bool columnDefault (const std::string& nametag, float* default);
256   bool setColumnDefault (const std::string& nametag, float default);
257   bool columnSpan (const std::string& nametag, int* min, int* max);
258   void* columnDesignatedVariable  (const std::string& nametag);
259   void* columnDestinationVariable (const std::string& nametag);
260   bool columnPacking (const std::string& nametag, float* low, float* high, 
261                       int* inbits);
262 
263 #endif /* COMMENT */
264 
265 
266 public:
267 
268   // type identifier ( is equal to type() for this object )
269   static const char typeId;
270 
271   // For routines which take a float or float* refering to a datum,
272   // there are analogous routines for int, short, long, and double.
273   // These require no separate explanation, and are grouped together
274   // later in the class definition.
275 
276   // - - - - -
277 
278   // --- Constructor, destructor and copy functions
279 
280   HepNtuple (HepFileManager* manager, const std::string& title, int id = 0);
281 
282   // HepNtuple (const HepNtuple& from);
283   // HepNtuple& operator=(const HepNtuple& from);
284   // These are not enabled yet ... we think that byte-wise copy
285   // is what we want in this case.  Otherwise use duplicate.
286 
287   virtual ~HepNtuple ();
288 
289   // makeClone copy the structure and the content of the HepTuple to
290   // a new HepTuple with the new title and the new id.
291   // When the manager is not precised, the new HepTuple is created in 
292   // the same manager of the copied HepTuple __BUT__ in the current
293   // directory (as opposed to the same directory as the copied HepTuple)
294   // makeEmpty only copies the structure !
295   virtual ZM_COVARIANT_TYPE(HepObj, HepNtuple ) & 
296           makeClone(const std::string& new_title, int new_id = 0) const;
297 
298   virtual ZM_COVARIANT_TYPE(HepObj, HepNtuple ) & 
299           makeClone(HepFileManager* manager, 
300                     const std::string& new_title, int new_id = 0) const;
301 
302   virtual ZM_COVARIANT_TYPE(HepObj, HepNtuple ) & 
303           makeEmpty(const std::string& new_title, int new_id = 0) const;
304 
305   virtual ZM_COVARIANT_TYPE(HepObj, HepNtuple ) & 
306           makeEmpty(HepFileManager* manager, 
307                     const std::string& new_title, int new_id = 0) const;
308 
309   // Append an existing ntuple to the current one.  Both nutple needs to
310   // have the same columns in the same orders (column name excepted)
311   virtual HepNtuple & append ( const HepNtuple& from );
312 
313   // Return true if the argument HepTuple has a column layout compatible
314   // with the current one.
315   virtual bool isCompatible ( const HepNtuple& hep );
316 
317   // --- Original HepNtuple form of column definition/filling  ---
318 
319   // We indicate routines present in the original HepNtuple with /*H*/
320 
321 // ************************************************************************* //
322   bool column (const std::string& nametag, float value, float defval=0);  /*H*/
323   bool newColumn (const std::string& nametag, float val, float defval=0); /*H*/
324 // ************************************************************************* //
325 
326   // This creates the column if it is not yet there and at the same time fills
327   // it. (The newColumn form fails if the column already exists.)
328   // Type checking at runtime happens, if you create via float and
329   // later fill Via int or whatever.
330   // We call this the Direct form; it is an amalgam of creation and filling.
331 
332   // You cannot mix the designated variable form with the column.
333 
334   // nametag is described in **[1]**
335 
336   // This form, which supplies a value, might routinely be used for filling
337   // data.  Therefore it ought not to return anything costly; it returns a
338   // bool indicating sucess (for instance, new columns may have been locked
339   // out, in which case it fails but we shouldn't destroy the job).
340 
341 // - - - - -
342 
343   // --- Other ways of defining columns: ---
344 
345   // All other column-definition methods return HepNtuple& this,
346   // so that a convenient syntax can be used.  See **[2]**
347   // They will return null pointer if for some reason you cannot do the
348   // requested action.
349 
350 // ************************************************************************* //
351   HepNtuple& columnAt (const std::string& nametag, float* address
352                                                  , float defval=0);
353 // ************************************************************************* //
354 
355   // Designated Variable form.  See **[7]**
356 
357   // You cannot mix this with the definition of a whole block including 
358   // this tag or with the Direct form.
359 
360 // ************************************************************************* //
361   HepNtuple& columnVia (const std::string& nametag, ZMuseMethod<float>* method,
362                         float defval=0);
363   HepNtuple& columnVia (const std::string& nametag, float(*function)(),
364                         float defval=0);
365 // ************************************************************************* //
366 
367   // Designated Accessor form.  For objects which avoid public data members.
368 
369   // An example is needed here:  See **[3]**
370 
371 // ************************************************************************* //
372   HepNtuple& columnArray (const std::string& nametag, int ncolumns
373                                                     , float defval=0);
374 // ************************************************************************* //
375 
376   // No-Designated-Variable form.
377   // Intended for a 1-D array which will be filled by Direct capture only.
378 
379   // To use this method to define column arrays of non-float data, see **[15]**
380 
381 // ************************************************************************* //
382   HepNtuple& columnDirect (const std::string& nametag, float defval=0);
383 // ************************************************************************* //
384 
385   // No-Designated-Variable form.
386   // Intended for a single column which will be filled by Direct capture only.
387 
388   // To use this method to define a column of non-float data, see **[15]**
389 
390 // - - - - -
391 
392 
393   // --- Refining column properties ---
394 
395   // The following methods allow the user to refine the column definition.
396   // For syntatic brevity, they also support a signature omitting the nametag
397   // (assuming the previous one).  See **[2]**
398 
399 // ************************************************************************* //
400   HepNtuple& pack (                           float min, float max, int nbits);
401   HepNtuple& pack (const std::string& nametag,float min, float max, int nbits);
402 // ************************************************************************* //
403 
404   // Pack the floats in a lossy manner, dividing the range into 2**nbits
405   // possible n-bit integers.  Even if the column data type is not float,
406   // the range is expressed as floats.
407 
408 
409 // ************************************************************************* //
410   HepNtuple& span  (                            int min, int max);
411   HepNtuple& span  (const std::string& nametag, int min, int max);
412 // ************************************************************************* //
413 
414   // This column becomes eligible to use as an index (see **[4]**) for
415   // other columns.  The maximum supplied delimits how many columns are
416   // defined based on the index.  An index column is packed in a lossless
417   // manner, assuming all values lie in the defined span.
418 
419 
420 // ************************************************************************* //
421   HepNtuple& dimension (const std::string& nametag, int dim);
422   HepNtuple& dimension (                            int dim);
423 // ************************************************************************* //
424 
425   // A one-dimensional array of columns.  These will end up with
426   // tags derived from nametag.  For example, if the tag is "XM"
427   // and dim is 100, the tags made by HBook would be XM(0), XM(1),
428   // ... XM(99).
429 
430 
431 // ************************************************************************* //
432   HepNtuple& dimension (const std::string& nametag,  int dim1,   int dim2,
433                         int dim3=0, int dim4=0, int dim5=0, int dim6=0,
434                         int dim7=0, int dim8=0, int dim9=0, int dim10=0);
435   HepNtuple& dimension (                        int dim1, int dim2,
436                         int dim3=0, int dim4=0, int dim5=0, int dim6=0,
437                         int dim7=0, int dim8=0, int dim9=0, int dim10=0);
438 // ************************************************************************* //
439 
440   // An N-dimensional array of columns -- up to 10 dimensions is supported.
441 
442   // Indices in each dimension are 0-based.  The data is of course supplied
443   // in a C "array" which implies a "first-index-varies-slowest" storage.
444   // The underlying manager may make column tags reflecting its own idea
445   // of how an array is labeled.  Our policy is to set up the dimensions
446   // such that The C++ array ends up as an array of columns of that same
447   // shape -- see **[5]**
448 
449 
450 
451 // ************************************************************************* //
452   HepNtuple& index (const std::string& nametag, const std::string& indextag);
453   HepNtuple& index (                            const std::string& indextag);
454 // ************************************************************************* //
455 
456   // Associates an index variable to an array of columns; this is how
457   // "variable length arrays" are supported.  Of course, depending on
458   // what storage mode is chosen, the underlying manager may or may not
459   // yield space savings when an index does not have its maximum value.
460 
461 
462   // indextag must refer to a column which is or will be set up as an index --
463   // it has (or will have) a defined span.  The column being refined must
464   // have defined dimensions.  The index variable applies to the first
465   // slowest varying dimension and its span replaces the stated extent
466   // of that dimension.
467 
468 // ************************************************************************* //
469   HepNtuple& characters  (const std::string& nametag, int length);
470   HepNtuple& characters  (                            int length);
471 // ************************************************************************* //
472 
473   // Define a fixed-length character std::string column.
474 
475   // When the type of column is char, a column holding single-byte integer
476   // data is formed.  An array of these may be formed in the usual way by
477   // the dimensions() method.
478 
479   // However, sometimes you may want instead a character std::string in the
480   // HepNtuple.  This can be delared by the charcters() method, supplying
481   // a fixed length for the std::string.  The semantics for these are quite
482   // different from the semantics for an array of floats or ints.  A
483   // particular restriction in the HBOOK implementtion is that it must be
484   // 4*K where K is between 1 and 8.  See **[13]**.
485 
486 
487 
488 // - - - - -
489 
490   // --- Defining blocks ---
491 
492   // Here is how to define a whole block at once. The HBOOK chform is used.
493 
494 // ************************************************************************* //
495   bool block (const std::string& blockName, const std::string& format, 
496               std::vector<void*> addresses);
497 // ************************************************************************* //
498 
499   // The designated variables for capturing data are specified by the
500   // addresses.  These need not be contiguous in memory, though typical
501   // usage might have See **[7]**
502 
503   // If not all the columns are to be captured via memory access, it is
504   // preferable to create each column separately using:
505   // columnDirect, columnAt or columnVia.
506 
507   // An awkward point is that the addresses must match the variable
508   // definitions in format.  That is, if format starts with IMAX, XMAX
509   // and the first two addresses supplied are those of a pair of floats,
510   // there will be no notice taken of the fact that you are storing the
511   // first float as an int.  Better safety can be achieved by doing
512   // columnAt() for each column.
513 
514   // There is, by the way, to be an extension to the format so that
515   // if the column name is followed by empty parens, this specifies
516   // the "address" supplied is that of an accessor function.  Again
517   // see **[3]**.
518 
519   // --- Preventing accidental creation of new columns ---
520 
521 // ************************************************************************* //
522   bool lockOutNewColumns ();
523   bool allowNewColumns ();
524   bool isLockedNewColumns () const;
525 // ************************************************************************* //
526 
527   // Prevents (or permits) new columns from being created after any data in
528   // the HepNtuple has been stored.  Returns the previous state of this:  true
529   // if new columns were already locked out.
530 
531   // HepFileManger::newNtuple() sets up a HepNtuple with new columns allowed;
532   // HepFileManger::oldNtuple() sets up a HepNtuple with new columns 
533   // locked out.
534 
535   // Adding a new column to a row-wise Ntuple may be implemented in a manner
536   // taking O(nrows) steps, so locking out new columns may be prudent.
537 
538   // isLockedNewColumns() returns the current state.
539 
540 // - - - - -
541 
542 
543   // --- Storage Strategy
544 
545   // These calls must be made before one starts to fill the HepNtuple.
546 
547   // The default is a Column-wise Disk-resident Ntuple with 8K-entry buffers.
548   // However, if the manager does not support Column-Wise (or for that matter
549   // disk-resident) storage, other supported defaults will apply.
550 
551 
552 // ************************************************************************* //
553   bool setRowWise ();
554   bool setColumnWise ();
555   bool setBlockWise ();
556 // ************************************************************************* //
557 
558   // Choose either row-wise (an entire row is contiguous) column-wise
559   // (each column is buffered in memory such that a large chunk of data
560   // for a single column is contiguous) or -- if the underlying manager
561   // supports it (HBOOK does not) block-wise storage.
562 
563   // Returns false if the manager does not support this mode.
564 
565 // ************************************************************************* //
566   bool setDiskResident ();
567   bool setMemResident ();
568   bool setSharedMemory (char sharedMemoryArea[]);
569 // ************************************************************************* //
570 
571   // Return false if the manager does not support this mode.
572 
573 // ************************************************************************* //
574   bool setNwbuff    (int nwbuff);
575   bool setBuffLimit (int nbytes);
576 // ************************************************************************* //
577 
578   // Set the number of entries per column to be kept in the in-memory buffers.
579   // set buffLimit() sets a limit on total buffer space used, which may cause
580   // the buffer sizes to be LESS that those implied by nwbuff.  Default is
581   // 8K entries per column for column-wise Ntuples, or the greater of 128K
582   // bytes and the size of a full row for row-wise.
583 
584 // ************************************************************************* //
585   bool setCircularBuffer (int nwbuff);
586   bool setDemandBuffers  (int nbytes);
587 // ************************************************************************* //
588 
589   // For in-memory or shared-memory HepNtuple, specifies whether to create a
590   // circular buffer in memory, dropping the oldest rows to make room for the
591   // newest, or to allocate another buffer of space any time you run out of
592   // room.  Default is demand buffers.
593 
594 // - - - - -
595 
596 
597   // --- How to fill the histogram ---
598 
599   // Capture of data, and storing captured data for a row and moving to next
600   // row, is handled by the following methods.  Some semantics are explained
601   // in note **[6]**, and are summarized here.
602 
603     // The act of supplying data for one or more columns is called
604     // capturing that data.  The act of adding the captured data for
605     // a row to the Ntuple is called storing the data.
606 
607     // The row number semantics for storing data is that of automatic
608     // append:  Store increments the row, and the user does not explicitly
609     // specify the row.
610 
611     // Capture of data can be done on a per-column basis.  Another
612     // option is to capture data for an entire block or row by supplying
613     // designated variables.  These are explained in note **[7]**.
614 
615     // The definition of the columns composing the HepNtuple may be extended
616     // after some data has been captured, and even after rows of data have been
617     // stored.  In particular, the use of the column(name, val) method without
618     // a specified block name can be done at any time.  Rules for other cases
619     // are described in **[6]**.
620 
621     // We do not permit data to be captured twice via multiple-column
622     // methods or by single column.  Capture methods that go over multiple
623     // columns (block or row) fill only the ones that were not filled for
624     // this row.  Users can overwrite a filled column by clearing it first.
625 
626 // ************************************************************************* //
627   bool captureThenStore ( );
628 // ************************************************************************* //
629 
630   // Capture data for all designated variables **[7]** in the entire row
631   // THAT HAVE NOT ALREADY BEEN CAPTURED,
632   // then store the data in the Ntuple, advancing to the next row.
633   // This is equivalent to the sequence capture(); storeCapturedData();
634   // and is the convenient way of filling a row.
635 
636 // ************************************************************************* //
637   bool capture (const std::string& nametag, float value);
638   int setExistingColumn (const std::string& nametag, float val);  /*H*/
639 // ************************************************************************* //
640 
641   // Capture data for the one column specified.  The column must have
642   // preveously been defined.  Assuming it has been, this is equivalent
643   // in effect to calling column() with the same arguments.  We call this
644   // "Direct" capture since the value is supplied rather than found in a
645   // designated variable.
646 
647 
648 // ************************************************************************* //
649   bool capture (const std::string& nametag, const float value[]);
650   bool capture (const std::string& nametag, const float value[], int indexval);
651 // ************************************************************************* //
652 
653   // Capture data for an array of columns.  The nametag must match that
654   // of an array of columns which had been defined.  This is a way to do
655   // "Direct" capture, if you wish not to capture the entire block.
656   // The value[] array should match in size the size defined for this array
657   // of columns; if an indexval is supplied, only that number of values for
658   // the slowest-varying dimension are captured.
659 
660   // See **[14]**
661 
662 
663 // ************************************************************************* //
664   bool captureColumn (const std::string& nametag);
665 // ************************************************************************* //
666 
667   // Capture data for one column entire block, via its designated variable
668   // (or access method).  See **[7]** and **[3]**.
669 
670 
671 // ************************************************************************* //
672   bool captureBlock (const std::string& blockName);
673 // ************************************************************************* //
674 
675   // Capture data for an entire block, via its designated variables **[7]**.
676 
677   // Not permitted if the block was already captured for this row; permitted if
678   // some columns were already captured--these will be skipped now.
679 
680 // ************************************************************************* //
681   bool capture ( );
682 // ************************************************************************* //
683 
684   // Capture data for all designated variables in the entire row.  **[7]**
685 
686 
687 // ************************************************************************* //
688   bool storeCapturedData ( );
689 // ************************************************************************* //
690 
691   // Store the data previously captured for this row of the Ntuple, advancing
692   // to the next row.  Captured data may include data capture both by Direct
693   // calls and by designated variables.  This **replaces** the method in
694   // HepNtuple named dumpData().
695 
696 // - - - - -
697 
698   // --- Clearing captured data ---
699 
700   // These are analogous to the capture routines, but used when rejecting
701   // data that had tentatively been captured.
702 
703 
704 // ************************************************************************* //
705   bool clearData ( );  /*H*/
706 // ************************************************************************* //
707 
708   // Clear previously captured data for this row:  all columns of all blocks.
709 
710 
711 // ************************************************************************* //
712   bool clearDataBlock (const std::string& blockName);
713 // ************************************************************************* //
714 
715   // Clear previously captured data for this row: columns in specified block.
716 
717 
718 // ************************************************************************* //
719   bool clearDataColumn (const std::string& nametag);
720 // ************************************************************************* //
721 
722   // Clear previously captured data for this row: This specific column or
723   // column array.
724 
725 // - - - - -
726 
727 
728   // --- Retrieving Ntuple data ---
729 
730   // The Ntuple must have been attached to using the manager method
731   // oldNtuple (or must be an active one created via newNtuple).
732   // Direct-style access to individual columns requires no other
733   // preparations; access to entire blocks or rows using designated
734   // destinations, will require preparation described below.
735 
736   // Retrieval methods have explicit row specification semantics; the user
737   // must provide the row number desired (zero-based) and increment it
738   // explicitly if he wants to loop over all the rows.
739 
740   // Read methods return the number of columns, blocks, or rows read.  Since
741   // zero is a valid return value, negative ints will be returned to signify
742   // erroneous operation (e.g. supplying an invalid nametag[].)  **[8]**
743 
744 // ************************************************************************* //
745   int nrows ( ) const;
746 // ************************************************************************* //
747 
748   // Returns the number of rows of data stored for the Ntuple.
749 
750 // ************************************************************************* //
751   bool readColumn (int irow, const std::string& nametag, float* value);
752 // ************************************************************************* //
753 
754   // Direct read of the value of a column, into *value.  In the case of an
755   // array of columns the nametag[] should include the specification of which
756   // element was wanted, e.g. "mycols(3,5)".
757 
758 
759 // ************************************************************************* //
760   int readColumnArray (int irow, const std::string& nametag, float values[]);
761 // ************************************************************************* //
762 
763   // Direct read of the value of a column, into an array at values[].
764   // The nametag[] should be that of the array of columns.
765   // The user must provide a large enough array at value[] to fit the array
766   // of columns.
767 
768   // The method returns the number of data elements actually captured which,
769   // in the case of indexed arrays, will be the value of its index variable
770   // (and may be less than the maximum number of columns possible).
771 
772 // ************************************************************************* //
773   int readBlock (int irow, const std::string& blockName);
774 // ************************************************************************* //
775 
776   // Read contents of specified block for this row, into the destination
777   // variables established.  All destination variables pertaining to this block
778   // will be filled; this need not be the whole block as written to the Ntuple
779   // but must include at least one variable.
780 
781   // Will return the number of columns filled.
782 
783 
784 // ************************************************************************* //
785   int readRow (int irow);
786 // ************************************************************************* //
787 
788   // Read contents of specified block for this row, into the destination
789   // variables established.  All destination variables established
790   // will be filled; this need not be the whole row but must include at
791   // least one variable.
792 
793   // Will return numbr of BLOCKS filled.
794 
795 
796 // ************************************************************************* //
797   int bulkReadColumn (int irow, int nrows,
798                       const std::string& nametag, float destination[]);
799 // ************************************************************************* //
800 
801   // Retrieve data from one column (which may be one element of an array of
802   // columns) for a whole range of rows.  Data not captured for a row will
803   // be reflected by the default value being placed in that slot of the
804   // destination array.
805 
806   // Bulk reads of a column may be particularly efficient for column-wise
807   // storage strategies, and gain no practical efficiency for row-wise.
808 
809   // The destination must be an array big enough to hold nrows floats.
810 
811   // The return value is the number of values placed; normally nrows, unless
812   // the end of the Ntuple is reached before getting nrows rows.
813 
814 
815 // - - - - -
816 
817 
818   // --- Establishing destination variables ---
819 
820   // A destination variable is to reading in Ntuple rows what a designated
821   // variable is to capturing rows:  Except for Direct forms, data read in
822   // is placed in the destination variables.  Note that for an Ntuple which
823   // is both being written and read back (not necessarily a recommended
824   // practice but certainly permitted), the destination variables may be
825   // the same or distinct from the designated variables for capture.
826 
827   // Destination definition methods return HepNtuple this, so that the
828   // convenient syntax for refining column definitions can be used.
829   // In general, the destination definition has to match the column
830   // definition used when the column was stored, but the match is tolerant
831   // of differences such as not specifying packing for read back.  See **[9]**.
832 
833   // These methods will return null pointer if for some reason you cannot do
834   // the requested action.
835 
836 
837 // ************************************************************************* //
838   HepNtuple& destinationAt (const std::string& nametag, float* address);
839 // ************************************************************************* //
840 
841   // Destination for one column OR array of columns.
842 
843   // For an array of columns, you need not refine the column definition using
844   // the method dimension(), since this information is available from the
845   // existing HepNtuple.  However, in this case address had better point to
846   // an array of floats, big enough to hold the column array.  Methods
847   // are available to check the dimensions of a column array.
848 
849   // For a single column within an array, the nametag form of "nametag(3,4)"
850   // is supported.
851 
852 
853 // ************************************************************************* //
854   HepNtuple& destinationVia (const std::string& nametag, 
855                              void (* setMethod) (float));
856   HepNtuple& destinationVia (const std::string& nametag,
857                              ZMsetMethod<float>* setMethod);
858   HepNtuple& destinationVia (const std::string& nametag, 
859                              void (* setMethod) (float[]));
860   HepNtuple& destinationVia (const std::string& nametag,
861                              ZMsetMethod<float*>* setMethod);
862 // ************************************************************************* //
863 
864   // Accessor form for destinations.  For destination objects which avoid
865   // public data members, requiring calling a method to set the desired data.
866 
867   // See **[10]**
868 
869 
870 
871 // ************************************************************************* //
872   bool blockDestinations (const std::string& blockName, 
873                           const std::string& format,
874                           std::vector<void*> addresses);
875 // ************************************************************************* //
876 
877   // Set up destinations for a whole block at a time.  See **[9]** for
878   // information on which aspects of format must match the original definition.
879 
880 // - - - - -
881 
882 
883   // --- Accessing information about the HepNtuple structure ---
884 
885   // These routines provide information about how the columns and blocks were
886   // defined, and so forth, as well as general information about this instance
887   // of HepNtuple.  They do not provide information that would change when each
888   // row of data is stored; the retrieval routines do that.
889 
890 // ************************************************************************* //
891   bool isRowWise ( ) const;
892   bool isColumnWise ( ) const;
893   bool isBlockWise ( ) const;
894   unsigned char resident ( ) const; // **[11]**
895   std::string sharedAreaName ( ) const;  // **[11]**
896   int nwbuff ( ) const;
897   int buffLimit ( ) const;
898   bool isCircularBuffer ( ) const;  // **[11]**
899   bool isDemandBuffers ( ) const;   // **[11]**
900 // ************************************************************************* //
901 
902 
903 // - - -
904   // General information
905 
906 // ************************************************************************* //
907   int nBlocks ( ) const;
908   std::string blockName (int blockNumber) const;
909 // ************************************************************************* //
910 
911   // Find the names of each of the blocks.  The semantics is that the user
912   // can learn how many blocks there are, and then find the name of each in
913   // turn, forming whatever sort of list or array is prefered.
914 
915 // ************************************************************************* //
916   std::string blockFormat (int blockNumber) const;
917   std::string blockFormat (const std::string& blockName) const;
918 // ************************************************************************* //
919 
920   // Return the format std::string for the columns in a block.  This might not
921   // look the same as the std::string used to define the block because it 
922   // includes both those columns, followed by any columns in that same block 
923   // that were directly created by the column() method.
924 
925 
926 // - - -
927 
928 
929   // Information about columns
930 
931 // ************************************************************************* //
932   int nColumns ( ) const;
933   int nColumns (const std::string& blockName) const;
934 // ************************************************************************* //
935 
936   // Number of columns in the whole HepNtuple or in a block.  A defined array
937   // of columns counts one here, as the purpose is to support looping over
938   // all the column definitions to get information.
939 
940 
941 // ************************************************************************* //
942   std::string nametag (int columnNumber) const;
943   std::string nametag (int columnNumber, const std::string& blockname) const;
944   std::string tag (int columnNumber) const;
945   std::string tag (int columnNumber, const std::string& blockname) const;
946 // ************************************************************************* //
947 
948   // Obtain the nametag (which can include blockname::tag), or just the column
949   // tag, of the n-th column in the HepTUple, or the n-th column in a block.
950   // The blockname can be blank (or empty) to find out about columns defined
951   // by column(), with no block information supplied in their nametag.
952 
953 
954 // ************************************************************************* //
955   std::string columnBlock (const std::string& tag) const;
956   std::string columnNametag (const std::string& tag) const;
957 // ************************************************************************* //
958 
959   // Find out what block a column is in (meaningful because tags must
960   // be unique).
961 
962 
963 // - - -
964   // The following methods provide information about a column specified by
965   // its nametag.
966 
967 // ************************************************************************* //
968 //  type_info columnType_info (const std::string& nametag) const;
969   ColumnData_t columnDataType (const std::string& nametag) const;
970 // ************************************************************************* //
971 // WARNING: Still need to define ColumnData_t or use a compliant compiler for
972 // type_info
973 
974   // Returns the type of variable in each column.  On fully compliant 
975   // compilers, the standard type_info mechanism is supported used.  
976   // For the convenience of users with not-yet-standard compliers, the header 
977   // provides a ColumnData_t enum.  **[12]**
978 
979 
980 // ************************************************************************* //
981   int columnDimensions (const std::string& nametag, int dims[] ) const;
982 // ************************************************************************* //
983 
984   // Returns number of dimensions, zero if this was not defined as an array of
985   // columns.  The extents in each dimension are put into dims[]; if an
986   // index variable is used, dims[0] will be the maximum value of that.
987   // dims[] should be an array of length 10, in case a 10-dimensional
988   // column array (the most we support) was established.
989 
990 
991 
992 // ************************************************************************* //
993   std::string columnIndex (const std::string& nametag) const;
994 // ************************************************************************* //
995 
996   // Returns the nametag of the index column established for this array of
997   // columns.  Returns an empty Std::String if the column is not an indexed 
998   // array.
999 
1000 // ************************************************************************* //
1001   bool columnDefault (const std::string& nametag, float* defval) const;
1002   bool setColumnDefault (const std::string& nametag, float defval) const;
1003 // ************************************************************************* //
1004 
1005   // Provides the default value for an un-captured column.  There are other
1006   // signatures taking int*, long*, short*, double*, bool*, and Std::String*.
1007   // They return false if the wrong type of pointer was provided for this
1008   // column type.
1009 
1010 
1011 // ************************************************************************* //
1012   bool columnSpan (const std::string& nametag, int* min, int* max) const;
1013 // ************************************************************************* //
1014 
1015   // Returns false if this column was not set up as an index column, with
1016   // a defined span.
1017 
1018 // - - -
1019 
1020   // The following are provided for completeness, though generally the user
1021   // either has established the information which he now seeks, or would not
1022   // normally care what the answer might be.
1023 
1024 
1025 // ************************************************************************* //
1026   void* columnDesignatedVariable  (const std::string& nametag) const;
1027   void* columnDestinationVariable (const std::string& nametag) const;
1028 // ************************************************************************* //
1029 
1030   // Will return 0 if designated or destination variable was not established.
1031 
1032 
1033 // ************************************************************************* //
1034   bool columnPacking (const std::string& nametag,
1035                       float* low, float* high, int* inbits) const;
1036 // ************************************************************************* //
1037 
1038   // False if no packing was specified.
1039 
1040 // - - - - -
1041 
1042 
1043   // --- Data types other than float ---
1044 
1045   // For routines which take a float or float* refering to a datum,
1046   // there are analogous routines for int, short, long, and double.
1047 
1048 #define HEPTUPLE_METHOD_LIST(TYPE)                                            \
1049   bool column (const std::string& nametag, TYPE value, TYPE defval=0);        \
1050   bool newColumn (const std::string& nametag, const TYPE value,               \
1051                   const TYPE defval=0);                                       \
1052   HepNtuple& columnAt  (const std::string& nametag,  TYPE* address,           \
1053                        TYPE defval=0);                                        \
1054   HepNtuple& columnVia (const std::string& nametag, ZMuseMethod<TYPE>* method,\
1055                        TYPE defval=0);                                        \
1056   HepNtuple& columnVia (const std::string& nametag, TYPE (*function)(),       \
1057                        TYPE defval=0);                                        \
1058   HepNtuple& columnArray (const std::string& nametag, int ncolumns,           \
1059                           TYPE defval=0);                                     \
1060   HepNtuple& columnDirect (const std::string& nametag, TYPE defval=0);        \
1061   bool capture   (const std::string& nametag,  const TYPE value);             \
1062   bool capture   (const std::string& nametag,  const TYPE value[]);           \
1063   bool capture   (const std::string& nametag,  const TYPE value[],            \
1064                   int indexval);                                              \
1065   int setExistingColumn (const std::string& nametag, TYPE val);  /*H*/        \
1066   bool readColumn (int irow, const std::string& nametag, TYPE* value);        \
1067   int readColumnArray (int irow, const std::string& nametag, TYPE values[]);  \
1068   int bulkReadColumn (int irow, int nrows,                                    \
1069                       const std::string& nametag, TYPE destination[]);        \
1070   HepNtuple& destinationAt ( const std::string& nametag, TYPE* address);      \
1071   HepNtuple& destinationVia ( const std::string& nametag,                     \
1072                            void (* setMethod) (TYPE));                        \
1073   HepNtuple& destinationVia ( const std::string& nametag,                     \
1074                            ZMsetMethod<TYPE>*  setMethod);                    \
1075   HepNtuple& destinationVia ( const std::string& nametag,                     \
1076                            void (* setMethod) (TYPE[]));                      \
1077   HepNtuple& destinationVia ( const std::string& nametag,                     \
1078                            ZMsetMethod<TYPE*>*  setMethod);                   \
1079   bool columnDefault (const std::string& nametag, TYPE* defval) const;        \
1080   bool setColumnDefault (const std::string& nametag, TYPE defval) const;
1081 
1082 // the Float4 version is already instiated above.
1083 HEPTUPLE_METHOD_LIST(Float8)
1084 #ifdef Float16
1085 HEPTUPLE_METHOD_LIST(Float16)
1086 #endif
1087 HEPTUPLE_METHOD_LIST(Int1)
1088 HEPTUPLE_METHOD_LIST(Int2)
1089 HEPTUPLE_METHOD_LIST(Int4)
1090 #ifdef Int8
1091 HEPTUPLE_METHOD_LIST(Int8)
1092 #endif
1093 HEPTUPLE_METHOD_LIST(bool)
1094 HEPTUPLE_METHOD_LIST(void*)
1095 
1096 
1097 protected:
1098 
1099         ///////////////////////
1100         //                   //
1101         // Protected Methods //
1102         //                   //
1103         ///////////////////////
1104 
1105   // Used for dummy construction ...
1106   // the object is then not valid ...
1107   HepNtuple( );                           // default constructor
1108 
1109   // Method use to retore block from existing file.
1110   bool restoreBlock (const std::string& blockName, const std::string& format);
1111 
1112   Block* unspecifiedBlock();
1113   // The name will be #0000001 for the first unspecified block,
1114   // and after it is frozen and fUB() is called again, #0000002, etc.
1115   // For row-wise, it will start as the title of the Ntuple, and after it
1116   // is frozen forming new blocks will require the special rewind()
1117   // action so the same name will be retained.
1118 
1119   Column* findColumn(const std::string& nameTag) const;
1120   // if the block name is not expressed in the name tag, it returns
1121   // "A" column with the given name unless the sub-class insure through
1122   // isAvalaible that each name is unique in the tuple
1123 
1124   Block* findBlock(const std::string& blockName) const;
1125 
1126   Column* currentColumn() const;
1127   void setCurrentColumn(Column* c);
1128   // query/set the last column used.
1129 
1130   virtual bool isNameAvailable(const std::string& nameTag) const;
1131   // returns true if nameTag can be used for a new column in this
1132   // HepNtuple
1133 
1134   virtual const TupleNameTag& parseNameTag(TupleNameTag& what,
1135                                            const std::string& nameTag,
1136                                            bool WithIndices = false) const;
1137   // Modify and return 'What' to contain the column name and the
1138   // eventual block name.
1139 
1140   // These functions might worth being public
1141   virtual bool isRowWiseEnabled() const = 0;
1142   virtual bool isColumnWiseEnabled() const = 0;
1143   virtual bool isBlockWiseEnabled() const = 0;
1144   virtual bool isDiskResidentEnabled() const = 0;
1145   virtual bool isMemResidentEnabled() const = 0;
1146   virtual bool isSharedMemoryEnabled() const = 0;
1147   virtual bool isNwbuffEnabled(int nwbuff) const = 0;
1148   virtual bool isBuffLimitEnabled(int limit) const = 0;
1149   virtual bool isDemandBuffersEnabled() const = 0;
1150   virtual bool isCircularBufferEnabled() const = 0;
1151   //  virtual bool isEnabled() const = 0;
1152 
1153   virtual bool isCaseSensitive() const = 0;
1154 
1155   // These methods tell if a manager can handle a certain type in
1156   // the given block.
1157   virtual bool isTypeEnabled(ColumnData_t type,Block *bk) = 0;
1158   virtual bool isTypeEnabled(ColumnData_t type) = 0;
1159 
1160   enum StorageGeometryName { ROW, COLUMN, BLOCK };
1161   enum BufferTypeName { CIRCULAR, DEMAND };
1162 
1163   StorageGeometryName storageGeometry() const;
1164   BufferTypeName bufferType () const;
1165 
1166   // simple-minded mutable accessor to the strategy ... it does
1167   // NOT verify if the newStrategy is possible.  Use the
1168   // specific setter for that (setRowWise, setColumnWise etc...)
1169 
1170   virtual bool setStorageGeometry(StorageGeometryName newStrategy);
1171   virtual bool setStorageLocation(unsigned char newLocation);
1172   virtual bool setSharedMemoryName(char sharedMemoryArea[]);
1173   virtual bool setNwbuffValue(int nwbuff);
1174   virtual bool setNrowsValue(int nrows);
1175   virtual bool setBuffLimitValue(int limit);
1176   virtual bool setBufferType(BufferTypeName type);
1177 
1178   // from a NULL-terminated character std::string (a valid chForm in HBOOK) to
1179   // create a block containing an array of ColumnAttribs.
1180   // Also, the number of columns can be obtain through the nColumns().
1181   std::vector<ColumnAttribs*> parseFormat(const std::string& chform);
1182 
1183   virtual bool addBlock(Block *b);
1184   virtual bool addColumn(Column *c);
1185   virtual bool addColumn(Block *b,Column *c);
1186 
1187   // methods to set/check if definition change happened.
1188   void changedDefinition();
1189   bool isDefinitionChanged();
1190 
1191   // methods to book and prepare for storage.
1192 
1193   virtual bool book() = 0;
1194   // this method should implement the booking the ntuple parts
1195 
1196   virtual bool prepareBlockForStoring(Block* bk);
1197   // Copy the captured data to the proper location for the manager.
1198 
1199   virtual bool storeWholeRow() = 0;
1200   virtual bool storeSingleBlock(Block* bk) =0;
1201   // Instruct the manager to store the row/block
1202 
1203   virtual int readWholeRow(int irow) = 0;
1204   virtual int readWholeBlock(Block* bk, int irow) = 0;
1205   virtual int readSingleColumn(Column* col, int irow) = 0;
1206   virtual int readSingleColumn(Column* col, const std::string& indices, 
1207                                int irow, void * val) = 0;
1208   virtual int readSingleColumn(Column* col, int irow, void * val) = 0;
1209   // Instruct the manager to read from file/memory into the destination
1210   // variable of all the columns of repectively the row, block, single column
1211   // For the first three functions ALL the listed columns are expected to have
1212   // destination variables (i,e. get the value at an address and send it to
1213   // col->set(void *addr);
1214 
1215   virtual int readWholeColumn(Column* col, const std::string& indices, 
1216                               int start_row, int nrows, 
1217                               char * val, std::string::size_type size);
1218   virtual int readWholeColumn(Column* col,  
1219                               int start_row, int nrows, 
1220                               char * val, std::string::size_type size);
1221   // Instruct the manager to read a whole column and store it into val
1222   // which is assume to be array of the same type as the column and of size
1223   // nrows.  This function are called from bulkReadColumn
1224   // The manager independent implementation loop over the equivalent 
1225   // readSingleColumn function
1226 
1227   int readBlock(Block *bk, int irow);
1228   // utility function used by readRow and readBlock
1229 
1230   // data members containing the columns/block definitions
1231 
1232   typedef std::map<std::string, Column*, 
1233                    std::less<std::string> > columnsMap;
1234   typedef std::map<std::string, Block*, 
1235                    std::less<std::string> > blocksMap;
1236   blocksMap blocks;
1237   columnsMap columns;
1238 
1239   bool _changedDefinition;
1240   // Used to check if any definition of the heptuple changed since
1241   // the last store.
1242 
1243 #ifdef NEVER
1244   // JMM experimenting with pretendToUse for overleaded functions  4 Dec. 2001
1245   void silenceCompiler();
1246 #endif
1247 
1248 private:
1249 
1250         //////////////////
1251         //              //
1252         // Private Data //
1253         //              //
1254         //////////////////
1255 
1256   // data members for the storage strategy
1257   StorageGeometryName _storageGeometry;
1258   unsigned char _storageLocation;
1259   char *_sharedMemoryAreaName;
1260   int _nwbuff;
1261   int _buffLimit;
1262   BufferTypeName _bufferType;
1263 
1264   Block * _unspecifiedBlock; // = 0;
1265         // A block currently suitable for adding new columns with unspecified
1266         // block name.  If the block gets frozen, then unspecifiedBlock
1267         // must become 0 to indicate that there is none at the moment.
1268 
1269   int _unspecifiedBlockNumber; // = 0;
1270         // Last trailing number that has previously been used to name an
1271         // unspecified block.  Eg, if this is 17, the next unspecified block
1272         // formed will be named #0000018.
1273 
1274   bool _lockNoNewColumns; // = false;
1275         // New columns may not be added to this HepNtuple because a store has
1276         // already been done AND the lockOutNewColumns method has been invoked.
1277 
1278   mutable Column* _currentColumn; // 0
1279         // Keep track of the last column used.
1280 
1281   int _nrows;
1282 
1283 
1284         /////////////////////
1285         //                 //
1286         // Private Methods //
1287         //                 //
1288         /////////////////////
1289 
1290 
1291         ///////////////////////
1292         //                   //
1293         // Exception Classes //
1294         //                   //
1295         ///////////////////////
1296 
1297 #ifdef COMMENT
1298         The following classes will change when we implement the exception
1299         mechanism, and will in particular become publicly derived from
1300         the ZMxGeneral base in HepNtuple class, which in turn is derived from
1301         the ZMexception base.
1302 
1303         For now we keep it minimal to just compile; ZMthrow will lead to
1304         an exit.
1305 #endif // COMMENT
1306 
1307 public:
1308   class ZMxGeneral;
1309   class ZMxProblem;
1310   class ZMxColumn;
1311   class ZMxNewColumn;
1312   class ZMxCapture;
1313 
1314 #if (defined(__GNUC__) && (__GNUC__ < 3) && __GNUC_MINOR__ < 90) || defined(WIN32)
1315   // GNU can not handle templated friends but we can trick it with the
1316   // following.
1317   // This could (should) be remplaced by a __NOTEMPLATEDFRIEND defined
1318   // in SoftRelTools/arch_spec.mk
1319 #define HEPTUPLE_TEMPLATE_FRIENDS(TYPE)                                       \
1320 friend bool captureF(const std::string& nametag, TYPE, HepNtuple* tuple);     \
1321 friend bool captureArrF(const std::string& nametag, const TYPE val[],         \
1322                         int indexVal,                                         \
1323                         HepNtuple* tuple);                                    \
1324 friend bool columnF(const std::string& nametag, TYPE value, TYPE defval,      \
1325                     HepNtuple* tuple);                                        \
1326 friend bool columnAtF(const std::string& nametag, TYPE* value, TYPE defval,   \
1327                     HepNtuple* tuple);                                        \
1328 friend bool columnViaF(const std::string& nametag, TYPE (*function)(),        \
1329                        TYPE defval,  HepNtuple* tuple);                       \
1330 friend bool columnViaM(const std::string& nametag, ZMuseMethod<TYPE>* method, \
1331                        TYPE defval,  HepNtuple* tuple);                       \
1332 friend Column* newColumnF(const std::string& nametag, TYPE value, TYPE defval,\
1333                        HepNtuple* tuple);                                     \
1334 friend ColumnT<TYPE>* addNewColumnF(const std::string& nameTag,               \
1335                                     TYPE defaultValue,                        \
1336                                     HepNtuple* tuple);                        \
1337 friend bool columnDefaultTmpl(const std::string& nametag, TYPE* def,          \
1338                                     const HepNtuple* tuple);                  \
1339 friend bool setColumnDefaultTmpl(const std::string& nametag, TYPE def,        \
1340                                     const HepNtuple* tuple);                  \
1341 friend bool readColumnF(int irow, const std::string& nametag,                 \
1342                            TYPE* destination, HepNtuple *tuple);              \
1343 friend int bulkReadColumnF(int irow, int nrows, const std::string& nametag,   \
1344                            TYPE* destination, HepNtuple *tuple);              \
1345 friend int readColumnArrayF ( int irow,  const std::string& nametag,          \
1346                               TYPE *destination, HepNtuple* tuple);           \
1347 friend ColumnT<TYPE>* getColumnT(const std::string &nametag,HepNtuple *hep,   \
1348                                  TYPE fortype);                               \
1349 friend ColumnT<TYPE>* getOrCreateColumnT(const std::string& nametag,          \
1350                                          TYPE defVal,                         \
1351                                          HepNtuple *hep);
1352 
1353 HEPTUPLE_TEMPLATE_FRIENDS(Int1)
1354 HEPTUPLE_TEMPLATE_FRIENDS(Int2)
1355 HEPTUPLE_TEMPLATE_FRIENDS(Int4)
1356 #ifdef Int8
1357 HEPTUPLE_TEMPLATE_FRIENDS(Int8)
1358 #endif
1359 HEPTUPLE_TEMPLATE_FRIENDS(Float4)
1360 HEPTUPLE_TEMPLATE_FRIENDS(Float8)
1361 #ifdef Float16
1362 HEPTUPLE_TEMPLATE_FRIENDS(Float16)
1363 #endif
1364 HEPTUPLE_TEMPLATE_FRIENDS(bool)
1365 HEPTUPLE_TEMPLATE_FRIENDS(void*)
1366 
1367 #else
1368 
1369 template <class TYPE> friend
1370 bool captureF(const std::string& nametag,TYPE, HepNtuple* tuple);
1371 
1372 template <class TYPE> friend
1373 bool captureArrF(const std::string& nametag, const TYPE val[],
1374                  int indexVal, HepNtuple* tuple);
1375 
1376 template <class TYPE> friend
1377 bool columnF(const std::string& nametag, TYPE value,
1378              TYPE defval,HepNtuple* tuple);     
1379 
1380 template <class TYPE> friend
1381 bool columnAtF(const std::string& nametag, TYPE* value,
1382                TYPE defval,HepNtuple* tuple);
1383 
1384 template <class TYPE> friend
1385 bool columnViaF(const std::string& nametag,
1386                 TYPE (*function)(),TYPE defval,  HepNtuple* tuple);
1387 
1388 template <class TYPE> friend
1389 bool columnViaM(const std::string& nametag,
1390                 ZMuseMethod<TYPE>* method,TYPE defval,  HepNtuple* tuple);
1391 
1392 template <class TYPE> friend
1393 Column* newColumnF(const std::string& nametag,
1394                    TYPE value, TYPE defval,HepNtuple* tuple);
1395 
1396 template <class TYPE> friend
1397 ColumnT<TYPE>* addNewColumnF(const std::string& nameTag,
1398                              TYPE defaultValue, HepNtuple* tuple);
1399 
1400 template <class TYPE> friend
1401 bool columnDefaultTmpl(const std::string& nametag, TYPE* def,
1402                        const HepNtuple* tuple);
1403 
1404 template <class TYPE> friend
1405 bool setColumnDefaultTmpl(const std::string& nametag, TYPE def,
1406                        const HepNtuple* tuple);
1407 
1408 template <class TYPE> friend
1409 bool readColumnF(int irow, const std::string& nametag,
1410                  TYPE* destination, HepNtuple *tuple);
1411 
1412 template <class TYPE> friend
1413 int bulkReadColumnF(int irow, int nrows,
1414                     const std::string& nametag,TYPE* destination, 
1415                     HepNtuple *tuple);
1416 
1417 template <class TYPE> friend
1418 int readColumnArrayF ( int irow,  const std::string& nametag,
1419                        TYPE *destination, HepNtuple* tuple);
1420 
1421 template <class TYPE> friend
1422 ColumnT<TYPE>* getColumnT(const std::string& nametag,
1423                           HepNtuple *hep,TYPE fortype);
1424 
1425 template <class TYPE> friend
1426 ColumnT<TYPE>* getOrCreateColumnT(const std::string& nametag,TYPE defVal,
1427                                   HepNtuple *hep);
1428 #endif
1429 }; // end of class HepNtuple
1430 
1431 
1432 ZM_END_NAMESPACE( zmht )        /*  }  // namespace zmht  */
1433 
1434 
1435 // include the inline methods
1436 
1437 #include "HepTuple/HepNtuple.icc"
1438 
1439 
1440 #ifdef COMMENT
1441 
1442                                 NOTES
1443                                 -----
1444 
1445 **[1]** Block and column name and tag
1446 
1447 Column tags have no length limit but must be unique within any given block.
1448 (For HBook, column tags must be unique over the entire ntuple and the
1449 concatenation of all column tags in any block may not exceed 1300 characters.)
1450 A column may be defined with no specified block (for example defined by the
1451 direct capture routine column(tag[], value).  What this means is that the user
1452 does not care what block this is grouped with, and does not intend to retrieve
1453 that data "by whole block."
1454 
1455 Actually, all columns with no specified block which were defined between one
1456 row-store and another will end up in the same block.
1457 
1458 Block names are treated as their first 8 characters.  When a column is defined,
1459 you may use a longer form for its name than just its column tag -- the format
1460 is bname::ctag and we call this a nametag.  For example, in the nametag
1461 "BLOCK5::PxDev" the column tag is PxDev and it is in block BLOCK5.
1462 
1463 Unfortunately, one cannot use block names as a namespace mechanism to allow
1464 disjoint users to choose their column tags arbitrarily:  The column tag must
1465 be unique across the entire HepNtuple when using the HBOOK manager.
1466 Some other form of column tag naming agreement must be reached for a given
1467 program.
1468 
1469 Other than the un-named ("don't care") block, which can be assigned anew when
1470 new columns are added after a store has been done, the block name assigned
1471 is the block name used.  We have abandoned the thought of automatically
1472 changing the block name under various conditions.
1473 
1474 This has a manager-specific consequence for HBOOK:
1475 
1476 Character string columns may have to be placed into distinct blocks from
1477 ordinary variables.  The manual implies this is necessary.  If so, it will be
1478 an error to mix character and numeric values in the same block if an HBOOK
1479 manager is used.
1480 
1481 **[2]** Convenient syntax for column definition
1482 
1483 You can combine definition of column nametag/designated variable, with
1484 refinements concerning packing, array dimensions, and so forth, in the 
1485 following compact syntax:
1486 
1487   HepNtuple *mytup; float whereItIs;
1488   mytup->columnAt
1489    ("mytag", &whereItIs).dimension(4,2).pack(0.1, 1.5, 12).index("JNUM");
1490 
1491 That is why these methods return a HepNtuple* (this).
1492 
1493 The one method which does double-duty as a capture method -- and therefore may
1494 be called thousands of times after the single column definition -- can still
1495 afford to return HepNtuple* (this).  For now, it returns a bool but that may
1496 change.
1497 
1498 **[3]** Example of designating an accessor function
1499 
1500 Say you have a structure SpaceVector v, and you want to put r into the 
1501 HepNtuple, but r is accessed by the method v.r().
1502 
1503   class SpaceVector { public: float r();  // and other stuff }
1504   SpaceVector v;
1505   HepNtuple *mytup;
1506   mytup->columnVia ("ThisBLK::Radius", v.r());
1507   // which is filled elsewhere in some loop, which then does ...
1508   mytup->capture("ThisBLK");  // captures data in ThisBLK, including
1509                               // calling v.r() to capture r.
1510 
1511 Of course, now v had better stick around as long as ThisBLK is being captured,
1512 otherwise the call to v.r() will be invlaid.  This is the same as always with
1513 designated variables:  They must remain in scope if their block is to be
1514 captured.
1515 
1516 **[4]** Arrays of columns, and Index variables
1517 
1518 An array of columns is treated as a collection of separate columns.  They all
1519 share the same array name, but the HBOOK column names, for example, will be
1520 like NAME(0,0) NAME(1,0) ... NAME(3,5), ... etc.  You in fact can retrieve a
1521 column by that specific array element name (but you cannot capture just one
1522 element at a time).  So for example, with columnwise storage you can get
1523 just X(3,2) for all rows stored, and do it very efficiently.
1524 
1525 Note that indices are zero-based.
1526 
1527 An index variable is how varying-length arrays are done.  It delimits the
1528 slowest-varying dimension, which in C++ is the first dimension (a in
1529 X[a][b][c]) but in Fortran is the last one (c in X(a,b,c)).  That first
1530 dimension of an indexed array is REPLACED in extent by the maximum set in
1531 the span of the index variable.
1532 
1533 When the index variable is less than its maximum possible value the remaining
1534 columns may not have anything stored for them.  HBOOK benefits from this
1535 optimization for column-wise Ntuples.  Such un-captured columns, if read back,
1536 will give the default value.
1537 
1538 **[5]** Array ordering
1539 
1540 Because the most important implementation assigns column array element names
1541 using the Fortran convention X(0,0) X(1,0), ... X(M, 0), X(0,1), ... X(M,N)
1542 the HepTuple package will go along with that.  This presents no problem at all
1543 on the side of filling the HepNtuple.
1544 
1545 The confusion happens when a user knows he has stored an array shaped as
1546 x[40][20] in column array X, and wants to retrieve specific element -- he would
1547 have to say X(15,35) to get back the element which was in the C++ array as
1548 x[35][15].  That is what we get for mixing the two languages; further attempts
1549 to rectify the confusion will only make things worse.  At least all our users
1550 KNOW to expect something cloudy whien this mixing goes on...
1551 
1552 **[6]** Semantics of filling an Ntuple
1553 
1554 The act of supplying data for one or more columns is called capturing that
1555 data.  The act of adding the captured data for a row to the Ntuple is called
1556 storing the data.  Data which is captured is not inevitably to be stored since
1557 the user can clearData for the row (for example when rejecting an event).
1558 Also, a subsequent capture for the same column will replace the earlier
1559 captured data.
1560 
1561 For managers which can benefit from the knowledge of which blocks were not
1562 filled,  by not storing a block for a particular row, the information is
1563 kept.  A block which has been captured is "marked"; clearing the block will
1564 "unmark" it, as well as setting all values to their defaults.
1565 
1566 The row number semantics for storing data is that of automatic append:  The
1567 "active" row in an empty Ntuple would start at zero, and each time a row is
1568 stored, will increment.  Thus you cannot overwrite a previously stored row, or
1569 leave a gap in row number.
1570 
1571 Capture of data can be done on a per-column basis using the "Direct" forms
1572 column(tag, value, defval) or capture(tag, value).  Another way is to capture
1573 data for an entire block or row by supplying designated variables.  These are
1574 explained in note **[7]**.
1575 
1576 The definition of the columns composing the HepNtuple may be extended
1577 after some data has been captured, and even after rows of data have been
1578 stored.  The rules are:
1579 
1580       * A column in an unnamed block may be defined at ANY time, as long
1581         as the column tag is unique.  Adding colummns after data has been
1582         stored is even reasonably efficient for columns-wise storage, but
1583         can be quite time-consuming for row-wise HepNtuple with lots of
1584         data already stored.
1585 
1586       * A column in a specific named block may be defined only if that block 
1587         has not yet been stored.  That is, if you capture a block (or data in a
1588         column in that block, then do storeCapturedData, then that block may no
1589         longer be added to.
1590 
1591       * A column in a specific named block may be defined even if that block
1592         has been captured (but not stored).  Of course, the value for that
1593         column would be the default value until it is captured.
1594 
1595       * A column may not be defined with the same tag as some other column
1596         previously defined (even if they are in different blocks).
1597 
1598       * The definition of a defined column may not be refined (adding packing
1599         information and so forth) after data has been captured for that column.
1600 
1601       * For completeness:  Storage strategy for the HepNtuple may be refined
1602         up until the first storeCapturedData is done, and no later.
1603 
1604 The mode of operation where column(name, val) without a specified block name
1605 is done at arbitrary times for definition and Direct capture is a preferred
1606 mode of operation prefered at BaBar, where their framework allows different
1607 contributors to add their own information to a common Ntuple, but may not
1608 call every contributor for every event.
1609 
1610 The act of adding a new column to an **EXISTING** ntuple, supplying data for
1611 each row for that column, is treated as part of the concept of manipulating
1612 ntuples, specifically, as a mode of combining two ntuples.  This will be
1613 implemented later.
1614 
1615 **[7]** Designated Variables and Destination Variables
1616 
1617 HBOOK has the convenience of allowing (forcing for heterogeneous column-wise
1618 Ntuples) the user to designate variables meaning that, ""Here is where the data
1619 will be when I want to fill a block or row.""  Those have to be in a COMMON
1620 block in HBOOK, to enforce a known pattern of word-alignment (namely, none).
1621 
1622 HepTuple, of course, retains this convenience, but allows the designated
1623 variables to be in any struct or structs, not necessarily contiguous.
1624 
1625 C++ compilers are free to word-align structs by adding padding.  So even
1626 if all the designated variables are in one struct, there would be a need to
1627 specify the addresses of each.  In HepTuple this is done either by columnAt(),
1628 or for a whole block at a time by the vector of addresses in block().
1629 
1630 We distinguish designated variables for filling the HepNtuple, from destination
1631 variables for retrieval.  To retrieve data other than one column or column
1632 array at a time, you must set up destinations for the data using
1633 destinationAt().
1634 
1635 Don''t forget to keep the designated and destination variables in scope!  If
1636 you don''t then either the HepTUple is being filled from meaningless data, or
1637 your retrival is putting data in a meaningless place!
1638 
1639 **[8]** Possible error returns for Read routines
1640 
1641 -1 Name not found
1642 -2 irow past end of Ntuple
1643 -3 No designated variables were established for desired block or row
1644 -4 Element of Column array read using tag without indices
1645 -5 Ordinary column read using readColumnArray
1646 
1647 Since accessing an existing Ntuple is inherently subject to these problems, we
1648 choose (for now) to return a code RATHER THAN to throw exceptions.  In
1649 particular, placing all access inside individual try constructs will be
1650 badly inefficient in an area that might matter.
1651 
1652 
1653 **[9]** Refining destination definitions
1654 
1655 To specify a destination well enough for retrieval to proceed, you need to
1656 specify:
1657 
1658 * The nametag and address, as in destinationAt().
1659 
1660 You do not need to specify, because the HepNtuple knows about, the following:
1661 
1662 - The dimensions of a column array
1663 - Packing information
1664 - The span of an index column
1665 - The tag of the column used as an index
1666 
1667 It you do specify unneeded information, and it clashes in a meaningful way with
1668 the actual information, the specification routine will return 0 instead of a
1669 pointer to the HepNtuple.  This should not be ignored; it probably means you 
1670 will fou up badly if you try to retrive data into space tailored to your wrong
1671 information!
1672 
1673 When an entire block is specified at a time, by blockDestinations(), the
1674 format supplied must match reality in tags, index variable, dimensions, and
1675 spans -- otherwise, there is too great a likelihood that reading into the
1676 supplied list of addresses will be blowing storage.  For example, if you think
1677 index variable J has a span of 0-200 and it can really go to 210, you probably
1678 are allocating 200 words of space to hold a possible 210-word output.
1679 
1680 Similarly, the number of columns in the format string must match the number of
1681 addressses in the list.  But these do not have to match the total number of
1682 columns in the block, or be in the same order -- you can skip columns on
1683 retrieval.  And packing information in the destination format string is 
1684 ignored.
1685 
1686 **[10]** SetMethods for destinations
1687 
1688 This is for purists who wish to fill their structures (from retireved Ntuple
1689 data) via "mutator methods" rather than direcly writing to their data.
1690 
1691 Say you have a structure SpaceVector v, and you have a method v.r(float) that
1692 would take one float value (IT MUST TAKE 1 VALUE FOR THIS FEATURE TO BE
1693 APPLICABLE) for r, and change the vector to keep the same theta and phi but use
1694 the new r.  This is not just storing r in a place; the actual x, y, and z all
1695 change.
1696 
1697   class SpaceVector { public: void r(float);  // and other stuff }
1698   SpaceVector v;
1699   HepNtuple *mytup;
1700   mytup->distinationVia ("ThisBLK::Radius", v.r());
1701   // which is filled elsewhere in some loop, which then does ...
1702   mytup->readBlock("ThisBLK");  // When up to Radius, it supplies that
1703                                 // value as the agrument to a call to
1704                                 // calling v.r().
1705 
1706 Of course, now v had better stick around as long as ThisBLK is being read,
1707 otherwise the call to v.r() will be invlaid.
1708 
1709 (Frankly, v.r(x) can do anything it wants to with x.  We just imagine it being
1710 used to modify some aspects of v.)
1711 
1712 You can use this mechanism to work with a single column or an array of
1713 columns.  In the latter case, you have mutator method which takes as an
1714 argument an float[] instead of a float.
1715 
1716 **[11]** Memory resident information
1717 
1718 The resident() method returns:
1719         'D' disk resident
1720         'M' memory resident
1721         'S' shared memory resident
1722 If shared memory resident, the method sharedAreaName returns the name of the
1723 shared section (otherwise, it returns a blank Std::String).  If the Ntuple
1724 is not disk resident, either a circular buffer is being used, or demand
1725 strategy (where additional buffers are added as the Ntuple grows).
1726 
1727 **[12]** Column data type identification
1728 
1729 On a compliant compiler one could do
1730   type_info x = mytup.columnType_info(ncol);
1731   if ( x == typeid(double) ) doWhatever;
1732 
1733 The alternative we supply is
1734   ColumnData_t x = mytup.columnDataType(ncol);
1735   if ( x == ColumnData_FLOAT8 ) doWhatever;
1736 
1737 Actually, that alternative may be more than a kludge for the compliance-
1738 differently-abled, because our types (FLOAT8 vs FLOAT4 etc.) more directly
1739 correspond to the types used underneath, R*8, R*4 and so forth.
1740 
1741 **[13]** Fixed-length character strings
1742 
1743 These correspond to the HBOOK C*4, C*8, ... C*32 formats.  They are different
1744 than ordinary char arrays in at least two ways:
1745 
1746 - Even with columnwise storage, all 4 or 8 or ... or 32 bytes are stored
1747   together.
1748 - If there is any differnece in byte swap issues, the underlying manager will
1749   treat these as character strings and apply the proper swap for those.
1750 
1751 Arrays of columns of fixed-length character strings -- e.g., the concept
1752 expressed by the format string X:C*16(3,4) -- are not supported.
1753 
1754 By the way, what if you want a true array (of arbitrary length, perhaps with an
1755 index, maybe mulit-dimensional) of "integer*1" objects?  Then you don''t invoke
1756 characters(), you invoke dimension().
1757 
1758 The HBOOK implementation MAY NOT ??? ALLOW YOU TO MIX CHARACTER STD::STRINGS AND
1759 ORDINARY DATA IN THE SAME BLOCK.
1760 
1761 **[14]** Direct capture of arrays of columns
1762 
1763 Notice that although a 1-dimensional array can be defined without designated
1764 variables (the columnArray() method), multi-dimensional arrays will always have
1765 designated variables.  Nonetheless, the
1766         capture (const string& nametag, float values[])
1767 method allows Direct capture; but if designated variables were assigned for
1768 that column array, one should be careful not to capture the block later lest
1769 the directly captured values be over-written.
1770 
1771 **[15]** columnArray method for non-float data
1772 
1773 In this method the default value is not required if float data is to be used --
1774 the signature without defval assumes float and sets defval=0.  But for coulmns
1775 of int, double, or other non-float data, the default value must be supplied.
1776 And if a constant is supplied, the user must be careful that the constant
1777 is of the desired data type, as that is the only way the method caln tell what
1778 type of columns the user wants.
1779 
1780 Similarly, columnDirect() requires a default value if non-float data is to
1781 be used, and the user must be careful that this is of the desired data type.
1782 
1783 #endif /* COMMENT */
1784 
1785 #endif // Code Guard HEPNTUPLE_H
1786 

source navigation ] diff markup ] identifier search ] freetext search ] file search ]

This page was automatically generated by the LXR engine.
The LXR team
Valid HTML 4.01!

Send problems or questions to cdfcode@fnal.gov