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