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