5d805cd3b1975384f4e86cacd665eb4f029d4071
[u/mrichter/AliRoot.git] / HLT / ITS / trackingSAP / AliHLTITSSAPTrackerComponent.cxx
1 // **************************************************************************
2 // This file is property of and copyright by the ALICE HLT Project          *
3 // ALICE Experiment at CERN, All rights reserved.                           *
4 //                                                                          *
5 // Primary Authors: Sergey Gorbunov <sergey.gorbunov@kip.uni-heidelberg.de> *
6 //                  Ivan Kisel <kisel@kip.uni-heidelberg.de>                *
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
19 ///  @file   AliHLTITSSAPTrackerComponent.h
20 ///  @author Ruben Shahoyan <ruben.shahoyan@cern.ch>
21 ///  @date   August 2014
22 ///  @brief  An ITS standalone primaries tracker/vertexer processing component for the HLT
23 ///  Adapted from HLT/ITS/tracking/AliHLTITSSAPTrackerComponent component
24
25 /////////////////////////////////////////////////////
26 //                                                 //
27 // a ITS tracker processing component for the HLT  //
28 //                                                 //
29 /////////////////////////////////////////////////////
30
31 #include "AliHLTITSSAPTrackerComponent.h"
32 #include "AliHLTArray.h"
33 #include "AliExternalTrackParam.h"
34 #include "TStopwatch.h"
35 #include "TMath.h"
36 #include "AliCDBEntry.h"
37 #include "AliCDBManager.h"
38 #include "AliGeomManager.h"
39 #include "TObjString.h"
40 #include <TClonesArray.h>
41 #include <TGeoGlobalMagField.h>
42 #include "AliITSSAPTracker.h"
43 #include "AliHLTITSSpacePointData.h"
44 #include "AliHLTITSClusterDataFormat.h"
45 #include "AliHLTDataTypes.h"
46 #include "AliHLTExternalTrackParam.h"
47 #include "AliGeomManager.h"
48 #include "AliHLTTrackMCLabel.h"
49 #include "AliITSRecPoint.h"
50 #include "AliHLTSAPTrackerData.h"
51 #include "AliHLTMessage.h"
52 #include "AliFlatESDVertex.h"
53 #include <map>
54
55 using namespace std;
56
57 /** ROOT macro for the implementation of ROOT specific class methods */
58 ClassImp( AliHLTITSSAPTrackerComponent )
59 AliHLTITSSAPTrackerComponent::AliHLTITSSAPTrackerComponent()
60 : fSolenoidBz( 0 ),
61   fBenchmark("ITSSAPTracker"),
62   fTracker(0),
63   fClusters(0)
64
65 {
66   // see header file for class documentation
67   // or
68   // refer to README to build package
69   // or
70   // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
71 }
72
73 AliHLTITSSAPTrackerComponent::AliHLTITSSAPTrackerComponent( const AliHLTITSSAPTrackerComponent& )
74   :AliHLTProcessor(),
75    fSolenoidBz( 0 ),
76    fBenchmark("ITSSAPTracker"),
77    fTracker(0),
78    fClusters(0)
79 {
80   // see header file for class documentation
81   HLTFatal( "copy constructor untested" );
82 }
83
84 AliHLTITSSAPTrackerComponent& AliHLTITSSAPTrackerComponent::operator=( const AliHLTITSSAPTrackerComponent& )
85 {
86   // see header file for class documentation
87   HLTFatal( "assignment operator untested" );
88   return *this;
89 }
90
91 AliHLTITSSAPTrackerComponent::~AliHLTITSSAPTrackerComponent()
92 {
93   // see header file for class documentation
94   delete fTracker;
95   delete fClusters;
96 }
97
98 //
99 // Public functions to implement AliHLTComponent's interface.
100 // These functions are required for the registration process
101 //
102
103 const char* AliHLTITSSAPTrackerComponent::GetComponentID()
104 {
105   // see header file for class documentation
106   return "ITSSAPTracker";
107 }
108
109 void AliHLTITSSAPTrackerComponent::GetInputDataTypes( vector<AliHLTComponentDataType>& list )
110 {
111   // see header file for class documentation
112   list.clear();
113   list.push_back( kAliHLTDataTypeESDVertex|kAliHLTDataOriginITS );
114   list.push_back( kAliHLTDataTypeClusters|kAliHLTDataOriginITSSSD );
115   list.push_back( kAliHLTDataTypeClusters|kAliHLTDataOriginITSSPD );
116   list.push_back( kAliHLTDataTypeClusters|kAliHLTDataOriginITSSDD );
117   list.push_back( kAliHLTDataTypeClusters|kAliHLTDataOriginITS );
118 }
119
120 AliHLTComponentDataType AliHLTITSSAPTrackerComponent::GetOutputDataType()
121 {
122   // see header file for class documentation  
123   return kAliHLTMultipleDataType;
124 }
125
126 int AliHLTITSSAPTrackerComponent::GetOutputDataTypes(AliHLTComponentDataTypeList& tgtList)
127 {
128   // see header file for class documentation  
129   tgtList.clear();
130   tgtList.push_back(kAliHLTDataTypeITSSAPData|kAliHLTDataOriginITS);
131   tgtList.push_back(kAliHLTDataTypeFlatESDVertex|kAliHLTDataOriginITS ); // RS??: is this correct?
132   return tgtList.size();
133 }
134
135 void AliHLTITSSAPTrackerComponent::GetOutputDataSize( unsigned long& constBase, double& inputMultiplier )
136 {
137   // define guess for the output data size
138   constBase = 200;       // minimum size
139   inputMultiplier = 2.; // size relative to input
140 }
141
142 AliHLTComponent* AliHLTITSSAPTrackerComponent::Spawn()
143 {
144   // see header file for class documentation
145   return new AliHLTITSSAPTrackerComponent;
146 }
147
148 void AliHLTITSSAPTrackerComponent::SetDefaultConfiguration()
149 {
150   // Set default configuration for the CA tracker component
151   // Some parameters can be later overwritten from the OCDB
152
153   fSolenoidBz = -5.00668;
154   
155 }
156
157 int AliHLTITSSAPTrackerComponent::ReadConfigurationString(  const char* arguments )
158 {
159   // Set configuration parameters for the CA tracker component from the string
160
161   int iResult = 0;
162   if ( !arguments ) return iResult;
163
164   TString allArgs = arguments;
165   TString argument;
166   int bMissingParam = 0;
167
168   TObjArray* pTokens = allArgs.Tokenize( " " );
169
170   int nArgs =  pTokens ? pTokens->GetEntries() : 0;
171
172   for ( int i = 0; i < nArgs; i++ ) {
173     argument = ( ( TObjString* )pTokens->At( i ) )->GetString();
174     if ( argument.IsNull() ) continue;
175
176     if ( argument.CompareTo( "-solenoidBz" ) == 0 ) {
177       if ( ( bMissingParam = ( ++i >= pTokens->GetEntries() ) ) ) break;
178       HLTWarning("argument -solenoidBz is deprecated, magnetic field set up globally (%f)", GetBz());
179       continue;
180     }
181
182     HLTError( "Unknown option \"%s\"", argument.Data() );
183     iResult = -EINVAL;
184   }
185   delete pTokens;
186
187   if ( bMissingParam ) {
188     HLTError( "Specifier missed for parameter \"%s\"", argument.Data() );
189     iResult = -EINVAL;
190   }
191
192   return iResult;
193 }
194
195
196 int AliHLTITSSAPTrackerComponent::ReadCDBEntry( const char* cdbEntry, const char* chainId )
197 {
198   // see header file for class documentation
199
200   const char* defaultNotify = "";
201
202   if ( !cdbEntry ) {
203     return 0;// need to add the HLT/ConfigITS/ITSTracker directory to cdb SG!!!
204     //cdbEntry = "HLT/ConfigITS/ITSTracker";
205     //defaultNotify = " (default)";
206     //chainId = 0;
207   }
208
209   HLTInfo( "configure from entry \"%s\"%s, chain id %s", cdbEntry, defaultNotify, ( chainId != NULL && chainId[0] != 0 ) ? chainId : "<none>" );
210   AliCDBEntry *pEntry = AliCDBManager::Instance()->Get( cdbEntry );//,GetRunNo());
211
212   if ( !pEntry ) {
213     HLTError( "cannot fetch object \"%s\" from CDB", cdbEntry );
214     return -EINVAL;
215   }
216
217   TObjString* pString = dynamic_cast<TObjString*>( pEntry->GetObject() );
218
219   if ( !pString ) {
220     HLTError( "configuration object \"%s\" has wrong type, required TObjString", cdbEntry );
221     return -EINVAL;
222   }
223
224   HLTInfo( "received configuration object string: \"%s\"", pString->GetString().Data() );
225
226   return  ReadConfigurationString( pString->GetString().Data() );
227 }
228
229
230 int AliHLTITSSAPTrackerComponent::Configure( const char* cdbEntry, const char* chainId, const char *commandLine )
231 {
232   // Configure the component
233   // There are few levels of configuration,
234   // parameters which are set on one step can be overwritten on the next step
235
236   //* read hard-coded values
237
238   SetDefaultConfiguration();
239
240   //* read the default CDB entry
241
242   int iResult1 = ReadCDBEntry( NULL, chainId );
243
244   //* read magnetic field
245
246   fSolenoidBz = GetBz();
247
248   //* read the actual CDB entry if required
249
250   int iResult2 = ( cdbEntry ) ? ReadCDBEntry( cdbEntry, chainId ) : 0;
251
252   //* read extra parameters from input (if they are)
253
254   int iResult3 = 0;
255
256   if ( commandLine && commandLine[0] != '\0' ) {
257     HLTInfo( "received configuration string from HLT framework: \"%s\"", commandLine );
258     iResult3 = ReadConfigurationString( commandLine );
259   }
260
261   // Initialise the tracker here
262
263   return iResult1 ? iResult1 : ( iResult2 ? iResult2 : iResult3 );
264 }
265
266
267
268 int AliHLTITSSAPTrackerComponent::DoInit( int argc, const char** argv )
269 {
270   // Configure the ITS tracker component
271
272   if ( fTracker ) return -EINPROGRESS;
273
274   if(AliGeomManager::GetGeometry()==NULL){
275     AliGeomManager::LoadGeometry();
276   }
277   AliGeomManager::ApplyAlignObjsFromCDB("ITS");
278
279   TString arguments = "";
280   for ( int i = 0; i < argc; i++ ) {
281     if ( !arguments.IsNull() ) arguments += " ";
282     arguments += argv[i];
283   }
284
285   int ret = Configure( NULL, NULL, arguments.Data() );
286
287   // Check field
288   if (!TGeoGlobalMagField::Instance()) {
289     HLTError("magnetic field not initialized, please set up TGeoGlobalMagField and AliMagF");
290     return -ENODEV;
291   }
292   fSolenoidBz=GetBz();
293
294   fTracker = new AliITSSAPTracker();
295   fTracker->Init();
296   fBenchmark.Reset();
297   fBenchmark.SetTimer(0,"total");
298   fBenchmark.SetTimer(1,"reco");
299   return ret;
300 }
301
302
303 int AliHLTITSSAPTrackerComponent::DoDeinit()
304 {
305   // see header file for class documentation
306   delete fTracker;
307   fTracker = 0;
308   return 0;
309 }
310
311
312
313 int AliHLTITSSAPTrackerComponent::Reconfigure( const char* cdbEntry, const char* chainId )
314 {
315   // Reconfigure the component from OCDB .
316
317   return Configure( cdbEntry, chainId, NULL );
318 }
319
320
321
322 int AliHLTITSSAPTrackerComponent::DoEvent
323 (
324   const AliHLTComponentEventData& evtData,
325   const AliHLTComponentBlockData* blocks,
326   AliHLTComponentTriggerData& /*trigData*/,
327   AliHLTUInt8_t* outputPtr,
328   AliHLTUInt32_t& size,
329   vector<AliHLTComponentBlockData>& outputBlocks )
330 {
331   //* process event
332
333   AliHLTUInt32_t maxBufferSize = size;
334   size = 0; // output size
335   
336   if (!IsDataEvent()) return 0;
337
338   if ( evtData.fBlockCnt <= 0 ) {
339     HLTWarning( "no blocks in event" );
340     return 0;
341   }
342
343   fBenchmark.StartNewEvent();
344   fBenchmark.Start(0);
345
346   // Event reconstruction in ITS
347
348   int iResult=0;
349
350
351   // Check if there is an SPD vertex
352   const AliESDVertex *vertexSPD = 0;
353
354   {
355     const TObject *iter = GetFirstInputObject(kAliHLTDataTypeESDVertex|kAliHLTDataOriginITSSPD);
356     if( iter != NULL  ) {
357       if( !( vertexSPD = dynamic_cast<AliESDVertex*>(const_cast<TObject*>( iter ) ) ) ){    
358         HLTError("ITS SPD vertex object is corrupted");
359         iResult = -EINVAL;    
360       }
361     }
362     else {
363       HLTWarning("No SPD vertex, skip ITS standalone reconstruction");
364       return 0;
365     }
366   }  
367
368   int nBlocks = evtData.fBlockCnt;
369   if (!fClusters) fClusters = new TClonesArray("AliITSRecPoint",1000);
370   //
371   int nClTotal = 0;
372   for (int ndx=0; ndx<nBlocks && iResult>=0; ndx++) {
373
374     const AliHLTComponentBlockData* iter = blocks+ndx;
375     
376     // Read ITS clusters
377
378     if ( (iter->fDataType == (kAliHLTDataTypeClusters|kAliHLTDataOriginITSSSD) ) || 
379          (iter->fDataType == (kAliHLTDataTypeClusters|kAliHLTDataOriginITSSPD) ) ||
380          (iter->fDataType == (kAliHLTDataTypeClusters|kAliHLTDataOriginITSSDD) ) ||
381          (iter->fDataType == (kAliHLTDataTypeClusters|kAliHLTDataOriginITS) ) 
382          ){
383       
384       fBenchmark.AddInput(iter->fSize);
385
386       AliHLTITSClusterData *inPtr=reinterpret_cast<AliHLTITSClusterData*>( iter->fPtr );
387       int nClusters = inPtr->fSpacePointCnt;
388       for( int icl=0; icl<nClusters; icl++ ){
389         AliHLTITSSpacePointData &d = inPtr->fSpacePoints[icl];
390
391         Int_t lab[4] = { d.fTracks[0], d.fTracks[1], d.fTracks[2], d.fIndex };
392         Int_t info[3] = { d.fNy, d.fNz, d.fLayer };
393         Float_t hit[6] = { d.fY, d.fZ, d.fSigmaY2, d.fSigmaZ2, d.fQ, d.fSigmaYZ };
394         if( d.fLayer==4 ) hit[5] = -hit[5];
395         // tracker does not out the clusters, add them to transient array
396         fTracker->AddCluster( new((*fClusters)[nClTotal++]) AliITSRecPoint(lab,hit,info) );
397       }   
398     }
399     
400   }// end read input blocks
401   
402   // Reconstruct the event
403   
404   fBenchmark.Start(1);
405   fTracker->SetSPDVertex(vertexSPD);
406   fTracker->ProcessEvent();
407   fBenchmark.Stop(1);
408
409   
410   // Fill output tracks
411   int nAddedTracks = 0;
412   {  
413     int nFoundTracks = fTracker->GetNTracks();
414     AliHLTUInt32_t blockSize = sizeof(AliHLTITSSAPTrackerDataContainer) + nFoundTracks*sizeof(AliHLTITSSAPTrackerData);
415     if( size + blockSize + AliFlatESDVertex::GetSize() > maxBufferSize ){       
416       HLTWarning( "Output buffer size exceed (buffer size %d, current size %d), %d tracks are not stored", 
417                   maxBufferSize, size + blockSize, nFoundTracks);
418       iResult = -ENOSPC;
419     }    
420     if( iResult>=0 ){
421       blockSize = sizeof(AliHLTITSSAPTrackerDataContainer);
422       AliHLTITSSAPTrackerDataContainer *data = reinterpret_cast<AliHLTITSSAPTrackerDataContainer*>(outputPtr);
423       data->fCount=0;
424       for (int itr=0;itr<nFoundTracks;itr++) {
425         const AliITSSAPTracker::ITStrack_t& track = fTracker->GetTrack(itr);
426         // the track is just a struct of 2 AliExternalTrackParams (params at vertex and at the outer ITS layer)
427         // + some extra info, see "struct ITStrack" in the AliITSSAPTracker.h
428         if ( track.paramOut.TestBit(AliITSSAPTracker::kInvalidBit) || 
429              track.paramInw.TestBit(AliITSSAPTracker::kInvalidBit)) continue;
430         // use only those tracks whose both inward and outward params are OK.
431         AliHLTITSSAPTrackerData &trcHLT = data->fTracks[data->fCount];
432         trcHLT.paramOut.SetExternalTrackParam(&track.paramOut);
433         trcHLT.paramInw.SetExternalTrackParam(&track.paramInw);
434         trcHLT.chi2 = track.chi2;
435         trcHLT.ncl  = track.ncl;
436         trcHLT.label = track.label;
437         data->fCount++;
438         blockSize += sizeof(AliHLTITSSAPTrackerData);
439         nAddedTracks++;
440       }
441       
442       AliHLTComponentBlockData resultData;
443       FillBlockData( resultData );
444       resultData.fOffset = size;
445       resultData.fSize = blockSize;      
446       resultData.fDataType = kAliHLTDataTypeITSSAPData|kAliHLTDataOriginITS;
447       fBenchmark.AddOutput(resultData.fSize);
448       outputBlocks.push_back( resultData );
449       size += resultData.fSize;
450     }
451   }
452
453   Bool_t vtxOK = kFALSE;
454   { // Fill output vertexTracks  
455     AliESDVertex& vtxTracks = fTracker->GetTrackVertex();
456     if ( iResult>=0 && vtxTracks.GetStatus()==1 ) {
457       AliFlatESDVertex *flatVtx = reinterpret_cast<AliFlatESDVertex*>( outputPtr + size );
458       flatVtx->SetFromESDVertex( vtxTracks );
459       AliHLTComponentBlockData resultData;
460       FillBlockData( resultData );
461       resultData.fOffset = size;
462       resultData.fSize = flatVtx->GetSize();      
463       resultData.fDataType = kAliHLTDataTypeFlatESDVertex|kAliHLTDataOriginITS;
464       fBenchmark.AddOutput(resultData.fSize);
465       outputBlocks.push_back( resultData );
466       size += resultData.fSize;
467       vtxOK = kTRUE;
468     }
469   }
470   //
471   fTracker->Clear();
472   fClusters->Clear();
473   //  
474   fBenchmark.Stop(0);
475
476   // Set log level to "Warning" for on-line system monitoring
477   HLTWarning( "ITS SAP Tracker: output %d tracks;  input %d clusters, VertexTracks: %s",
478            nAddedTracks, nClTotal, vtxOK ? "OK" : "Found" );
479
480   HLTInfo(fBenchmark.GetStatistics());
481   return iResult;
482 }