]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/TPCLib/AliHLTTPCHWClusterTransformComponent.cxx
handling the 0.5 offset for pad coordinate in the HWCF data decoder class; all subseq...
[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-=pad*pad;
267          sigmaY2*=padpitch*padpitch;
268          sigmaZ2-=time*time;
269          sigmaZ2*=zwidth*zwidth;
270          c.SetPadRow(padrow);
271          c.SetCharge(charge);
272          c.SetSigmaY2(sigmaY2);
273          c.SetSigmaZ2(sigmaZ2);
274          c.SetQMax(cl.GetQMax());
275
276          Float_t xyz[3];
277          fTransform.Transform( minSlice, padrow, pad, time, xyz );
278          c.SetX(xyz[0]);
279          c.SetY(xyz[1]);
280          c.SetZ(xyz[2]);
281
282          // set the cluster ID so that the cluster dump printout is the same for FCF and SCF
283          c.SetID( minSlice, minPartition, outPtr->fSpacePointCnt );
284          
285          HLTDebug("Cluster number %d: %f, Y: %f, Z: %f, charge: %d \n", outPtr->fSpacePointCnt, cluster.fX, cluster.fY, cluster.fZ, (UInt_t)cluster.fCharge);
286          
287          outPtr->fSpacePointCnt++; 
288        } // end of loop over clusters
289      }     
290      HLTDebug("Number of found clusters: %d", outPtr->fSpacePointCnt);
291      
292      UInt_t mysize = sizeof(AliHLTTPCClusterData) + sizeof(AliHLTTPCSpacePointData)*outPtr->fSpacePointCnt;
293  
294      AliHLTComponentBlockData bd;
295      FillBlockData( bd );
296      bd.fOffset = size;
297      bd.fSize = mysize;
298      bd.fSpecification = iter->fSpecification;     
299      if(fDataId==kFALSE) bd.fDataType = AliHLTTPCDefinitions::fgkClustersDataType;
300      else                bd.fDataType = AliHLTTPCDefinitions::fgkAlterClustersDataType;
301      
302      //HLTDebug("datatype: %s", DataType2Text(bd.fDataType).c_str());
303      
304      outputBlocks.push_back( bd );
305      
306      fBenchmark.AddOutput(bd.fSize);    
307      size   += mysize;
308      outputPtr += mysize;
309   
310      if (fPublishRawClusters) {
311
312        long maxRawClusters = ((long)maxOutSize-size-sizeof(AliHLTTPCRawClusterData))/sizeof(AliHLTTPCRawCluster);
313        
314        if( maxRawClusters<=0 ) {
315          HLTWarning("No more space to add raw clusters, exiting!");
316          iResult  = -ENOSPC;
317        } else {       
318
319          // copy raw cluster data from input
320          
321          AliHLTTPCRawClusterData* outputRaw= (AliHLTTPCRawClusterData*)(outputPtr);
322        
323          outputRaw->fVersion = 0;
324          outputRaw->fCount = 0;
325
326          // check if there are clusters available, if not the format might
327          // not even been decoded at that moment 
328          if (fpDecoder->GetNumberOfClusters()>0) {
329          for (AliHLTTPCHWCFData::iterator cl=fpDecoder->begin(); cl!=fpDecoder->end(); ++cl) {
330            if(outputRaw->fCount>=maxRawClusters){
331              HLTWarning("No more space to add clusters, exiting!");
332              iResult  = -ENOSPC;
333              break;
334            }
335            AliHLTTPCRawCluster &c = outputRaw->fClusters[outputRaw->fCount];
336            int padrow=cl.GetPadRow();
337            if (padrow<0) {
338              // something wrong here, padrow is stored in the cluster header
339              // word which has bit pattern 0x3 in bits bit 30 and 31 which was
340              // not recognized
341              break;
342            }
343            padrow+=AliHLTTPCTransform::GetFirstRow(minPartition);
344            AliHLTUInt32_t charge= cl.GetCharge();
345
346            float pad =cl.GetPad();
347            float time =cl.GetTime();
348            float sigmaP2=cl.GetSigmaY2();
349            float sigmaT2=cl.GetSigmaZ2();
350            sigmaP2-=pad*pad;
351            sigmaT2-=time*time;
352            c.SetPadRow(padrow);
353            c.SetCharge(charge);
354            c.SetPad(pad);  
355            c.SetTime(time);
356            c.SetSigmaY2(sigmaP2);
357            c.SetSigmaZ2(sigmaT2);
358            c.SetQMax(cl.GetQMax());
359
360            // store cluster and continue
361            outputRaw->fCount++;
362          }
363          }
364
365          // fill into HLT output data
366          AliHLTComponentBlockData bdRawClusters;
367          FillBlockData( bdRawClusters );
368          bdRawClusters.fOffset = size;
369          bdRawClusters.fSize = sizeof(AliHLTTPCRawClusterData)+outputRaw->fCount*sizeof(AliHLTTPCRawCluster);
370          bdRawClusters.fSpecification = iter->fSpecification;
371          bdRawClusters.fDataType = AliHLTTPCDefinitions::fgkRawClustersDataType | kAliHLTDataOriginTPC;
372          outputBlocks.push_back( bdRawClusters );
373          fBenchmark.AddOutput(bdRawClusters.fSize);
374          size   += bdRawClusters.fSize;
375          outputPtr += bdRawClusters.fSize;
376        }
377      }
378   } // end of loop over data blocks  
379   
380   fBenchmark.Stop(0);
381   HLTInfo(fBenchmark.GetStatistics());
382   
383   return iResult;
384 } // end DoEvent()
385
386 int AliHLTTPCHWClusterTransformComponent::ScanConfigurationArgument(int argc, const char** argv){
387
388   // see header file for class documentation
389
390   if (argc<=0) return 0;
391   int i=0;
392   TString argument=argv[i];
393
394   if (argument.CompareTo("-solenoidBz")==0){
395     if (++i>=argc) return -EPROTO;
396     argument=argv[i];
397     AliTPCcalibDB*  calib=AliTPCcalibDB::Instance();
398     if(!calib){
399       HLTError("CalibDB instance cannot be created.");
400       return 0;
401     }
402     Float_t magneticField = argument.Atof();
403     calib->SetExBField(magneticField);
404     HLTInfo("SolenoidBz is set to %f in the calibDB",magneticField);
405     return 2;
406   }
407
408   if (argument.CompareTo("-change-dataId")==0){
409     HLTDebug("Change data ID received.");
410     fDataId = kTRUE;
411     return 1;
412   }
413   
414   if (argument.CompareTo("-charge-threshold")==0) {
415     if (++i>=argc) return -EPROTO;
416     argument=argv[i];    
417     HLTInfo("The argument -charge-threshold is deprecated.");
418     return 2;
419   }    
420
421   if (argument.CompareTo("-publish-raw")==0) {
422     fPublishRawClusters=kTRUE;
423     return 1;
424   }  
425   
426   // unknown argument
427   return -EINVAL;
428 }
429
430 int AliHLTTPCHWClusterTransformComponent::Reconfigure(const char* /*cdbEntry*/, const char* /*chainId*/) { 
431   // see header file for class documentation
432   return ConfigureFromCDBTObjString(fgkOCDBEntryHWTransform);
433 }
434
435 void AliHLTTPCHWClusterTransformComponent::PrintDebug(AliHLTUInt32_t *buffer, Int_t size){
436 // see header file for class documentation 
437
438   HLTInfo("The size is: %d", size);
439   for(Int_t n32bit=0; n32bit<size; n32bit++){
440     
441     AliHLTUInt8_t *wordPtr = reinterpret_cast<AliHLTUInt8_t*>(&buffer[n32bit]);
442     //    cout << "word ptr initialized"<<endl;
443     for(Int_t w=3;w>=0;w--){
444       //     cout <<"accessing word"<<endl;
445       AliHLTUInt8_t word = wordPtr[w];
446       //     cout<< "word was accessed"<<endl; 
447       for(int n=7; n>=0; n--){
448         //print the byte values
449         if((((word>>n)<<7)&0x80) != 0){
450           printf("1");
451         }
452         else{
453           printf("0");
454         }
455       }
456       printf("  ");
457     }
458     printf("\n");
459   }
460 } // end of PrintDebug
461
462 void AliHLTTPCHWClusterTransformComponent::GetOCDBObjectDescription( TMap* const targetMap)
463 {
464   // Get a list of OCDB object description needed for the particular component
465   if (!targetMap) return;
466   
467   // OCDB entries for component arguments
468
469   targetMap->Add(new TObjString("HLT/ConfigTPC/TPCHWClusterTransform"), new TObjString("component argument for the charge threshold"));
470   
471   // OCDB entries to be fetched by the TAXI (access via the AliTPCcalibDB class)
472   targetMap->Add(new TObjString("TPC/Calib/Parameters"),    new TObjString("unknown content"));
473   targetMap->Add(new TObjString("TPC/Calib/TimeDrift"),     new TObjString("drift velocity calibration"));
474   targetMap->Add(new TObjString("TPC/Calib/Temperature"),   new TObjString("temperature map"));
475   targetMap->Add(new TObjString("TPC/Calib/PadGainFactor"), new TObjString("gain factor pad by pad"));
476   targetMap->Add(new TObjString("TPC/Calib/ClusterParam"),  new TObjString("cluster parameters"));
477   
478   // OCDB entries needed to be fetched by the Pendolino
479   targetMap->Add(new TObjString("TPC/Calib/AltroConfig"), new TObjString("contains the altro config, e.g. info about the L0 trigger timing"));
480   targetMap->Add(new TObjString("GRP/CTP/CTPtiming"),     new TObjString("content used in the cluster coordinate transformation in relation to the L0 trigger timing"));
481
482   // OCDB entries necessary for replaying data on the HLT cluster
483   targetMap->Add(new TObjString("GRP/GRP/Data"), new TObjString("contains magnetic field info"));  
484  
485   // OCDB entries needed to suppress fatals/errors/warnings during reconstruction
486   targetMap->Add(new TObjString("TPC/Calib/PadTime0"),    new TObjString("time0 offset pad by pad"));
487   targetMap->Add(new TObjString("TPC/Calib/PadNoise"),    new TObjString("pad noise values"));
488   targetMap->Add(new TObjString("TPC/Calib/Pedestals"),   new TObjString("pedestal info"));
489   targetMap->Add(new TObjString("TPC/Calib/Pulser"),      new TObjString("pulser info"));
490   targetMap->Add(new TObjString("TPC/Calib/CE"),          new TObjString("CE laser calibration result"));
491   targetMap->Add(new TObjString("TPC/Calib/Raw"),         new TObjString("unknown content"));
492   targetMap->Add(new TObjString("TPC/Calib/QA"),          new TObjString("not important"));
493   targetMap->Add(new TObjString("TPC/Calib/Mapping"),     new TObjString("unknown content"));
494   targetMap->Add(new TObjString("TPC/Calib/Goofie"),      new TObjString("Goofie values, not used at the moment (05.03.2010)"));
495   targetMap->Add(new TObjString("TPC/Calib/HighVoltage"), new TObjString("high voltage values, not used"));
496   targetMap->Add(new TObjString("TPC/Calib/Ref"),         new TObjString("unknown content"));
497 }