1 // $Id: AliHLTTRDTrackerV1Component.cxx 23618 2008-01-29 13:07:38Z hristov $
3 /**************************************************************************
4 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
6 * Authors: Matthias Richter <Matthias.Richter@ift.uib.no> *
7 * Timm Steinbeck <timm@kip.uni-heidelberg.de> *
8 * for The ALICE Off-line Project. *
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 **************************************************************************/
19 /** @file AliHLTTRDTrackerV1Component.cxx
20 @author Timm Steinbeck, Matthias Richter
22 @brief A TRDTrackerV1 processing component for the HLT. */
28 #include "AliHLTTRDTrackerV1Component.h"
29 #include "AliHLTTRDDefinitions.h"
30 #include "AliHLTTRDCluster.h"
31 #include "AliHLTTRDTrack.h"
36 #include "AliGeomManager.h"
37 #include "AliCDBManager.h"
38 #include "AliESDEvent.h"
39 #include "AliMagFMaps.h"
40 #include "AliESDfriend.h"
42 #include "AliTRDcalibDB.h"
43 #include "AliTRDReconstructor.h"
44 #include "AliTRDtrackerV1.h"
45 #include "AliTRDrecoParam.h"
51 #ifdef HAVE_VALGRIND_CALLGRIND_H
52 #include <valgrind/callgrind.h>
54 #define CALLGRIND_START_INSTRUMENTATION() do { } while (0)
55 #define CALLGRIND_STOP_INSTRUMENTATION() do { } while (0)
58 ClassImp(AliHLTTRDTrackerV1Component);
60 AliHLTTRDTrackerV1Component::AliHLTTRDTrackerV1Component():
62 fOutputPercentage(100), // By default we copy to the output exactly what we got as input
63 fStrorageDBpath("local://$ALICE_ROOT"),
66 fGeometryFileName(""),
67 fUseHLTClusters(kFALSE),
68 fUseHLTTracks(kFALSE),
73 // Default constructor
75 fGeometryFileName = getenv("ALICE_ROOT");
76 fGeometryFileName += "/HLT/TRD/geometry.root";
79 AliHLTTRDTrackerV1Component::~AliHLTTRDTrackerV1Component()
84 const char* AliHLTTRDTrackerV1Component::GetComponentID()
86 // Return the component ID const char *
87 return "TRDTrackerV1"; // The ID of this component
90 void AliHLTTRDTrackerV1Component::GetInputDataTypes( vector<AliHLTComponent_DataType>& list)
92 // Get the list of input data
93 list.clear(); // We do not have any requirements for our input data type(s).
94 list.push_back( AliHLTTRDDefinitions::fgkClusterDataType );
97 AliHLTComponent_DataType AliHLTTRDTrackerV1Component::GetOutputDataType()
99 // Get the output data type
100 return AliHLTTRDDefinitions::fgkClusterDataType;
103 void AliHLTTRDTrackerV1Component::GetOutputDataSize( unsigned long& constBase, double& inputMultiplier )
105 // Get the output data size
107 inputMultiplier = ((double)fOutputPercentage)/100.0;
110 // Spawn function, return new instance of this class
111 AliHLTComponent* AliHLTTRDTrackerV1Component::Spawn()
113 return new AliHLTTRDTrackerV1Component;
117 * Convert AliTRDtrackV1 to AliHLTTRDTrack
118 * Add HLTTrack to the output, defined by pointer
119 * Fill block desctiptors
120 * Return size of the added to ouput objects
122 //============================================================================
123 AliHLTUInt32_t AliHLTTRDTrackerV1Component::AddToOutput(TClonesArray* inTrackArray, AliHLTUInt8_t* output)
125 cout << "\nWriting tracks to the Memory\n ============= \n";
126 AliTRDtrackV1* track = 0;
127 AliHLTUInt32_t addedSize = 0;
128 AliHLTUInt8_t *iterPtr = output;
129 AliHLTTRDTrack * outPtr = (AliHLTTRDTrack*)iterPtr;
132 Int_t nbTracks = inTrackArray->GetEntries();
133 for (Int_t iTrack = 0; iTrack<nbTracks; iTrack++){
134 AliHLTUInt32_t trackSize=0;
136 track = dynamic_cast<AliTRDtrackV1*>(inTrackArray->At(iTrack));
139 AliHLTTRDTrack *hltTrack = new (outPtr) AliHLTTRDTrack(track);
140 trackSize = hltTrack->GetSize();
141 addedSize += trackSize;
142 HLTDebug("addedSize %i, trackSize %i", addedSize, trackSize);
144 iterPtr += trackSize;
145 outPtr = (AliHLTTRDTrack*)iterPtr;
152 int AliHLTTRDTrackerV1Component::DoInit( int argc, const char** argv )
154 // perform initialization. We check whether our relative output size is specified in the arguments.
155 fOutputPercentage = 100;
160 Int_t iRecoParamType = -1; // default will be the low flux
161 Int_t iNtimeBins = -1; // number of time bins for the tracker to use
162 Int_t iMagneticField = -1; // magnetic field: 0==OFF and 1==ON
163 Bool_t bHLTMode = kTRUE, bWriteClusters = kFALSE;
167 HLTDebug("argv[%d] == %s", i, argv[i] );
168 if ( !strcmp( argv[i], "output_percentage" ) )
172 HLTError("Missing output_percentage parameter");
175 HLTDebug("argv[%d+1] == %s", i, argv[i+1] );
176 fOutputPercentage = strtoul( argv[i+1], &cpErr, 0 );
179 HLTError("Cannot convert output_percentage parameter '%s'", argv[i+1] );
182 HLTInfo("Output percentage set to %lu %%", fOutputPercentage );
187 else if ( !strcmp( argv[i], "-NTimeBins" ) )
191 HLTError("Missing -NTimeBins parameter");
194 HLTDebug("Arguments", "argv[%d+1] == %s", i, argv[i+1] );
195 iNtimeBins = strtoul( argv[i+1], &cpErr, 0 );
198 HLTError("Wrong Argument. Cannot convert -NTimeBins parameter '%s'", argv[i+1] );
205 else if ( strcmp( argv[i], "-cdb" ) == 0)
209 HLTError( "Missing -cdb argument");
212 fStrorageDBpath = argv[i+1];
213 HLTInfo("DB storage is %s", fStrorageDBpath.c_str() );
218 else if ( strcmp( argv[i], "-geometry" ) == 0)
222 HLTError("Missing -geometry argument");
225 fGeometryFileName = argv[i+1];
226 HLTInfo("GeomFile storage is %s",
227 fGeometryFileName.c_str() );
232 // the flux parametrizations
233 else if ( strcmp( argv[i], "-lowflux" ) == 0)
236 HLTDebug("Low flux reco selected.");
241 else if ( strcmp( argv[i], "-highflux" ) == 0)
244 HLTDebug("Low flux reco selected.");
248 else if ( strcmp( argv[i], "-cosmics" ) == 0)
251 HLTDebug("Cosmic test reco selected.");
255 else if ( strcmp( argv[i], "-magnetic_field_ON" ) == 0)
260 else if ( strcmp( argv[i], "-magnetic_field_OFF" ) == 0)
265 else if ( strcmp( argv[i], "-writeClusters" ) == 0)
267 bWriteClusters = kTRUE;
268 HLTDebug("input clusters are expected to be in a TTree.");
271 else if ( strcmp( argv[i], "-offlineMode" ) == 0)
274 HLTDebug("Using standard offline tracking.");
277 else if ( strcmp( argv[i], "-useHLTClusters" ) == 0)
279 fUseHLTClusters = kTRUE;
281 HLTInfo("expecting AliHLTCluster as input");
283 else if ( strcmp( argv[i], "-useHLTTracks" ) == 0)
285 fUseHLTTracks = kTRUE;
287 HLTInfo("Using AliHLTTrack to pass data further in the chain");
290 HLTError("Unknown option '%s'", argv[i] );
296 // THE "REAL" INIT COMES HERE
297 // offline condition data base
298 fCDB = AliCDBManager::Instance();
301 HLTError("Could not get CDB instance", "fCDB 0x%x", fCDB);
306 fCDB->SetRun(0); // THIS HAS TO BE RETRIEVED !!!
307 fCDB->SetDefaultStorage(fStrorageDBpath.c_str());
308 HLTDebug("CDB instance", "fCDB 0x%x", fCDB);
311 // check if the N of time bins make sense
314 HLTError("Sorry. Tracker needs number of time bins. At the moment you have to provide it with -NTimeBins <value>. The simulation always had 24 and the real data 30. Take your pick. Make sure the information is correct. Ask offline to implement how to propagate this information into clusters/cluster tree.");
318 if (iNtimeBins < 24 || iNtimeBins > 30)
320 HLTWarning("The number of time bins seems to be strange = %d. But okay. Let's try it...", iNtimeBins);
323 HLTDebug("The number of time bins = %d.", iNtimeBins);
324 AliTRDtrackerV1::SetNTimeBins(iNtimeBins);
326 // !!!! THIS IS IMPORTANT
327 // init alifield map - temporarly via parameter - should come from a DB or DCS ?
329 if (iMagneticField < 0)
332 HLTWarning("No magnetic field switch stated. Use -magnetic_field_ON or -magnetic_field_OFF flag. Defaulting to OFF = NO MAGNETIC FIELD");
335 if (iMagneticField == 0)
337 // magnetic field OFF
338 fField = new AliMagFMaps("Maps","Maps", 2, 0., 10., 1);
339 HLTDebug("Magnetic field is OFF.");
342 if (iMagneticField == 1)
345 fField = new AliMagFMaps("Maps","Maps", 2, 1., 10., 1);
346 HLTDebug("Magnetic field is ON.");
351 HLTError("Unable to init the field. Trouble at this point.");
355 // kTRUE sets the map uniform
356 AliTracker::SetFieldMap(fField,kTRUE);
358 // reconstruction parameters
359 if (iRecoParamType < 0 || iRecoParamType > 2)
361 HLTWarning("No reco param selected. Use -lowflux -highflux -cosmics flags. Defaulting to low flux.");
365 if (iRecoParamType == 0)
367 fRecoParam = AliTRDrecoParam::GetLowFluxParam();
368 HLTDebug("Low flux params init.");
371 if (iRecoParamType == 1)
373 fRecoParam = AliTRDrecoParam::GetHighFluxParam();
374 HLTDebug("High flux params init.");
377 if (iRecoParamType == 2)
379 fRecoParam = AliTRDrecoParam::GetCosmicTestParam();
380 HLTDebug("Cosmic Test params init.");
385 HLTError("No reco params initialized. Sniffing big trouble!");
389 fReconstructor = new AliTRDReconstructor();
390 // fRecoParam->SetChi2Y(.1);
391 // fRecoParam->SetChi2Z(5.);
392 fReconstructor->SetRecoParam(fRecoParam);
393 // write clusters [cw] = true
394 // track seeding (stand alone tracking) [sa] = true
395 // PID method in reconstruction (NN) [nn] = true
396 // write online tracklets [tw] = false
397 // drift gas [ar] = false
398 // sl_tr_0 = StreamLevel_task_Level
399 // fReconstructor->SetOption("sa,!cw,hlt,sl_tr_0");
400 TString recoOptions="sa,sl_tr_0";
404 recoOptions += ",cw";
408 recoOptions += ",!cw";
411 recoOptions += ",hlt";
413 fReconstructor->SetOption(recoOptions.Data());
414 HLTDebug("Reconstructor options are: %s",recoOptions.Data());
416 if((AliGeomManager::GetGeometry()) == NULL){
418 if ( TFile::Open(fGeometryFileName.c_str())) {
419 AliGeomManager::LoadGeometry(fGeometryFileName.c_str());
422 HLTError("Cannot load geometry from file %s",fGeometryFileName.c_str());
427 HLTInfo("Geometry Already Loaded");
429 // create the tracker
430 fTracker = new AliTRDtrackerV1();
431 fTracker->SetReconstructor(fReconstructor);
432 HLTDebug("TRDTracker at 0x%x", fTracker);
436 HLTError("Unable to create the tracker!");
443 int AliHLTTRDTrackerV1Component::DoDeinit()
445 // Deinitialization of the component
450 fTracker->SetClustersOwner(kFALSE);
454 // We need to set clusters in Reconstructor to null to prevent from
455 // double deleting, since we delete TClonesArray by ourself in DoEvent.
456 fReconstructor->SetClusters(0x0);
457 delete fReconstructor;
458 fReconstructor = 0x0;
460 AliTRDcalibDB::Terminate();
465 int AliHLTTRDTrackerV1Component::DoEvent( const AliHLTComponentEventData& evtData,
466 const AliHLTComponentBlockData* blocks,
467 AliHLTComponent_TriggerData& /*trigData*/,
468 AliHLTUInt8_t* outputPtr,
469 AliHLTUInt32_t& size,
470 vector<AliHLTComponent_BlockData>& outputBlocks )
473 Bool_t bWriteClusters = fReconstructor->IsWritingClusters();
475 HLTDebug("NofBlocks %lu", evtData.fBlockCnt );
477 AliHLTUInt32_t totalSize = 0, offset = 0;
478 AliHLTUInt32_t dBlockSpecification = 0;
480 vector<AliHLTComponent_DataType> expectedDataTypes;
481 GetInputDataTypes(expectedDataTypes);
482 if (evtData.fEventID == 1)
483 CALLGRIND_START_INSTRUMENTATION();
484 for ( unsigned long iBlock = 0; iBlock < evtData.fBlockCnt; iBlock++ )
486 const AliHLTComponentBlockData &block = blocks[iBlock];
488 AliHLTComponentDataType inputDataType = block.fDataType;
489 Bool_t correctDataType = kFALSE;
491 for(UInt_t i = 0; i < expectedDataTypes.size(); i++)
492 if( expectedDataTypes.at(i) == inputDataType)
493 correctDataType = kTRUE;
494 if (!correctDataType)
496 HLTDebug( "Block # %i/%i; Event 0x%08LX (%Lu) Wrong received datatype: %s - Skipping",
497 iBlock, evtData.fBlockCnt-1,
498 evtData.fEventID, evtData.fEventID,
499 DataType2Text(inputDataType).c_str());
503 HLTDebug("We get the right data type: Block # %i/%i; Event 0x%08LX (%Lu) Received datatype: %s",
504 iBlock, evtData.fBlockCnt-1,
505 evtData.fEventID, evtData.fEventID,
506 DataType2Text(inputDataType).c_str());
509 TTree *clusterTree = 0x0;
510 TClonesArray* clusterArray = 0x0;
511 ReadAndLoadClusters(clusterTree, clusterArray, &block);
513 // maybe it is not so smart to create it each event? clear is enough ?
514 AliESDEvent *esd = new AliESDEvent();
515 esd->CreateStdContent();
516 fTracker->Clusters2Tracks(esd);
518 //here transport the esd tracks further
519 Int_t nTracks = esd->GetNumberOfTracks();
520 Int_t nTRDTracks = esd->GetNumberOfTrdTracks();
521 HLTInfo("Number of tracks == %d == Number of TRD tracks %d", nTracks, nTRDTracks);
523 TClonesArray* trdTracks = fTracker->GetListOfTracks();
526 totalSize += TransportTracks(trdTracks, outputPtr, outputBlocks, offset, dBlockSpecification);
528 HLTDebug("Bad array trdTracks = 0x%x", trdTracks);
529 HLTDebug("totalSize: %i", totalSize);
531 // if ( totalSize > allocSize )
533 // HLTError("Too much data; Data written over allowed buffer. Amount written: %lu, allowed amount: %lu.",
534 // totalSize, size );
538 //here we are deleting clusters (but not the TClonesArray itself)
539 fTracker->UnloadClusters();
541 AliTRDReconstructor::SetClusters(0x0);
546 //clusterArray->Delete();
552 HLTDebug("Event is done. size written to the output is %i", size);
553 // CALLGRIND_STOP_INSTRUMENTATION();
559 * ReadClusters from the component input and load them to the tracker
561 //============================================================================
562 void AliHLTTRDTrackerV1Component::ReadAndLoadClusters(TTree *inClusterTree,
563 TClonesArray *inClusterArray, const AliHLTComponentBlockData *inBlock)
565 Bool_t bWriteClusters = fReconstructor->IsWritingClusters();
566 const AliHLTComponentBlockData &block = *inBlock;
569 TObject *tobjin = 0x0;
570 int ibForce = 0; // almost obsolet
573 tobjin = (TObject *)GetFirstInputObject( AliHLTTRDDefinitions::fgkClusterDataType, "TTree", ibForce);
574 HLTDebug("1stBLOCK; Pointer = 0x%x", tobjin);
575 inClusterTree = (TTree*)tobjin;
578 HLTDebug("CLUSTERS; Pointer to TTree = 0x%x Name = %s", inClusterTree, inClusterTree->GetName());
579 HLTDebug("TTree of clusters: nbEntries = %i", inClusterTree->GetEntriesFast());
580 fTracker->LoadClusters(inClusterTree);
584 HLTError("First Input Block is not a TTree 0x%x", tobjin);
587 else if (fUseHLTClusters)
589 inClusterArray = new TClonesArray("AliTRDcluster"); // would be nice to allocate memory for all clusters here.
590 ReadClusters(inClusterArray, block.fPtr, block.fSize);
591 HLTDebug("TClonesArray of clusters: nbEntries = %i", inClusterArray->GetEntriesFast());
592 fTracker->LoadClusters(inClusterArray);
596 tobjin = (TObject *)GetFirstInputObject( AliHLTTRDDefinitions::fgkClusterDataType, "TClonesArray", ibForce);
597 HLTDebug("1stBLOCK; Pointer = 0x%x", tobjin);
598 inClusterArray = (TClonesArray*)tobjin;
601 HLTDebug("CLUSTERS; Pointer to TClonesArray = 0x%x Name = %s", inClusterArray, inClusterArray->GetName());
602 HLTDebug("TClonesArray of clusters: nbEntries = %i", inClusterArray->GetEntriesFast());
603 fTracker->LoadClusters(inClusterArray);
607 HLTError("First Input Block not a TClonesArray 0x%x", tobjin);
613 * Read cluster to the TClonesArray from the memory
615 //============================================================================
616 Int_t AliHLTTRDTrackerV1Component::ReadClusters(TClonesArray *outArray, void* inputPtr, AliHLTUInt32_t size)
618 //HLTDebug("\nReading clusters from the Memory\n ============= \n");
619 AliHLTTRDCluster * curCluster;
620 UInt_t clusterSize = sizeof(AliHLTTRDCluster), curSize = 0;
623 curCluster = (AliHLTTRDCluster*) inputPtr;
624 while (curSize + clusterSize <= size)
626 // HLTDebug(" fX = %f; fY = %f; fZ = %f", curCluster->fX, curCluster->fY, curCluster->fZ);
628 AliTRDcluster* curTRDCluster = new((*outArray)[i]) AliTRDcluster();
629 curCluster->ExportTRDCluster(curTRDCluster);
630 // HLTDebug(" fX = %f; fY = %f; fZ = %f", curTRDCluster->GetX(), curTRDCluster->GetY(), curTRDCluster->GetZ());
631 curSize += clusterSize;
634 //cout << " current readed size is " << curSize << "/" << size << endl;
640 * Transport tracks to the next component
641 * Return Numbers of bytes written to the output
643 //============================================================================
644 AliHLTUInt32_t AliHLTTRDTrackerV1Component::TransportTracks(TClonesArray *inTracksArray, AliHLTUInt8_t* output,
645 vector<AliHLTComponent_BlockData>& outputBlocks, AliHLTUInt32_t inOffset, AliHLTUInt32_t inSpec)
647 Int_t nbTracks=inTracksArray->GetEntriesFast();
650 HLTDebug("We have an output array: pointer to inTracksArray = 0x%x, nbEntries = %i", inTracksArray, nbTracks);
652 // Using low-level interface
653 // with interface classes
654 AliHLTUInt32_t addedSize = AddToOutput(inTracksArray, output);
657 AliHLTComponentBlockData bd;
661 bd.fOffset = inOffset;
662 bd.fSize = addedSize;
663 bd.fSpecification = inSpec;
664 bd.fDataType = AliHLTTRDDefinitions::fgkTRDSATracksDataType;
665 outputBlocks.push_back( bd );
666 HLTDebug("BD fPtr 0x%x, fOffset %i, fSize %i, fSpec 0x%x", bd.fPtr, bd.fOffset, bd.fSize, bd.fSpecification);
671 inTracksArray->BypassStreamer(kFALSE);
672 PushBack(inTracksArray, AliHLTTRDDefinitions::fgkTRDSATracksDataType);