#pragma implementation
using namespace std;
#include "hpartialevent.h"

#include "hades.h"
#include "hmatrixcategory.h"
#include "htree.h"
#include <TBrowser.h>
#include <TBuffer.h>
#include <TClass.h>
#include <stdlib.h>
#include <TROOT.h>
#include "hdebug.h"
#include <iostream> 
#include <iomanip>

//*-- Author : Manuel Sanchez
//*-- Modified : 20/01/2002 by Manuel Sanchez
//*-- Modified : 16/06/2000 by R. Holzmann
//*-- Modified : 7/10/98 by Manuel Sanchez
//*-- Modified : 16/04/98 9:17 by Manuel Sanchez 
//*-- Copyright : GENP (Univ. Santiago de Compostela)

//_HADES_CLASS_DESCRIPTION 
/////////////////////////////////////////////////
//HPartialEvent 
//(UML Diagram) //

// 
//   Each partial events holds the data (i.e. the HDataObjects) corresponding 
// to each main detection system; like Mdcs, Rich...
//
//   These data in a partial event are organized in categories, which stand
// for the different types of data in the partial event. For example, in the
// partial event for the Mdcs there will be a category holding the objects with
// raw data (i.e. the objects instatiating a HMdcRaw). So conceptually the
// categories are "kind of data" and they hold the objects of a particular
// kind (instatiating a particular class).
//
//   The categories are the responsible of giving access to the objects they 
// hold (see HCategory), but a partial event must also allow the user to 
// access the data stored into it; that's done using the function getCategory()
// which returns a particular category, so the user can ask that category for
// the data object he wants. For example, let's say we have a HLocation object
// loc pointing to any location, and a HPartialEvent par with the Mdc's data; 
// if we want to get the raw data object pointed by loc we should use:
//
//    par->getCategory(catMdcRaw)->getObject(loc);
//
//    And this function will return the pursued data object.
//
//////////////////////////////////////////////////////////////////////////

