]> git.uio.no Git - u/mrichter/AliRoot.git/blob - EVE/Alieve/TPCData.cxx
Functionality of defunct AliMpManuList is now in AliMpDetElement, filled from DDLStor...
[u/mrichter/AliRoot.git] / EVE / Alieve / TPCData.cxx
1 // $Header$
2
3 #include "TPCData.h"
4
5 #include <Alieve/TPCSectorData.h>
6
7 #include <AliSimDigits.h>
8 #include <AliTPCParam.h>
9 #include <AliTPCRawStream.h>
10 #include <TTree.h>
11
12 using namespace Reve;
13 using namespace Alieve;
14
15 //______________________________________________________________________
16 // TPCData
17 //
18 // A central manager for TPC data of an event.  Can read digits (from
19 // a tree: LoadDigits()) and raw-data (via AliRawReader: LoadRaw()).
20 //
21 // The sector data is stored in 36 TPCSectorData objects.
22 // Sectors 0 - 17: +z side, 18 - 35: -z side.
23 // No separation of inner/outer segments, use row numbers for addressing.
24 //
25 // Threshold application and pedestal subtraction can be performed at
26 // load time: use SetLoadThreshold(thresh) and SetLoadPedestal(ped).
27 //
28 // For raw-data (loaded using LoadRaw) pedestals can be calculated
29 // automatically per pad. Use SetAutoPedestal(kTRUE) to activate it. 
30 // You might still want to set load threshold (default iz zero).
31 //
32
33 ClassImp(TPCData)
34
35 TPCData::TPCData() :
36   fSectors(36), fSectorBlockSize(65536),
37   fLoadThreshold(0), fLoadPedestal(0), fAutoPedestal(kFALSE)
38 {
39   TPCSectorData::InitStatics();
40 }
41
42 TPCData::~TPCData()
43 {
44   DeleteAllSectors();
45 }
46
47 /**************************************************************************/
48
49 void TPCData::CreateSector(Int_t sector)
50 {
51   if(fSectors[sector] == 0)
52     fSectors[sector] = new TPCSectorData(sector, fSectorBlockSize);
53 }
54
55 void TPCData::CreateAllSectors()
56 {
57   for(Int_t s=0; s<36; ++s)
58     CreateSector(s);
59 }
60
61 void TPCData::DropAllSectors()
62 {
63   for(Int_t s=0; s<36; ++s) {
64     if(fSectors[s] != 0)
65       fSectors[s]->DropData();
66   }
67 }
68
69 void TPCData::DeleteAllSectors()
70 {
71   for(Int_t s=0; s<36; ++s) {
72     delete fSectors[s];
73     fSectors[s] = 0;
74   }
75 }
76
77 /**************************************************************************/
78
79 TPCSectorData* TPCData::GetSectorData(Int_t sector, Bool_t spawnSectors)
80 {
81   if(sector < 0 || sector > 35) return 0;
82   if(fSectors[sector] == 0 && spawnSectors)
83     CreateSector(sector);
84   return fSectors[sector];
85 }
86
87 /**************************************************************************/
88
89 void TPCData::LoadDigits(TTree* tree, Bool_t spawnSectors)
90 {
91   // Load data from TTree of AliSimDigits.
92   // If spawnSectors is false only sectors that have been created previously
93   // via CreateSector() are loaded.
94   // If spawnSectors is true sectors are created if data for them is encountered.
95
96   AliSimDigits digit, *digitPtr = &digit;
97   tree->GetBranch("Segment")->SetAddress(&digitPtr);
98   
99   Int_t sector, row, pad, curPad;
100   Short_t time, signal;
101   Bool_t  inFill = kFALSE;
102   TPCSectorData* secData = 0;
103
104   Int_t numEnt = (Int_t) tree->GetEntries();
105   for (Int_t ent=0; ent<numEnt; ent++) {
106     tree->GetEntry(ent);
107     Alieve::TPCSectorData::GetParam().AdjustSectorRow(digit.GetID(), sector, row);
108     if(sector >= 36) {
109       sector -= 36;
110       row    += TPCSectorData::GetInnSeg().GetNRows();
111     }
112     secData = GetSectorData(sector, spawnSectors);
113     if(secData == 0)
114       continue;
115
116     if(digit.First() == kFALSE)
117       continue;
118     curPad = -1;
119     do {
120       pad    = digit.CurrentColumn();
121       time   = digit.CurrentRow();
122       signal = digit.CurrentDigit();
123
124       if(pad != curPad) {
125         if(inFill)
126           secData->EndPad(fAutoPedestal, fLoadThreshold);
127         secData->BeginPad(row, pad, kFALSE);
128         curPad = pad;
129         inFill = kTRUE;
130       }
131       if(fAutoPedestal) {
132         secData->RegisterData(time, signal);
133       } else {
134         signal -= fLoadPedestal;
135         if(signal >= fLoadThreshold)
136           secData->RegisterData(time, signal);
137       }
138
139     } while (digit.Next());
140     if(inFill) {
141       secData->EndPad(fAutoPedestal, fLoadThreshold);
142       inFill = kFALSE;
143     }
144   }
145 }
146
147 void TPCData::LoadRaw(AliTPCRawStream& input, Bool_t spawnSectors, Bool_t warn)
148 {
149   // Load data from AliTPCRawStream.
150   // If spawnSectors is false only sectors that have been created previously
151   // via CreateSector() are loaded.
152   // If spawnSectors is true sectors are created if data for them is encountered.
153
154   static const Exc_t eH("TPCData::LoadRaw ");
155
156   Int_t   sector = -1, row = -1, pad = -1, rowOffset = 0;
157   Short_t time,  signal;
158   Bool_t  inFill   = kFALSE;
159   Short_t lastTime = 9999;
160   Bool_t  lastTimeWarn = kFALSE;
161   TPCSectorData* secData = 0;
162
163   Short_t threshold = fLoadThreshold;
164
165   while (input.Next()) {
166     if (input.IsNewSector()) {
167       if(inFill) {
168         secData->EndPad(fAutoPedestal, threshold);
169         inFill = kFALSE;
170       }
171       sector = input.GetSector();
172       if(sector >= 36) {
173         sector -= 36;
174         rowOffset = TPCSectorData::GetInnSeg().GetNRows();
175       } else {
176         rowOffset = 0;
177       }
178       secData = GetSectorData(sector, spawnSectors);
179     }
180     if (secData == 0)
181       continue;
182
183     if (input.IsNewPad()) {
184       if(inFill) {
185         secData->EndPad(fAutoPedestal, threshold);
186         inFill = kFALSE;
187       }
188       row = input.GetRow() + rowOffset;
189       pad = input.GetPad();
190
191       if(pad >= TPCSectorData::GetNPadsInRow(row)) {
192         if(warn) {
193           Warning(eH.Data(), "pad out of range (row=%d, pad=%d, maxpad=%d).",
194                   row, pad, TPCSectorData::GetNPadsInRow(row));
195         }
196         continue;
197       }
198
199       TPCSectorData::PadRowHack* prh = secData->GetPadRowHack(row, pad);
200       if(prh != 0) {
201         threshold = prh->fThrExt + Short_t(prh->fThrFac*fLoadThreshold);
202       } else {
203         threshold = fLoadThreshold;
204       }
205
206       secData->BeginPad(row, pad, kTRUE);
207       inFill   = kTRUE;
208       lastTime = 1024;  lastTimeWarn = kFALSE;
209     }
210
211     time   = input.GetTime();
212     signal = input.GetSignal();
213     if(time >= lastTime) {
214       if(lastTimeWarn == kFALSE) {
215         if(warn)
216           Warning(eH.Data(), "time out of order (row=%d, pad=%d, time=%d, lastTime=%d).",
217                   row, pad, time, lastTime);
218         lastTimeWarn = kTRUE;
219       }
220       continue;
221     }
222     lastTime = time;
223     if(fAutoPedestal) {
224       secData->RegisterData(time, signal);
225     } else {
226       signal -= fLoadPedestal;
227       if(signal > threshold)
228         secData->RegisterData(time, signal);
229     }
230   }
231
232   if(inFill) {
233     secData->EndPad(fAutoPedestal, threshold);
234     inFill = kFALSE;
235   }
236 }