ROOT logo
#pragma implementation
using namespace std;
#include <hcategory.h>
#include <hiterator.h>
#include <hdebug.h>
#include "hfilter.h"
#include <iostream> 
#include <iomanip>
#include <stdio.h>

//*-- Author : Manuel Sanchez manuel@fpddv1.usc.es
//*-- Modified : 25/09/98 by Manuel Sanchez
//*-- Modified : 29/02/00 by Denis Bertini
//*-- Copyright : GENP (Univ. Santiago de Compostela)

//_HADES_CLASS_DESCRIPTION 
////////////////////////////////////
//HCategory (ABC)
// 
//   The HCategory class is an abstract base class. So the real work is 
// made by the derived classes. These derived classes correspond to different
// strategies to store the data objects in memory and in file. The classes
// derived from HCategory can also indicate the way they want to be stored in
// a Root tree (the TBranch layout), for that purpose the makeBranch() function
// can be overloaded.
//
//   A HCategory encapsulates one category of data; that is one kind of data
// (mdc raw data,rich rings...), and it is responsible of giving the user 
// access to the objects held by that category. The category is also able to
// hold one header with common information for all the objects in the category.
//
//   The class provides functions to access the objects in the category:
//
//   Each data object in the category is stored in a particular location 
// (see HLocation), so to access an object you must give its location and use
// the method: getObject(HLocation &aLoc). This method returns one only object,
// if you want a collection with all the objects corresponding to a particular 
// location (i.e, all the raw data in the second chamber of the first sector...)
// then use query(TCollection *col,HLocation &aLoc) with col being the 
// collection where to store the result. You can also iterate on all the 
// objects in the category or the objects corresponding to a particular location
// using the HIterator created by MakeIterator() or MakeReverseIterator()
//
//   The category is also responsible of allocating new objects, this can be 
// done through the functions getSlot(HLocation &aLoc) and 
// getNewSlot(HLocation &aLoc)  which return a place in memory where to 
// allocate the new object (a slot) corresponding to the location aLoc. The
// strategy of letting the HCategory to manage the memory has the advantage 
// that it allows the category to have the memory preallocated.
//
//   Example:
//    {
//     HLocation loc; //Allocates loc pointing to a location
//     HMdcRaw *raw; //Declaration of a pointer to a TObject
//     HCategory *cat; //Pointer to a generic category
//     ...
//     //loc is set to point to the location (2,2,1); this could be something
//     //like: sector 2, mdc 2, plane 1.
//     loc.set(3,2,2,1); 
//     //Ask for the slot at location "loc" and stores its address in raw
//     //if there is not such a slot, the getSlot() method will return NULL
//     raw=cat->getSlot(loc);
//     //If we have a valid slot (raw!=NULL) then allocate a new object of
//     //class HMdcRaw at the addres given by raw using the operator 
//     //"new with placement" 
//     if (raw!=NULL) raw=new(raw) HMdcRaw;
//    }
//     
//   Each category can be persistent or not; so if it's persistent it
// will be stored in the output file (if any) and if it's not, then it won't
// be stored in the output file. To control the persistency of a category
// the setPersistency() method is provided
//
//   Here follows a description of the common methods every class inherited 
// from HCategory provides:
//
//  TObject *&getNewSlot(HLocation &aLoc)
//    Returns a memory slot for location aLoc where you can place a new object
//   aLoc gives the indexes for the location of the new object except the last 
//   one. So the function returns the first empty slot in aLoc.
//
//  TObject *&getSlot(HLocation &aLoc)
//     The same as before, but now aLoc gives the complete location of the new
//    object 
//  TObject *getObject(HLocation &aLoc)
//    Returns the object at the location aLoc
//  
//  TClonesArray *getClones(HLocation &aLoc)
//    Returns a clones array with the objects corresponding to the HLocation 
//    aLoc.
//
//  Bool_t query(TCollection *aCol,HLocation &aLoc,HFilter &aFilter)
//    Adds to aCol all objects in the category corresponding to the location 
//    aLoc and passing the filter aFilter. There are also functions without 
//    aFilter or without aLoc
//
//  Bool_t filter(HLocation &aLoc,HFilter &aFilter)
//  Bool_t filter(HFilter &aFilter)
//    The same as before but now the objects not verifying the conditions are 
//   deleted off the category
//
////////////////////////////////