ClassImp(HPartialEvent)

 HPartialEvent::HPartialEvent(void) {
  //Default constructor
  fHeader=NULL;
  fRecLevel=1;
  fCategories=new TObjArray(32);
  setExpandedStreamer(kFALSE);
}

 HPartialEvent::HPartialEvent(const Text_t *aName,
			     const Text_t *aTitle,
			     Cat_t aBaseCat) : HEvent(aName,aTitle) 
{
  //Allocates a new HPartial event with name aName and title aTitle
  //
  // aBaseCat is the identifier of the lower category that will be stored in
  // this partial event, for example: if the user wants to allocate a partial
  // event holding the Mdc data, then aBaseCat should be: catMdc; which is a
  // constant defined in HadDef.h
  fHeader=NULL;
  fBaseCategory=aBaseCat;
  fRecLevel=rlRaw;
  fCategories=new TObjArray(32);
  setExpandedStreamer(kFALSE);
}
   
 HPartialEvent::~HPartialEvent(void) {
  //Clears the event 
 if (fCategories) {
   fCategories->Delete();
   delete fCategories;
 }
}

 void HPartialEvent::activateBranch(TTree *tree,Int_t splitLevel) {
  // Activates those branches in the TTree tree whose names are equal to those
  //of the branches that would be generated with the current event structure if
  //the function makeBranch() is called, being the split level=splitLevel
  //
  // This way if we have a TTree with a lot of branches and we only need some
  //of them to fill data in the event structure we are using at a given moment,
  //then we only activate those branches and the others are not read
  TString cad;
  Text_t name[255];
  
#if DEBUG_LEVEL>2
  gDebuger->enterFunc("HPartialEvent::activateBranch");
#endif
  if (fCategories) {
    if (splitLevel==2) {
      TObjArray &vector=*fCategories;
      HCategory **cat;
      Int_t i;
      TBranch *brHead=0;
      TBranch *brCategory=0;

      for (i=0;i<=vector.GetLast();i++) {
	cat=(HCategory **)&vector[i];
	if ( (*cat)!=NULL && ((*cat)->IsPersistent())) {
	  if ( (*cat)->isSelfSplitable()) 
	    (*cat)->activateBranch(tree,splitLevel);
	  else {
	    cad=(*cat)->getClassName();
	    cad += ".";
	    brCategory = tree->GetBranch(cad.Data());
	    if (brCategory) { //Post ROOT3 splitting
	      tree->SetBranchAddress(cad.Data(),cat);
	      (*cat)->activateBranch(tree,splitLevel);
	      tree->SetBranchStatus(cad.Data(),1);
	      cad=(*cat)->getClassName(); cad+="*";
	      tree->SetBranchStatus(cad.Data(),1);
	    } else {
	      cad=(*cat)->getClassName();
	      brCategory = tree->GetBranch(cad.Data());
	      if (brCategory) { //Pre ROOT3 splitting
		tree->SetBranchAddress(cad.Data(),cat);
		(*cat)->activateBranch(tree,splitLevel);
		tree->SetBranchStatus(cad.Data(),1);
		cad=(*cat)->getClassName(); cad+=".*";
		tree->SetBranchStatus(cad.Data(),1);
	      } else {
		Warning("activateBranch","Category %s not found in tree",
			cad.Data());
	      }
	    }
    	  }
	}
      }
      sprintf(name,"%s.Header",GetName());
      brHead=tree->GetBranch(name);
      if (brHead) { //Pre ROOT3 splitting
	tree->SetBranchAddress(name,&fHeader);
	tree->SetBranchStatus(name,1);
      }
    }
  }
#if DEBUG_LEVEL>2
  gDebuger->leaveFunc("return HPartialEvent::activateBranch");
#endif
}
 
 void HPartialEvent::makeBranch(TBranch *parent) { 
  // Makes branches for each category in the partial event and for the split
  //tree, then those branches are added to the list of subbranches of "parent"
  //
  // This method is called by Hades::makeTree() 
  TBranch *b=NULL;
  TString cad;
  Text_t name[255];

  if (fCategories) {
    if (gHades->getSplitLevel()==2) {
      TObjArray &vector=*fCategories;
      HCategory **cat;
      Int_t i;
      for (i=0;i<=vector.GetLast();i++) {
	cat=(HCategory **)&vector[i];
	if ( (*cat)!=NULL && ((*cat)->IsPersistent())) {
	  if ( (*cat)->isSelfSplitable()) {
	    b=gHades->getTree()->Branch((*cat)->getClassName(),
					    (*cat)->ClassName(),
					    cat,gHades->getTreeBufferSize(),0);
	    //parent->GetListOfBranches()->Add(b);
	    //(*cat)->makeBranch(b);
	  } else {
	    sprintf(name,"%s.",(*cat)->getClassName());
	    b=gHades->getTree()->Branch(name,
					    (*cat)->ClassName(),
					    cat,gHades->getTreeBufferSize(),99);
	    //parent->GetListOfBranches()->Add(b);
	  }
	}
      }
 
//       cout << fName->Data() << " " << fHeader << endl;
//       if (fHeader) {
// 	sprintf(name,"%s_fHeader.",fName->Data());
// 	gHades->getTree()->Branch(name,fHeader->ClassName(),&fHeader,4000);
//       }
    }
  }
  //  if (fHeader && gHades->getTree()) {
  //    sprintf(name,"%s.Header",GetName());
  //    b=gHades->getTree()->Branch(name,fHeader->IsA()->GetName(),&fHeader,4000,1);
  //    if (b) parent->GetListOfBranches()->Add(b);
  //  }
}

 Bool_t HPartialEvent::addCategory(Cat_t aCat,HCategory *cat,Option_t *) {
  // Adds the category "cat", identified by "aCat" to the partial event.
  addCategory(aCat,cat);
  return kTRUE;
}

 void HPartialEvent::addCategory(Cat_t aCat,HCategory *category) {
  // Adds the category "category", which is identified by aCat, to the partial
  //event
  //
  // Before using this function the user should setup the HCategory "category"
  //
#if DEBUG_LEVEL>2
  gDebuger->enterFunc("HPartialEvent::addCategory");
#endif
  fCategories->AddAtAndExpand(category,aCat-fBaseCategory);
  category->setCategory(aCat);
#if DEBUG_LEVEL>2
  gDebuger->leaveFunc("HPartialEvent::addCategory");
#endif
}

 Bool_t HPartialEvent::removeCategory(Cat_t aCat) {
  //Removes the category aCat from this partial event and deletes it.
  HCategory *category=0;
  category=(HCategory *)fCategories->At(aCat-fBaseCategory);
  if (category==0) return kFALSE;
  fCategories->RemoveAt(aCat-fBaseCategory);
  delete category;
  return kTRUE;
}

 TObjArray *HPartialEvent::getCategories(void) {
  // Returns an array with all the categories held by this event
  //
  // To add categories to the partial event use HPartialEvent::addCategory()
  return fCategories;
}

 HCategory *HPartialEvent::getCategory(Cat_t aCat) {
  // Returns a pointer to the category identified by "aCat"
  HCategory *cat;
  cat=(HCategory *)fCategories->At(aCat-fBaseCategory);
  return cat;
}
      
 void HPartialEvent::Clear(Option_t *) {
  // Clears the partial event,i.e. deletes all objects in the partial event
  //but keeping its structure.
  //
  // After the reconstruction of each event, the HEvent::Clear function must
  //be called in order to make place for the new data. 
 TIter nextCat(fCategories);
 HCategory *cat;

 while ((cat=(HCategory *)nextCat())!=NULL) {
    cat->Clear();
 }
}

 void HPartialEvent::clearAll(Int_t level) {
  //See HEvent
  if (level>1) {
    Clear();
  } else {
    if (fCategories) fCategories->Delete();
  }
}

 void HPartialEvent::setRecLevel(Int_t aRecLevel) {
  // Sets the reconstruction level of the event, this is useful to know which
  //categories in the event are already reconstructed.
  fRecLevel=aRecLevel;
}

 void HPartialEvent::setPersistency(Bool_t fPersistency) {
  Int_t nCat = fCategories->GetEntriesFast();
  for (Int_t i=0; i<nCat; i++) { // loop over categories
    HCategory* cat = (HCategory*)(fCategories->At(i));
    if (cat) cat->HCategory::setPersistency(fPersistency);
  }  
}

 Int_t HPartialEvent::getRecLevel(void) {
  // Returns the reconstruction level of the partial event.
  return fRecLevel;
}

 void HPartialEvent::Browse(TBrowser *b) {
  // Method used to browse a partial event with a Root browser.
  //
  // This function will be called by a Root browser, not by the user
  if (!fCategories) return;
  TIter next(fCategories);
  HCategory *cat;

  while ((cat=(HCategory *)next())!=NULL) {
     if (cat->InheritsFrom("HSplitCategory")) b->Add(cat,cat->getClassName());
     else cat->Browse(b);
  }
}

 void HPartialEvent::Streamer(TBuffer &R__b)
{
  // Stream an object of class HPartialEvent.
  TObjArray *catNames=0;
  Int_t nCategories=0;
  HCategory *category=0;
  char buffer[255];

  if (R__b.IsReading()) {
    Version_t R__v = R__b.ReadVersion(); if (R__v) { }
    HEvent::Streamer(R__b);
    R__b >> fRecLevel;
    R__b >> fBaseCategory;
    R__b >> fHeader;
    if (R__v == 2 && !hasExpandedStreamer() ) {
      if (fCategories) fCategories->Delete();
      R__b >> fCategories;
    } else {
      R__b >> catNames;
      nCategories=catNames->GetEntriesFast();
      for (Int_t i=0;i<nCategories;i++) {
	if (catNames->At(i)!=NULL) {
	  strcpy(buffer,((TObjString *)catNames->At(i))->GetString().Data());
	  if (gROOT->GetClass(buffer)) {
	    category=(HCategory *)gDirectory->Get(buffer);
	    fCategories->AddAtAndExpand(category,i);
	  }
	}
      }
      delete catNames;
    }
  } else {
    R__b.WriteVersion(HPartialEvent::IsA());
    HEvent::Streamer(R__b);
    R__b << fRecLevel;
    R__b << fBaseCategory;
    R__b << fHeader;
    if (!hasExpandedStreamer()) {
      R__b << fCategories;
    } else {
      nCategories=fCategories->GetEntriesFast(); 
      catNames=new TObjArray(nCategories);
      for (Int_t i=0;i<nCategories;i++) {
	category=(HCategory *)fCategories->At(i);
	if (category) { 
	 if (category->IsPersistent())
	  catNames->AddAt(new TObjString(category->getClassName()),i);
	}
      }
      R__b << catNames;
      for (Int_t i=0;i<nCategories;i++) { 
	category=(HCategory *)fCategories->At(i);
	if (category) { 
	  if (category->IsPersistent())
	    category->Write(category->getClassName());
	}
      }
      delete catNames;
    }
  }
}  



ROOT page - Class index - Class Hierarchy - Top of the page

This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.