3 //**************************************************************************
4 //* This file is property of and copyright by the ALICE HLT Project *
5 //* ALICE Experiment at CERN, All rights reserved. *
7 //* Primary Authors: Gaute Ovrebekk <ovrebekk@ift.uib.no> *
8 //* for The ALICE HLT 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 AliHLTTPCTrackHistoComponent.cxx
20 @author Gaute Ovrebekk, Matthias Richter
22 @brief The TPC conformal mapping tracker component.
29 #include "AliHLTTPCTrackHistoComponent.h"
30 #include "AliHLTTPCTransform.h"
31 #include "AliHLTTPCClusterDataFormat.h"
32 #include "AliHLTTPCTrackletDataFormat.h"
33 #include "AliHLTTPCMemHandler.h"
34 #include "AliHLTTPCDefinitions.h"
35 #include "AliHLTTPCTrackArray.h"
36 #include "AliHLTTPCTrack.h"
37 //#include "AliHLTGlobalBarrelTrack.h"
38 #include "AliHLTExternalTrackParam.h"
39 #include "AliHLTDataTypes.h"
46 #include "TObjString.h"
47 #include "TObjArray.h"
50 AliHLTTPCTrackHistoComponent gAliHLTTPCTrackHistoComponent;
52 /** ROOT macro for the implementation of ROOT specific class methods */
53 ClassImp(AliHLTTPCTrackHistoComponent)
55 AliHLTTPCTrackHistoComponent::AliHLTTPCTrackHistoComponent()
65 fMeanMultiplicity(NULL),
70 //fNClusterVsXY(NULL),
73 //fClustersArray(NULL),
76 // see header file for class documentation
78 // refer to README to build package
80 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
83 AliHLTTPCTrackHistoComponent::~AliHLTTPCTrackHistoComponent(){
84 // see header file for class documentation
87 // Public functions to implement AliHLTComponent's interface.
88 // These functions are required for the registration process
90 const char* AliHLTTPCTrackHistoComponent::GetComponentID(){
91 // see header file for class documentation
93 return "TPCTrackHisto";
96 void AliHLTTPCTrackHistoComponent::GetInputDataTypes(AliHLTComponentDataTypeList& list){
97 // see header file for class documentation
99 list.push_back(AliHLTTPCDefinitions::fgkClustersDataType|kAliHLTDataOriginTPC);
100 list.push_back(AliHLTTPCDefinitions::fgkTrackSegmentsDataType|kAliHLTDataOriginTPC);
101 //list.push_back(AliHLTTPCDefinitions::fgkTracksDataType);
102 list.push_back(kAliHLTDataTypeTrack|kAliHLTDataOriginTPC);
103 list.push_back(kAliHLTDataTypeTObjArray|kAliHLTDataOriginTPC);
106 AliHLTComponentDataType AliHLTTPCTrackHistoComponent::GetOutputDataType(){
107 // see header file for class documentation
108 return kAliHLTMultipleDataType;
111 int AliHLTTPCTrackHistoComponent::GetOutputDataTypes(AliHLTComponentDataTypeList& tgtList){
112 // see header file for class documentation
114 tgtList.push_back(kAliHLTDataTypeTNtuple|kAliHLTDataOriginTPC);
115 tgtList.push_back(kAliHLTDataTypeHistogram|kAliHLTDataOriginTPC);
116 return tgtList.size();
119 void AliHLTTPCTrackHistoComponent::GetOutputDataSize( unsigned long& constBase, double& inputMultiplier ){
120 // see header file for class documentation
123 inputMultiplier = 1;// XXX TODO: Find more realistic value
126 AliHLTComponent* AliHLTTPCTrackHistoComponent::Spawn(){
127 // see header file for class documentation
128 return new AliHLTTPCTrackHistoComponent;
131 int AliHLTTPCTrackHistoComponent::DoInit( int argc, const char** argv ){
132 // see header file for class documentation
134 fClusters = new TNtuple("fClusters", "fClusters", "charge:qmax:residualY:residualZ:event");
135 fTracks = new TNtuple("fTracks", "fTracks", "pt:eta:psi:nclusters:event");
136 fTracksArray = new AliHLTTPCTrackArray();
138 fMultiplicity = new TH1F("fMultiplicity", "Track multiplicity per event", 1000, 0, 1000);
139 fMeanMultiplicity = new TH1F("fMeanMultiplicity", "Mean track multiplicity vs. #evt", 10000/fNEvtMod, 0, 10000);
140 fDeDxVsP = new TProfile("fDeDxVsP", "E-deposition per unit length vs. p",100, 0, 100);
143 TString configuration = "";
144 TString argument = "";
145 for(int i=0; i<argc && iResult>=0; i++){
147 if(!configuration.IsNull()) configuration += " ";
148 configuration += argument;
151 if(!configuration.IsNull()){
152 iResult = Configure(configuration.Data());
157 int AliHLTTPCTrackHistoComponent::DoDeinit(){
158 // see header file for class documentation
164 delete fMultiplicity;
165 delete fMeanMultiplicity;
171 int AliHLTTPCTrackHistoComponent::DoEvent(const AliHLTComponentEventData& /*evtData*/, AliHLTComponentTriggerData& /*trigData*/){
172 // see header file for class documentation
174 if(GetFirstInputBlock(kAliHLTDataTypeSOR) || GetFirstInputBlock(kAliHLTDataTypeEOR)) return 0;
178 if(!fTracksArray) fTracksArray = new AliHLTTPCTrackArray();
180 const AliHLTComponentBlockData *iter = NULL;
182 // //----------------- loop over slice tracks ----------------------//
184 // for(iter = GetFirstInputBlock(AliHLTTPCDefinitions::fgkTrackSegmentsDataType); iter != NULL; iter = GetNextInputBlock()){
185 // if(iter->fDataType!=AliHLTTPCDefinitions::fgkTrackSegmentsDataType)continue;
186 // ReadTracks(iter,totalTracks);
191 //----------------- loop over cluster blocks ---------------------//
193 Int_t totalSpacePoints = 0;
195 for(iter = GetFirstInputBlock(AliHLTTPCDefinitions::fgkClustersDataType); iter != NULL; iter = GetNextInputBlock()){
197 if(iter->fDataType!=AliHLTTPCDefinitions::fgkClustersDataType) continue;
199 AliHLTUInt8_t minSlice = AliHLTTPCDefinitions::GetMinSliceNr(*iter);
200 AliHLTUInt8_t minPartition = AliHLTTPCDefinitions::GetMinPatchNr(*iter);
201 //HLTDebug("Input Data - TPC cluster - slice/partition: %d/%d.", minSlice, minPartition);
203 const AliHLTTPCClusterData* clusterData = (const AliHLTTPCClusterData*)iter->fPtr;
204 Int_t nSpacepoint = (Int_t)clusterData->fSpacePointCnt;
205 totalSpacePoints += nSpacepoint;
206 HLTDebug("TrackHisto component found %d spacepoints in slice %d partition %d", nSpacepoint, minSlice, minPartition);
208 AliHLTTPCSpacePointData *clusters = (AliHLTTPCSpacePointData*)clusterData->fSpacePoints;
210 if(fClustersArray[minSlice][minPartition] != NULL){
211 //delete(fClustersArray[minSlice][minPartition]);
212 fClustersArray[minSlice][minPartition] = NULL;
215 // fill the array with AliHLTTPCSpacePointData pointers
216 // it will be used in the track loop to access information
217 // for the used clusters only
218 fClustersArray[minSlice][minPartition] = clusters;
219 fNSpacePoints[minSlice][minPartition] = nSpacepoint;
221 if(nSpacepoint==0) fClustersArray[minSlice][minPartition] = NULL;
223 } // end of loop over cluster data blocks
225 HLTInfo("TrackHisto found %d spacepoints",totalSpacePoints);
230 //----------------- loop over merged tracks -------------------//
232 Int_t totalTracks = 0;
234 for(iter = GetFirstInputBlock(kAliHLTDataTypeTrack|kAliHLTDataOriginTPC); iter != NULL; iter = GetNextInputBlock()){
235 if(iter->fDataType != (kAliHLTDataTypeTrack|kAliHLTDataOriginTPC)) continue;
236 ReadTracks(iter,totalTracks);
239 HLTInfo("TrackHisto found %d tracks", totalTracks);
241 fMultiplicity->Fill(totalTracks);
243 fNtotTracks += totalTracks;
244 if(fNEvents%fNEvtMod==0){
245 fMeanMultiplicity->Fill(fNEvents, Float_t(fNtotTracks)/(fNEvtMod));
246 //HLTInfo("Event number: %d, total tracks accummulated %d", fNEvents, fNtotTracks);
252 delete fTracksArray; fTracksArray = NULL;
256 int AliHLTTPCTrackHistoComponent::Configure(const char* arguments){
257 // see header file for class documentation
260 if (!arguments) return iResult;
262 TString allArgs=arguments;
265 TObjArray* pTokens=allArgs.Tokenize(" ");
267 for (int i=0; i<pTokens->GetEntries() && iResult>=0; i++) {
268 argument=((TObjString*)pTokens->At(i))->GetString();
269 if (argument.IsNull()) continue;
271 HLTError("unknown argument %s", argument.Data());
280 void AliHLTTPCTrackHistoComponent::ReadTracks(const AliHLTComponentBlockData* iter,Int_t &tt){
281 // see header file for class documentation
283 AliHLTUInt8_t slice = AliHLTTPCDefinitions::GetMinSliceNr(*iter);
284 AliHLTUInt8_t partition = AliHLTTPCDefinitions::GetMinPatchNr(*iter);
286 if( slice < fMinSlice ) fMinSlice = slice;
287 if( slice > fMaxSlice ) fMaxSlice = slice;
288 if( partition < fMinPartition ) fMinPartition = partition;
289 if( partition > fMaxPartition ) fMaxPartition = partition;
291 AliHLTTracksData *trackData = (AliHLTTracksData*)(iter->fPtr);
292 AliHLTUInt32_t nTracks = trackData->fCount;
294 AliHLTExternalTrackParam *track = (AliHLTExternalTrackParam*)trackData->fTracklets;
297 fTracksArray->FillTracksChecked(trackData->fTracklets,trackData->fCount,iter->fSize,slice,true);
299 Int_t usedSpacePoints = 0;
301 for(AliHLTUInt32_t i=0;i<nTracks;i++){
303 AliHLTTPCTrack * tpcTrack = 0;
304 tpcTrack = (AliHLTTPCTrack*) fTracksArray->GetTrack(i);
305 if(!tpcTrack) continue;
306 Double_t trackLength = GetTrackLength(tpcTrack);
308 UInt_t nHits = track->fNPoints;
309 fTracks->Fill( track->fq1Pt, track->fSinPsi, track->fTgl, nHits, GetEventId() );
311 const UInt_t *hitnum = track->fPointIDs;
313 Double_t totCharge = 0;
314 for(UInt_t h=0; h<nHits; h++){
316 UInt_t idTrack = hitnum[h];
317 Int_t sliceTrack = (idTrack>>25) & 0x7f;
318 Int_t patchTrack = (idTrack>>22) & 0x7;
319 UInt_t pos = idTrack&0x3fffff;
321 // use the fClustersArray that was filled in the cluster loop
322 if( !fClustersArray[sliceTrack][patchTrack] ) continue;
323 if( fNSpacePoints[sliceTrack][patchTrack]<pos ) HLTError("Space point array out of boundaries!");
325 Float_t resy = 0., resz = 0.;
327 FillResidual(pos,sliceTrack,patchTrack,resy,resz);
329 totCharge += (fClustersArray[sliceTrack][patchTrack])[pos].fCharge;
331 fClusters->Fill( (fClustersArray[sliceTrack][patchTrack])[pos].fCharge, (fClustersArray[sliceTrack][patchTrack])[pos].fQMax, resy, resz, GetEventId() );
336 if(trackLength > 0) fDeDxVsP->Fill(track->fq1Pt*TMath::Sqrt(1.+track->fTgl*track->fTgl), totCharge/trackLength);
338 UChar_t *tmpP = (UChar_t*)track;
339 tmpP += sizeof(AliHLTExternalTrackParam)+track->fNPoints*sizeof(UInt_t);
340 track = (AliHLTExternalTrackParam*)tmpP;
344 /* //HLTDebug ( "Input Data - TPC cluster - Slice/Patch: %d/%d.", slice, partition );
345 AliHLTTPCTrackletData* trackData = (AliHLTTPCTrackletData*) iter->fPtr;
346 AliHLTUInt32_t nTracks = trackData->fTrackletCnt;
347 fTracksArray->FillTracksChecked(trackData->fTracklets,trackData->fTrackletCnt,iter->fSize,slice,true);
349 //HLTInfo("TrackHisto found %d Tracks in slice %d partition %d", nTracks, slice, partition);
350 AliHLTTPCTrackSegmentData *tracks = (AliHLTTPCTrackSegmentData*) trackData->fTracklets;
352 for(AliHLTUInt32_t i=0;i<nTracks;i++){
353 UInt_t nHits = tracks->fNPoints;
355 fTracks->Fill(tracks->fPt,tracks->fPsi,tracks->fTgl,nHits,GetEventId());
357 const UInt_t *hitnum = tracks->fPointIDs;
358 for(UInt_t h=0; h<nHits; h++){
359 UInt_t idTrack = hitnum[h];
360 Int_t sliceTrack = (idTrack>>25) & 0x7f;
361 Int_t patchTrack = (idTrack>>22) & 0x7;
362 UInt_t pos = idTrack&0x3fffff;
363 fTrackClusterID[sliceTrack][patchTrack].push_back(pos);
365 UChar_t *tmpP = (UChar_t*)tracks;
366 tmpP += sizeof(AliHLTTPCTrackSegmentData)+tracks->fNPoints*sizeof(UInt_t);
367 tracks = (AliHLTTPCTrackSegmentData*)tmpP;
372 void AliHLTTPCTrackHistoComponent::PushHisto(){
373 // see header file for class documentation
375 AliHLTUInt32_t fSpecification = AliHLTTPCDefinitions::EncodeDataSpecification(fMinSlice,fMaxSlice,fMinPartition,fMaxPartition);
377 PushBack( (TObject*)fTracks, kAliHLTDataTypeTNtuple |kAliHLTDataOriginTPC, fSpecification);
378 PushBack( (TObject*)fClusters, kAliHLTDataTypeTNtuple |kAliHLTDataOriginTPC, fSpecification);
379 PushBack( (TObject*)fMultiplicity, kAliHLTDataTypeHistogram|kAliHLTDataOriginTPC, fSpecification);
380 PushBack( (TObject*)fMeanMultiplicity, kAliHLTDataTypeHistogram|kAliHLTDataOriginTPC, fSpecification);
381 PushBack( (TObject*)fDeDxVsP, kAliHLTDataTypeHistogram|kAliHLTDataOriginTPC, fSpecification);
384 void AliHLTTPCTrackHistoComponent::FillResidual(UInt_t pos,AliHLTUInt8_t slice,AliHLTUInt8_t partition,Float_t& resy,Float_t& resz){
385 // see header file for class documentation
387 AliHLTTPCSpacePointData *cl = &fClustersArray[slice][partition][pos];
390 AliHLTTPCTrack *gtrack = NULL;
392 for(int i=0;i<fTracksArray->GetNTracks();i++){
394 AliHLTTPCTrack *tt = fTracksArray->GetCheckedTrack(i);
395 UInt_t *hitnum =tt->GetHitNumbers();
396 Int_t nHits = tt->GetNHits();
398 for(Int_t h=0; h<nHits; h++){
400 Int_t Tslice = (id>>25) & 0x7f;
401 Int_t Tpatch = (id>>22) & 0x7;
402 UInt_t Tpos = id&0x3fffff;
403 if(Tslice==slice && Tpatch==partition && Tpos==pos){
412 Int_t tslice = gtrack->GetSector();
415 Double_t radius = gtrack->GetRadius(); // radius
416 Double_t kappa = gtrack->GetKappa(); // curvature = 1/R , signed
417 Double_t lambda = atan( gtrack->GetTgl() ); // dipAngle lambda
419 // ------------------------------------
420 // ++ Get first/last point of the track
422 Double_t xyzL[3]; // lastpoint of track
423 Double_t xyzF[3]; // firstpoint of track
425 xyzF[0] = gtrack->GetFirstPointX();
426 xyzF[1] = gtrack->GetFirstPointY();
427 xyzF[2] = gtrack->GetFirstPointZ();
429 xyzL[0] = gtrack->GetLastPointX();
430 xyzL[1] = gtrack->GetLastPointY();
431 xyzL[2] = gtrack->GetLastPointZ();
433 // --------------------------
434 // ++ Calculate length of the track
436 Double_t s = 0.; // length of the track
437 if ( AliHLTTPCTransform::GetBFieldValue() == 0. || kappa == 0 )
438 s = sqrt ( (xyzL[0] - xyzF[0])*(xyzL[0] - xyzF[0]) + (xyzL[1] - xyzF[1])*(xyzL[1] - xyzF[1]) );
440 // Calculate the length of the track. If it is to flat in in s,z plane use sxy, otherwise use sz
441 if (fabs(lambda) > 0.05){
442 // length of track calculated out of z
443 s = fabs( (xyzL[2] - xyzF[2]) / sin(lambda) ); // length of track calculated out of z
446 Double_t d = (xyzL[0] - xyzF[0])*(xyzL[0] - xyzF[0]) + (xyzL[1] - xyzF[1])*(xyzL[1] - xyzF[1]);
447 // length of track calculated out of xy
448 s = fabs ( acos( 0.5 * (2 - (d / (radius*radius)))) / ( kappa * cos(lambda) ) );
453 gtrack->Rotate(tslice,kTRUE);
455 //Double_t padrows = 0;
457 Float_t xyzC[3]; // cluster tmp
458 Float_t xyzTtmp[3]; // track tmp
464 Int_t padrow = AliHLTTPCTransform::GetPadRow(cl->fX);
466 xyzTtmp[0] = gtrack->GetFirstPointX();
468 if(gtrack->GetCrossingPoint(padrow,xyzTtmp)) {
469 // ----------------------
470 // ++ Calculate Residuals
472 Float_t deltaY = ( xyzC[1] - xyzTtmp[1] );
473 Float_t deltaZ = ( xyzC[2] - xyzTtmp[2] );
483 Double_t AliHLTTPCTrackHistoComponent::GetTrackLength(AliHLTTPCTrack *hltTrack)
486 AliHLTTPCTrack * gtrack = hltTrack;
488 //Caculate the HLT Track Length
490 Double_t radius = gtrack->GetRadius(); // radius
491 Double_t kappa = gtrack->GetKappa(); // curvature = 1/R , signed
492 Double_t lambda = atan( gtrack->GetTgl() ); // dipAngle lambda
494 // ------------------------------------
495 // ++ Get first/last point of the track
497 Double_t xyzL[3]; // lastpoint of track
498 Double_t xyzF[3]; // firstpoint of track
500 xyzF[0] = gtrack->GetFirstPointX();
501 xyzF[1] = gtrack->GetFirstPointY();
502 xyzF[2] = gtrack->GetFirstPointZ();
504 xyzL[0] = gtrack->GetLastPointX();
505 xyzL[1] = gtrack->GetLastPointY();
506 xyzL[2] = gtrack->GetLastPointZ();
508 // --------------------------
509 // ++ Calculate length of the track
511 Double_t s = 0.; // length of the track
512 if ( AliHLTTPCTransform::GetBFieldValue() == 0. || kappa == 0 )
513 s = sqrt ( (xyzL[0] - xyzF[0])*(xyzL[0] - xyzF[0])
514 + (xyzL[1] - xyzF[1])*(xyzL[1] - xyzF[1]) );
516 // Calculate the length of the track. If it is to flat in in s,z plane use sxy, otherwise use sz
517 if (fabs(lambda) > 0.05){
518 // length of track calculated out of z
519 s = fabs( (xyzL[2] - xyzF[2]) / sin(lambda) ); // length of track calculated out of z
521 Double_t d = (xyzL[0] - xyzF[0])*(xyzL[0] - xyzF[0])
522 + (xyzL[1] - xyzF[1])*(xyzL[1] - xyzF[1]);
523 // length of track calculated out of xy
524 s = fabs ( acos( 0.5 * (2 - (d / (radius*radius))))
525 / ( kappa * cos(lambda) ) );