ClassImp(HCategory)

 TObject *gNullObjectP = 0;

HCategory::HCategory(void)
{
  //Default constructor 
 fCat=catInvalid;
 fBranchingLevel=0;
 fPersistency=kTRUE;
 fHeader = 0;
}

HCategory::~HCategory(void) {
  //Destructor. 
}

void HCategory::activateBranch(TTree *tree,Int_t splitLevel) {
  // If a category generates its own branches in a different way than that
  //provided with HTree::makeBranch (see isSelfSplitable()) then it must 
  //override the makeBranch function as well as the activateBranch function..
  //
  // The activate branch is intended to activate those branches in the TTree
  //tree whose names correspond to the names of the branches that would be 
  //created by makeBranch() in this category. To do such a thing the Root 
  //methods: TTree::SetBranchAddress() and TTree::SetBranchStatus() need to
  //be called.
  //
  // As a default activateBranch() does nothing
#if DEBUG_LEVEL>2
  gDebuger->enterFunc("HCategory::activateBranch");
#endif
  if (tree==NULL) Warning("HCategory::activateBranch","tree is NULL");
  if (splitLevel<0) Warning("HCategory::activateBranch","invalid split level");
#if DEBUG_LEVEL>2
  gDebuger->leaveFunc("HCategory::activateBranch");
#endif
}

void HCategory::setBranchingLevel(Int_t nLevel) {
  //Sets the branching level.
  //
  // The branching level is directly related with the number of indexes needed
  //to identify an object in the category (the number of indexes in the object's
  //location). For example, in the HMatrixCategory those two numbers are equal;
  //however in HSplitCategory the branching level is equal to the number of
  //indexes needed to unambiguosly identify an object in the category minus 1.
 fBranchingLevel=nLevel;
}

void HCategory::setCategory(Cat_t aCat) {
  //Sets the identifier for this particular category
 fCat=aCat;
}

Cat_t HCategory::getCategory(void) {
  //Returns the identifier of this particular category
 return fCat;
}

Int_t HCategory::getBranchingLevel(void) {
  //Returns the branching level for this category.
  //
  // The branching level is directly related with the number of indexes needed
  //to identify an object in the category (the number of indexes in the object's
  //location). For example, in the HMatrixCategory those two numbers are equal;
  //however in HSplitCategory the branching level is equal to the number of
  //indexes needed to unambiguosly identify an object in the category minus 1.
 return fBranchingLevel;
}

Bool_t HCategory::IsPersistent(void) {
  //Returns kTRUE if the category is persistent and kFALSE if it is not.
  return fPersistency;
}

void HCategory::setPersistency(Bool_t per) {
  // Sets the persistency of the category
  //
  // Input:
  //   per=kTRUE  --> The category is persistent
  //   per=kFALSE --> The category is not persistent.
  fPersistency=per;
}

Bool_t HCategory::IsFolder(void) const {
  return kTRUE;
}

TIterator *HCategory::MakeReverseIterator(void) {
  //Makes an HIterator which iterates backwards
  return MakeIterator("catIter",kIterBackward);
}

Bool_t HCategory::query(TCollection *aCol,HFilter &aFilter) {
  // Stores in the collection aCol pointers to all the objects in the category
  //verifying the condition given by the filter aFilter.
  //
  // Returns kTRUE if everything works Ok, kFALSE in other case
  HIterator *iter=(HIterator *)MakeIterator();
  TObject *data=NULL;
  iter->Reset();
  while ( (data=(TObject *)iter->Next())!=NULL) {
    if (aFilter.check(data)) aCol->Add(data);
  }
  return kTRUE;
}

