22fdc90eaf8579d8f1815f08c01f25798c276e93
[u/mrichter/AliRoot.git] / HLT / TPCLib / comp / AliHLTTPCDataCompressionMonitorComponent.cxx
1 // $Id$
2 //**************************************************************************
3 //* This file is property of and copyright by the ALICE HLT Project        * 
4 //* ALICE Experiment at CERN, All rights reserved.                         *
5 //*                                                                        *
6 //* Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no>        *
7 //*                  for The ALICE HLT Project.                            *
8 //*                                                                        *
9 //* Permission to use, copy, modify and distribute this software and its   *
10 //* documentation strictly for non-commercial purposes is hereby granted   *
11 //* without fee, provided that the above copyright notice appears in all   *
12 //* copies and that both the copyright notice and this permission notice   *
13 //* appear in the supporting documentation. The authors make no claims     *
14 //* about the suitability of this software for any purpose. It is          *
15 //* provided "as is" without express or implied warranty.                  *
16 //**************************************************************************
17
18 /// @file   AliHLTTPCDataCompressionMonitorComponent.cxx
19 /// @author Matthias Richter
20 /// @date   2011-09-12
21 /// @brief  TPC component for monitoring of data compression
22 ///
23
24 #include "AliHLTTPCDataCompressionMonitorComponent.h"
25 #include "AliHLTTPCDataCompressionComponent.h"
26 #include "AliHLTTPCDataCompressionDecoder.h"
27 #include "AliHLTTPCDefinitions.h"
28 #include "AliHLTTPCHWCFData.h"
29 #include "AliHLTTPCDefinitions.h"
30 #include "AliHLTTPCClusterDataFormat.h"
31 #include "AliHLTTPCRawCluster.h"
32 #include "AliHLTTPCTransform.h"
33 #include "AliHLTTPCTrackGeometry.h"
34 #include "AliHLTTPCHWCFSpacePointContainer.h"
35 #include "AliHLTErrorGuard.h"
36 #include "AliHLTComponentBenchmark.h"
37 #include "AliRawDataHeader.h"
38 #include "AliTPCclusterMI.h"
39 #include "AliTPCROC.h"
40 #include "TH1I.h"
41 #include "TH1F.h"
42 #include "TH1D.h"
43 #include "TH2I.h"
44 #include "TH2F.h"
45 #include "TH2D.h"
46 #include "TH3I.h"
47 #include "TH3F.h"
48 #include "TH3D.h"
49 #include "TProfile.h"
50 #include "TFile.h"
51 #include "TObjArray.h"
52 #include "TList.h"
53 #include <memory>
54
55 ClassImp(AliHLTTPCDataCompressionMonitorComponent)
56
57 AliHLTTPCDataCompressionMonitorComponent::AliHLTTPCDataCompressionMonitorComponent()
58   : AliHLTProcessor()
59   , fpBenchmark(NULL)
60   , fpDecoder(NULL)
61   , fpHWClusterDecoder(NULL)
62   , fHistoHWCFDataSize(NULL)
63   , fHistoHWCFReductionFactor(NULL)
64   , fHistoTotalReductionFactor(NULL)
65   , fHistoNofClusters(NULL)
66   , fHistoNofClustersReductionFactor(NULL)
67   , fHistogramFile()
68   , fMonitoringContainer(NULL)
69   , fVerbosity(0)
70   , fFlags(0)
71   , fPublishingMode(kPublishSeparate)
72 {
73 }
74
75 AliHLTTPCDataCompressionMonitorComponent::~AliHLTTPCDataCompressionMonitorComponent()
76 {
77   /// destructor
78 }
79
80
81 const char* AliHLTTPCDataCompressionMonitorComponent::GetComponentID()
82 {
83   /// inherited from AliHLTComponent: id of the component
84   return "TPCDataCompressorMonitor";
85 }
86
87
88 void AliHLTTPCDataCompressionMonitorComponent::GetInputDataTypes( AliHLTComponentDataTypeList& tgtList)
89 {
90   /// inherited from AliHLTComponent: list of data types in the vector reference
91   tgtList.clear();
92   tgtList.push_back(AliHLTTPCDefinitions::fgkHWClustersDataType);
93   tgtList.push_back(kAliHLTDataTypeTrack|kAliHLTDataOriginTPC);
94   tgtList.push_back(AliHLTTPCDefinitions::fgkRawClustersDataType);
95   tgtList.push_back(AliHLTTPCDefinitions::RemainingClustersCompressedDataType());
96   tgtList.push_back(AliHLTTPCDefinitions::ClusterTracksCompressedDataType());  
97 }
98
99 AliHLTComponentDataType AliHLTTPCDataCompressionMonitorComponent::GetOutputDataType()
100 {
101   /// inherited from AliHLTComponent: output data type of the component.
102   return kAliHLTMultipleDataType;
103 }
104
105 int AliHLTTPCDataCompressionMonitorComponent::GetOutputDataTypes(AliHLTComponentDataTypeList& tgtList)
106 {
107   /// inherited from AliHLTComponent: multiple output data types of the component.
108   tgtList.clear();
109   tgtList.push_back(kAliHLTDataTypeHistogram|kAliHLTDataOriginTPC);
110   return tgtList.size();
111 }
112
113 void AliHLTTPCDataCompressionMonitorComponent::GetOutputDataSize( unsigned long& constBase, double& inputMultiplier )
114 {
115   /// inherited from AliHLTComponent: output data size estimator
116   constBase=10000000;
117   inputMultiplier=1.0;
118 }
119
120 AliHLTComponent* AliHLTTPCDataCompressionMonitorComponent::Spawn()
121 {
122   /// inherited from AliHLTComponent: spawn function.
123   return new AliHLTTPCDataCompressionMonitorComponent;
124 }
125
126 int AliHLTTPCDataCompressionMonitorComponent::DoEvent( const AliHLTComponentEventData& /*evtData*/, 
127                                                        const AliHLTComponentBlockData* /*inputBlocks*/, 
128                                                        AliHLTComponentTriggerData& /*trigData*/,
129                                                        AliHLTUInt8_t* /*outputPtr*/,
130                                                        AliHLTUInt32_t& /*size*/,
131                                                        AliHLTComponentBlockDataList& /*outputBlocks*/ )
132 {
133   /// inherited from AliHLTProcessor: data processing
134   int iResult=0;
135
136   AliHLTUInt32_t eventType=gkAliEventTypeUnknown;
137   if (!IsDataEvent(&eventType)) {
138     if (eventType==gkAliEventTypeEndOfRun && fPublishingMode!=kPublishOff) {
139       iResult=Publish(fPublishingMode);
140     }
141     return iResult;
142   }
143
144   if (GetBenchmarkInstance()) {
145     GetBenchmarkInstance()->StartNewEvent();
146     GetBenchmarkInstance()->Start(0);
147   }
148
149   const AliHLTComponentBlockData* pDesc=NULL;
150   unsigned rawDataSize=0;
151   unsigned rawEventSizeFromRCUtrailer=0;
152   unsigned hwclustersDataSize=0;
153   unsigned nofClusters=0;
154   unsigned compDataSize=0; 
155   
156   // check size of TPC raw data
157   for (pDesc=GetFirstInputBlock(kAliHLTDataTypeDDLRaw | kAliHLTDataOriginTPC);
158        pDesc!=NULL; pDesc=GetNextInputBlock()) {
159     fFlags|=kHaveRawData;
160     rawDataSize+=pDesc->fSize;
161   }
162
163   // check size of HWCF data and add to the MonitoringContainer
164   for (pDesc=GetFirstInputBlock(AliHLTTPCDefinitions::fgkHWClustersDataType);
165        pDesc!=NULL; pDesc=GetNextInputBlock()) {
166     fFlags|=kHaveHWClusters;
167     // FIXME: the decoding can now be handled via the data container
168     if (pDesc->fSize<=sizeof(AliRawDataHeader)) continue;
169     if (fpHWClusterDecoder) {
170       hwclustersDataSize+=pDesc->fSize;
171       AliHLTUInt8_t* pData=reinterpret_cast<AliHLTUInt8_t*>(pDesc->fPtr);
172       pData+=sizeof(AliRawDataHeader);
173       if (fpHWClusterDecoder->Init(pData, pDesc->fSize-sizeof(AliRawDataHeader))<0 ||
174           (fpHWClusterDecoder->CheckVersion()<0 && (int)(pDesc->fSize-sizeof(AliRawDataHeader))>fpHWClusterDecoder->GetRCUTrailerSize())) {
175         HLTError("data block of type %s corrupted: can not decode format",
176                  AliHLTComponent::DataType2Text(pDesc->fDataType).c_str());
177       } else {
178         nofClusters+=fpHWClusterDecoder->GetNumberOfClusters();
179         if (fpHWClusterDecoder->GetRCUTrailer()) {
180           // first word of the RCU trailer contains the payload size in 32bit words
181           const AliHLTUInt32_t*  pRCUTrailer=reinterpret_cast<const AliHLTUInt32_t*>(fpHWClusterDecoder->GetRCUTrailer());
182           AliHLTUInt32_t payloadSize=(*pRCUTrailer)&0x00ffffff;
183           rawEventSizeFromRCUtrailer+=sizeof(AliRawDataHeader)
184             + payloadSize*sizeof(AliHLTUInt32_t)
185             + fpHWClusterDecoder->GetRCUTrailerSize();
186         }
187       }
188     }
189     if (fMonitoringContainer) {
190       fMonitoringContainer->AddRawData(pDesc);
191     }
192   }
193
194   if (fMonitoringContainer && fpDecoder) {
195     if (GetBenchmarkInstance()) {
196       GetBenchmarkInstance()->Start(1);
197     }
198
199     for (pDesc=GetFirstInputBlock(AliHLTTPCDefinitions::RemainingClusterIdsDataType());
200          pDesc!=NULL; pDesc=GetNextInputBlock()) {
201       iResult=fMonitoringContainer->AddClusterIds(pDesc);
202     }
203
204     for (pDesc=GetFirstInputBlock(AliHLTTPCDefinitions::ClusterIdTracksDataType());
205          pDesc!=NULL; pDesc=GetNextInputBlock()) {
206       iResult=fMonitoringContainer->AddClusterIds(pDesc);
207     }
208
209     // read data
210     AliHLTTPCDataCompressionDecoder& decoder=*fpDecoder;
211     decoder.Clear();
212     bool bHaveRawClusters=false;
213     for (pDesc=GetFirstInputBlock(AliHLTTPCDefinitions::RawClustersDataType());
214          pDesc!=NULL; pDesc=GetNextInputBlock()) {
215       // Note: until r51411 and v5-01-Rev-03 the compressed cluster format was sent with data
216       // type {CLUSTRAW,TPC }, the version member indicated the actual type of data
217       // These data do not include the 0.5 shift in pad position, that's wht it has
218       // to be added in the unpacking. This is a very special case, this data type and
219       // data version==1 only occured in the early TPC data compression test runs with
220       // v5-01-Rev-01
221       if (pDesc->fSize<sizeof(AliHLTTPCRawClusterData)) continue;
222       const AliHLTTPCRawClusterData* clusterData = reinterpret_cast<const AliHLTTPCRawClusterData*>(pDesc->fPtr);
223       if (!clusterData) continue;
224       if (clusterData->fVersion==1) {
225         // compressed clusters without the pad shift
226         // data type {CLUSTRAW,TPC } with version==1
227         decoder.SetPadShift(0.5);
228       } else {
229         decoder.SetPadShift(0.0);
230       }
231       bHaveRawClusters=true;
232       iResult=decoder.ReadClustersPartition(fMonitoringContainer->BeginRemainingClusterBlock(0, pDesc->fSpecification),
233                                             reinterpret_cast<AliHLTUInt8_t*>(pDesc->fPtr),
234                                             pDesc->fSize,
235                                             pDesc->fSpecification);
236       if (iResult<0) {
237         HLTError("reading of partition clusters failed with error %d", iResult);
238       }
239     }
240
241     decoder.SetPadShift(0.0);
242
243     if (!bHaveRawClusters) {
244     for (pDesc=GetFirstInputBlock(AliHLTTPCDefinitions::RemainingClustersCompressedDataType());
245          pDesc!=NULL; pDesc=GetNextInputBlock()) {
246       iResult=decoder.ReadClustersPartition(fMonitoringContainer->BeginRemainingClusterBlock(0, pDesc->fSpecification),
247                                             reinterpret_cast<AliHLTUInt8_t*>(pDesc->fPtr),
248                                             pDesc->fSize,
249                                             pDesc->fSpecification);
250       compDataSize+=pDesc->fSize;
251     }
252
253     for (pDesc=GetFirstInputBlock(AliHLTTPCDefinitions::ClusterTracksCompressedDataType());
254          pDesc!=NULL; pDesc=GetNextInputBlock()) {
255       iResult=decoder.ReadTrackModelClustersCompressed(fMonitoringContainer->BeginTrackModelClusterBlock(0),
256                                                reinterpret_cast<AliHLTUInt8_t*>(pDesc->fPtr),
257                                                pDesc->fSize,
258                                                pDesc->fSpecification);
259       compDataSize+=pDesc->fSize;
260     }
261     } else {
262       if (GetFirstInputBlock(AliHLTTPCDefinitions::RemainingClustersCompressedDataType()) ||
263           GetFirstInputBlock(AliHLTTPCDefinitions::ClusterTracksCompressedDataType())) {
264         ALIHLTERRORGUARD(5, "conflicting data blocks, monitoring histograms already filled from raw cluster data, ignoring blocks of compressed partition and track clusters");
265       }              
266     }
267     if (GetBenchmarkInstance()) {
268       GetBenchmarkInstance()->Stop(1);
269     }
270
271     fMonitoringContainer->Clear();
272   }
273
274   if ((fFlags&kHaveHWClusters)!=0 && (fFlags&kHaveRawData)!=0) {
275     if (rawDataSize!=rawEventSizeFromRCUtrailer && rawEventSizeFromRCUtrailer>0) {
276       HLTError("got different raw event size from raw data and rcu trailer: raw %d, rcu trailer %d", rawDataSize, rawEventSizeFromRCUtrailer);
277     }
278   }
279   if (rawDataSize==0)
280     rawDataSize=rawEventSizeFromRCUtrailer;
281
282   float hwcfratio=0;
283   float ratio=0;
284   float totalratio=0;
285   if (hwclustersDataSize) {hwcfratio=(float)rawDataSize; hwcfratio/=hwclustersDataSize;}
286   if (compDataSize) {ratio=(float)hwclustersDataSize; ratio/=compDataSize;}
287   if (compDataSize) {totalratio=(float)rawDataSize; totalratio/=compDataSize;}
288   if (fHistoHWCFDataSize)        fHistoHWCFDataSize       ->Fill(rawDataSize/1024, hwclustersDataSize/1024);
289   if (fHistoHWCFReductionFactor) fHistoHWCFReductionFactor->Fill(rawDataSize/1024, hwcfratio);
290   if (fHistoTotalReductionFactor && nofClusters>0)
291     fHistoTotalReductionFactor->Fill(rawDataSize/1024, totalratio);
292   if (fHistoNofClusters)         fHistoNofClusters        ->Fill(rawDataSize/1024, nofClusters);
293   if (fHistoNofClustersReductionFactor && nofClusters>0)
294     fHistoNofClustersReductionFactor ->Fill(nofClusters, ratio);
295   HLTInfo("raw data %d, hwcf data %d, comp data %d, ratio %f, %d clusters, total compression ratio %f\n", rawDataSize, hwclustersDataSize, compDataSize, ratio, nofClusters, totalratio);
296
297   if (iResult>=0 && fPublishingMode!=kPublishOff) {
298     iResult=Publish(fPublishingMode);
299   }
300
301   if (GetBenchmarkInstance()) {
302     GetBenchmarkInstance()->Stop(0);
303     GetBenchmarkInstance()->AddInput(compDataSize);
304     HLTBenchmark("%s", GetBenchmarkInstance()->GetStatistics());
305   }
306
307   return iResult;
308 }
309
310 int AliHLTTPCDataCompressionMonitorComponent::Publish(int mode)
311 {
312   /// publish to output
313   // additional histograms derived from the main ones to publish
314   TObjArray *derivedHistos = new TObjArray();
315   derivedHistos->SetOwner(kTRUE);
316
317   // FIXME: code needs to be optimized, maybe a bit to much new and delete for the
318   // moment, the data type might need adjustment
319   int iResult=0;
320   TObjArray* pArray=mode==kPublishArray?(new TObjArray):NULL;
321   TList* pList=mode==kPublishList?(new TList):NULL;
322   if (mode==kPublishSeparate) {
323     if (fHistoHWCFDataSize)        PushBack(fHistoHWCFDataSize       , kAliHLTDataTypeHistogram|kAliHLTDataOriginTPC);
324     if (fHistoHWCFReductionFactor) PushBack(fHistoHWCFReductionFactor, kAliHLTDataTypeHistogram|kAliHLTDataOriginTPC);
325     if (fHistoNofClusters)         PushBack(fHistoNofClusters        , kAliHLTDataTypeHistogram|kAliHLTDataOriginTPC);
326     if (fHistoNofClustersReductionFactor) PushBack(fHistoNofClustersReductionFactor, kAliHLTDataTypeHistogram|kAliHLTDataOriginTPC);
327     if (fHistoTotalReductionFactor) PushBack(fHistoTotalReductionFactor, kAliHLTDataTypeHistogram|kAliHLTDataOriginTPC);
328   } else if (pList) {
329     if (fHistoHWCFDataSize)        pList->Add(fHistoHWCFDataSize->Clone());
330     if (fHistoHWCFReductionFactor) pList->Add(fHistoHWCFReductionFactor->Clone());
331     if (fHistoNofClusters)         pList->Add(fHistoNofClusters->Clone());
332     if (fHistoNofClustersReductionFactor) pList->Add(fHistoNofClustersReductionFactor->Clone());
333     if (fHistoTotalReductionFactor) pList->Add(fHistoTotalReductionFactor->Clone());
334   } else if (pArray) {
335     if (fHistoHWCFDataSize)        pArray->Add(fHistoHWCFDataSize->Clone());
336     if (fHistoHWCFReductionFactor) pArray->Add(fHistoHWCFReductionFactor->Clone());
337     if (fHistoNofClusters)         pArray->Add(fHistoNofClusters->Clone());
338     if (fHistoNofClustersReductionFactor) pArray->Add(fHistoNofClustersReductionFactor->Clone());
339     if (fHistoTotalReductionFactor) pArray->Add(fHistoTotalReductionFactor->Clone());
340   }
341
342
343   if (fMonitoringContainer) {
344     static const char* searchIds[] = {"fHistograms", "fHistograms2D", "fHistograms3D", NULL};
345     const char** searchId=searchIds;
346     while (*searchId && iResult>=0) {
347       const TObject* o=fMonitoringContainer->FindObject(*searchId);
348       if (o) {
349         const TObjArray* histograms=dynamic_cast<const TObjArray*>(o);
350         if (histograms) {
351           for (int i=0; i<histograms->GetEntriesFast() && iResult>=0; i++) {
352             if (!histograms->At(i)) continue;
353             ///
354             TString name=histograms->At(i)->GetName();
355             if( (name.CompareTo(fgkHistogramDefinitions2D[kHistogramQMaxSector].fName)==0) ||
356                 (name.CompareTo(fgkHistogramDefinitions2D[kHistogramSigmaY2Sector].fName)==0) ||
357                 (name.CompareTo(fgkHistogramDefinitions2D[kHistogramSigmaZ2Sector].fName)==0) ){
358               TH2F *h1=(TH2F*)histograms->At(i);
359               TProfile *h2 = (TProfile*)(h1->ProfileX());
360               derivedHistos->Add(h2);
361             }
362             if( name.CompareTo(fgkHistogramDefinitions3D[kHistogramPadrowPadSector].fName)==0) {
363               TH3F *h1=(TH3F*)histograms->At(i);
364               for (int j=1; j<=72; j++) {
365               h1->GetXaxis()->SetRange(j,j);
366               TString histoname = Form("zy_%d",j);
367               TH2F *h2 = (TH2F*)h1->Project3D(histoname.Data());
368               derivedHistos->Add(h2);
369               }
370             }
371             ///
372             if (mode==kPublishSeparate) {
373               iResult=PushBack(histograms->At(i), kAliHLTDataTypeHistogram|kAliHLTDataOriginTPC);
374             } else if (pList) {
375               pList->Add(histograms->At(i)->Clone());
376             } else if (pArray) {
377               pArray->Add(histograms->At(i)->Clone());
378             }
379           }
380           for (int i=0; i<derivedHistos->GetEntriesFast() && iResult>=0; i++) {
381             if (mode==kPublishSeparate) {
382               iResult=PushBack(derivedHistos->At(i), kAliHLTDataTypeHistogram|kAliHLTDataOriginTPC);
383             } else if (pList) {
384               pList->Add(derivedHistos->At(i)->Clone());
385             } else if (pArray) {
386               pArray->Add(derivedHistos->At(i)->Clone());
387             }       
388           }
389         }
390       } else {
391         HLTError("failed to find object \"%s\"", *searchId);
392       }
393       searchId++;
394     }
395   }
396
397   if (pArray) {
398     iResult=PushBack(pArray, kAliHLTDataTypeTObjArray|kAliHLTDataOriginTPC);
399     pArray->SetOwner(kTRUE);
400     delete pArray;
401     pArray=NULL;
402   }
403   if (pList) {
404     iResult=PushBack(pList, kAliHLTDataTypeTObject|kAliHLTDataOriginTPC);
405     pList->SetOwner(kTRUE);
406     delete pList;
407     pList=NULL;
408   }
409   return iResult;
410 }
411
412 int AliHLTTPCDataCompressionMonitorComponent::DoInit( int argc, const char** argv )
413 {
414   /// inherited from AliHLTComponent: component initialisation and argument scan.
415   int iResult=0;
416
417   // component configuration
418   //Stage 1: default initialization.
419   //Default values.
420   fFlags=0;
421
422   //Stage 2: OCDB.
423   TString cdbPath("HLT/ConfigTPC/");
424   cdbPath += GetComponentID();
425   //
426   // iResult = ConfigureFromCDBTObjString(cdbPath);
427   // if (iResult < 0) 
428   //   return iResult;
429
430   //Stage 3: command line arguments.
431   if (argc && (iResult = ConfigureFromArgumentString(argc, argv)) < 0)
432     return iResult;
433
434   std::auto_ptr<AliHLTTPCHWCFData> hwClusterDecoder(new AliHLTTPCHWCFData);
435   std::auto_ptr<AliDataContainer> dataContainer(new AliDataContainer);
436
437   std::auto_ptr<TH2I> histoHWCFDataSize(new TH2I("HWCFDataSize",
438                                                  "HW ClusterFinder Size",
439                                                  100, 0., 80000., 100, 0., 80000.));
440   if (histoHWCFDataSize.get()) {
441     TAxis* xaxis=histoHWCFDataSize->GetXaxis();
442     if (xaxis) xaxis->SetTitle("raw data size [kB]");
443     TAxis* yaxis=histoHWCFDataSize->GetYaxis();
444     if (yaxis) yaxis->SetTitle("compressed data size [kb]");
445   }
446
447   std::auto_ptr<TH2I> histoHWCFReductionFactor(new TH2I("HWCFReductionFactor",
448                                                         "Data reduction HW ClusterFinder vs. raw data size",
449                                                         100, 0., 80000., 30, 0., 3.));
450   if (histoHWCFReductionFactor.get()) {
451     TAxis* xaxis=histoHWCFReductionFactor->GetXaxis();
452     if (xaxis) xaxis->SetTitle("raw data size [kB]");
453     TAxis* yaxis=histoHWCFReductionFactor->GetYaxis();
454     if (yaxis) yaxis->SetTitle("reduction factor");
455   }
456
457   std::auto_ptr<TH2I> histoTotalReductionFactor(new TH2I("TotalReductionFactor",
458                                                          "Total reduction Factor vs. raw data size",
459                                                          100, 0., 80000., 100, 0., 10.));
460   if (histoTotalReductionFactor.get()) {
461     TAxis* xaxis=histoTotalReductionFactor->GetXaxis();
462     if (xaxis) xaxis->SetTitle("raw data size [kB]");
463     TAxis* yaxis=histoTotalReductionFactor->GetYaxis();
464     if (yaxis) yaxis->SetTitle("reduction factor");
465   }
466
467   std::auto_ptr<TH2I> histoNofClusters(new TH2I("NofClusters",
468                                                "Number of HLT TPC clusters",
469                                                100, 0., 80000., 500, 0., 3000000.));
470   if (histoNofClusters.get()) {
471     TAxis* xaxis=histoNofClusters->GetXaxis();
472     if (xaxis) xaxis->SetTitle("raw data size [kB]");
473     TAxis* yaxis=histoNofClusters->GetYaxis();
474     if (yaxis) yaxis->SetTitle("N. of clusters");
475   }
476
477   std::auto_ptr<TH2I> histoNofClustersReductionFactor(new TH2I("ReductionFactorVsNofClusters",
478                                                                "Reduction Factor vs. Number of HLT TPC clusters",
479                                                                500, 0., 3000000., 100, 0., 10.));
480   if (histoNofClustersReductionFactor.get()) {
481     TAxis* xaxis=histoNofClustersReductionFactor->GetXaxis();
482     if (xaxis) xaxis->SetTitle("N. of clusters");
483     TAxis* yaxis=histoNofClustersReductionFactor->GetYaxis();
484     if (yaxis) yaxis->SetTitle("reduction factor");
485   }
486
487   std::auto_ptr<AliHLTComponentBenchmark> benchmark(new AliHLTComponentBenchmark);
488   if (benchmark.get()) {
489     benchmark->SetTimer(0,"total");
490     benchmark->SetTimer(1,"clusterdecoding");
491   } else {
492     return -ENOMEM;
493   }
494
495   auto_ptr<AliHLTTPCDataCompressionDecoder> decoder(new AliHLTTPCDataCompressionDecoder);
496   if (!decoder.get()) {
497     return -ENOMEM;
498   }
499
500
501   fHistoHWCFDataSize=histoHWCFDataSize.release();
502   fHistoHWCFReductionFactor=histoHWCFReductionFactor.release();
503   fHistoTotalReductionFactor=histoTotalReductionFactor.release();
504   fHistoNofClusters=histoNofClusters.release();
505   fHistoNofClustersReductionFactor=histoNofClustersReductionFactor.release();
506
507   fpHWClusterDecoder=hwClusterDecoder.release();
508   fMonitoringContainer=dataContainer.release();
509   fpBenchmark=benchmark.release();
510   fpDecoder=decoder.release();
511
512   return iResult;
513 }
514
515 int AliHLTTPCDataCompressionMonitorComponent::DoDeinit()
516 {
517   /// inherited from AliHLTComponent: component cleanup
518   int iResult=0;
519
520   if (fpBenchmark) delete fpBenchmark; fpBenchmark=NULL;
521   if (fpDecoder) delete fpDecoder;
522   fpDecoder=NULL;
523   if (fpHWClusterDecoder) delete fpHWClusterDecoder;
524   fpHWClusterDecoder=NULL;
525
526   if (!fHistogramFile.IsNull()) {
527     TFile out(fHistogramFile, "RECREATE");
528     if (!out.IsZombie()) {
529       out.cd();
530       if (fHistoHWCFDataSize) fHistoHWCFDataSize->Write();
531       if (fHistoHWCFReductionFactor) fHistoHWCFReductionFactor->Write();
532       if (fHistoTotalReductionFactor) fHistoTotalReductionFactor->Write();
533       if (fHistoNofClusters) fHistoNofClusters->Write();
534       if (fHistoNofClustersReductionFactor) fHistoNofClustersReductionFactor->Write();
535       if (fMonitoringContainer) {
536         const TObject* o1=fMonitoringContainer->FindObject("fHistograms");
537         const TObject* o2=fMonitoringContainer->FindObject("fHistograms2D");
538         const TObject* o3=fMonitoringContainer->FindObject("fHistograms3D");
539         if (o1) o1->Write();
540         if (o2) o2->Write();
541         if (o3) o3->Write();
542       }
543       out.Close();
544     }
545   }
546   if (fHistoHWCFDataSize) delete fHistoHWCFDataSize;
547   fHistoHWCFDataSize=NULL;
548   if (fHistoHWCFReductionFactor) delete fHistoHWCFReductionFactor;
549   fHistoHWCFReductionFactor=NULL;
550   if (fHistoTotalReductionFactor) delete fHistoTotalReductionFactor;
551   fHistoTotalReductionFactor=NULL;
552   if (fHistoNofClusters) delete fHistoNofClusters;
553   fHistoNofClusters=NULL;
554   if (fHistoNofClustersReductionFactor) delete fHistoNofClustersReductionFactor;
555   fHistoNofClustersReductionFactor=NULL;
556   if (fMonitoringContainer) {
557     fMonitoringContainer->Clear();
558     delete fMonitoringContainer;
559   }
560   fMonitoringContainer=NULL;
561
562
563   return iResult;
564 }
565
566 int AliHLTTPCDataCompressionMonitorComponent::ScanConfigurationArgument(int argc, const char** argv)
567 {
568   /// inherited from AliHLTComponent: argument scan
569   int iResult=0;
570   if (argc<1) return 0;
571   int bMissingParam=0;
572   int i=0;
573   TString argument=argv[i];
574
575   do {
576     // -histogram-file
577     if (argument.CompareTo("-histogram-file")==0) {
578       if ((bMissingParam=(++i>=argc))) break;
579       fHistogramFile=argv[i++];
580       return i;
581     }
582     // -publishing-mode
583     if (argument.CompareTo("-publishing-mode")==0) {
584       if ((bMissingParam=(++i>=argc))) break;
585       TString option=argv[i++];
586       if (option.CompareTo("off")==0)           fPublishingMode=kPublishOff     ;
587       else if (option.CompareTo("separate")==0) fPublishingMode=kPublishSeparate;
588       else if (option.CompareTo("list")==0)     fPublishingMode=kPublishList    ;
589       else if (option.CompareTo("array")==0)    fPublishingMode=kPublishArray   ;
590       else {
591         HLTError("invalid option \"%s\" for argument \"%s\", expecting 'off', 'separate', 'list', or 'array'", option.Data(), argument.Data());
592         return -EPROTO;
593       }
594       return i;
595     }
596   } while (0); // using do-while only to have break available
597
598   if (bMissingParam) {
599     HLTError("missing parameter for argument %s", argument.Data());
600     iResult=-EPROTO;
601   }
602
603   return iResult;
604 }
605
606 AliHLTTPCDataCompressionMonitorComponent::AliDataContainer::AliDataContainer()
607   : fHistograms(new TObjArray)  
608   , fHistograms2D(new TObjArray)  
609   , fHistograms3D(new TObjArray)    
610   , fHistogramPointers()
611   , fHistogram2DPointers()
612   , fHistogram3DPointers()
613   , fRemainingClusterIds()
614   , fTrackModelClusterIds()
615   , fCurrentClusterIds(NULL)
616   , fRawData(NULL)
617   , fCurrentCluster()
618   , fSector(-1)
619   , fBegin()
620   , fMaxSigmaY2Scaled((0x1<<AliHLTTPCDefinitions::fgkClusterParameterDefinitions[AliHLTTPCDefinitions::kSigmaY2].fBitLength)-1)
621   , fMaxSigmaZ2Scaled((0x1<<AliHLTTPCDefinitions::fgkClusterParameterDefinitions[AliHLTTPCDefinitions::kSigmaZ2].fBitLength)-1)
622 {
623   /// constructor
624   memset(&fCurrentCluster, 0, sizeof(AliHLTTPCRawCluster));
625   if (fHistograms) {
626     fHistograms->SetOwner(kTRUE);
627     fHistogramPointers.resize(kNumberOfHistograms, NULL);
628     for (const AliHistogramDefinition* definition=fgkHistogramDefinitions;
629          definition->fName!=NULL; definition++) {
630       fHistogramPointers[definition->fId]=new TH1D(definition->fName,
631                                                   definition->fTitle,
632                                                   definition->fBins,
633                                                   definition->fLowerBound,
634                                                   definition->fUpperBound
635                                                   );
636       if (fHistogramPointers[definition->fId]) {
637         fHistogramPointers[definition->fId]->SetOption(definition->fDrawOptions);
638       fHistograms->AddAt(fHistogramPointers[definition->fId], definition->fId);
639       }
640     }
641   }
642   ///
643   if (fHistograms2D) {
644     fHistograms2D->SetOwner(kTRUE);
645     fHistogram2DPointers.resize(kNumberOfHistograms2D, NULL);
646     for (const AliHistogramDefinition2D* definition=fgkHistogramDefinitions2D;
647          definition->fName!=NULL; definition++) {
648       fHistogram2DPointers[definition->fId]=new TH2D(definition->fName,
649                                                      definition->fTitle,
650                                                      definition->fBinsX,
651                                                      definition->fLowerBoundX,
652                                                      definition->fUpperBoundX,
653                                                      definition->fBinsY,
654                                                      definition->fLowerBoundY,
655                                                      definition->fUpperBoundY
656                                                      );
657       if (fHistogram2DPointers[definition->fId]) {
658         fHistogram2DPointers[definition->fId]->SetOption(definition->fDrawOptions);
659       fHistograms2D->AddAt(fHistogram2DPointers[definition->fId], definition->fId);
660       }
661     }
662   }
663   ///
664   if (fHistograms3D) {
665     fHistograms3D->SetOwner(kTRUE);
666     fHistogram3DPointers.resize(kNumberOfHistograms3D, NULL);
667     for (const AliHistogramDefinition3D* definition=fgkHistogramDefinitions3D;
668          definition->fName!=NULL; definition++) {
669       fHistogram3DPointers[definition->fId]=new TH3D(definition->fName,
670                                                      definition->fTitle,
671                                                      definition->fBinsX,
672                                                      definition->fLowerBoundX,
673                                                      definition->fUpperBoundX,
674                                                      definition->fBinsY,
675                                                      definition->fLowerBoundY,
676                                                      definition->fUpperBoundY,
677                                                      definition->fBinsZ,
678                                                      definition->fLowerBoundZ,
679                                                      definition->fUpperBoundZ
680                                                      );
681       if (fHistogram3DPointers[definition->fId]) {
682         fHistogram3DPointers[definition->fId]->SetOption(definition->fDrawOptions);
683       fHistograms3D->AddAt(fHistogram3DPointers[definition->fId], definition->fId);
684       }
685     }
686   }
687   
688 }
689
690 const AliHLTTPCDataCompressionMonitorComponent::AliHistogramDefinition AliHLTTPCDataCompressionMonitorComponent::fgkHistogramDefinitions[] = {
691   {kHistogramPadrow,        "padrow"   , "padrow; padrow; counts"                  ,  160,   0.,   160., ""},
692   {kHistogramHWCFPad,       "hwcfpad"  , "hwcfpad; pad; counts"                    ,  280,   0.,   140., ""},
693   {kHistogramPad,           "pad"      , "pad; pad; counts"                        ,  280,   0.,   140., ""},
694   {kHistogramTime,          "timebin"  , "timebin; time; counts"                   , 1024,   0.,  1024., ""},
695   {kHistogramSigmaY2,       "sigmaY2"  , "sigmaY2; #sigma_{Y}^{2}; counts"         ,  100,   0.,     1., ""},
696   {kHistogramSigmaZ2,       "sigmaZ2"  , "sigmaZ2; #sigma_{Z}^{2}; counts"         ,  100,   0.,     1., ""},
697   {kHistogramCharge,        "charge"   , "charge; charge; counts"                  , 1024,   0., 65536., ""},
698   {kHistogramQMax,          "qmax"     , "qmax; Q_{max}; counts"                   ,  128,   0.,  1024., ""},
699   {kHistogramDeltaPadrow,   "d_padrow" , "d_padrow; #Delta padrow; counts"         , 1000,  -1.,     1., ""},
700   {kHistogramDeltaPad,      "d_pad"    , "d_pad; #Delta pad; counts"               , 1000,  -1.,     1., ""},
701   {kHistogramDeltaTime,     "d_time"   , "d_time; #Delta time; counts"             , 1000,  -1.,     1., ""},
702   {kHistogramDeltaSigmaY2,  "d_sigmaY2", "d_sigmaY2; #Delta #sigma_{Y}^{2}; counts", 1000,  -1.,     1., ""},
703   {kHistogramDeltaSigmaZ2,  "d_sigmaZ2", "d_sigmaZ2; #Delta #sigma_{Z}^{2}; counts", 1000,  -1.,     1., ""},
704   {kHistogramDeltaCharge,   "d_charge" , "d_charge; #Delta charge"                 , 1000,  -1.,     1., ""},
705   {kHistogramDeltaQMax,     "d_qmax"   , "d_qmax; #Delta Q_{max}"                  , 1000,  -1.,     1., ""},
706   {kHistogramOutOfRange,    "ResError" , "Residual Error; padrow; counts"          ,  159,   0.,   159., ""},
707   {kNumberOfHistograms, NULL, NULL, 0,0.,0., NULL}
708 };
709
710 const AliHLTTPCDataCompressionMonitorComponent::AliHistogramDefinition2D AliHLTTPCDataCompressionMonitorComponent::fgkHistogramDefinitions2D[] = {
711   {kHistogramQMaxSector,    "qmaxsector"   , "qmaxsector; sector; Q_{max}"           ,  72,   0.,  72., 1024,   0., 1024., "colz"},
712   {kHistogramSigmaY2Sector, "sigmaY2sector", "sigmaY2sector; sector; #sigma_{Y}^{2}" ,  72,   0.,  72.,  100,   0.,    1., "colz"},
713   {kHistogramSigmaZ2Sector, "sigmaZ2sector", "sigmaZ2sector; sector; #sigma_{Z}^{2}" ,  72,   0.,  72.,  100,   0.,    1., "colz"},
714   {kHistogramXYA,            "XYA", "XY - A side; X[cm]; Y[cm]"                      , 100,-300., 300.,  100,-300.,  300., "colz"},
715   {kHistogramXYC,            "XYC", "XY - C side; X[cm]; Y[cm]"                      , 100,-300., 300.,  100,-300.,  300., "colz"},
716   {kNumberOfHistograms2D, NULL, NULL, 0,0.,0., 0,0.,0., NULL}
717 };
718
719 const AliHLTTPCDataCompressionMonitorComponent::AliHistogramDefinition3D AliHLTTPCDataCompressionMonitorComponent::fgkHistogramDefinitions3D[] = {
720   {kHistogramPadrowPadSector,"padrowpadsector","padrowpadsector; sector; pad;padrow", 72,0.,72., 140,0.,140., 159,0.,159., ""},
721   {kNumberOfHistograms3D, NULL, NULL, 0,0.,0., 0,0.,0., 0,0.,0., NULL}
722 };
723
724 AliHLTTPCDataCompressionMonitorComponent::AliDataContainer::~AliDataContainer()
725 {
726   /// dectructor
727   if (fRawData) delete fRawData;
728   if (fHistograms) delete fHistograms;
729   if (fHistograms2D) delete fHistograms2D;
730   if (fHistograms3D) delete fHistograms3D;
731 }
732
733 AliHLTTPCDataCompressionMonitorComponent::AliDataContainer::iterator& AliHLTTPCDataCompressionMonitorComponent::AliDataContainer::BeginPartitionClusterBlock(int /*count*/, AliHLTUInt32_t specification)
734 {
735   /// iterator of remaining clusters block of specification
736   AliHLTUInt8_t slice=AliHLTTPCDefinitions::GetMinSliceNr(specification);
737   AliHLTUInt8_t partition=AliHLTTPCDefinitions::GetMinPatchNr(specification);
738   unsigned index=slice*AliHLTTPCTransform::GetNumberOfPatches()+partition;
739   if (index<fRemainingClusterIds.size())
740     fCurrentClusterIds=&fRemainingClusterIds[index];
741   else
742     fCurrentClusterIds=NULL;
743   fBegin=iterator(this);
744   return fBegin;
745 }
746
747 AliHLTTPCDataCompressionMonitorComponent::AliDataContainer::iterator& AliHLTTPCDataCompressionMonitorComponent::AliDataContainer::BeginTrackModelClusterBlock(int /*count*/)
748 {
749   /// iterator of track model clusters
750   if (fTrackModelClusterIds.fIds && fTrackModelClusterIds.fSize>0)
751     fCurrentClusterIds=&fTrackModelClusterIds;
752   else
753     fCurrentClusterIds=NULL;
754   fBegin=iterator(this);
755   return fBegin;
756 }
757
758 int AliHLTTPCDataCompressionMonitorComponent::AliDataContainer::AddRawData(const AliHLTComponentBlockData* pDesc)
759 {
760   /// add raw data bloack
761   int iResult=0;
762   if (pDesc->fDataType==AliHLTTPCDefinitions::HWClustersDataType()) {
763     if (!fRawData) fRawData=new AliHLTTPCHWCFSpacePointContainer(AliHLTTPCHWCFSpacePointContainer::kModeCreateMap);
764     if (!fRawData) return -ENOMEM;
765     if ((iResult=fRawData->AddInputBlock(pDesc))<0) return iResult;
766     AliHLTSpacePointContainer::AliHLTSpacePointPropertyGrid* pSpacePointGrid=AliHLTTPCHWCFSpacePointContainer::AllocateIndexGrid();
767     if (pSpacePointGrid) {
768       fRawData->PopulateAccessGrid(pSpacePointGrid, pDesc->fSpecification);
769       fRawData->SetSpacePointPropertyGrid(pDesc->fSpecification, pSpacePointGrid);
770     }
771     return 0;
772   }
773   return -ENODATA;  
774 }
775
776 int AliHLTTPCDataCompressionMonitorComponent::AliDataContainer::AddClusterIds(const AliHLTComponentBlockData* pDesc)
777 {
778   /// add cluster id block for remaining or track model clusters
779   if (!pDesc) return -EINVAL;
780   if (pDesc->fDataType==AliHLTTPCDefinitions::ClusterIdTracksDataType()) {
781     fTrackModelClusterIds.fIds=reinterpret_cast<AliHLTUInt32_t*>(pDesc->fPtr);
782     fTrackModelClusterIds.fSize=pDesc->fSize/sizeof(AliHLTUInt32_t);
783     return 0;
784   }
785   if (pDesc->fDataType==AliHLTTPCDefinitions::RemainingClusterIdsDataType()) {
786     AliHLTUInt8_t slice=AliHLTTPCDefinitions::GetMinSliceNr(pDesc->fSpecification);
787     AliHLTUInt8_t partition=AliHLTTPCDefinitions::GetMinPatchNr(pDesc->fSpecification);
788     unsigned index=slice*AliHLTTPCTransform::GetNumberOfPatches()+partition;
789     if (fRemainingClusterIds.size()<=index) {
790       if ((int)fRemainingClusterIds.size()<AliHLTTPCTransform::GetNSlice()*AliHLTTPCTransform::GetNumberOfPatches()) {
791         fRemainingClusterIds.resize(AliHLTTPCTransform::GetNSlice()*AliHLTTPCTransform::GetNumberOfPatches());
792       } else {
793         fRemainingClusterIds.resize(index+1);
794       }
795     }
796     fRemainingClusterIds[index].fIds=reinterpret_cast<AliHLTUInt32_t*>(pDesc->fPtr);
797     fRemainingClusterIds[index].fSize=pDesc->fSize/sizeof(AliHLTUInt32_t);
798     return 0;
799   }
800   return -ENODATA;
801 }
802
803 AliHLTUInt32_t AliHLTTPCDataCompressionMonitorComponent::AliDataContainer::GetClusterId(int clusterNo) const
804 {
805   /// get the cluster id from the current cluster id block (optional)
806   if (!fCurrentClusterIds ||
807       clusterNo<0 ||
808       (int)fCurrentClusterIds->fSize<=clusterNo)
809     return kAliHLTVoidDataSpec;
810   return fCurrentClusterIds->fIds[clusterNo];
811 }
812
813 AliHLTUInt32_t AliHLTTPCDataCompressionMonitorComponent::AliDataContainer::FindNearestCluster(int slice, int partition, const AliHLTTPCRawCluster& cluster) const
814 {
815   /// get the cluster id of the nearest original cluster
816   if (!fRawData) return kAliHLTVoidDataSpec;
817   AliHLTUInt32_t key=AliHLTTPCDefinitions::EncodeDataSpecification(slice, slice, partition, partition);
818   // FIXME: AliHLTIndexGrid::Index is not declared const
819   AliHLTSpacePointContainer::AliHLTSpacePointPropertyGrid* pGrid=const_cast<AliHLTSpacePointContainer::AliHLTSpacePointPropertyGrid*>(fRawData->GetSpacePointPropertyGrid(key));
820   if (!pGrid) return kAliHLTVoidDataSpec;
821   AliHLTUInt32_t clusterId=kAliHLTVoidDataSpec;
822   // search a 4x4 matrix out of the 9x9 matrix around the cell addressed by
823   // pad and time
824   float padrow=(float)cluster.GetPadRow()-AliHLTTPCTransform::GetFirstRow(partition);
825   float pad=cluster.GetPad();
826   float time=cluster.GetTime();
827   float minr2=-1.;
828   const float padpitch=AliHLTTPCTransform::GetPadPitchWidth(partition);
829   const float zwidth=AliHLTTPCTransform::GetZWidth();
830   float maxDeltaPad=AliHLTTPCDefinitions::GetMaxClusterDeltaPad();
831   float maxDeltaTime=AliHLTTPCDefinitions::GetMaxClusterDeltaTime();
832   int rowindex=pGrid->GetXIndex(padrow);
833   int padstartindex=pGrid->GetYIndex(pad);
834   int timestartindex=pGrid->GetZIndex(time);
835   int cellindex=pGrid->Index(rowindex, padstartindex, timestartindex);
836   float centerpad=pGrid->GetCenterY(cellindex);
837   float centertime=pGrid->GetCenterZ(cellindex);
838   if ((TMath::Abs(centerpad-pad)>maxDeltaPad && pad>0.) ||
839       (TMath::Abs(centertime-time)>maxDeltaTime && time>0.)) {
840     ALIHLTERRORGUARD(20, "invalid pad center calculation, please check dimensions if dimensions of index grid match the maximum possible deviation");
841   }
842
843   int paddirection=1;
844   int timedirection=1;
845   if (centerpad>pad) paddirection=-1;
846   if (centertime>time) timedirection=-1;
847   for (int padcount=0, padindex=padstartindex; padcount<2; padcount++, padindex+=paddirection) {
848     if (padindex<0) continue;
849     if (padindex>=pGrid->GetDimensionY()) break;
850     for (int timecount=0, timeindex=timestartindex; timecount<2; timecount++, timeindex+=timedirection) {
851       if (timeindex<0) continue;
852       if (timeindex>=pGrid->GetDimensionZ()) break;
853       cellindex=pGrid->Index(rowindex, padindex, timeindex);
854       float cellpad=pGrid->GetCenterY(cellindex);
855       float celltime=pGrid->GetCenterZ(cellindex);
856       for (AliHLTSpacePointContainer::AliHLTSpacePointPropertyGrid::iterator& cl=pGrid->begin((float)padrow, cellpad, celltime);
857            cl!=pGrid->end(); cl++) {
858         if (cl.Data().fTrackId>=0) continue;
859         if (fRawData->GetCharge(cl.Data().fId)!=cluster.GetCharge() ||
860             fRawData->GetQMax(cl.Data().fId)!=cluster.GetQMax()) continue;
861         if (TMath::Abs(padrow-fRawData->GetX(cl.Data().fId))>=1.) {
862           HLTError("slice %d, partition %d, cluster 0x%08x: mismatch on padrow: %f  vs. cluster %f", slice, partition, cl.Data().fId, padrow, fRawData->GetX(cl.Data().fId));
863           continue;
864         }
865         float clusterpad=fRawData->GetY(cl.Data().fId);
866         float clustertime=fRawData->GetZ(cl.Data().fId);
867         clusterpad-=pad;
868         clusterpad*=padpitch;
869         clustertime-=time;
870         clustertime*=zwidth;
871         float r2=clusterpad*clusterpad+clustertime*clustertime;
872         if (minr2<0. || r2<minr2) {
873           clusterId=cl.Data().fId;
874           cl.Data().fTrackId=1;
875           minr2=r2;
876         }
877       }
878     }
879   }
880   return clusterId;
881 }
882
883 void AliHLTTPCDataCompressionMonitorComponent::AliDataContainer::FillPadRow(int row, int slice, AliHLTUInt32_t /*clusterId*/)
884 {
885   /// fill padrow histogram
886   unsigned index=kHistogramPadrow;
887   fCurrentCluster.SetPadRow(row);
888   // the inner sectors consist of readout partitions 0 and 1, if the row
889   // is smaller than first row of readout partition 2, its an inner sector
890   if (row<AliHLTTPCTransform::GetFirstRow(2)) {
891     fSector = slice;
892   } else {
893     fSector = slice+AliHLTTPCTransform::GetNSlice();
894   }
895   if (index<fHistogramPointers.size() && fHistogramPointers[index]!=NULL)
896     fHistogramPointers[index]->Fill(row);
897 }
898
899 void AliHLTTPCDataCompressionMonitorComponent::AliDataContainer::FillPad(float pad, AliHLTUInt32_t /*clusterId*/)
900 {
901   /// fill pad histogram
902   fCurrentCluster.SetPad(pad);
903   int currentRow=fCurrentCluster.GetPadRow();
904   unsigned index=kHistogramPad;
905   if (index<fHistogramPointers.size() && fHistogramPointers[index]!=NULL)
906     fHistogramPointers[index]->Fill(pad);
907
908   index=kHistogramPadrowPadSector;
909   if (index<fHistogram3DPointers.size() && fHistogram3DPointers[index]!=NULL)
910     fHistogram3DPointers[index]->Fill(fSector,pad,currentRow);
911   
912   AliTPCROC *roc=AliTPCROC::Instance();
913   if (roc) {
914   Float_t pos[3]={0.,0.,0.};
915   roc->GetPositionGlobal(fSector, fSector>35?currentRow-63:currentRow, (int)pad, pos); 
916   if (fSector<=17 || (fSector>=36&&fSector<=53))
917     //Sectors 0 to 17 and 36 to 53 are on the A side, sectors 18 to 35 and 54 to 71 are on the C side. 
918     { 
919       index=kHistogramXYA;
920       if (index<fHistogram2DPointers.size() && fHistogram2DPointers[index]!=NULL)
921         fHistogram2DPointers[index]->Fill(pos[0],pos[1]);
922     } else {
923     index=kHistogramXYC;
924     if (index<fHistogram2DPointers.size() && fHistogram2DPointers[index]!=NULL)
925       fHistogram2DPointers[index]->Fill(pos[0],pos[1]);
926   }
927   }
928
929 }
930
931 void AliHLTTPCDataCompressionMonitorComponent::AliDataContainer::FillTime(float time, AliHLTUInt32_t /*clusterId*/)
932 {
933   /// fill pad histogram
934   fCurrentCluster.SetTime(time);
935   unsigned index=kHistogramTime;
936   if (index<fHistogramPointers.size() && fHistogramPointers[index]!=NULL)
937     fHistogramPointers[index]->Fill(time);
938 }
939
940 void AliHLTTPCDataCompressionMonitorComponent::AliDataContainer::FillSigmaY2(float sigmaY2, AliHLTUInt32_t /*clusterId*/, int partition)
941 {
942   /// fill sigmaY2 histogram
943   fCurrentCluster.SetSigmaY2(sigmaY2);
944   unsigned index=kHistogramSigmaY2;
945   /// take account for different pad widths
946   float weight=AliHLTTPCTransform::GetPadPitchWidth(partition);
947   if (index<fHistogramPointers.size() && fHistogramPointers[index]!=NULL)
948     fHistogramPointers[index]->Fill(sigmaY2*weight*weight);
949
950   index=kHistogramSigmaY2Sector;
951   if (index<fHistogram2DPointers.size() && fHistogram2DPointers[index]!=NULL)
952     fHistogram2DPointers[index]->Fill(fSector,sigmaY2*weight*weight);
953
954 }
955
956 void AliHLTTPCDataCompressionMonitorComponent::AliDataContainer::FillSigmaZ2(float sigmaZ2, AliHLTUInt32_t /*clusterId*/)
957 {
958   /// fill sigmaZ2 histogram
959   fCurrentCluster.SetSigmaZ2(sigmaZ2);
960   unsigned index=kHistogramSigmaZ2;
961   // FIXME: this is just a fixed value, to be correct the values from the global
962   // parameter block has to be used
963   float weight=AliHLTTPCTransform::GetZWidth();
964   if (index<fHistogramPointers.size() && fHistogramPointers[index]!=NULL)
965     fHistogramPointers[index]->Fill(sigmaZ2*weight*weight);
966
967   index=kHistogramSigmaZ2Sector;
968   if (index<fHistogram2DPointers.size() && fHistogram2DPointers[index]!=NULL)
969     fHistogram2DPointers[index]->Fill(fSector,sigmaZ2*weight*weight);
970
971 }
972
973 void AliHLTTPCDataCompressionMonitorComponent::AliDataContainer::FillCharge(unsigned charge, AliHLTUInt32_t /*clusterId*/)
974 {
975   /// fill charge histogram
976   fCurrentCluster.SetCharge(charge);
977   unsigned index=kHistogramCharge;
978   if (index<fHistogramPointers.size() && fHistogramPointers[index]!=NULL)
979     fHistogramPointers[index]->Fill(charge);
980 }
981
982 void AliHLTTPCDataCompressionMonitorComponent::AliDataContainer::FillQMax(unsigned qmax, AliHLTUInt32_t /*clusterId*/)
983 {
984   /// fill qmax histogram
985   fCurrentCluster.SetQMax(qmax);
986   unsigned index=kHistogramQMax;
987   if (index<fHistogramPointers.size() && fHistogramPointers[index]!=NULL)
988     fHistogramPointers[index]->Fill(qmax);
989
990   index=kHistogramQMaxSector;
991   if (index<fHistogram2DPointers.size() && fHistogram2DPointers[index]!=NULL)
992     fHistogram2DPointers[index]->Fill(fSector,qmax);
993 }
994
995 void AliHLTTPCDataCompressionMonitorComponent::AliDataContainer::Fill(int slice, int partition, AliHLTUInt32_t clusterId)
996 {
997   /// fill cluster histograms requiring the full cluster information
998   
999   // TODO: the complete filling of histograms can be moved to this function
1000   // and the cluster struct be filled in the iterator
1001   // The delta histograms are filled here either by using the specified
1002   // cluster, or the nearest cluster on the padrow with identical charge
1003   // and qmax is searched for comparison.
1004   if (clusterId==kAliHLTVoidDataSpec) {
1005     clusterId=FindNearestCluster(slice, partition, fCurrentCluster);
1006   }
1007   if (clusterId==kAliHLTVoidDataSpec) return;
1008   bool bResidualError=false;
1009   int currentRow=fCurrentCluster.GetPadRow();
1010
1011     unsigned index=kHistogramDeltaPadrow;
1012     if (index<fHistogramPointers.size() && fHistogramPointers[index]!=NULL && fRawData) {
1013       if (fRawData->Check(clusterId)) {
1014         fHistogramPointers[index]->Fill(fCurrentCluster.GetPadRow()-fRawData->GetX(clusterId));
1015       }
1016     }
1017
1018     index=kHistogramDeltaPad;
1019     if (index<fHistogramPointers.size() && fHistogramPointers[index]!=NULL && fRawData) {
1020       if (fRawData->Check(clusterId)) {
1021         float dPad=fCurrentCluster.GetPad()-fRawData->GetY(clusterId);
1022         fHistogramPointers[index]->Fill(dPad);
1023         static const float maxdPad=0.015; // better 100um for 4 and 6mm pad width
1024         if (TMath::Abs(dPad)>maxdPad) {
1025           //HLTError("cluster 0x%08x slice %d partition %d: pad difference %f - max %f", clusterId, slice, partition, dPad, maxdPad);
1026           bResidualError=true;
1027         }
1028       }
1029     }
1030
1031     index=kHistogramDeltaTime;
1032     if (index<fHistogramPointers.size() && fHistogramPointers[index]!=NULL && fRawData) {
1033       if (fRawData->Check(clusterId)) {
1034         float dTime=fCurrentCluster.GetTime()-fRawData->GetZ(clusterId);
1035         fHistogramPointers[index]->Fill(dTime);
1036         static const float maxdTime=0.04; // corresponds to 100um
1037         if (TMath::Abs(dTime)>maxdTime) {
1038           //HLTError("cluster 0x%08x slice %d partition %d: time difference %f - max %f", clusterId, slice, partition, dTime, maxdTime);
1039           bResidualError=true;
1040         }
1041       }
1042     }
1043
1044     index=kHistogramDeltaSigmaY2;
1045     if (index<fHistogramPointers.size() && fHistogramPointers[index]!=NULL && fRawData) {
1046       if (fRawData->Check(clusterId)) {
1047         float factor=AliHLTTPCDefinitions::fgkClusterParameterDefinitions[AliHLTTPCDefinitions::kSigmaY2].fScale;
1048         float sigma=fRawData->GetYWidth(clusterId)*factor;
1049         if (sigma>fMaxSigmaY2Scaled) sigma=fMaxSigmaY2Scaled;
1050         sigma/=factor;
1051         fHistogramPointers[index]->Fill(fCurrentCluster.GetSigmaY2()-sigma);
1052       }
1053     }
1054
1055     index=kHistogramDeltaSigmaZ2;
1056     if (index<fHistogramPointers.size() && fHistogramPointers[index]!=NULL && fRawData) {
1057       if (fRawData->Check(clusterId)) {
1058         float factor=AliHLTTPCDefinitions::fgkClusterParameterDefinitions[AliHLTTPCDefinitions::kSigmaZ2].fScale;
1059         float sigma=fRawData->GetZWidth(clusterId)*factor;
1060         if (sigma>fMaxSigmaZ2Scaled) sigma=fMaxSigmaZ2Scaled;
1061         sigma/=factor;
1062         fHistogramPointers[index]->Fill(fCurrentCluster.GetSigmaZ2()-sigma);
1063       }
1064     }
1065
1066     index=kHistogramDeltaCharge;
1067     if (index<fHistogramPointers.size() && fHistogramPointers[index]!=NULL && fRawData) {
1068       if (fRawData->Check(clusterId)) {
1069         fHistogramPointers[index]->Fill(fCurrentCluster.GetCharge()-fRawData->GetCharge(clusterId));
1070       }
1071     }
1072
1073     index=kHistogramDeltaQMax;
1074     if (index<fHistogramPointers.size() && fHistogramPointers[index]!=NULL && fRawData) {
1075       if (fRawData->Check(clusterId)) {
1076         fHistogramPointers[index]->Fill(fCurrentCluster.GetQMax()-fRawData->GetQMax(clusterId));
1077       }
1078     }
1079
1080     if (bResidualError) {
1081     index=kHistogramOutOfRange;
1082     if (index<fHistogramPointers.size() && fHistogramPointers[index]!=NULL && fRawData) {
1083       fHistogramPointers[index]->Fill(currentRow>=0?currentRow:0);
1084     }
1085     }
1086
1087     index=kHistogramHWCFPad;
1088     if (index<fHistogramPointers.size() && fHistogramPointers[index]!=NULL && fRawData)
1089       fHistogramPointers[index]->Fill(fRawData->GetY(clusterId));
1090 }
1091
1092 void AliHLTTPCDataCompressionMonitorComponent::AliDataContainer::Clear(Option_t * option)
1093 {
1094   /// internal cleanup
1095   if (fRawData) fRawData->Clear(option);
1096 }
1097
1098 TObject* AliHLTTPCDataCompressionMonitorComponent::AliDataContainer::FindObject(const char *name) const
1099 {
1100   /// get histogram object  
1101   if (!name) return NULL;
1102   if ( strcmp(name,"fHistograms")   == 0 )
1103     return fHistograms;
1104   if ( strcmp(name,"fHistograms2D") == 0 )
1105     return fHistograms2D;
1106   if ( strcmp(name,"fHistograms3D") == 0 )
1107     return fHistograms3D;
1108
1109   return NULL;
1110 }