Qmax for merged clusters fixed
[u/mrichter/AliRoot.git] / HLT / TPCLib / AliHLTTPCHWClusterTransformComponent.cxx
1 // $Id$
2
3 //**************************************************************************
4 //* This file is property of and copyright by the ALICE HLT Project        *
5 //* ALICE Experiment at CERN, All rights reserved.                         *
6 //*                                                                        *
7 //* Primary Authors: Kalliopi Kanaki <Kalliopi.Kanaki@ift.uib.no>          *
8 //*                  for The ALICE HLT Project.                            *
9 //*                                                                        *
10 //* Permission to use, copy, modify and distribute this software and its   *
11 //* documentation strictly for non-commercial purposes is hereby granted   *
12 //* without fee, provided that the above copyright notice appears in all   *
13 //* copies and that both the copyright notice and this permission notice   *
14 //* appear in the supporting documentation. The authors make no claims     *
15 //* about the suitability of this software for any purpose. It is          *
16 //* provided "as is" without express or implied warranty.                  *
17 //**************************************************************************
18
19 /** @file   AliHLTTPCHWClusterTransformComponent.cxx
20     @author Kalliopi Kanaki
21     @date   
22     @brief 
23 */
24
25 #if __GNUC__>= 3
26 using namespace std;
27 #endif
28 #include "AliHLTTPCHWClusterTransformComponent.h"
29 #include "AliHLTTPCDefinitions.h"
30 #include "AliHLTTPCTransform.h"
31 #include "AliHLTTPCSpacePointData.h"
32 #include "AliHLTTPCClusterDataFormat.h"
33 #include "AliRawDataHeader.h"
34 #include "AliHLTTPCRawCluster.h"
35 #include "AliHLTTPCHWCFEmulator.h"
36 #include "AliHLTTPCHWCFData.h"
37 #include "AliHLTErrorGuard.h"
38
39 #include "AliCDBManager.h"
40 #include "AliCDBEntry.h"
41 #include "AliTPCcalibDB.h"
42
43 #include "TMath.h"
44 #include "TObjString.h" 
45 #include <cstdlib>
46 #include <cerrno>
47 #include <sys/time.h>
48
49 ClassImp(AliHLTTPCHWClusterTransformComponent) //ROOT macro for the implementation of ROOT specific class methods
50
51 const char* AliHLTTPCHWClusterTransformComponent::fgkOCDBEntryHWTransform="HLT/ConfigTPC/TPCHWClusterTransform";
52
53 AliHLTTPCHWClusterTransformComponent::AliHLTTPCHWClusterTransformComponent()
54 :
55 fDataId(kFALSE),
56 fTransform(),
57 fPublishRawClusters(kFALSE),
58 fpDecoder(NULL),
59 fBenchmark("HWClusterTransform")
60 {
61   // see header file for class documentation
62   // or
63   // refer to README to build package
64   // or
65   // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt  
66
67   fBenchmark.Reset();
68   fBenchmark.SetTimer(0,"total");
69 }
70
71 AliHLTTPCHWClusterTransformComponent::~AliHLTTPCHWClusterTransformComponent()
72
73   // destructor
74   if (!fpDecoder) delete fpDecoder;
75   fpDecoder=NULL;
76 }
77
78 const char* AliHLTTPCHWClusterTransformComponent::GetComponentID() { 
79 // see header file for class documentation
80
81   return "TPCHWClusterTransform";
82 }
83
84 void AliHLTTPCHWClusterTransformComponent::GetInputDataTypes( vector<AliHLTComponentDataType>& list) { 
85   // see header file for class documentation
86
87   list.clear(); 
88   list.push_back( AliHLTTPCDefinitions::fgkHWClustersDataType );
89 }
90
91 AliHLTComponentDataType AliHLTTPCHWClusterTransformComponent::GetOutputDataType() { 
92   // see header file for class documentation
93
94   return AliHLTTPCDefinitions::fgkClustersDataType;
95 }
96
97 int AliHLTTPCHWClusterTransformComponent::GetOutputDataTypes(AliHLTComponentDataTypeList& tgtList) { 
98   // see header file for class documentation
99
100   tgtList.clear();
101   tgtList.push_back(AliHLTTPCDefinitions::fgkClustersDataType| kAliHLTDataOriginTPC);
102   tgtList.push_back(AliHLTTPCDefinitions::fgkAliHLTDataTypeClusterMCInfo | kAliHLTDataOriginTPC );
103   tgtList.push_back(AliHLTTPCDefinitions::fgkRawClustersDataType  | kAliHLTDataOriginTPC );
104   return tgtList.size();
105 }
106
107 void AliHLTTPCHWClusterTransformComponent::GetOutputDataSize( unsigned long& constBase, double& inputMultiplier ) { 
108   // see header file for class documentation
109   constBase = 0;
110   inputMultiplier = 3.0;
111 }
112
113 AliHLTComponent* AliHLTTPCHWClusterTransformComponent::Spawn() { 
114   // see header file for class documentation
115
116   return new AliHLTTPCHWClusterTransformComponent();
117 }
118         
119 int AliHLTTPCHWClusterTransformComponent::DoInit( int argc, const char** argv ) { 
120 // see header file for class documentation
121   
122   AliTPCcalibDB *calib=AliTPCcalibDB::Instance();  
123   if(!calib){
124     HLTError("AliTPCcalibDB does not exist");
125     return -ENOENT;
126   }
127   calib->SetRun(GetRunNo());
128   calib->UpdateRunInformations(GetRunNo());
129
130   int err = fTransform.Init( GetBz(), GetTimeStamp() );
131
132   if( err!=0 ){
133     HLTError("Cannot retrieve offline transform from AliTPCcalibDB");
134     return -ENOENT;
135   }
136
137   int iResult=0;
138   iResult = ConfigureFromCDBTObjString(fgkOCDBEntryHWTransform);
139
140   if (iResult>=0 && argc>0)
141     iResult=ConfigureFromArgumentString(argc, argv);
142
143   if (iResult>=0) {
144     fpDecoder=new AliHLTTPCHWCFData;
145     if (!fpDecoder) iResult=-ENOMEM;
146   }
147   
148   return iResult;
149 } // end DoInit()
150
151 int AliHLTTPCHWClusterTransformComponent::DoDeinit() { 
152   // see header file for class documentation   
153   if (!fpDecoder) delete fpDecoder;
154   fpDecoder=NULL;
155
156   return 0;
157 }
158
159 int AliHLTTPCHWClusterTransformComponent::DoEvent(const AliHLTComponentEventData& evtData, 
160                                                   const AliHLTComponentBlockData* blocks, 
161                                                   AliHLTComponentTriggerData& /*trigData*/, AliHLTUInt8_t* outputPtr, 
162                                                   AliHLTUInt32_t& size, 
163                                                   vector<AliHLTComponentBlockData>& outputBlocks ){
164   // see header file for class documentation
165    
166   UInt_t maxOutSize = size;
167   size = 0;
168   int iResult = 0;
169   if(!IsDataEvent()) return 0;
170
171   if (!fpDecoder) return -ENODEV;
172
173   fBenchmark.StartNewEvent();
174   fBenchmark.Start(0);
175
176   fTransform.SetCurrentTimeStamp( GetTimeStamp() );
177   
178   for( unsigned long ndx=0; ndx<evtData.fBlockCnt; ndx++ ){
179      
180     const AliHLTComponentBlockData *iter   = blocks+ndx;
181     
182     fBenchmark.AddInput(iter->fSize);
183     
184     HLTDebug("Event 0x%08LX (%Lu) received datatype: %s - required datatype: %s",
185              evtData.fEventID, evtData.fEventID, 
186              DataType2Text( iter->fDataType).c_str(), 
187              DataType2Text(AliHLTTPCDefinitions::fgkHWClustersDataType).c_str());                       
188  
189     if(iter->fDataType == (AliHLTTPCDefinitions::fgkAliHLTDataTypeClusterMCInfo | kAliHLTDataOriginTPC) ){
190       // simply forward MC labels
191       
192       if( size+iter->fSize > maxOutSize ){
193         HLTWarning( "Output buffer (%db) is too small, required %db", maxOutSize, size+iter->fSize);
194         iResult  = -ENOSPC;
195         break;
196       }
197
198       memcpy( outputPtr, iter->fPtr, iter->fSize );
199       
200       AliHLTComponentBlockData bd;
201       FillBlockData( bd );
202       bd.fOffset = size;
203       bd.fSize = iter->fSize;
204       bd.fSpecification = iter->fSpecification;     
205       bd.fDataType = iter->fDataType;
206       outputBlocks.push_back( bd );     
207       fBenchmark.AddOutput(bd.fSize);    
208       size   += bd.fSize;
209       outputPtr += bd.fSize;
210       continue;
211     }
212
213     if(iter->fDataType != (AliHLTTPCDefinitions::fgkHWClustersDataType | kAliHLTDataOriginTPC)) continue;                        
214         
215     UInt_t minSlice     = AliHLTTPCDefinitions::GetMinSliceNr(*iter); 
216     UInt_t minPartition = AliHLTTPCDefinitions::GetMinPatchNr(*iter);
217     //UInt_t maxSlice     = AliHLTTPCDefinitions::GetMaxSliceNr(*iter); 
218     //UInt_t maxPartition = AliHLTTPCDefinitions::GetMaxPatchNr(*iter);
219     float padpitch=1.0;
220     if ((int)minPartition<AliHLTTPCTransform::GetNRowLow())
221       padpitch=AliHLTTPCTransform::GetPadPitchWidthLow();
222     else
223       padpitch=AliHLTTPCTransform::GetPadPitchWidthUp();
224     float zwidth=AliHLTTPCTransform::GetZWidth();
225
226     fBenchmark.SetName(Form("HWClusterTransform slice %d patch %d",minSlice,minPartition));
227
228     HLTDebug("minSlice: %d, minPartition: %d", minSlice, minPartition);
229     
230     AliHLTTPCClusterData* outPtr  = (AliHLTTPCClusterData*)outputPtr;
231     outPtr->fSpacePointCnt=0;
232
233     long maxPoints = ((long)maxOutSize-size-sizeof(AliHLTTPCClusterData))/sizeof(AliHLTTPCSpacePointData);
234
235     AliHLTUInt32_t *buffer;     
236     buffer = (AliHLTUInt32_t*)iter->fPtr;  
237      
238      // skip the first 8 32-bit CDH words
239      buffer += 8;
240      UInt_t bufferSize32 = ((Int_t)iter->fSize - sizeof(AliRawDataHeader) )/sizeof(AliHLTUInt32_t);
241
242      if (fpDecoder->Init(reinterpret_cast<AliHLTUInt8_t*>(buffer), bufferSize32*sizeof(AliHLTUInt32_t))>=0 && fpDecoder->CheckVersion()>=0) {
243        for (AliHLTTPCHWCFData::iterator cl=fpDecoder->begin(); cl!=fpDecoder->end(); ++cl) {
244          if(outPtr->fSpacePointCnt>=maxPoints){
245            HLTWarning("No more space to add clusters, exiting!");
246            iResult  = -ENOSPC;
247            break;
248          }
249
250          AliHLTTPCSpacePointData& c=outPtr->fSpacePoints[outPtr->fSpacePointCnt];
251          int padrow=cl.GetPadRow();
252          if (padrow<0) {
253            // something wrong here, padrow is stored in the cluster header
254            // word which has bit pattern 0x3 in bits bit 30 and 31 which was
255            // not recognized
256            ALIHLTERRORGUARD(1, "can not read cluster header word");
257            break;
258          }
259          padrow+=AliHLTTPCTransform::GetFirstRow(minPartition);
260          AliHLTUInt32_t charge=cl.GetCharge();
261
262          float pad=cl.GetPad();
263          float time=cl.GetTime();
264          float sigmaY2=cl.GetSigmaY2();
265          float sigmaZ2=cl.GetSigmaZ2();
266          sigmaY2*=padpitch*padpitch;
267          sigmaZ2*=zwidth*zwidth;
268          c.SetPadRow(padrow);
269          c.SetCharge(charge);
270          c.SetSigmaY2(sigmaY2);
271          c.SetSigmaZ2(sigmaZ2);
272          c.SetQMax(cl.GetQMax());
273
274          Float_t xyz[3];
275          fTransform.Transform( minSlice, padrow, pad, time, xyz );
276          c.SetX(xyz[0]);
277          c.SetY(xyz[1]);
278          c.SetZ(xyz[2]);
279
280          // set the cluster ID so that the cluster dump printout is the same for FCF and SCF
281          c.SetID( minSlice, minPartition, outPtr->fSpacePointCnt );
282          
283          HLTDebug("Cluster number %d: %f, Y: %f, Z: %f, charge: %d \n", outPtr->fSpacePointCnt, cluster.fX, cluster.fY, cluster.fZ, (UInt_t)cluster.fCharge);
284          
285          outPtr->fSpacePointCnt++; 
286        } // end of loop over clusters
287      }     
288      HLTDebug("Number of found clusters: %d", outPtr->fSpacePointCnt);
289      
290      UInt_t mysize = sizeof(AliHLTTPCClusterData) + sizeof(AliHLTTPCSpacePointData)*outPtr->fSpacePointCnt;
291  
292      AliHLTComponentBlockData bd;
293      FillBlockData( bd );
294      bd.fOffset = size;
295      bd.fSize = mysize;
296      bd.fSpecification = iter->fSpecification;     
297      if(fDataId==kFALSE) bd.fDataType = AliHLTTPCDefinitions::fgkClustersDataType;
298      else                bd.fDataType = AliHLTTPCDefinitions::fgkAlterClustersDataType;
299      
300      //HLTDebug("datatype: %s", DataType2Text(bd.fDataType).c_str());
301      
302      outputBlocks.push_back( bd );
303      
304      fBenchmark.AddOutput(bd.fSize);    
305      size   += mysize;
306      outputPtr += mysize;
307   
308      if (fPublishRawClusters) {
309
310        long maxRawClusters = ((long)maxOutSize-size-sizeof(AliHLTTPCRawClusterData))/sizeof(AliHLTTPCRawCluster);
311        
312        if( maxRawClusters<=0 ) {
313          HLTWarning("No more space to add raw clusters, exiting!");
314          iResult  = -ENOSPC;
315        } else {       
316
317          // copy raw cluster data from input
318          
319          AliHLTTPCRawClusterData* outputRaw= (AliHLTTPCRawClusterData*)(outputPtr);
320        
321          outputRaw->fVersion = 0;
322          outputRaw->fCount = 0;
323
324          // check if there are clusters available, if not the format might
325          // not even been decoded at that moment 
326          if (fpDecoder->GetNumberOfClusters()>0) {
327          for (AliHLTTPCHWCFData::iterator cl=fpDecoder->begin(); cl!=fpDecoder->end(); ++cl) {
328            if(outputRaw->fCount>=maxRawClusters){
329              HLTWarning("No more space to add clusters, exiting!");
330              iResult  = -ENOSPC;
331              break;
332            }
333            AliHLTTPCRawCluster &c = outputRaw->fClusters[outputRaw->fCount];
334            int padrow=cl.GetPadRow();
335            if (padrow<0) {
336              // something wrong here, padrow is stored in the cluster header
337              // word which has bit pattern 0x3 in bits bit 30 and 31 which was
338              // not recognized
339              break;
340            }
341            padrow+=AliHLTTPCTransform::GetFirstRow(minPartition);
342            AliHLTUInt32_t charge= cl.GetCharge();
343
344            float pad =cl.GetPad();
345            float time =cl.GetTime();
346            float sigmaP2=cl.GetSigmaY2();
347            float sigmaT2=cl.GetSigmaZ2();
348            c.SetPadRow(padrow);
349            c.SetCharge(charge);
350            c.SetPad(pad);  
351            c.SetTime(time);
352            c.SetSigmaY2(sigmaP2);
353            c.SetSigmaZ2(sigmaT2);
354            c.SetQMax(cl.GetQMax());
355
356            // store cluster and continue
357            outputRaw->fCount++;
358          }
359          }
360
361          // fill into HLT output data
362          AliHLTComponentBlockData bdRawClusters;
363          FillBlockData( bdRawClusters );
364          bdRawClusters.fOffset = size;
365          bdRawClusters.fSize = sizeof(AliHLTTPCRawClusterData)+outputRaw->fCount*sizeof(AliHLTTPCRawCluster);
366          bdRawClusters.fSpecification = iter->fSpecification;
367          bdRawClusters.fDataType = AliHLTTPCDefinitions::fgkRawClustersDataType | kAliHLTDataOriginTPC;
368          outputBlocks.push_back( bdRawClusters );
369          fBenchmark.AddOutput(bdRawClusters.fSize);
370          size   += bdRawClusters.fSize;
371          outputPtr += bdRawClusters.fSize;
372        }
373      }
374   } // end of loop over data blocks  
375   
376   fBenchmark.Stop(0);
377   HLTInfo(fBenchmark.GetStatistics());
378   
379   return iResult;
380 } // end DoEvent()
381
382 int AliHLTTPCHWClusterTransformComponent::ScanConfigurationArgument(int argc, const char** argv){
383
384   // see header file for class documentation
385
386   if (argc<=0) return 0;
387   int i=0;
388   TString argument=argv[i];
389
390   if (argument.CompareTo("-solenoidBz")==0){
391     if (++i>=argc) return -EPROTO;
392     argument=argv[i];
393     AliTPCcalibDB*  calib=AliTPCcalibDB::Instance();
394     if(!calib){
395       HLTError("CalibDB instance cannot be created.");
396       return 0;
397     }
398     Float_t magneticField = argument.Atof();
399     calib->SetExBField(magneticField);
400     HLTInfo("SolenoidBz is set to %f in the calibDB",magneticField);
401     return 2;
402   }
403
404   if (argument.CompareTo("-change-dataId")==0){
405     HLTDebug("Change data ID received.");
406     fDataId = kTRUE;
407     return 1;
408   }
409   
410   if (argument.CompareTo("-charge-threshold")==0) {
411     if (++i>=argc) return -EPROTO;
412     argument=argv[i];    
413     HLTInfo("The argument -charge-threshold is deprecated.");
414     return 2;
415   }    
416
417   if (argument.CompareTo("-publish-raw")==0) {
418     fPublishRawClusters=kTRUE;
419     return 1;
420   }  
421   
422   // unknown argument
423   return -EINVAL;
424 }
425
426 int AliHLTTPCHWClusterTransformComponent::Reconfigure(const char* /*cdbEntry*/, const char* /*chainId*/) { 
427   // see header file for class documentation
428   return ConfigureFromCDBTObjString(fgkOCDBEntryHWTransform);
429 }
430
431 void AliHLTTPCHWClusterTransformComponent::PrintDebug(AliHLTUInt32_t *buffer, Int_t size){
432 // see header file for class documentation 
433
434   HLTInfo("The size is: %d", size);
435   for(Int_t n32bit=0; n32bit<size; n32bit++){
436     
437     AliHLTUInt8_t *wordPtr = reinterpret_cast<AliHLTUInt8_t*>(&buffer[n32bit]);
438     //    cout << "word ptr initialized"<<endl;
439     for(Int_t w=3;w>=0;w--){
440       //     cout <<"accessing word"<<endl;
441       AliHLTUInt8_t word = wordPtr[w];
442       //     cout<< "word was accessed"<<endl; 
443       for(int n=7; n>=0; n--){
444         //print the byte values
445         if((((word>>n)<<7)&0x80) != 0){
446           printf("1");
447         }
448         else{
449           printf("0");
450         }
451       }
452       printf("  ");
453     }
454     printf("\n");
455   }
456 } // end of PrintDebug
457
458 void AliHLTTPCHWClusterTransformComponent::GetOCDBObjectDescription( TMap* const targetMap)
459 {
460   // Get a list of OCDB object description needed for the particular component
461   if (!targetMap) return;
462   
463   // OCDB entries for component arguments
464
465   targetMap->Add(new TObjString("HLT/ConfigTPC/TPCHWClusterTransform"), new TObjString("component argument for the charge threshold"));
466   
467   // OCDB entries to be fetched by the TAXI (access via the AliTPCcalibDB class)
468   targetMap->Add(new TObjString("TPC/Calib/Parameters"),    new TObjString("unknown content"));
469   targetMap->Add(new TObjString("TPC/Calib/TimeDrift"),     new TObjString("drift velocity calibration"));
470   targetMap->Add(new TObjString("TPC/Calib/Temperature"),   new TObjString("temperature map"));
471   targetMap->Add(new TObjString("TPC/Calib/PadGainFactor"), new TObjString("gain factor pad by pad"));
472   targetMap->Add(new TObjString("TPC/Calib/ClusterParam"),  new TObjString("cluster parameters"));
473   
474   // OCDB entries needed to be fetched by the Pendolino
475   targetMap->Add(new TObjString("TPC/Calib/AltroConfig"), new TObjString("contains the altro config, e.g. info about the L0 trigger timing"));
476   targetMap->Add(new TObjString("GRP/CTP/CTPtiming"),     new TObjString("content used in the cluster coordinate transformation in relation to the L0 trigger timing"));
477
478   // OCDB entries necessary for replaying data on the HLT cluster
479   targetMap->Add(new TObjString("GRP/GRP/Data"), new TObjString("contains magnetic field info"));  
480  
481   // OCDB entries needed to suppress fatals/errors/warnings during reconstruction
482   targetMap->Add(new TObjString("TPC/Calib/PadTime0"),    new TObjString("time0 offset pad by pad"));
483   targetMap->Add(new TObjString("TPC/Calib/PadNoise"),    new TObjString("pad noise values"));
484   targetMap->Add(new TObjString("TPC/Calib/Pedestals"),   new TObjString("pedestal info"));
485   targetMap->Add(new TObjString("TPC/Calib/Pulser"),      new TObjString("pulser info"));
486   targetMap->Add(new TObjString("TPC/Calib/CE"),          new TObjString("CE laser calibration result"));
487   targetMap->Add(new TObjString("TPC/Calib/Raw"),         new TObjString("unknown content"));
488   targetMap->Add(new TObjString("TPC/Calib/QA"),          new TObjString("not important"));
489   targetMap->Add(new TObjString("TPC/Calib/Mapping"),     new TObjString("unknown content"));
490   targetMap->Add(new TObjString("TPC/Calib/Goofie"),      new TObjString("Goofie values, not used at the moment (05.03.2010)"));
491   targetMap->Add(new TObjString("TPC/Calib/HighVoltage"), new TObjString("high voltage values, not used"));
492   targetMap->Add(new TObjString("TPC/Calib/Ref"),         new TObjString("unknown content"));
493 }