+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * *
+ * Author: The ALICE Off-line Project. *
+ * Contributors are mentioned in the code where appropriate. *
+ * *
+ * Permission to use, copy, modify and distribute this software and its *
+ * documentation strictly for non-commercial purposes is hereby granted *
+ * without fee, provided that the above copyright notice appears in all *
+ * copies and that both the copyright notice and this permission notice *
+ * appear in the supporting documentation. The authors make no claims *
+ * about the suitability of this software for any purpose. It is *
+ * provided "as is" without express or implied warranty. *
+ **************************************************************************/
+
+/* $Header$ */
+
///////////////////////////////////////////////////////////////////////////////
// //
// Base class for ALICE modules. Both sensitive modules (detectors) and //
// //
//Begin_Html
/*
-<img src="gif/AliDetectorClass.gif">
+<img src="picts/AliDetectorClass.gif">
*/
//End_Html
// //
///////////////////////////////////////////////////////////////////////////////
+
+#include <assert.h>
+
+#include <TBrowser.h>
+#include <TFile.h>
+#include <TFolder.h>
+#include <TROOT.h>
+#include <TTree.h>
+#include <Riostream.h>
+
+#include "AliConfig.h"
#include "AliDetector.h"
-#include "AliRun.h"
#include "AliHit.h"
#include "AliPoints.h"
-#include <TClass.h>
-#include <TNode.h>
-#include <TRandom.h>
+#include "AliRun.h"
+#include "AliTrackReference.h"
+
// Static variables for the hit iterator routines
static Int_t sMaxIterHit=0;
static Int_t sCurIterHit=0;
+
ClassImp(AliDetector)
-//_____________________________________________________________________________
-AliDetector::AliDetector()
+//_______________________________________________________________________
+AliDetector::AliDetector():
+ fTimeGate(200.e-9),
+ fIshunt(0),
+ fNhits(0),
+ fNdigits(0),
+ fBufferSize(1600),
+ fHits(0),
+ fDigits(0),
+ fDigitsFile(0),
+ fPoints(0),
+ fTrackReferences(0),
+ fMaxIterTrackRef(0),
+ fCurrentIterTrackRef(0)
{
//
// Default constructor for the AliDetector class
//
- fNhits = 0;
- fNdigits = 0;
- fPoints = 0;
- fHits = 0;
- fDigits = 0;
- fTimeGate = 200.e-9;
- fBufferSize = 16000;
}
+//_______________________________________________________________________
+AliDetector::AliDetector(const AliDetector &det):
+ AliModule(det),
+ fTimeGate(200.e-9),
+ fIshunt(0),
+ fNhits(0),
+ fNdigits(0),
+ fBufferSize(1600),
+ fHits(0),
+ fDigits(0),
+ fDigitsFile(0),
+ fPoints(0),
+ fTrackReferences(0),
+ fMaxIterTrackRef(0),
+ fCurrentIterTrackRef(0)
+{
+ det.Copy(*this);
+}
+
//_____________________________________________________________________________
-AliDetector::AliDetector(const char* name,const char *title):AliModule(name,title)
+AliDetector::AliDetector(const char* name,const char *title):
+ AliModule(name,title),
+ fTimeGate(200.e-9),
+ fIshunt(0),
+ fNhits(0),
+ fNdigits(0),
+ fBufferSize(1600),
+ fHits(0),
+ fDigits(0),
+ fDigitsFile(0),
+ fPoints(0),
+ fTrackReferences(new TClonesArray("AliTrackReference", 100)),
+ fMaxIterTrackRef(0),
+ fCurrentIterTrackRef(0)
{
//
// Normal constructor invoked by all Detectors.
// Add this Detector to the global list of Detectors in Run.
//
- fTimeGate = 200.e-9;
fActive = kTRUE;
- fNhits = 0;
- fHits = 0;
- fDigits = 0;
- fNdigits = 0;
- fPoints = 0;
- fBufferSize = 16000;
+ AliConfig::Instance()->Add(this);
+
}
-//_____________________________________________________________________________
+//_______________________________________________________________________
AliDetector::~AliDetector()
{
//
// Destructor
//
- fNhits = 0;
- fNdigits = 0;
- //
+
// Delete space point structure
- if (fPoints) fPoints->Delete();
- delete fPoints;
- fPoints = 0;
+ if (fPoints) {
+ fPoints->Delete();
+ delete fPoints;
+ fPoints = 0;
+ }
+ // Delete digits structure
+ if (fDigits) {
+ fDigits->Delete();
+ delete fDigits;
+ fDigits = 0;
+ }
+ if (fDigitsFile) delete [] fDigitsFile;
}
-
-//_____________________________________________________________________________
+
+//_______________________________________________________________________
+void AliDetector::Publish(const char *dir, void *address, const char *name)
+{
+ //
+ // Register pointer to detector objects.
+ //
+ TFolder *topFolder = dynamic_cast<TFolder *>(gROOT->FindObjectAny("/Folders"));
+ if (topFolder) {
+ TFolder *folder = dynamic_cast<TFolder *>(topFolder->FindObjectAny(dir));
+ // TFolder *folder = dynamic_cast<TFolder *>(gROOT->FindObjectAny(dir));
+ if (!folder) {
+ cerr << "Cannot register: Missing folder: " << dir << endl;
+ } else {
+ TFolder *subfolder = dynamic_cast<TFolder *>(folder->FindObjectAny(this->GetName()));
+
+ if(!subfolder)
+ subfolder = folder->AddFolder(this->GetName(),this->GetTitle());
+ if (address) {
+ TObject **obj = static_cast<TObject **>(address);
+ if ((*obj)->InheritsFrom(TCollection::Class())) {
+ TCollection *collection = dynamic_cast<TCollection *>(*obj);
+ if (name)
+ collection->SetName(name);
+ }
+ subfolder->Add(*obj);
+ }
+ }
+ }
+}
+
+//_______________________________________________________________________
+TBranch* AliDetector::MakeBranchInTree(TTree *tree, const char* name,
+ void* address, Int_t size,
+ const char *file)
+{
+ return(MakeBranchInTree(tree,name,0,address,size,99,file));
+}
+
+//_______________________________________________________________________
+TBranch* AliDetector::MakeBranchInTree(TTree *tree, const char* name,
+ const char *classname,
+ void* address,Int_t size,
+ Int_t splitlevel, const char *file)
+{
+ //
+ // Makes branch in given tree and diverts them to a separate file
+ //
+ if (GetDebug()>1)
+ printf("* MakeBranch * Making Branch %s \n",name);
+
+ TDirectory *cwd = gDirectory;
+ TBranch *branch = 0;
+
+ if (classname) {
+ branch = tree->Branch(name,classname,address,size,splitlevel);
+ } else {
+ branch = tree->Branch(name,address,size);
+ }
+
+ if (file) {
+ char * outFile = new char[strlen(gAlice->GetBaseFile())+strlen(file)+2];
+ sprintf(outFile,"%s/%s",gAlice->GetBaseFile(),file);
+ branch->SetFile(outFile);
+ TIter next( branch->GetListOfBranches());
+ while ((branch=dynamic_cast<TBranch*>(next()))) {
+ branch->SetFile(outFile);
+ }
+ delete outFile;
+
+ cwd->cd();
+
+ if (GetDebug()>1)
+ printf("* MakeBranch * Diverting Branch %s to file %s\n",name,file);
+ }
+ const char *folder = 0;
+ TString folderName(name);
+
+ if (!strncmp(tree->GetName(),"TreeE",5)) folder = "RunMC/Event/Data";
+ if (!strncmp(tree->GetName(),"TreeK",5)) folder = "RunMC/Event/Data";
+ if (!strncmp(tree->GetName(),"TreeH",5)) {
+ folder = "RunMC/Event/Data/Hits";
+ folderName = "Hits" ;
+ }
+ if (!strncmp(tree->GetName(),"TreeTrackReferences",5)) {
+ folder = "RunMC/Event/Data/TrackReferences";
+ folderName = "TrackReferences" ;
+ }
+
+ if (!strncmp(tree->GetName(),"TreeD",5)) {
+ folder = "Run/Event/Data";
+ folderName = "Digits" ;
+ }
+ if (!strncmp(tree->GetName(),"TreeS",5)) {
+ folder = "RunMC/Event/Data/SDigits";
+ folderName = "SDigits" ;
+ }
+ if (!strncmp(tree->GetName(),"TreeR",5)) folder = "Run/Event/RecData";
+
+ if (folder) {
+ if (GetDebug())
+ printf("%15s: Publishing %s to %s\n",ClassName(),name,folder);
+ Publish(folder,address, folderName.Data());
+ }
+ return branch;
+}
+
+//_______________________________________________________________________
void AliDetector::Browse(TBrowser *b)
{
//
}
}
-//_____________________________________________________________________________
+//_______________________________________________________________________
+void AliDetector::Copy(AliDetector &) const
+{
+ //
+ // Copy *this onto det -- not implemented
+ //
+ Fatal("Copy","Not implemented\n");
+}
+
+//_______________________________________________________________________
void AliDetector::FinishRun()
{
//
//
}
-//_____________________________________________________________________________
+//_______________________________________________________________________
+void AliDetector::RemapTrackReferencesIDs(Int_t *map)
+{
+ //
+ // Remapping track reference
+ // Called at finish primary
+ //
+ if (!fTrackReferences) return;
+ for (Int_t i=0;i<fTrackReferences->GetEntries();i++){
+ AliTrackReference * ref = dynamic_cast<AliTrackReference*>(fTrackReferences->UncheckedAt(i));
+ if (ref) {
+ Int_t newID = map[ref->GetTrack()];
+ if (newID>=0) ref->SetTrack(newID);
+ else ref->SetTrack(-1);
+
+ }
+ }
+}
+
+//_______________________________________________________________________
AliHit* AliDetector::FirstHit(Int_t track)
{
//
//
sMaxIterHit=fHits->GetEntriesFast();
sCurIterHit=0;
- if(sMaxIterHit) return (AliHit*) fHits->UncheckedAt(0);
+ if(sMaxIterHit) return dynamic_cast<AliHit*>(fHits->UncheckedAt(0));
else return 0;
}
-//_____________________________________________________________________________
+
+//_______________________________________________________________________
+AliTrackReference* AliDetector::FirstTrackReference(Int_t track)
+{
+ //
+ // Initialise the hit iterator
+ // Return the address of the first hit for track
+ // If track>=0 the track is read from disk
+ // while if track<0 the first hit of the current
+ // track is returned
+ //
+ if(track>=0) {
+ gAlice->ResetTrackReferences();
+ gAlice->TreeTR()->GetEvent(track);
+ }
+ //
+ fMaxIterTrackRef = fTrackReferences->GetEntriesFast();
+ fCurrentIterTrackRef = 0;
+ if(fMaxIterTrackRef) return dynamic_cast<AliTrackReference*>(fTrackReferences->UncheckedAt(0));
+ else return 0;
+}
+
+//_______________________________________________________________________
AliHit* AliDetector::NextHit()
{
//
//
if(sMaxIterHit) {
if(++sCurIterHit<sMaxIterHit)
- return (AliHit*) fHits->UncheckedAt(sCurIterHit);
+ return dynamic_cast<AliHit*>(fHits->UncheckedAt(sCurIterHit));
else
return 0;
} else {
}
}
-//_____________________________________________________________________________
+//_______________________________________________________________________
+AliTrackReference* AliDetector::NextTrackReference()
+{
+ //
+ // Return the next hit for the current track
+ //
+ if(fMaxIterTrackRef) {
+ if(++fCurrentIterTrackRef<fMaxIterTrackRef)
+ return dynamic_cast<AliTrackReference*>(fTrackReferences->UncheckedAt(fCurrentIterTrackRef));
+ else
+ return 0;
+ } else {
+ printf("* AliDetector::NextTrackReference * TrackReference Iterator called without calling FistTrackReference before\n");
+ return 0;
+ }
+}
+
+//_______________________________________________________________________
void AliDetector::LoadPoints(Int_t)
{
//
//
if (fHits == 0) return;
//
- if (fPoints == 0) fPoints = new TObjArray(gAlice->GetNtrack());
Int_t nhits = fHits->GetEntriesFast();
if (nhits == 0) return;
+ Int_t tracks = gAlice->GetNtrack();
+ if (fPoints == 0) fPoints = new TObjArray(tracks);
AliHit *ahit;
//
+ Int_t *ntrk=new Int_t[tracks];
+ Int_t *limi=new Int_t[tracks];
+ Float_t **coor=new Float_t*[tracks];
+ for(Int_t i=0;i<tracks;i++) {
+ ntrk[i]=0;
+ coor[i]=0;
+ limi[i]=0;
+ }
+ //
AliPoints *points = 0;
- Int_t trko=-99, trk;
+ Float_t *fp=0;
+ Int_t trk;
+ Int_t chunk=nhits/4+1;
//
// Loop over all the hits and store their position
for (Int_t hit=0;hit<nhits;hit++) {
- ahit = (AliHit*)fHits->UncheckedAt(hit);
- if(trko!=(trk=ahit->GetTrack())) {
+ ahit = dynamic_cast<AliHit*>(fHits->UncheckedAt(hit));
+ trk=ahit->GetTrack();
+ assert(trk<=tracks);
+ if(ntrk[trk]==limi[trk]) {
//
// Initialise a new track
- trko=trk;
- points = new AliPoints(nhits);
- fPoints->AddAt(points,trk);
+ fp=new Float_t[3*(limi[trk]+chunk)];
+ if(coor[trk]) {
+ memcpy(fp,coor[trk],sizeof(Float_t)*3*limi[trk]);
+ delete [] coor[trk];
+ }
+ limi[trk]+=chunk;
+ coor[trk] = fp;
+ } else {
+ fp = coor[trk];
+ }
+ fp[3*ntrk[trk] ] = ahit->X();
+ fp[3*ntrk[trk]+1] = ahit->Y();
+ fp[3*ntrk[trk]+2] = ahit->Z();
+ ntrk[trk]++;
+ }
+ //
+ for(trk=0; trk<tracks; ++trk) {
+ if(ntrk[trk]) {
+ points = new AliPoints();
points->SetMarkerColor(GetMarkerColor());
- points->SetMarkerStyle(GetMarkerStyle());
points->SetMarkerSize(GetMarkerSize());
points->SetDetector(this);
points->SetParticle(trk);
+ points->SetPolyMarker(ntrk[trk],coor[trk],GetMarkerStyle());
+ fPoints->AddAt(points,trk);
+ delete [] coor[trk];
+ coor[trk]=0;
}
- points->SetPoint(hit,ahit->fX,ahit->fY,ahit->fZ);
}
+ delete [] coor;
+ delete [] ntrk;
+ delete [] limi;
}
-//_____________________________________________________________________________
-void AliDetector::MakeBranch(Option_t *option)
+//_______________________________________________________________________
+void AliDetector::MakeBranch(Option_t *option, const char *file)
{
//
// Create a new branch in the current Root Tree
// The branch of fHits is automatically split
//
+
char branchname[10];
sprintf(branchname,"%s",GetName());
//
// Get the pointer to the header
- char *H = strstr(option,"H");
+ const char *cH = strstr(option,"H");
//
- if (fHits && gAlice->TreeH() && H) {
- gAlice->TreeH()->Branch(branchname,&fHits, fBufferSize);
- printf("* AliDetector::MakeBranch * Making Branch %s for hits\n",branchname);
+ if (fHits && gAlice->TreeH() && cH) {
+ MakeBranchInTree(gAlice->TreeH(),
+ branchname, &fHits, fBufferSize, file) ;
}
+
+ const char *cD = strstr(option,"D");
+
+ if (cD) {
+ if (file) {
+ fDigitsFile = new char[strlen (file)];
+ strcpy(fDigitsFile,file);
+ }
+ }
+}
+//_______________________________________________________________________
+void AliDetector::MakeBranchTR(Option_t *option, const char *file)
+{
+ //
+ // Create a new branch in the current Root Tree
+ // The branch of fHits is automatically split
+ //
+
+ char branchname[10];
+ sprintf(branchname,"%s",GetName());
+ //
+ // Get the pointer to the header
+ const char *cTR = strstr(option,"T");
+ //
+ if (fTrackReferences && gAlice->TreeTR() && cTR) {
+ MakeBranchInTree(gAlice->TreeTR(),
+ branchname, &fTrackReferences, fBufferSize, file) ;
+ }
}
-//_____________________________________________________________________________
+//_______________________________________________________________________
void AliDetector::ResetDigits()
{
//
if (fDigits) fDigits->Clear();
}
-//_____________________________________________________________________________
+//_______________________________________________________________________
void AliDetector::ResetHits()
{
//
if (fHits) fHits->Clear();
}
-//_____________________________________________________________________________
+//_______________________________________________________________________
+void AliDetector::ResetTrackReferences()
+{
+ //
+ // Reset number of hits and the hits array
+ //
+ fMaxIterTrackRef = 0;
+ if (fTrackReferences) fTrackReferences->Clear();
+}
+
+//_______________________________________________________________________
void AliDetector::ResetPoints()
{
//
}
}
-//_____________________________________________________________________________
+//_______________________________________________________________________
void AliDetector::SetTreeAddress()
{
//
branch = treeD->GetBranch(branchname);
if (branch) branch->SetAddress(&fDigits);
}
-}
-//_____________________________________________________________________________
-void AliDetector::Streamer(TBuffer &R__b)
-{
- //
- // Stream an object of class Detector.
- //
- if (R__b.IsReading()) {
- Version_t R__v = R__b.ReadVersion(); if (R__v) { }
- TNamed::Streamer(R__b);
- TAttLine::Streamer(R__b);
- TAttMarker::Streamer(R__b);
- AliModule::Streamer(R__b);
- R__b >> fTimeGate;
- R__b >> fIshunt;
- //R__b >> fNhits;
- //
- // Stream the pointers but not the TClonesArrays
- R__b >> fHits; // diff
- R__b >> fDigits; // diff
-
- } else {
- R__b.WriteVersion(AliDetector::IsA());
- TNamed::Streamer(R__b);
- TAttLine::Streamer(R__b);
- TAttMarker::Streamer(R__b);
- AliModule::Streamer(R__b);
- R__b << fTimeGate;
- R__b << fIshunt;
- //R__b << fNhits;
- //
- // Stream the pointers but not the TClonesArrays
- R__b << fHits; // diff
- R__b << fDigits; // diff
+ // Branch address for tr tree
+ TTree *treeTR = gAlice->TreeTR();
+ if (treeTR && fTrackReferences) {
+ branch = treeTR->GetBranch(branchname);
+ if (branch) branch->SetAddress(&fTrackReferences);
}
}
+