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 AliHLTTPCTrackGeometry.cxx
20 /// @author Matthias Richter
22 /// @brief Desciption of a track by a sequence of track points
25 #include "AliHLTTPCTrackGeometry.h"
26 #include "AliHLTTPCTransform.h"
27 #include "AliHLTTPCSpacePointData.h"
28 #include "AliHLTTPCClusterDataFormat.h"
29 #include "AliHLTTPCSpacePointContainer.h"
30 #include "AliHLTTPCDefinitions.h"
31 #include "AliHLTComponent.h"
32 #include "AliHLTGlobalBarrelTrack.h"
36 /** ROOT macro for the implementation of ROOT specific class methods */
37 ClassImp(AliHLTTPCTrackGeometry)
39 AliHLTTPCTrackGeometry::AliHLTTPCTrackGeometry()
40 : AliHLTTrackGeometry()
42 /// standard constructor
45 AliHLTTPCTrackGeometry::AliHLTTPCTrackGeometry(const AliHLTTPCTrackGeometry& src)
46 : AliHLTTrackGeometry(src)
51 AliHLTTPCTrackGeometry& AliHLTTPCTrackGeometry::operator=(const AliHLTTPCTrackGeometry& src)
53 /// assignment operator
54 AliHLTTrackGeometry::operator=(src);
58 AliHLTTPCTrackGeometry::~AliHLTTPCTrackGeometry()
63 float AliHLTTPCTrackGeometry::GetPlaneAlpha(AliHLTUInt32_t planeId) const
65 /// alpha of the plane
66 UInt_t slice=AliHLTTPCSpacePointData::GetSlice(planeId);
67 float alpha=( slice + 0.5 ) * TMath::Pi() / 9.0;
68 if (alpha>TMath::TwoPi()) alpha-=TMath::TwoPi();
72 float AliHLTTPCTrackGeometry::GetPlaneR(AliHLTUInt32_t planeId) const
74 /// radial distance from global {0,0,0}
75 UInt_t partition=AliHLTTPCSpacePointData::GetPatch(planeId);
76 UInt_t number=AliHLTTPCSpacePointData::GetNumber(planeId);
77 Int_t row=AliHLTTPCTransform::GetFirstRow(partition)+number;
78 return AliHLTTPCTransform::Row2X(row);
81 float AliHLTTPCTrackGeometry::GetPlaneTheta(AliHLTUInt32_t /*planeId*/) const
83 /// theta of the plane
87 bool AliHLTTPCTrackGeometry::CheckBounds(AliHLTUInt32_t planeId, float u, float /*v*/) const
89 /// check bounds in u and v coordinate
90 float r=GetPlaneR(planeId);
91 if (r<AliHLTTPCTransform::GetFirstRow(0)) return false;
93 // TODO: check if the pad width needs to be considered here
94 return TMath::Abs(TMath::ASin(u/r))<=TMath::Pi()/18;
97 int AliHLTTPCTrackGeometry::CalculateTrackPoints(const AliHLTExternalTrackParam& track)
99 /// calculate the track points, expects the global magnetic field to be initialized
100 AliHLTGlobalBarrelTrack bt(track);
101 return CalculateTrackPoints(bt);
104 int AliHLTTPCTrackGeometry::CalculateTrackPoints(AliHLTGlobalBarrelTrack& track)
106 /// calculate the track points, expects the global magnetic field to be initialized
110 firstpadrow<AliHLTTPCTransform::GetNRows() &&
111 AliHLTTPCTransform::Row2X(firstpadrow)+AliHLTTPCTransform::GetPadLength(firstpadrow)<track.GetX();
113 if (firstpadrow>=AliHLTTPCTransform::GetNRows()) return 0;
114 iResult=CalculateTrackPoints(track, firstpadrow, 1);
115 if (iResult>=0 && firstpadrow>0)
116 iResult=CalculateTrackPoints(track, firstpadrow-1, -1);
120 int AliHLTTPCTrackGeometry::CalculateTrackPoints(AliHLTGlobalBarrelTrack& track, int firstpadrow, int step)
122 /// calculate the track points, expects the global magnetic field to be initialized
123 float offsetAlpha=0.0;
124 for (int padrow=firstpadrow; padrow>=0 && padrow<AliHLTTPCTransform::GetNRows(); padrow+=step) {
125 float x=AliHLTTPCTransform::Row2X(padrow);
133 // start calculation of crossing points with padrow planes in the slice of the first point
134 // plane alpha corresponds to alpha of the track, switch to neighboring slice if the result
136 if ((result=track.CalculateCrossingPoint(x, track.GetAlpha()-offsetAlpha, y, z))<1) break;
137 float pointAlpha=TMath::ATan(y/x);
138 if (TMath::Abs(pointAlpha)>TMath::Pi()/18) {
139 offsetAlpha+=(pointAlpha>0?-1:1)*TMath::Pi()/9;
142 } while (result==0 && shift++<maxshift);
143 if (result<1) continue;
144 float planealpha=track.GetAlpha()-offsetAlpha;
145 if (planealpha<0) planealpha+=TMath::TwoPi();
146 int slice=int(9*planealpha/TMath::Pi());
147 //if (z<0) slice+=18;
148 int partition=AliHLTTPCTransform::GetPatch(padrow);
149 int row=padrow-AliHLTTPCTransform::GetFirstRow(partition);
150 UInt_t id=AliHLTTPCSpacePointData::GetID(slice, partition, row);
151 if (TMath::Abs(planealpha-GetPlaneAlpha(id))>0.0001) {
152 HLTError("alpha missmatch for plane %08x (slice %d): alpha from id %f (%.0f), expected %f (%.0f)", id, slice, GetPlaneAlpha(id), 180*GetPlaneAlpha(id)/TMath::Pi(), planealpha, 180*planealpha/TMath::Pi());
154 AddTrackPoint(AliHLTTrackPoint(id, y, z));
159 int AliHLTTPCTrackGeometry::FindMatchingTrackPoint(AliHLTUInt32_t spacepointId, float spacepoint[3], AliHLTUInt32_t& planeId)
161 /// find the track point which can be associated to a spacepoint with coordinates and id
162 UInt_t slice=AliHLTTPCSpacePointData::GetSlice(spacepointId);
163 UInt_t partition=AliHLTTPCSpacePointData::GetPatch(spacepointId);
164 int row=AliHLTTPCTransform::GetPadRow(spacepoint[0]);
165 if (row<AliHLTTPCTransform::GetFirstRow(partition) || row>AliHLTTPCTransform::GetLastRow(partition)) {
166 HLTError("row number %d calculated from x value %f is outside slice %d partition %d", row, spacepoint[0], slice, partition);
169 row-=AliHLTTPCTransform::GetFirstRow(partition);
170 UInt_t id=AliHLTTPCSpacePointData::GetID(slice, partition, row);
171 const AliHLTTrackPoint* point=GetTrackPoint(id);
172 if (!point && slice<18) {
173 id=AliHLTTPCSpacePointData::GetID(slice+18, partition, row);
174 point=GetTrackPoint(id);
175 } else if (!point && slice>=18) {
176 id=AliHLTTPCSpacePointData::GetID(slice-18, partition, row);
177 point=GetTrackPoint(id);
181 if (point->HaveAssociatedSpacePoint()) return 0; // already occupied
184 if (TMath::Abs(point->GetU()-spacepoint[1])>maxdy) return -ENOENT;
185 //if (TMath::Abs(point->GetV()-spacepoint[2])>maxdz) return -ENOENT;
191 AliHLTSpacePointContainer* AliHLTTPCTrackGeometry::ConvertToSpacePoints() const
193 /// create a collection of all points
194 std::auto_ptr<AliHLTTPCSpacePointContainer> spacepoints(new AliHLTTPCSpacePointContainer);
195 if (!spacepoints.get()) return NULL;
197 const vector<AliHLTTrackPoint>& trackPoints=GetTrackPoints();
199 while (i<trackPoints.size()) {
200 // allocate buffer for all points, even though the buffer might not be filled
201 // completely because of a partition change
202 int nofPoints=trackPoints.size()-i;
203 int blocksize=sizeof(AliHLTTPCClusterData)+nofPoints*sizeof(AliHLTTPCSpacePointData);
204 AliHLTUInt8_t* pBuffer=spacepoints->Alloc(blocksize);
205 if (!pBuffer) return NULL;
206 AliHLTTPCClusterData* pClusterData=reinterpret_cast<AliHLTTPCClusterData*>(pBuffer);
207 pClusterData->fSpacePointCnt=0;
208 AliHLTTPCSpacePointData* pClusters=pClusterData->fSpacePoints;
210 int currentPartition=-1;
211 for (; i<trackPoints.size(); i++) {
212 AliHLTUInt32_t planeId=trackPoints[i].GetId();
213 int slice=AliHLTTPCSpacePointData::GetSlice(planeId);
214 int partition=AliHLTTPCSpacePointData::GetPatch(planeId);
215 int number=AliHLTTPCSpacePointData::GetNumber(planeId);
216 if ((currentSlice>=0 && currentSlice!=slice) || (currentPartition>=0 && currentPartition!=partition)) {
217 // change of partition or slice, need to go to next block
218 // 2011-07-26 currently all spacepoints go into one block, if separated
219 // blocks per partition are needed one has to leave the inner loop here
220 // and set the data block specification below
221 // Caution: not tested, only the last block seems to make it through
225 currentPartition=partition;
226 pClusters[pClusterData->fSpacePointCnt].fX=GetPlaneR(planeId);
227 pClusters[pClusterData->fSpacePointCnt].fY=trackPoints[i].GetU();
228 pClusters[pClusterData->fSpacePointCnt].fZ=trackPoints[i].GetV();
229 pClusters[pClusterData->fSpacePointCnt].fID=planeId;
230 pClusters[pClusterData->fSpacePointCnt].fPadRow=AliHLTTPCTransform::GetFirstRow(partition)+number;
231 pClusters[pClusterData->fSpacePointCnt].fSigmaY2=0.;
232 pClusters[pClusterData->fSpacePointCnt].fSigmaZ2=0.;
233 pClusters[pClusterData->fSpacePointCnt].fCharge=0;
234 pClusters[pClusterData->fSpacePointCnt].fQMax=0;
235 pClusters[pClusterData->fSpacePointCnt].fUsed=0;
236 pClusters[pClusterData->fSpacePointCnt].fTrackN=0;
237 pClusterData->fSpacePointCnt++;
239 AliHLTComponentBlockData bd;
240 AliHLTComponent::FillBlockData(bd);
243 AliHLTComponent::SetDataType(bd.fDataType, "CLUSTERS", "TPC ");
244 bd.fSpecification=//AliHLTTPCDefinitions::EncodeDataSpecification(currentSlice, currentSlice, currentPartition, currentPartition);
245 spacepoints->AddInputBlock(&bd);
248 return spacepoints.release();