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: Matthias Richter <Matthias.Richter@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 AliHLTGlobalBarrelTrack.cxx
20 @author Matthias Richter
22 @brief An AliKalmanTrack implementation for global HLT barrel tracks.
25 // see header file for class documentation
27 // refer to README to build package
29 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
34 #include "AliHLTGlobalBarrelTrack.h"
35 #include "AliHLTSpacePointContainer.h"
36 #include "AliHLTTrackGeometry.h"
37 #include "AliHLTMisc.h"
38 #include "TClonesArray.h"
45 /** ROOT macro for the implementation of ROOT specific class methods */
46 ClassImp(AliHLTGlobalBarrelTrack)
48 AliHLTGlobalBarrelTrack::AliHLTGlobalBarrelTrack()
60 // see header file for class documentation
62 // refer to README to build package
64 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
67 AliHLTGlobalBarrelTrack::AliHLTGlobalBarrelTrack(const AliHLTGlobalBarrelTrack& t)
70 , fLastX(t.GetLastPointX())
71 , fLastY(t.GetLastPointY())
72 , fTrackID(t.TrackID())
73 , fHelixRadius(t.fHelixRadius)
74 , fHelixCenterX(t.fHelixCenterX)
75 , fHelixCenterY(t.fHelixCenterY)
79 // see header file for class documentation
80 fPoints.assign(t.fPoints.begin(), t.fPoints.end());
83 AliHLTGlobalBarrelTrack::AliHLTGlobalBarrelTrack(const AliHLTExternalTrackParam& p )
88 , fTrackID(p.fTrackID)
95 // see header file for class documentation
97 // the 5 track parameters are named in the AliHLTExternalTrackParam
98 // while AliExternalTrackParam just uses an array[5]
99 // the members have the same order, fY is the first one
100 Set(p.fX, p.fAlpha, &p.fY, p.fC);
101 SetPoints(p.fPointIDs, p.fNPoints);
102 SetNumberOfClusters(p.fNPoints);
103 //SetIntegratedLength(GetPathLengthTo( GetLastPointX(), b);
106 AliHLTGlobalBarrelTrack::AliHLTGlobalBarrelTrack(const AliExternalTrackParam& p )
118 // see header file for class documentation
119 *(dynamic_cast<AliExternalTrackParam*>(this))=p;
122 AliHLTGlobalBarrelTrack::~AliHLTGlobalBarrelTrack()
124 // see header file for class documentation
128 Double_t AliHLTGlobalBarrelTrack::GetPathLengthTo( Double_t x, Double_t b ) const
130 // calculate the trajectory length for dx step
132 Double_t dx = x - GetX();
133 Double_t ey = GetSnp();
134 if( TMath::Abs( ey )>=kAlmost1 ) return 0;
136 Double_t ex = TMath::Sqrt(1-ey*ey);
137 Double_t k = GetC(b);
139 Double_t ey1 = k * dx + ey;
141 // check for intersection with X=x
143 if ( TMath::Abs( ey1 ) >= kAlmost1 ) return 0;
145 Double_t ex1 = TMath::Sqrt(1-ey1*ey1);
147 Double_t ss = ey + ey1;
148 Double_t cc = ex + ex1;
150 if ( TMath::Abs( cc ) < 1.e-4 ) return 0;
152 Double_t tg = ss / cc;
153 Double_t dl = dx * TMath::Sqrt( 1 + tg * tg );
154 Double_t dSin = dl * k / 2;
155 if ( dSin > 1 ) dSin = 1;
156 if ( dSin < -1 ) dSin = -1;
157 Double_t dS = ( TMath::Abs( k ) > 1.e-4 ) ? ( 2 * TMath::ASin( dSin ) / k ) : dl;
159 return dS*TMath::Sqrt(1 + GetTgl()*GetTgl() );
165 int AliHLTGlobalBarrelTrack::ConvertTrackDataArray(const AliHLTTracksData* pTracks, unsigned sizeInByte, vector<AliHLTGlobalBarrelTrack> &tgtArray )
167 // see header file for class documentation
169 if (!pTracks || sizeInByte<sizeof(AliHLTTracksData) || pTracks->fCount==0) return 0;
171 const AliHLTUInt8_t* pEnd=reinterpret_cast<const AliHLTUInt8_t*>(pTracks);
174 tgtArray.resize(pTracks->fCount + tgtArray.size());
175 const AliHLTUInt8_t* pCurrent=reinterpret_cast<const AliHLTUInt8_t*>(pTracks->fTracklets);
176 for (unsigned i=0; i<pTracks->fCount; i++) {
177 if (pCurrent+sizeof(AliHLTExternalTrackParam)>pEnd) {
178 iResult=-EINVAL; break;
180 const AliHLTExternalTrackParam* track=reinterpret_cast<const AliHLTExternalTrackParam*>(pCurrent);
181 if (pCurrent+sizeof(AliHLTExternalTrackParam)+track->fNPoints*sizeof(UInt_t)>pEnd) {
182 iResult=-EINVAL; break;
185 pCurrent+=sizeof(AliHLTExternalTrackParam)+track->fNPoints*sizeof(UInt_t);
187 if (iResult<0) tgtArray.clear();
188 else iResult=tgtArray.size();
192 UInt_t AliHLTGlobalBarrelTrack::GetNumberOfPoints() const
194 // see header file for class documentation
195 return fPoints.size();
198 const UInt_t* AliHLTGlobalBarrelTrack::GetPoints() const
200 // see header file for class documentation
201 if (fPoints.size()==0) return NULL;
205 int AliHLTGlobalBarrelTrack::SetPoints(const UInt_t* pArray, UInt_t arraySize)
207 // see header file for class documentation
208 if (!pArray || arraySize==0) return 0;
209 fPoints.resize(arraySize);
210 for (unsigned i=0; i<arraySize; i++) fPoints[i]=pArray[i];
211 return fPoints.size();
214 int AliHLTGlobalBarrelTrack::CalculateHelixParams()
216 // calculate radius and center of the helix
217 // using the global magnetic field
218 return CalculateHelixParams(AliHLTMisc::Instance().GetBz());
221 int AliHLTGlobalBarrelTrack::CalculateHelixParams(float bfield)
223 // calculate radius and center of the helix
224 if (TMath::Abs(bfield)<kAlmost0) {
225 // no magnetic field -> straight lines
226 fHelixRadius=kVeryBig;
227 fHelixCenterX=kVeryBig;
228 fHelixCenterY=kVeryBig;
230 fHelixRadius = GetSignedPt()/(-kB2C*bfield);
231 Double_t trackPhi = Phi()-GetAlpha();
233 //cout << "Helix: phi=" << trackPhi << " x=" << GetX() << " y=" << GetY() << endl;
234 fHelixCenterX = GetX() + fHelixRadius * sin(trackPhi);
235 fHelixCenterY = GetY() - fHelixRadius * cos(trackPhi);
236 //cout << "Helix: center" << " x=" << fHelixCenterX << " y=" << fHelixCenterY << endl;
241 int AliHLTGlobalBarrelTrack::CalculateCrossingPoint(float xPlane, float alphaPlane, float& y, float& z)
243 // calculate crossing point of helix with a plane in yz
244 // in the local coordinates of the plane
246 if (TMath::Abs(fHelixRadius)<kAlmost0 &&
247 (iResult=CalculateHelixParams())<0) {
251 if (TMath::Abs(fHelixRadius)>=kVeryBig) {
252 // no magnetic field -> straight lines
254 // rotate helix center to local coordinates of the plane reference frame
255 float cosa=TMath::Cos(alphaPlane-GetAlpha());
256 float sina=TMath::Sin(alphaPlane-GetAlpha());
257 float cx= fHelixCenterX * cosa + fHelixCenterY * sina;
258 float cy=-fHelixCenterX * sina + fHelixCenterY * cosa;
260 // crossing point of helix with plane
261 Double_t aa = (cx - xPlane)*(cx - xPlane);
262 Double_t r2 = fHelixRadius*fHelixRadius;
263 if(aa > r2) // no crossing
266 Double_t aa2 = sqrt(r2 - aa);
267 Double_t y1 = cy + aa2;
268 Double_t y2 = cy - aa2;
270 if(TMath::Abs(y2) < TMath::Abs(y1)) y = y2;
272 // calculate the arc length between (x,y) and (x0,y0) with radius (cx,cy)
273 // reference point is (x0,y0) rotated by the diffence of the plane angle and
274 // the track reference frame angle alpha
276 Double_t angle1 = atan2((y - cy),(xPlane - cx));
277 if(angle1 < 0) angle1 += TMath::TwoPi();
279 // 2) angle of (x0,y0)
280 float x0= GetX() * cosa + GetY() * sina;
281 float y0=-GetX() * sina + GetY() * cosa;
282 Double_t angle2 = atan2((y0 - cy),(x0 - cx));
283 if(angle2 < 0) angle2 += TMath::TwoPi();
285 // 3) angle between (x,y) and (x0,y0)
286 Double_t diffangle = angle1 - angle2;
287 diffangle = fmod(diffangle,TMath::TwoPi());
290 Double_t arclength = TMath::Abs(diffangle*fHelixRadius);
292 // 5) direction depending on whether going outwards or inwards
293 int direction=GetX()>xPlane?-1:1;
294 z = GetZ() + direction*arclength*GetTgl();
296 //cout << "x=" << xPlane << " y=" << y << " cx=" << cx << " cy=" << cy << " a1=" << angle1 << " a2=" << angle2 << " diffa=" << diffangle << " s=" << arclength << " z=" << z << endl;
301 void AliHLTGlobalBarrelTrack::Print(Option_t* option) const
303 // see header file for class documentation
304 cout << "********* Track Id: " << fTrackID << " *******************" << endl;
305 AliExternalTrackParam::Print(option);
306 // cout << " Alpha " << GetAlpha();
307 // cout << " X " << GetX();
308 // cout << " Y " << GetY();
309 // cout << " Z " << GetZ() << endl;
310 // cout << " Snp " << GetSnp();
311 // cout << " Tgl " << GetTgl();
312 // cout << " Signed1Pt " << GetSigned1Pt() << endl;
315 void AliHLTGlobalBarrelTrack::Draw(Option_t *option)
317 /// Inherited from TObject, draw the track
319 float center[2]={0.5,0.5};
321 if (TMath::Abs(fHelixRadius)<kAlmost0 &&
322 (CalculateHelixParams())<0) {
326 TString strOption(option);
327 if (strOption.IsNull()) strOption="spacepoints trackarc";
328 std::auto_ptr<TObjArray> tokens(strOption.Tokenize(" "));
329 if (!tokens.get()) return;
330 for (int i=0; i<tokens->GetEntriesFast(); i++) {
331 if (!tokens->At(i)) continue;
333 TString arg=tokens->At(i)->GetName();
336 if (arg.BeginsWith(key)) {
337 arg.ReplaceAll(key, "");
342 if (arg.BeginsWith(key)) {
343 arg.ReplaceAll(key, "");
344 center[0]=arg.Atof();
348 if (arg.BeginsWith(key)) {
349 arg.ReplaceAll(key, "");
350 center[1]=arg.Atof();
354 if (arg.CompareTo(key)==0) {
355 if (fSpacePoints) DrawProjXYSpacePoints(option, fSpacePoints, scale, center);
359 if (arg.CompareTo(key)==0) {
360 DrawProjXYTrack(option, scale, center);
366 int AliHLTGlobalBarrelTrack::DrawProjXYSpacePoints(Option_t */*option*/, const AliHLTSpacePointContainer* spacePoints, const float scale, float center[2])
368 /// draw space points
371 if (!spacePoints) return -EINVAL;
373 const UInt_t* pointids=GetPoints();
374 for (unsigned i=0; i<GetNumberOfPoints() && pointids; i++) {
375 float clusterphi=spacePoints->GetPhi(pointids[i]);
376 float cosphi=TMath::Cos(clusterphi);
377 float sinphi=TMath::Sin(clusterphi);
378 float clusterx=spacePoints->GetX(pointids[i]);
379 float clustery=spacePoints->GetY(pointids[i]);
381 float pointx= clusterx*sinphi + clustery*cosphi;
382 float pointy=-clusterx*cosphi + clustery*sinphi;
384 // FIXME: cleanup of marker objects
385 TMarker* m=new TMarker(pointx/(2*scale)+center[0], pointy/(2*scale)+center[1], 3);
386 m->SetMarkerColor(markerColor);
392 // FIXME: make this a general geometry definition
393 // through an abstract class interface
394 const Double_t gkTPCX[159] = {
556 int AliHLTGlobalBarrelTrack::DrawProjXYTrack(Option_t *option, const float scale, float center[2])
559 bool bDrawArc=false; // draw TArc
560 bool bNoTrackPoints=false; // don't draw track points
561 TString strOption(option);
562 if (strOption.IsNull()) strOption="spacepoints trackarc";
563 std::auto_ptr<TObjArray> tokens(strOption.Tokenize(" "));
564 if (!tokens.get()) return 0;
565 for (int i=0; i<tokens->GetEntriesFast(); i++) {
566 if (!tokens->At(i)) continue;
568 TString arg=tokens->At(i)->GetName();
571 if (arg.BeginsWith(key)) {
576 if (arg.BeginsWith(key)) {
582 float cosa=TMath::Cos(GetAlpha());
583 float sina=TMath::Sin(GetAlpha());
587 firstpoint[0]= GetX()*sina + GetY()*cosa;
588 firstpoint[1]=-GetX()*cosa + GetY()*sina;
590 //cout << " first point alpha=" << GetAlpha() << " x: " << firstpoint[0] << " y: " << firstpoint[1] << endl;
591 // FIXME: cleanup of marker objects
592 TMarker* m=new TMarker(firstpoint[0]/(2*scale)+center[0], firstpoint[1]/(2*scale)+center[1], 29);
594 m->SetMarkerColor(2);
598 // draw points in step width and remember the last point
599 float lastpoint[2]={0.0, 0.0};
601 for (; firstpadrow<159 && gkTPCX[firstpadrow]<GetX(); firstpadrow++);
602 DrawProjXYTrackPoints(option, scale, center, firstpadrow, -1, firstpoint);
603 DrawProjXYTrackPoints(option, scale, center, firstpadrow, 1, lastpoint);
606 if (TMath::Abs(fHelixRadius)>=kVeryBig) {
607 // no magnetic field -> straight lines
609 // rotate helix center to local coordinates of the plane reference frame
610 float cx= fHelixCenterX * sina + fHelixCenterY * cosa;
611 float cy=-fHelixCenterX * cosa + fHelixCenterY * sina;
613 float diffx=cx-firstpoint[0];
614 float diffy=cy-firstpoint[1];
616 float phimax=2*TMath::Pi();
617 if (TMath::Abs(diffx)<kAlmost0) {
618 phimin=TMath::Pi()/2;
620 phimin=TMath::ATan(diffy/diffx);
622 if (diffx>0) phimin+=TMath::Pi();
624 diffx=cx-lastpoint[0];
625 diffy=cy-lastpoint[1];
626 if (TMath::Abs(diffx)<kAlmost0) {
627 phimax=TMath::Pi()/2;
629 phimax=TMath::ATan(diffy/diffx);
631 //cout << "diffx=" << diffx << " diffy=" << diffy << " phimin=" << phimin << " phimax=" << phimax << endl;
632 if (diffx>0) phimax+=TMath::Pi();
633 if (phimax<0 && phimin>=0 &&
634 phimax+TMath::TwoPi()-phimin<TMath::Pi()) phimax+=TMath::TwoPi();
635 //if (phimax<0 && TMath::Abs(phimax-phimin)<TMath::Pi()) phimax+=TMath::TwoPi();
636 if (phimax-phimin>TMath::Pi()) phimax-=TMath::TwoPi();
638 if (0/*phimin>phimax*/) {
643 phimin*=360.0/(2*TMath::Pi());
644 phimax*=360.0/(2*TMath::Pi());
645 //cout << " cx=" << cx << " cy=" << cy << " r=" << fHelixRadius << " phimin=" << phimin << " phimax=" << phimax << endl;
646 // FIXME: cleanup of graphics objects
647 TArc* tarc=new TArc(cx/(2*scale)+center[0], cy/(2*scale)+center[1], TMath::Abs(fHelixRadius)/(2*scale), phimin, phimax);
649 tarc->SetFillStyle(0);
656 int AliHLTGlobalBarrelTrack::DrawProjXYTrackPoints(Option_t */*option*/, const float scale, const float center[2], int firstpadrow, int step, float point[2])
658 // draw points in step width and return the last point
659 float offsetAlpha=0.0;
660 float cosa=TMath::Cos(GetAlpha());
661 float sina=TMath::Sin(GetAlpha());
663 for (int padrow=firstpadrow; padrow>=0 && padrow<159; padrow+=step) {
664 float x=gkTPCX[padrow];
672 if ((result=CalculateCrossingPoint(x, GetAlpha()-offsetAlpha, y, z))<1) break;
673 float pointAlpha=TMath::ATan(y/x);
674 if (TMath::Abs(pointAlpha)>TMath::Pi()/18) {
675 offsetAlpha+=(pointAlpha>0?-1:1)*TMath::Pi()/9;
678 cosa=TMath::Cos(GetAlpha()-offsetAlpha);
679 sina=TMath::Sin(GetAlpha()-offsetAlpha);
681 } while (result==0 && shift++<maxshift);
682 if (result<1) continue;
683 point[0]= x*sina + y*cosa;
684 point[1]=-x*cosa + y*sina;
686 //cout << x << " : x=" << x << " y=" << y << endl;
687 // FIXME: cleanup of TMarker objects?
688 TMarker* m=new TMarker(point[0]/(2*scale)+center[0], point[1]/(2*scale)+center[1], z>=0?2:5);
689 m->SetMarkerColor(markerColor);
695 void AliHLTGlobalBarrelTrack::SetTrackGeometry(AliHLTTrackGeometry* points)
697 /// set the instance to the track points container
699 if (!fTrackPoints) return;
700 fTrackPoints->SetTrackId(GetID());
703 int AliHLTGlobalBarrelTrack::AssociateSpacePoints(AliHLTTrackGeometry* trackpoints, AliHLTSpacePointContainer& spacepoints) const
705 /// associate the track space points to the calculated track points
706 AliHLTTrackGeometry* instance=trackpoints;
707 if (!instance) instance=fTrackPoints;
708 if (!instance) return 0;
710 UInt_t nofIds=GetNumberOfPoints();
711 const UInt_t* ids=GetPoints();
712 int result=instance->AssociateSpacePoints(ids, nofIds, spacepoints);
716 int AliHLTGlobalBarrelTrack::ReadTracks(const char* filename, TClonesArray& tgt, AliHLTComponentDataType /*dt*/, unsigned /*specification*/)
718 // open block from file and add to collection
719 if (!filename) return -EINVAL;
721 TString input=filename;
722 input+="?filetype=raw";
723 std::auto_ptr<TFile> pFile(new TFile(input));
724 if (!pFile.get()) return -ENOMEM;
725 if (pFile->IsZombie()) return -ENOENT;
729 std::auto_ptr<TArrayC> buffer(new TArrayC);
730 if (!buffer.get()) return -ENOMEM;
732 buffer->Set(pFile->GetSize());
733 if (pFile->ReadBuffer(buffer->GetArray(), buffer->GetSize())==0) {
734 const AliHLTTracksData* pTracks=reinterpret_cast<const AliHLTTracksData*>(buffer->GetArray());
735 vector<AliHLTGlobalBarrelTrack> tracks;
736 iResult=ConvertTrackDataArray(pTracks, buffer->GetSize(), tracks);
738 int offset=tgt.GetEntriesFast();
739 tgt.ExpandCreate(offset+tracks.size());
740 for (unsigned i=0; i<tracks.size(); i++) {
741 new (tgt[offset+i]) AliHLTGlobalBarrelTrack(tracks[i]);
743 iResult=tracks.size();
745 //HLTError("failed to convert tracks from file %s size %d byte(s) ", filename, pFile->GetSize());
748 //HLTError("failed reading %d byte(s) from file %s", pFile->GetSize(), filename);
755 int AliHLTGlobalBarrelTrack::ReadTrackList(const char* listfile, TClonesArray& tgt, AliHLTComponentDataType dt, unsigned specification)
757 // open blank separated list of files and read tracks
758 ifstream list(listfile);
759 if (!list.good()) return -ENOENT;
763 while (file.ReadLine(list)) {
764 //HLTInfo("adding tracks from file %s", file.Data());
765 int iResult=ReadTracks(file.Data(), tgt, dt, specification);
767 //HLTInfo("failed to add data from file %s: error %d", file.Data(), iResult);