1 //**************************************************************************
2 //* This file is property of and copyright by the ALICE HLT Project *
3 //* ALICE Experiment at CERN, All rights reserved. *
5 //* Primary Authors: S.Gorbunov <sergey.gorbunov@kip.uni-heidelberg.de> *
6 //* for The ALICE HLT Project. *
8 //* Permission to use, copy, modify and distribute this software and its *
9 //* documentation strictly for non-commercial purposes is hereby granted *
10 //* without fee, provided that the above copyright notice appears in all *
11 //* copies and that both the copyright notice and this permission notice *
12 //* appear in the supporting documentation. The authors make no claims *
13 //* about the suitability of this software for any purpose. It is *
14 //* provided "as is" without express or implied warranty. *
15 //**************************************************************************
17 /** @file AliHLTGlobalVertexerComponent.cxx
18 @author Sergey Gorbunov
19 @brief Component for reconstruct primary vertex and V0's
26 #include "AliHLTGlobalVertexerComponent.h"
27 #include "AliHLTDataTypes.h"
28 #include "AliHLTExternalTrackParam.h"
29 #include "AliHLTGlobalBarrelTrack.h"
30 #include "AliCDBEntry.h"
31 #include "AliCDBManager.h"
34 #include "TObjString.h"
35 #include "TObjArray.h"
36 #include "AliESDEvent.h"
37 #include "AliESDtrack.h"
38 #include "AliESDVertex.h"
40 #include "AliHLTMessage.h"
42 #include "AliKFParticle.h"
43 #include "AliKFVertex.h"
44 #include "TStopwatch.h"
46 /** ROOT macro for the implementation of ROOT specific class methods */
47 ClassImp(AliHLTGlobalVertexerComponent)
49 AliHLTGlobalVertexerComponent::AliHLTGlobalVertexerComponent()
55 fFitTracksToVertex(1),
56 fConstrainedTrackDeviation(4.),
57 fV0DaughterPrimDeviation( 2.5 ),
58 fV0PrimDeviation( 3.5 ),
60 fV0DecayLengthInSigmas(3.),
72 // see header file for class documentation
74 // refer to README to build package
76 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
80 AliHLTGlobalVertexerComponent::~AliHLTGlobalVertexerComponent()
82 // see header file for class documentation
84 if( fTrackInfos ) delete[] fTrackInfos;
87 // Public functions to implement AliHLTComponent's interface.
88 // These functions are required for the registration process
90 const char* AliHLTGlobalVertexerComponent::GetComponentID()
92 // see header file for class documentation
94 return "GlobalVertexer";
97 void AliHLTGlobalVertexerComponent::GetInputDataTypes(AliHLTComponentDataTypeList& list)
99 // see header file for class documentation
101 list.push_back( kAliHLTDataTypeESDObject );
102 list.push_back( kAliHLTDataTypeTrack|kAliHLTDataOriginITS );
103 list.push_back( kAliHLTDataTypeTrack|kAliHLTDataOriginTPC );
106 AliHLTComponentDataType AliHLTGlobalVertexerComponent::GetOutputDataType()
108 // see header file for class documentation
109 return kAliHLTMultipleDataType;
112 int AliHLTGlobalVertexerComponent::GetOutputDataTypes(AliHLTComponentDataTypeList& tgtList)
115 // see header file for class documentation
117 tgtList.push_back( kAliHLTDataTypeGlobalVertexer|kAliHLTDataOriginOut);
118 tgtList.push_back( kAliHLTDataTypeESDVertex|kAliHLTDataOriginOut);
119 tgtList.push_back( kAliHLTDataTypeESDObject|kAliHLTDataOriginOut);
120 return tgtList.size();
123 void AliHLTGlobalVertexerComponent::GetOutputDataSize( unsigned long& constBase, double& inputMultiplier )
125 // see header file for class documentation
126 // XXX TODO: Find more realistic values.
128 inputMultiplier = 2.;
131 AliHLTComponent* AliHLTGlobalVertexerComponent::Spawn()
133 // see header file for class documentation
134 return new AliHLTGlobalVertexerComponent;
137 int AliHLTGlobalVertexerComponent::DoInit( int argc, const char** argv )
150 fV0TimeLimit = 10.e-3;
155 TString configuration="";
157 for (int i=0; i<argc && iResult>=0; i++) {
159 if (!configuration.IsNull()) configuration+=" ";
160 configuration+=argument;
163 if (!configuration.IsNull()) {
164 iResult=Configure(configuration.Data());
170 int AliHLTGlobalVertexerComponent::DoDeinit()
172 // see header file for class documentation
174 if( fTrackInfos ) delete[] fTrackInfos;
177 fFitTracksToVertex = 1;
178 fConstrainedTrackDeviation = 4.;
179 fV0DaughterPrimDeviation = 2.5 ;
180 fV0PrimDeviation =3.5;
182 fV0DecayLengthInSigmas = 3.;
184 fV0TimeLimit = 10.e-3;
189 int AliHLTGlobalVertexerComponent::DoEvent( const AliHLTComponentEventData& /*evtData*/,
190 AliHLTComponentTriggerData& /*trigData*/ )
192 //cout<<"AliHLTGlobalVertexerComponent::DoEvent called"<<endl;
194 if ( GetFirstInputBlock( kAliHLTDataTypeSOR ) || GetFirstInputBlock( kAliHLTDataTypeEOR ) )
201 vector< AliExternalTrackParam > tracks;
202 vector< int > trackId;
203 vector< pair<int,int> > v0s;
205 AliESDEvent *event = 0;
207 for ( const TObject *iter = GetFirstInputObject(kAliHLTDataTypeESDObject); iter != NULL; iter = GetNextInputObject() ) {
208 event = dynamic_cast<AliESDEvent*>(const_cast<TObject*>( iter ) );
209 if( !event ) continue;
210 event->GetStdContent();
211 Int_t nESDTracks=event->GetNumberOfTracks();
213 for (Int_t iTr=0; iTr<nESDTracks; iTr++){
214 AliESDtrack *pTrack = event->GetTrack(iTr);
215 if( !pTrack ) continue;
216 if( pTrack->GetKinkIndex(0)>0) continue;
217 if( !( pTrack->GetStatus()&AliESDtrack::kTPCin ) ) continue;
218 tracks.push_back(*pTrack);
219 trackId.push_back(iTr);
224 if( tracks.size()==0 ){
226 for (const AliHLTComponentBlockData* pBlock=GetFirstInputBlock(kAliHLTDataTypeTrack|kAliHLTDataOriginITS);
227 pBlock!=NULL; pBlock=GetNextInputBlock()) {
229 AliHLTTracksData* dataPtr = reinterpret_cast<AliHLTTracksData*>( pBlock->fPtr );
230 int nTracks = dataPtr->fCount;
232 AliHLTExternalTrackParam* currOutTrack = dataPtr->fTracklets;
233 for( int itr=0; itr<nTracks; itr++ ){
234 AliHLTGlobalBarrelTrack t(*currOutTrack);
235 tracks.push_back( t );
236 trackId.push_back( currOutTrack->fTrackID );
237 unsigned int dSize = sizeof( AliHLTExternalTrackParam ) + currOutTrack->fNPoints * sizeof( unsigned int );
238 currOutTrack = ( AliHLTExternalTrackParam* )( (( Byte_t * )currOutTrack) + dSize );
243 if( tracks.size()==0 ){
244 for (const AliHLTComponentBlockData* pBlock=GetFirstInputBlock(kAliHLTDataTypeTrack|kAliHLTDataOriginTPC);
245 pBlock!=NULL; pBlock=GetNextInputBlock()) {
247 AliHLTTracksData* dataPtr = reinterpret_cast<AliHLTTracksData*>( pBlock->fPtr );
248 int nTracks = dataPtr->fCount;
249 AliHLTExternalTrackParam* currOutTrack = dataPtr->fTracklets;
250 for( int itr=0; itr<nTracks; itr++ ){
251 AliHLTGlobalBarrelTrack t(*currOutTrack);
252 tracks.push_back( t );
253 trackId.push_back( currOutTrack->fTrackID );
254 unsigned int dSize = sizeof( AliHLTExternalTrackParam ) + currOutTrack->fNPoints * sizeof( unsigned int );
255 currOutTrack = ( AliHLTExternalTrackParam* )( (( Byte_t * )currOutTrack) + dSize );
261 // primary vertex & V0's
263 AliKFParticle::SetField( GetBz() );
265 { //* Fill fTrackInfo array
269 if( fTrackInfos ) delete[] fTrackInfos;
271 fNTracks=tracks.size();
272 fTrackInfos = new AliESDTrackInfo[ fNTracks ];
273 for (Int_t iTr=0; iTr<fNTracks; iTr++){
274 AliESDTrackInfo &info = fTrackInfos[iTr];
276 info.fPrimUsedFlag = 0;
277 info.fParticle = AliKFParticle( tracks[iTr], 211 );
280 fStatTimeR1+=timer1.RealTime();
281 fStatTimeC1+=timer1.CpuTime();
287 fStatTimeR2+=timer2.RealTime();
288 fStatTimeC2+=timer2.CpuTime();
292 fStatTimeR3+=timer3.RealTime();
293 fStatTimeC3+=timer3.CpuTime();
295 int *buf = new int[sizeof(AliHLTGlobalVertexerData)/sizeof(int)+1 + fNTracks + 2*v0s.size()];
296 AliHLTGlobalVertexerData *data = reinterpret_cast<AliHLTGlobalVertexerData*>(buf);
298 if( data) { // fill the output structure
300 data->fFitTracksToVertex = fFitTracksToVertex;
301 for( int i=0; i<3; i++ ) data->fPrimP[i] = fPrimaryVtx.Parameters()[i];
302 for( int i=0; i<6; i++ ) data->fPrimC[i] = fPrimaryVtx.CovarianceMatrix()[i];
303 data->fPrimChi2 = fPrimaryVtx.GetChi2();
304 data->fPrimNContributors = fPrimaryVtx.GetNContributors();
305 data->fNPrimTracks = 0;
306 for( Int_t i = 0; i<fNTracks; i++ ){
307 if( !fTrackInfos[i].fPrimUsedFlag ) continue;
308 if( fTrackInfos[i].fPrimDeviation > fConstrainedTrackDeviation ) continue;
309 data->fTrackIndices[ (data->fNPrimTracks)++ ] = trackId[i];
311 int *listV0 = data->fTrackIndices + data->fNPrimTracks;
312 data->fNV0s = v0s.size();
313 for( int i=0; i<data->fNV0s; i++ ){
314 listV0[2*i] = trackId[v0s[i].first];
315 listV0[2*i+1] = trackId[v0s[i].second];
318 unsigned int blockSize = sizeof(AliHLTGlobalVertexerData) + (data->fNPrimTracks + 2*data->fNV0s)*sizeof(int);
320 iResult = PushBack( reinterpret_cast<void*>(data), blockSize, kAliHLTDataTypeGlobalVertexer|kAliHLTDataOriginOut );
324 // output the vertex if found
326 if( iResult==0 && data && data->fPrimNContributors >=3 ){
327 AliESDVertex vESD( data->fPrimP, data->fPrimC, data->fPrimChi2, data->fPrimNContributors );
328 iResult = PushBack( (TObject*) &vESD, kAliHLTDataTypeESDVertex|kAliHLTDataOriginOut,0 );
332 // output the ESD event
333 if( iResult==0 && event && data ){
334 FillESD( event, data );
335 iResult = PushBack( event, kAliHLTDataTypeESDObject|kAliHLTDataOriginOut, 0);
341 fStatTimeR+=timer.RealTime();
342 fStatTimeC+=timer.CpuTime();
346 //if( fStatNEv%100==0 )
347 cout<<"SG: "<<GetComponentID()<<": "<<fStatNEvents<<" events, real time: total= "
348 <<fStatTimeR/fStatNEvents*1.e3<<" / create= "<<fStatTimeR1/fStatNEvents*1.e3
349 <<" / vprim= "<<fStatTimeR2/fStatNEvents*1.e3<<" / v0= "<<fStatTimeR3/fStatNEvents*1.e3
350 <<", CPU: total= "<<fStatTimeC/fStatNEvents*1.e3<<" / create= "<<fStatTimeC1/fStatNEvents*1.e3
351 <<" / vprim= "<<fStatTimeC2/fStatNEvents*1.e3<<" / v0= "<<fStatTimeC2/fStatNEvents*1.e3
358 int AliHLTGlobalVertexerComponent::Configure(const char* arguments)
362 if (!arguments) return iResult;
364 TString allArgs=arguments;
367 TObjArray* pTokens=allArgs.Tokenize(" ");
371 for (int i=0; i<pTokens->GetEntries() && iResult>=0; i++) {
372 argument=((TObjString*)pTokens->At(i))->GetString();
373 if (argument.IsNull()) continue;
375 if (argument.CompareTo("-fitTracksToVertex")==0) {
376 if ((bMissingParam=(++i>=pTokens->GetEntries()))) break;
377 HLTInfo("fitTracksToVertex is set set to: %s", ((TObjString*)pTokens->At(i))->GetString().Data());
378 fFitTracksToVertex=((TObjString*)pTokens->At(i))->GetString().Atoi();
381 else if (argument.CompareTo("-constrainedTrackDeviation")==0) {
382 if ((bMissingParam=(++i>=pTokens->GetEntries()))) break;
383 HLTInfo("constrainedTrackDeviation is set set to: %s", ((TObjString*)pTokens->At(i))->GetString().Data());
384 fConstrainedTrackDeviation=((TObjString*)pTokens->At(i))->GetString().Atof();
387 else if (argument.CompareTo("-v0DaughterPrimDeviation")==0) {
388 if ((bMissingParam=(++i>=pTokens->GetEntries()))) break;
389 HLTInfo("v0DaughterPrimDeviation is set set to: %s", ((TObjString*)pTokens->At(i))->GetString().Data());
390 fV0DaughterPrimDeviation=((TObjString*)pTokens->At(i))->GetString().Atof();
393 else if (argument.CompareTo("-v0PrimDeviation")==0) {
394 if ((bMissingParam=(++i>=pTokens->GetEntries()))) break;
395 HLTInfo("v0PrimDeviation is set set to: %s", ((TObjString*)pTokens->At(i))->GetString().Data());
396 fV0PrimDeviation=((TObjString*)pTokens->At(i))->GetString().Atof();
399 else if (argument.CompareTo("-v0Chi")==0) {
400 if ((bMissingParam=(++i>=pTokens->GetEntries()))) break;
401 HLTInfo("v0Chi is set set to: %s", ((TObjString*)pTokens->At(i))->GetString().Data());
402 fV0Chi=((TObjString*)pTokens->At(i))->GetString().Atof();
405 else if (argument.CompareTo("-v0DecayLengthInSigmas")==0) {
406 if ((bMissingParam=(++i>=pTokens->GetEntries()))) break;
407 HLTInfo("v0DecayLengthInSigmas is set set to: %s", ((TObjString*)pTokens->At(i))->GetString().Data());
408 fV0DecayLengthInSigmas=((TObjString*)pTokens->At(i))->GetString().Atof();
411 else if (argument.CompareTo("-v0MinEventRate")==0) {
412 if ((bMissingParam=(++i>=pTokens->GetEntries()))) break;
413 HLTInfo("Minimum event rate for V0 finder is set set to: %s", ((TObjString*)pTokens->At(i))->GetString().Data());
414 Double_t rate = ((TObjString*)pTokens->At(i))->GetString().Atof();
415 fV0TimeLimit = (rate >0 ) ?1./rate :60; // 1 minute maximum time
419 HLTError("unknown argument %s", argument.Data());
427 HLTError("missing parameter for argument %s", argument.Data());
434 int AliHLTGlobalVertexerComponent::Reconfigure(const char* cdbEntry, const char* chainId)
436 // see header file for class documentation
438 return 0; // no CDB path is set so far
441 const char* path="HLT/ConfigTPC/KryptonHistoComponent";
442 const char* defaultNotify="";
445 defaultNotify=" (default)";
448 HLTInfo("reconfigure from entry %s%s, chain id %s", path, defaultNotify,(chainId!=NULL && chainId[0]!=0)?chainId:"<none>");
449 AliCDBEntry *pEntry = AliCDBManager::Instance()->Get(path/*,GetRunNo()*/);
451 TObjString* pString=dynamic_cast<TObjString*>(pEntry->GetObject());
453 HLTInfo("received configuration object string: \'%s\'", pString->GetString().Data());
454 iResult=Configure(pString->GetString().Data());
456 HLTError("configuration object \"%s\" has wrong type, required TObjString", path);
459 HLTError("can not fetch object \"%s\" from CDB", path);
468 void AliHLTGlobalVertexerComponent::FindPrimaryVertex()
470 //* Find event primary vertex
472 const AliKFParticle **vSelected = new const AliKFParticle*[fNTracks]; //* Selected particles for the vertex fit
473 Int_t *vIndex = new int [fNTracks]; //* Indices of selected particles
474 Bool_t *vFlag = new bool [fNTracks]; //* Flags returned by the vertex finder
476 fPrimaryVtx.Initialize();
477 //fPrimaryVtx.SetBeamConstraint(fESD->GetDiamondX(),fESD->GetDiamondY(),0,
478 //TMath::Sqrt(fESD->GetSigma2DiamondX()),TMath::Sqrt(fESD->GetSigma2DiamondY()),5.3);
480 fPrimaryVtx.SetBeamConstraint( 0, 0, 0, 3., 3., 5.3 );
483 for( Int_t i = 0; i<fNTracks; i++){
484 if(!fTrackInfos[i].fOK ) continue;
485 //if( fESD->GetTrack(i)->GetTPCNcls()<60 ) continue;
486 const AliKFParticle &p = fTrackInfos[i].fParticle;
487 Double_t chi = p.GetDeviationFromVertex( fPrimaryVtx );
488 if( chi > fConstrainedTrackDeviation ) continue;
489 vSelected[nSelected] = &(fTrackInfos[i].fParticle);
490 vIndex[nSelected] = i;
493 fPrimaryVtx.ConstructPrimaryVertex( vSelected, nSelected, vFlag, fConstrainedTrackDeviation );
495 for( Int_t i = 0; i<nSelected; i++){
496 if( vFlag[i] ) fTrackInfos[vIndex[i]].fPrimUsedFlag = 1;
499 for( Int_t i = 0; i<fNTracks; i++ ){
500 AliESDTrackInfo &info = fTrackInfos[i];
501 info.fPrimDeviation = info.fParticle.GetDeviationFromVertex( fPrimaryVtx );
504 //cout<<"SG: prim vtx event"<<fStatNEvents<<": n selected="<<nSelected<<", ncont="<<fPrimaryVtx.GetNContributors()<<endl;
506 if( fPrimaryVtx.GetNContributors()<3 ){
507 for( Int_t i = 0; i<fNTracks; i++)
508 fTrackInfos[i].fPrimUsedFlag = 0;
516 void AliHLTGlobalVertexerComponent::FindV0s( vector<pair<int,int> > v0s )
520 AliKFVertex &primVtx = fPrimaryVtx;
521 if( primVtx.GetNContributors()<3 ) return;
527 for( Int_t iTr = 0; iTr<fNTracks && run; iTr++ ){ //* first daughter
529 AliESDTrackInfo &info = fTrackInfos[iTr];
530 if( !info.fOK ) continue;
531 if( info.fParticle.GetQ() >0 ) continue;
532 if( info.fPrimDeviation < fV0DaughterPrimDeviation ) continue;
534 for( Int_t jTr = 0; jTr<fNTracks; jTr++ ){ //* second daughter
537 AliESDTrackInfo &jnfo = fTrackInfos[jTr];
538 if( !jnfo.fOK ) continue;
539 if( jnfo.fParticle.GetQ() < 0 ) continue;
540 if( jnfo.fPrimDeviation < fV0DaughterPrimDeviation ) continue;
542 // check the time once a while...
544 if( (++statN)%100 ==0 ){
545 if( timer.RealTime()>= fV0TimeLimit ){ run = 0; break; }
549 //* check if the particles fit
551 if( info.fParticle.GetDeviationFromParticle(jnfo.fParticle) > fV0Chi ) continue;
553 //* construct V0 mother
555 AliKFParticle v0( info.fParticle, jnfo.fParticle );
559 if( v0.GetChi2()<0 || v0.GetChi2() > fV0Chi*fV0Chi*v0.GetNDF() ) continue;
561 //* subtruct daughters from primary vertex
563 AliKFVertex primVtxCopy = primVtx;
565 if( info.fPrimUsedFlag ){
566 if( primVtxCopy.GetNContributors()<=2 ) continue;
567 primVtxCopy -= info.fParticle;
569 if( jnfo.fPrimUsedFlag ){
570 if( primVtxCopy.GetNContributors()<=2 ) continue;
571 primVtxCopy -= jnfo.fParticle;
573 //* Check v0 Chi^2 deviation from primary vertex
575 if( v0.GetDeviationFromVertex( primVtxCopy ) > fV0PrimDeviation ) continue;
577 //* Add V0 to primary vertex to improve the primary vertex resolution
581 //* Set production vertex for V0
583 v0.SetProductionVertex( primVtxCopy );
585 //* Get V0 decay length with estimated error
587 Double_t length, sigmaLength;
588 if( v0.GetDecayLength( length, sigmaLength ) ) continue;
590 //* Reject V0 if it decays too close[sigma] to the primary vertex
592 if( length < fV0DecayLengthInSigmas*sigmaLength ) continue;
596 v0s.push_back(pair<int,int>(iTr,jTr));
604 void AliHLTGlobalVertexerComponent::FillESD( AliESDEvent *event, AliHLTGlobalVertexerData *data
607 //* put output of a vertexer to the esd event
609 Int_t nESDTracks = event->GetNumberOfTracks();
611 const int *listPrim = data->fTrackIndices;
612 const int *listV0 = data->fTrackIndices + data->fNPrimTracks;
614 std::map<int,int> mapId;
615 bool *constrainedToVtx = new bool[nESDTracks];
617 for( int i=0; i<nESDTracks; i++ ){
618 constrainedToVtx[i] = 0;
619 if( !event->GetTrack(i) ) continue;
620 mapId[ event->GetTrack(i)->GetID() ] = i;
623 if( data->fPrimNContributors >=3 ){
625 AliESDVertex vESD( data->fPrimP, data->fPrimC, data->fPrimChi2, data->fPrimNContributors );
626 event->SetPrimaryVertexTracks( &vESD );
628 // relate tracks to the primary vertex
630 if( data->fFitTracksToVertex ){
631 for( Int_t i = 0; i<data->fNPrimTracks; i++ ){
632 Int_t id = listPrim[ i ];
633 map<int,int>::iterator it = mapId.find(id);
634 if( it==mapId.end() ) continue;
635 Int_t itr = it->second;
636 event->GetTrack(itr)->RelateToVertex( &vESD, event->GetMagneticField(),100. );
637 constrainedToVtx[ itr ] = 1;
642 //* add ESD v0s and relate tracks to v0s
645 for( int i=0; i<data->fNV0s; i++ ){
647 Int_t id1 = listV0[ 2*i ];
648 Int_t id2 = listV0[ 2*i + 1];
649 map<int,int>::iterator it = mapId.find(id1);
650 if( it==mapId.end() ) continue;
651 Int_t iTr = it->second;
652 it = mapId.find(id2);
653 if( it==mapId.end() ) continue;
654 Int_t jTr = it->second;
656 AliESDv0 v0( *event->GetTrack( iTr ), iTr, *event->GetTrack( jTr ), jTr );
659 // relate the tracks to the vertex
661 if( data->fFitTracksToVertex ){
662 if( constrainedToVtx[iTr] || constrainedToVtx[jTr] ) continue;
664 double sigma[3] = {.1,.1,.1};
666 AliESDVertex vESD(pos, sigma);
667 event->GetTrack(iTr)->RelateToVertex( &vESD, event->GetMagneticField(),100. );
668 event->GetTrack(jTr)->RelateToVertex( &vESD, event->GetMagneticField(),100. );
669 constrainedToVtx[iTr] = 1;
670 constrainedToVtx[jTr] = 1;
674 delete[] constrainedToVtx;