Update of the SSD on-line clusterfinder:
[u/mrichter/AliRoot.git] / HLT / ITS / AliHLTITSClusterFinderComponent.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: Gaute Øvrebekk <st05886@alf.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   AliHLTITSClusterFinderComponent.cxx
19     @author Gaute Øvrebekk <st05886@alf.uib.no>
20     @date   
21     @brief  Component to run offline clusterfinders
22 */
23
24 #if __GNUC__>= 3
25 using namespace std;
26 #endif
27
28 #include "AliHLTITSClusterFinderComponent.h" 
29
30 #include "AliCDBEntry.h"
31 #include "AliCDBManager.h"
32 #include "AliHLTDataTypes.h"
33 #include "AliITSgeomTGeo.h"
34 #include "AliITSRecPoint.h"
35 #include "AliHLTITSSpacePointData.h"
36 #include "AliHLTITSClusterDataFormat.h"
37 #include <AliHLTDAQ.h>
38 #include "AliGeomManager.h"
39 #include "AliITSRecoParam.h"
40 #include "AliITSReconstructor.h"
41 #include "AliHLTITSClusterFinderSPD.h"
42 #include "AliHLTITSClusterFinderSSD.h"
43
44 #include <cstdlib>
45 #include <cerrno>
46 #include "TString.h"
47 #include "TObjString.h"
48 #include <sys/time.h>
49
50 /** ROOT macro for the implementation of ROOT specific class methods */
51 ClassImp(AliHLTITSClusterFinderComponent);
52
53 AliHLTITSClusterFinderComponent::AliHLTITSClusterFinderComponent(int mode)
54   :
55   fModeSwitch(mode),
56   fInputDataType(kAliHLTVoidDataType),
57   fOutputDataType(kAliHLTVoidDataType),
58   fUseOfflineFinder(0),
59   fNModules(0),
60   fId(0),
61   fNddl(0),
62   fClusters(NULL),
63   fRawReader(NULL),
64   fDettype(NULL),
65   fgeom(NULL),
66   fgeomInit(NULL),
67   fSPD(NULL),
68   fSSD(NULL),
69   tD(NULL),
70   tR(NULL),
71   fclusters()
72
73   // see header file for class documentation
74   // or
75   // refer to README to build package
76   // or
77   // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
78
79   switch(fModeSwitch){
80   case kClusterFinderSPD:
81     fInputDataType  = kAliHLTDataTypeDDLRaw | kAliHLTDataOriginITSSPD;
82     fOutputDataType = kAliHLTDataTypeClusters|kAliHLTDataOriginITSSPD;
83     break;
84   case kClusterFinderSDD:        
85     fInputDataType  = kAliHLTDataTypeDDLRaw | kAliHLTDataOriginITSSDD;
86     fOutputDataType = kAliHLTDataTypeClusters|kAliHLTDataOriginITSSDD;
87     break;
88   case kClusterFinderSSD:
89     fInputDataType  = kAliHLTDataTypeDDLRaw | kAliHLTDataOriginITSSSD;
90     fOutputDataType = kAliHLTDataTypeClusters|kAliHLTDataOriginITSSSD;
91     break;
92   case kClusterFinderDigits:
93     fInputDataType  = kAliHLTDataTypeAliTreeD|kAliHLTDataOriginITS;
94     fOutputDataType = kAliHLTDataTypeClusters|kAliHLTDataOriginITS;
95     break;
96   default:
97     HLTFatal("unknown cluster finder");
98   }
99 }
100
101 AliHLTITSClusterFinderComponent::~AliHLTITSClusterFinderComponent() 
102 {
103   // see header file for class documentation
104   delete fRawReader;
105   delete fDettype;
106   delete fgeomInit;  
107   delete fSPD;
108   delete fSSD;
109 }
110
111 // Public functions to implement AliHLTComponent's interface.
112 // These functions are required for the registration process
113
114 const char* AliHLTITSClusterFinderComponent::GetComponentID()
115 {
116   // see header file for class documentation
117   switch(fModeSwitch){
118   case kClusterFinderSPD:
119     return "ITSClusterFinderSPD";
120     break;
121   case kClusterFinderSDD:        
122     return "ITSClusterFinderSDD";
123     break;
124   case kClusterFinderSSD:
125     return "ITSClusterFinderSSD";
126     break;
127   case kClusterFinderDigits:
128     return "ITSClusterFinderDigits";
129     break;
130   }
131   return "";
132 }
133
134 void AliHLTITSClusterFinderComponent::GetInputDataTypes( vector<AliHLTComponentDataType>& list) 
135 {
136   // see header file for class documentation
137   list.clear(); 
138   list.push_back( fInputDataType );
139 }
140
141 AliHLTComponentDataType AliHLTITSClusterFinderComponent::GetOutputDataType() 
142 {
143   // see header file for class documentation
144   return fOutputDataType;
145 }
146
147 void AliHLTITSClusterFinderComponent::GetOutputDataSize( unsigned long& constBase, double& inputMultiplier ) {
148   // see header file for class documentation
149   constBase = 0;
150   inputMultiplier = 100;
151 }
152
153 AliHLTComponent* AliHLTITSClusterFinderComponent::Spawn() {
154   // see header file for class documentation
155   return new AliHLTITSClusterFinderComponent(fModeSwitch);
156 }
157         
158 Int_t AliHLTITSClusterFinderComponent::DoInit( int argc, const char** argv ) {
159   // see header file for class documentation
160   /*
161   fStatTime = 0;
162   fStatTimeAll = 0;
163   fStatTimeC = 0;
164   fStatTimeAllC = 0;
165   fStatNEv = 0;
166   */
167   if(fModeSwitch==kClusterFinderSPD) {
168     HLTDebug("using ClusterFinder for SPD");
169     //fNModules=AliITSgeomTGeo::GetNDetectors(1)*AliITSgeomTGeo::GetNLadders(1) + AliITSgeomTGeo::GetNDetectors(2)*AliITSgeomTGeo::GetNLadders(2);
170     fId=AliHLTDAQ::DdlIDOffset("ITSSPD");
171     fNddl=AliHLTDAQ::NumberOfDdls("ITSSPD");
172   }
173   else if(fModeSwitch==kClusterFinderSDD) {
174     HLTDebug("using ClusterFinder for SDD");
175     //fNModules=AliITSgeomTGeo::GetNDetectors(3)*AliITSgeomTGeo::GetNLadders(3) + AliITSgeomTGeo::GetNDetectors(4)*AliITSgeomTGeo::GetNLadders(4);
176     fId=AliHLTDAQ::DdlIDOffset("ITSSDD");
177     fNddl=AliHLTDAQ::NumberOfDdls("ITSSDD");
178   }
179   else if(fModeSwitch==kClusterFinderSSD) {
180     HLTDebug("using ClusterFinder for SSD");
181     //fNModules=AliITSgeomTGeo::GetNDetectors(5)*AliITSgeomTGeo::GetNLadders(5) + AliITSgeomTGeo::GetNDetectors(6)*AliITSgeomTGeo::GetNLadders(6);
182     fId=AliHLTDAQ::DdlIDOffset("ITSSSD");
183     fNddl=AliHLTDAQ::NumberOfDdls("ITSSSD");
184   }
185   else if(fModeSwitch==kClusterFinderDigits) {
186     //tR = new TTree();
187   }
188   else{
189      HLTFatal("No mode set for clusterfindercomponent");
190   }
191
192   //Removed the warning for loading default RecoParam in HLT
193   AliITSRecoParam *par = AliITSRecoParam::GetLowFluxParam();
194   AliITSReconstructor *rec = new AliITSReconstructor();
195   rec->SetRecoParam(par);
196   
197   AliCDBManager* man = AliCDBManager::Instance();
198   if (!man->IsDefaultStorageSet()){
199     HLTError("Default CDB storage has not been set !");
200     return -ENOENT;
201   }
202
203   if(AliGeomManager::GetGeometry()==NULL){
204     AliGeomManager::LoadGeometry();
205   }
206
207  //fgeomInit = new AliITSInitGeometry(kvSPD02,2);
208   fgeomInit = new AliITSInitGeometry(kvPPRasymmFMD,2);
209   //fgeomInit->InitAliITSgeom(fgeom);
210   fgeom = fgeomInit->CreateAliITSgeom();
211  
212   fNModules = fgeom->GetIndexMax();
213
214   fClusters = new TClonesArray*[fNModules]; 
215   for (Int_t iModule = 0; iModule < fNModules; iModule++) {
216     fClusters[iModule] = NULL;
217   } 
218
219   //set dettype
220   fDettype = new AliITSDetTypeRec();
221   fDettype->SetITSgeom(fgeom); 
222   fDettype->SetDefaults();
223   fDettype->SetDefaultClusterFindersV2(kTRUE); 
224
225   if ( fRawReader )
226     return -EINPROGRESS;
227
228   fRawReader = new AliRawReaderMemory();
229   fSPD = new AliHLTITSClusterFinderSPD( fDettype );
230   fSSD = new AliHLTITSClusterFinderSSD( fDettype, fRawReader );
231
232   TString arguments = "";
233   for ( int i = 0; i < argc; i++ ) {
234     if ( !arguments.IsNull() ) arguments += " ";
235     arguments += argv[i];
236   }
237
238   tD = NULL;
239   tR = NULL;
240
241   return Configure( arguments.Data() );
242 }
243
244 Int_t AliHLTITSClusterFinderComponent::DoDeinit() {
245   // see header file for class documentation
246
247   if ( fRawReader )
248     delete fRawReader;
249   fRawReader = NULL;
250
251   if ( fDettype )
252     delete fDettype;
253   fDettype = NULL;
254
255   if ( fgeomInit )
256     delete fgeomInit;
257   fgeomInit = NULL;
258   
259   delete fSPD;
260   fSPD = 0;
261
262   delete fSSD;
263   fSSD = 0;
264
265   for (Int_t iModule = 0; iModule < fNModules; iModule++) {
266     if(fClusters[iModule] != NULL){
267       fClusters[iModule]->Delete();
268       delete fClusters[iModule];
269     }
270     fClusters[iModule] = NULL;
271   } 
272   
273   fUseOfflineFinder = 0;
274
275   return 0;
276 }
277
278 // #include "TStopwatch.h"
279
280 int AliHLTITSClusterFinderComponent::DoEvent
281 (
282  const AliHLTComponentEventData& evtData,
283  const AliHLTComponentBlockData* blocks,
284  AliHLTComponentTriggerData& /*trigData*/,
285  AliHLTUInt8_t* outputPtr,
286  AliHLTUInt32_t& size,
287   vector<AliHLTComponentBlockData>& outputBlocks )
288 {
289  // see header file for class documentation
290   
291   AliHLTUInt32_t maxBufferSize = size;
292   size = 0; // output size
293
294   if (!IsDataEvent()) return 0;
295   
296   if ( evtData.fBlockCnt<=0 )
297     {
298       HLTDebug("no blocks in event" );
299       return 0;
300     }
301   
302   // TStopwatch timer;
303   Int_t ret = 0;
304   //std::vector<AliITSRecPoint> vclusters;
305   if(fModeSwitch==kClusterFinderDigits) {
306     for ( const TObject *iter = GetFirstInputObject(fInputDataType); iter != NULL; iter = GetNextInputObject() ) {  
307       tD = dynamic_cast<TTree*>(const_cast<TObject*>( iter ) );
308       if(!tD){
309         HLTFatal("No Digit Tree found");
310         return -1;
311       }
312       tR = new TTree();
313       fDettype->SetTreeAddressD(tD);
314       fDettype->MakeBranch(tR,"R");
315       fDettype->SetTreeAddressR(tR);
316       Option_t *opt="All";
317       fDettype->DigitsToRecPoints(tD,tR,0,opt,kTRUE);
318       
319       TClonesArray * fRecPoints;
320       tR->SetBranchAddress("ITSRecPoints",&fRecPoints);
321       for(Int_t treeEntry=0;treeEntry<tR->GetEntries();treeEntry++){
322         tR->GetEntry(treeEntry);
323         for(Int_t tCloneEntry=0;tCloneEntry<fRecPoints->GetEntries();tCloneEntry++){
324           AliITSRecPoint *recpoint=(AliITSRecPoint*)fRecPoints->At(tCloneEntry);
325           fclusters.push_back(*recpoint);
326         }
327       }
328       
329       if(tR){
330         tR->Delete();
331       }
332       UInt_t nClusters=fclusters.size();
333       
334       UInt_t bufferSize = nClusters * sizeof(AliHLTITSSpacePointData) + sizeof(AliHLTITSClusterData);
335       if( size + bufferSize > maxBufferSize ){
336         HLTWarning( "Output buffer size exceed (buffer size %d, current size %d)", maxBufferSize, size+bufferSize);
337         ret = -ENOSPC;      
338         break;          
339       }
340       if( nClusters>0 ){
341
342         RecPointToSpacePoint(outputPtr,size);
343         
344         AliHLTComponentBlockData bd;
345         FillBlockData( bd );
346         bd.fOffset = size;
347         bd.fSize = bufferSize;
348         bd.fSpecification = 0x00000000;
349         bd.fDataType = GetOutputDataType();
350         outputBlocks.push_back( bd );
351         size += bufferSize;
352         
353         fclusters.clear();      
354       }
355     }
356   }
357   else{
358       
359     // -- Loop over blocks
360     for( const AliHLTComponentBlockData* iter = GetFirstInputBlock(fInputDataType); iter != NULL; iter = GetNextInputBlock() ) {
361       
362       // -- Debug output of datatype --
363       HLTDebug("Event 0x%08LX (%Lu) received datatype: %s - required datatype: %s",
364                evtData.fEventID, evtData.fEventID, 
365                DataType2Text(iter->fDataType).c_str(), 
366                DataType2Text(fInputDataType).c_str());
367       
368       // -- Check for the correct data type
369       if ( iter->fDataType != (fInputDataType) )  
370         continue;
371       
372       // -- Get equipment ID out of specification
373       AliHLTUInt32_t spec = iter->fSpecification;
374       
375       Int_t id = fId;
376       for ( Int_t ii = 0; ii < fNddl ; ii++ ) {   //number of ddl's
377         if ( spec & 0x00000001 ) {
378           id += ii;
379           break;
380         }
381         spec = spec >> 1 ;
382       }
383       
384       // -- Set equipment ID to the raw reader
385       
386       if(!fRawReader->AddBuffer((UChar_t*) iter->fPtr, iter->fSize, id)){
387         HLTWarning("Could not add buffer");
388       }
389       // TStopwatch timer1;
390       
391       if(fModeSwitch==kClusterFinderSPD && !fUseOfflineFinder){ fSPD->RawdataToClusters( fRawReader, fclusters ); }
392       else if(fModeSwitch==kClusterFinderSSD && !fUseOfflineFinder){ fSSD->RawdataToClusters( fclusters ); }
393       else{
394         if(fModeSwitch==kClusterFinderSPD && fUseOfflineFinder) {fDettype->DigitsToRecPoints(fRawReader,fClusters,"SPD");}
395         if(fModeSwitch==kClusterFinderSSD && fUseOfflineFinder) {fDettype->DigitsToRecPoints(fRawReader,fClusters,"SSD");}
396         if(fModeSwitch==kClusterFinderSDD) {fDettype->DigitsToRecPoints(fRawReader,fClusters,"SDD");}
397         for(int i=0;i<fNModules;i++){
398           if(fClusters[i] != NULL){
399             for(int j=0;j<fClusters[i]->GetEntriesFast();j++){
400               AliITSRecPoint *recpoint = (AliITSRecPoint*) (fClusters[i]->At(j));
401               fclusters.push_back(*recpoint);
402             }
403             fClusters[i]->Delete();
404             delete fClusters[i];
405           }
406           fClusters[i] = NULL;
407         }     
408       }
409       
410       // timer1.Stop();
411       // fStatTime+=timer1.RealTime();
412       // fStatTimeC+=timer1.CpuTime();
413       
414       fRawReader->ClearBuffers();    
415          
416       UInt_t nClusters=fclusters.size();
417       
418       UInt_t bufferSize = nClusters * sizeof(AliHLTITSSpacePointData) + sizeof(AliHLTITSClusterData);
419       if( size + bufferSize > maxBufferSize ){
420         HLTWarning( "Output buffer size exceed (buffer size %d, current size %d)", maxBufferSize, size+bufferSize);
421         ret = -ENOSPC;      
422         break;          
423       }
424       if( nClusters>0 ){
425
426         RecPointToSpacePoint(outputPtr,size);
427
428         AliHLTComponentBlockData bd;
429         FillBlockData( bd );
430         bd.fOffset = size;
431         bd.fSize = bufferSize;
432         bd.fSpecification = iter->fSpecification;
433         bd.fDataType = GetOutputDataType();
434         outputBlocks.push_back( bd );
435         size += bufferSize;
436         
437         fclusters.clear();      
438       }
439       
440     } // input blocks
441   }
442   /*
443   timer.Stop();
444   
445   fStatTimeAll+=timer.RealTime();
446   fStatTimeAllC+=timer.CpuTime();
447   fStatNEv++;
448   if( fStatNEv%1000==0 && fStatTimeAll>0.0 && fStatTime>0.0 && fStatTimeAllC>0.0 && fStatTimeC>0.0)
449     cout<<fStatTimeAll/fStatNEv*1.e3<<" "<<fStatTime/fStatNEv*1.e3<<" "
450         <<fStatTimeAllC/fStatNEv*1.e3<<" "<<fStatTimeC/fStatNEv*1.e3<<" ms"<<endl;
451   */
452
453   return ret;
454 }
455
456 int AliHLTITSClusterFinderComponent::Configure(const char* arguments)
457 {
458   
459   int iResult=0;
460   
461   if (!arguments) return iResult;
462   
463   TString allArgs=arguments;
464   TString argument;
465   
466   TObjArray* pTokens=allArgs.Tokenize(" ");
467   
468   if (pTokens) {
469     for (int i=0; i<pTokens->GetEntries() && iResult>=0; i++) {
470       argument=((TObjString*)pTokens->At(i))->GetString();
471       if (argument.IsNull()) continue;      
472       if (argument.CompareTo("-use-offline-finder")==0) {
473         fUseOfflineFinder = 1;
474         HLTInfo("Off-line ClusterFinder will be used");
475         continue;
476       }
477       /*
478       else if (argument.CompareTo("")==0) {
479         HLTInfo("");
480         continue;
481       }
482       */
483       else {
484         HLTError("unknown argument %s", argument.Data());
485         iResult=-EINVAL;
486         break;
487       }
488     }
489     delete pTokens;
490   }
491   
492   return iResult;
493 }
494
495 int AliHLTITSClusterFinderComponent::Reconfigure(const char* cdbEntry, const char* chainId)
496 {
497   // see header file for class documentation
498   int iResult=0;
499   
500   const char* path="HLT/ConfigITS/ClusterFinderComponent";
501   const char* defaultNotify="";
502   if (cdbEntry) {
503     path=cdbEntry;
504     defaultNotify=" (default)";
505   }
506   if (path) {
507     HLTInfo("reconfigure from entry %s%s, chain id %s", path, defaultNotify,(chainId!=NULL && chainId[0]!=0)?chainId:"<none>");
508     AliCDBEntry *pEntry = AliCDBManager::Instance()->Get(path);
509     if (pEntry) {
510       TObjString* pString=dynamic_cast<TObjString*>(pEntry->GetObject());
511       if (pString) {
512         HLTInfo("received configuration object string: \'%s\'", pString->GetString().Data());
513         iResult=Configure(pString->GetString().Data());
514       } else {
515         HLTError("configuration object \"%s\" has wrong type, required TObjString", path);
516       }
517     } else {
518       HLTError("can not fetch object \"%s\" from CDB", path);
519     }
520   }
521   
522   return iResult;
523 }
524 void AliHLTITSClusterFinderComponent::RecPointToSpacePoint(AliHLTUInt8_t* outputPtr,AliHLTUInt32_t& size){
525   AliHLTITSClusterData *outputClusters = reinterpret_cast<AliHLTITSClusterData*>(outputPtr + size);
526   outputClusters->fSpacePointCnt=fclusters.size();    
527   int clustIdx=0;
528   for(int i=0;i<fclusters.size();i++){
529     AliITSRecPoint *recpoint = (AliITSRecPoint*) &(fclusters[i]);
530     outputClusters->fSpacePoints[clustIdx].fY=recpoint->GetY();
531     outputClusters->fSpacePoints[clustIdx].fZ=recpoint->GetZ();
532     outputClusters->fSpacePoints[clustIdx].fSigmaY2=recpoint->GetSigmaY2();
533     outputClusters->fSpacePoints[clustIdx].fSigmaZ2=recpoint->GetSigmaZ2();
534     outputClusters->fSpacePoints[clustIdx].fSigmaYZ=recpoint->GetSigmaYZ();
535     outputClusters->fSpacePoints[clustIdx].fQ=recpoint->GetQ();
536     outputClusters->fSpacePoints[clustIdx].fNy=recpoint->GetNy();
537     outputClusters->fSpacePoints[clustIdx].fNz=recpoint->GetNz();
538     outputClusters->fSpacePoints[clustIdx].fLayer=recpoint->GetLayer();
539     outputClusters->fSpacePoints[clustIdx].fIndex=recpoint->GetDetectorIndex() | recpoint->GetPindex() | recpoint->GetNindex();
540     outputClusters->fSpacePoints[clustIdx].fTracks[0]=recpoint->GetLabel(0);
541     outputClusters->fSpacePoints[clustIdx].fTracks[1]=recpoint->GetLabel(1);
542     outputClusters->fSpacePoints[clustIdx].fTracks[2]=recpoint->GetLabel(2);      
543     clustIdx++;
544   }
545 }