Bool_t HCategory::query(TCollection *aCol,HLocation &aLoc) {
  // Stores in the collection aCol pointers to all the objects in the category
  //corresponding to the location aLoc.
  //
  // Returns kTRUE if everything works Ok, kFALSE in other case
  HIterator *iter=(HIterator *)MakeIterator();
  TObject *data=NULL;
  iter->gotoLocation(aLoc);
  while ( (data=(TObject *)iter->Next())!=NULL) {
    aCol->Add(data);
  }
  return kTRUE;
}

Bool_t HCategory::query(TCollection *aCol,HLocation &aLoc,HFilter &aFilter) {
  // Stores in the collection aCol pointers to all the objects in the category
  //verifying the condition given by the filter aFilter and corresponding to 
  //the location aLoc
  //
  // Returns kTRUE if everything works Ok, kFALSE in other case.
  HIterator *iter=(HIterator *)MakeIterator();
  TObject *data=NULL;
  iter->gotoLocation(aLoc);
  while ( (data=(TObject *)iter->Next())!=NULL) {
    if (aFilter.check(data)) aCol->Add(data);
  }
  return kTRUE;
}

const Text_t *HCategory::getClassName(void) {
  AbstractMethod("getClassName");
  return "";
}

void HCategory::makeBranch(TBranch *parent) { 
  AbstractMethod("makeBranch"); 
}

TObject *&HCategory::getNewSlot(HLocation &aLoc,Int_t* pIndex) { 
  AbstractMethod("getNewSlot");
  return gNullObjectP;
}

TObject *&HCategory::getSlot(HLocation &aLoc,Int_t* pIndex) {
  AbstractMethod("getSlot");
  return gNullObjectP;
}

TObject *HCategory::getObject(HLocation &aLoc) {
  AbstractMethod("getObject");
  return 0;
}

Bool_t HCategory::filter(HFilter &aFilter) {
  AbstractMethod("filter");
  return kFALSE;
}

Bool_t HCategory::filter(HLocation &aLoc,HFilter &aFilter) {
  AbstractMethod("filter");
  return kFALSE;
}

void HCategory::Clear(Option_t *opt) {
  AbstractMethod("Clear");
}

Bool_t HCategory::isSelfSplitable(void) {
  AbstractMethod("isSelfSplitable");
  return kFALSE;
}

TIterator *HCategory::MakeIterator(Option_t *opt, Bool_t dir) {
  AbstractMethod("MakeIterator");
  return 0;
}

