2 // Main authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007
4 /**************************************************************************
5 * Copyright(c) 1998-2008, ALICE Experiment at CERN, all rights reserved. *
6 * See http://aliceinfo.cern.ch/Offline/AliRoot/License.html for *
7 * full copyright notice. *
8 **************************************************************************/
10 #include "AliEveTPCData.h"
12 #include <EveDet/AliEveTPCSectorData.h>
14 #include <AliSimDigits.h>
15 #include <AliTPCParam.h>
16 #include <AliTPCRawStreamV3.h>
19 //==============================================================================
20 //==============================================================================
22 //==============================================================================
24 //______________________________________________________________________________
26 // A central manager for TPC data of an event. Can read digits (from
27 // a tree: LoadDigits()) and raw-data (via AliRawReader: LoadRaw()).
29 // The sector data is stored in 36 AliEveTPCSectorData objects.
30 // Sectors 0 - 17: +z side, 18 - 35: -z side.
31 // No separation of inner/outer segments, use row numbers for addressing.
33 // Threshold application and pedestal subtraction can be performed at
34 // load time: use SetLoadThreshold(thresh) and SetLoadPedestal(ped).
36 // For raw-data (loaded using LoadRaw) pedestals can be calculated
37 // automatically per pad. Use SetAutoPedestal(kTRUE) to activate it.
38 // You might still want to set load threshold (default iz zero).
41 ClassImp(AliEveTPCData)
43 AliEveTPCData::AliEveTPCData() :
44 fSectors(36), fSectorBlockSize(65536),
45 fLoadThreshold(0), fLoadPedestal(0), fAutoPedestal(kFALSE)
49 AliEveTPCSectorData::InitStatics();
52 AliEveTPCData::~AliEveTPCData()
54 // Destructor, deletes all sector-data.
59 /******************************************************************************/
61 void AliEveTPCData::CreateSector(Int_t sector)
63 // Create sector-data for sector if it does not exist already.
65 if (fSectors[sector] == 0)
66 fSectors[sector] = new AliEveTPCSectorData(sector, fSectorBlockSize);
69 void AliEveTPCData::CreateAllSectors()
71 // Create all 36 sectors.
73 for (Int_t s=0; s<36; ++s)
77 void AliEveTPCData::DropAllSectors()
79 // Drop data of all existing sectors.
81 for (Int_t s=0; s<36; ++s) {
83 fSectors[s]->DropData();
87 void AliEveTPCData::DeleteAllSectors()
89 // Delete all sector-data.
91 for (Int_t s=0; s<36; ++s) {
97 /******************************************************************************/
99 AliEveTPCSectorData* AliEveTPCData::GetSectorData(Int_t sector, Bool_t spawnSectors)
101 // Get sector-data for sector. If spawnSectors is true, the
102 // sector-data is created if it does not exist already.
104 if (sector < 0 || sector > 35) return 0;
105 if (fSectors[sector] == 0 && spawnSectors)
106 CreateSector(sector);
107 return fSectors[sector];
110 /******************************************************************************/
112 void AliEveTPCData::LoadDigits(TTree* tree, Bool_t spawnSectors)
114 // Load data from TTree of AliSimDigits.
115 // If spawnSectors is false only sectors that have been created previously
116 // via CreateSector() are loaded.
117 // If spawnSectors is true sectors are created if data for them is encountered.
119 AliSimDigits digit, *digitPtr = &digit;
120 tree->GetBranch("Segment")->SetAddress(&digitPtr);
122 Int_t sector, row, pad, curPad;
123 Short_t time, signal;
124 Bool_t inFill = kFALSE;
125 AliEveTPCSectorData* secData = 0;
127 Int_t numEnt = (Int_t) tree->GetEntries();
128 for (Int_t ent=0; ent<numEnt; ent++) {
130 AliEveTPCSectorData::GetParam().AdjustSectorRow(digit.GetID(), sector, row);
133 row += AliEveTPCSectorData::GetInnSeg().GetNRows();
135 secData = GetSectorData(sector, spawnSectors);
139 if (digit.First() == kFALSE)
143 pad = digit.CurrentColumn();
144 time = digit.CurrentRow();
145 signal = digit.CurrentDigit();
149 secData->EndPad(fAutoPedestal, fLoadThreshold);
150 secData->BeginPad(row, pad, kFALSE);
155 secData->RegisterData(time, signal);
157 signal -= fLoadPedestal;
158 if (signal >= fLoadThreshold)
159 secData->RegisterData(time, signal);
162 } while (digit.Next());
164 secData->EndPad(fAutoPedestal, fLoadThreshold);
170 void AliEveTPCData::LoadRaw(AliTPCRawStreamV3& input, Bool_t spawnSectors, Bool_t warn)
172 // Load data from AliTPCRawStreamV3.
173 // If spawnSectors is false only sectors that have been created previously
174 // via CreateSector() are loaded.
175 // If spawnSectors is true sectors are created if data for them is encountered.
177 static const TEveException kEH("AliEveTPCData::LoadRaw ");
179 Int_t sector = -1, row = -1, pad = -1, rowOffset = 0;
180 Short_t time, signal;
181 Bool_t inFill = kFALSE;
182 Short_t pdrwCnt = 9999; // Count time-bins in padrow; needed to detect more than 1024 time-bins per padrow.
183 Short_t lastTime = 9999; // Last time-bin stored; needed to check for out-of-order time bins.
184 Bool_t pdrwCntWarn = kFALSE;
185 Bool_t lastTimeWarn = kFALSE;
186 AliEveTPCSectorData* secData = 0;
188 Short_t threshold = fLoadThreshold;
190 while (input.NextDDL()) {
191 if (input.IsNewSector()) {
193 secData->EndPad(fAutoPedestal, threshold);
196 sector = input.GetSector();
199 rowOffset = AliEveTPCSectorData::GetInnSeg().GetNRows();
203 secData = GetSectorData(sector, spawnSectors);
208 while (input.NextChannel()) {
209 if (input.IsNewPad()) {
211 secData->EndPad(fAutoPedestal, threshold);
214 row = input.GetRow() + rowOffset;
215 pad = input.GetPad();
217 if (pad >= AliEveTPCSectorData::GetNPadsInRow(row) || pad < 0) {
219 Warning(kEH.Data(), "pad out of range (row=%d, pad=%d, maxpad=%d).",
220 row, pad, AliEveTPCSectorData::GetNPadsInRow(row));
225 threshold = fLoadThreshold;
227 secData->BeginPad(row, pad, kTRUE);
229 pdrwCnt = 0; pdrwCntWarn = kFALSE;
230 lastTime = 1024; lastTimeWarn = kFALSE;
233 while (input.NextBunch()) {
234 const UShort_t *signalarr = input.GetSignals();
236 Int_t starttime = input.GetStartTimeBin();
237 for (Int_t i = 0; i < input.GetBunchLength(); i++) {
239 signal = signalarr[i];
241 if (pdrwCnt > 1024) {
242 if (pdrwCntWarn == kFALSE) {
244 Warning(kEH.Data(), "more than 1024 time-bins (row=%d, pad=%d, time=%d).\nFurther warnings of this type will be suppressed for this padrow.",
250 if (time >= lastTime) {
251 if (lastTimeWarn == kFALSE) {
253 Warning(kEH.Data(), "time out of order (row=%d, pad=%d, time=%d, lastTime=%d).\nFurther warnings of this type will be suppressed for this padrow.",
254 row, pad, time, lastTime);
255 lastTimeWarn = kTRUE;
261 secData->RegisterData(time, signal);
263 signal -= fLoadPedestal;
264 if (signal > threshold)
265 secData->RegisterData(time, signal);
273 secData->EndPad(fAutoPedestal, threshold);