void HCategory::Streamer(TBuffer &R__b)
{
   // Stream an object of class HCategory.
   Bool_t temp; 
   if (R__b.IsReading()) {
      Version_t R__v = R__b.ReadVersion(); if (R__v) { }
      TObject::Streamer(R__b);
      if (R__v<2) R__b >> temp;
      R__b >> fCat;
      R__b >> fBranchingLevel;
      R__b >> fHeader;
   } else {
      R__b.WriteVersion(HCategory::IsA());
      TObject::Streamer(R__b);
//      R__b << fPersistency;
      R__b << fCat;
      R__b << fBranchingLevel;
      R__b << fHeader;
   }
}


 hcategory.cc:1
 hcategory.cc:2
 hcategory.cc:3
 hcategory.cc:4
 hcategory.cc:5
 hcategory.cc:6
 hcategory.cc:7
 hcategory.cc:8
 hcategory.cc:9
 hcategory.cc:10
 hcategory.cc:11
 hcategory.cc:12
 hcategory.cc:13
 hcategory.cc:14
 hcategory.cc:15
 hcategory.cc:16
 hcategory.cc:17
 hcategory.cc:18
 hcategory.cc:19
 hcategory.cc:20
 hcategory.cc:21
 hcategory.cc:22
 hcategory.cc:23
 hcategory.cc:24
 hcategory.cc:25
 hcategory.cc:26
 hcategory.cc:27
 hcategory.cc:28
 hcategory.cc:29
 hcategory.cc:30
 hcategory.cc:31
 hcategory.cc:32
 hcategory.cc:33
 hcategory.cc:34
 hcategory.cc:35
 hcategory.cc:36
 hcategory.cc:37
 hcategory.cc:38
 hcategory.cc:39
 hcategory.cc:40
 hcategory.cc:41
 hcategory.cc:42
 hcategory.cc:43
 hcategory.cc:44
 hcategory.cc:45
 hcategory.cc:46
 hcategory.cc:47
 hcategory.cc:48
 hcategory.cc:49
 hcategory.cc:50
 hcategory.cc:51
 hcategory.cc:52
 hcategory.cc:53
 hcategory.cc:54
 hcategory.cc:55
 hcategory.cc:56
 hcategory.cc:57
 hcategory.cc:58
 hcategory.cc:59
 hcategory.cc:60
 hcategory.cc:61
 hcategory.cc:62
 hcategory.cc:63
 hcategory.cc:64
 hcategory.cc:65
 hcategory.cc:66
 hcategory.cc:67
 hcategory.cc:68
 hcategory.cc:69
 hcategory.cc:70
 hcategory.cc:71
 hcategory.cc:72
 hcategory.cc:73
 hcategory.cc:74
 hcategory.cc:75
 hcategory.cc:76
 hcategory.cc:77
 hcategory.cc:78
 hcategory.cc:79
 hcategory.cc:80
 hcategory.cc:81
 hcategory.cc:82
 hcategory.cc:83
 hcategory.cc:84
 hcategory.cc:85
 hcategory.cc:86
 hcategory.cc:87
 hcategory.cc:88
 hcategory.cc:89
 hcategory.cc:90
 hcategory.cc:91
 hcategory.cc:92
 hcategory.cc:93
 hcategory.cc:94
 hcategory.cc:95
 hcategory.cc:96
 hcategory.cc:97
 hcategory.cc:98
 hcategory.cc:99
 hcategory.cc:100
 hcategory.cc:101
 hcategory.cc:102
 hcategory.cc:103
 hcategory.cc:104
 hcategory.cc:105
 hcategory.cc:106
 hcategory.cc:107
 hcategory.cc:108
 hcategory.cc:109
 hcategory.cc:110
 hcategory.cc:111
 hcategory.cc:112
 hcategory.cc:113
 hcategory.cc:114
 hcategory.cc:115
 hcategory.cc:116
 hcategory.cc:117
 hcategory.cc:118
 hcategory.cc:119
 hcategory.cc:120
 hcategory.cc:121
 hcategory.cc:122
 hcategory.cc:123
 hcategory.cc:124
 hcategory.cc:125
 hcategory.cc:126
 hcategory.cc:127
 hcategory.cc:128
 hcategory.cc:129
 hcategory.cc:130
 hcategory.cc:131
 hcategory.cc:132
 hcategory.cc:133
 hcategory.cc:134
 hcategory.cc:135
 hcategory.cc:136
 hcategory.cc:137
 hcategory.cc:138
 hcategory.cc:139
 hcategory.cc:140
 hcategory.cc:141
 hcategory.cc:142
 hcategory.cc:143
 hcategory.cc:144
 hcategory.cc:145
 hcategory.cc:146
 hcategory.cc:147
 hcategory.cc:148
 hcategory.cc:149
 hcategory.cc:150
 hcategory.cc:151
 hcategory.cc:152
 hcategory.cc:153
 hcategory.cc:154
 hcategory.cc:155
 hcategory.cc:156
 hcategory.cc:157
 hcategory.cc:158
 hcategory.cc:159
 hcategory.cc:160
 hcategory.cc:161
 hcategory.cc:162
 hcategory.cc:163
 hcategory.cc:164
 hcategory.cc:165
 hcategory.cc:166
 hcategory.cc:167
 hcategory.cc:168
 hcategory.cc:169
 hcategory.cc:170
 hcategory.cc:171
 hcategory.cc:172
 hcategory.cc:173
 hcategory.cc:174
 hcategory.cc:175
 hcategory.cc:176
 hcategory.cc:177
 hcategory.cc:178
 hcategory.cc:179
 hcategory.cc:180
 hcategory.cc:181
 hcategory.cc:182
 hcategory.cc:183
 hcategory.cc:184
 hcategory.cc:185
 hcategory.cc:186
 hcategory.cc:187
 hcategory.cc:188
 hcategory.cc:189
 hcategory.cc:190
 hcategory.cc:191
 hcategory.cc:192
 hcategory.cc:193
 hcategory.cc:194
 hcategory.cc:195
 hcategory.cc:196
 hcategory.cc:197
 hcategory.cc:198
 hcategory.cc:199
 hcategory.cc:200
 hcategory.cc:201
 hcategory.cc:202
 hcategory.cc:203
 hcategory.cc:204
 hcategory.cc:205
 hcategory.cc:206
 hcategory.cc:207
 hcategory.cc:208
 hcategory.cc:209
 hcategory.cc:210
 hcategory.cc:211
 hcategory.cc:212
 hcategory.cc:213
 hcategory.cc:214
 hcategory.cc:215
 hcategory.cc:216
 hcategory.cc:217
 hcategory.cc:218
 hcategory.cc:219
 hcategory.cc:220
 hcategory.cc:221
 hcategory.cc:222
 hcategory.cc:223
 hcategory.cc:224
 hcategory.cc:225
 hcategory.cc:226
 hcategory.cc:227
 hcategory.cc:228
 hcategory.cc:229
 hcategory.cc:230
 hcategory.cc:231
 hcategory.cc:232
 hcategory.cc:233
 hcategory.cc:234
 hcategory.cc:235
 hcategory.cc:236
 hcategory.cc:237
 hcategory.cc:238
 hcategory.cc:239
 hcategory.cc:240
 hcategory.cc:241
 hcategory.cc:242
 hcategory.cc:243
 hcategory.cc:244
 hcategory.cc:245
 hcategory.cc:246
 hcategory.cc:247
 hcategory.cc:248
 hcategory.cc:249
 hcategory.cc:250
 hcategory.cc:251
 hcategory.cc:252
 hcategory.cc:253
 hcategory.cc:254
 hcategory.cc:255
 hcategory.cc:256
 hcategory.cc:257
 hcategory.cc:258
 hcategory.cc:259
 hcategory.cc:260
 hcategory.cc:261
 hcategory.cc:262
 hcategory.cc:263
 hcategory.cc:264
 hcategory.cc:265
 hcategory.cc:266
 hcategory.cc:267
 hcategory.cc:268
 hcategory.cc:269
 hcategory.cc:270
 hcategory.cc:271
 hcategory.cc:272
 hcategory.cc:273
 hcategory.cc:274
 hcategory.cc:275
 hcategory.cc:276
 hcategory.cc:277
 hcategory.cc:278
 hcategory.cc:279
 hcategory.cc:280
 hcategory.cc:281
 hcategory.cc:282
 hcategory.cc:283
 hcategory.cc:284
 hcategory.cc:285
 hcategory.cc:286
 hcategory.cc:287
 hcategory.cc:288
 hcategory.cc:289
 hcategory.cc:290
 hcategory.cc:291
 hcategory.cc:292
 hcategory.cc:293
 hcategory.cc:294
 hcategory.cc:295
 hcategory.cc:296
 hcategory.cc:297
 hcategory.cc:298
 hcategory.cc:299
 hcategory.cc:300
 hcategory.cc:301
 hcategory.cc:302
 hcategory.cc:303
 hcategory.cc:304
 hcategory.cc:305
 hcategory.cc:306
 hcategory.cc:307
 hcategory.cc:308
 hcategory.cc:309
 hcategory.cc:310