1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
16 //-------------------------------------------------------------------------
18 // This is the future base for managing the clusters in barrel detectors.
19 // It is fully interfaced with the ROOT geometrical modeller TGeo.
20 // Each cluster contains XYZ coordinates in the local tracking c.s. and
21 // the unique ID of the sensitive detector element which continas the
22 // cluster. The coordinates in global c.s. are computed using the interface
23 // to TGeo and will be not overwritten by the derived sub-detector cluster
26 // cvetan.cheshkov@cern.ch & jouri.belikov@cern.ch 5/3/2007
27 //-------------------------------------------------------------------------
29 #include <TGeoManager.h>
30 #include <TGeoMatrix.h>
31 #include <TGeoPhysicalNode.h>
33 #include "AliCluster.h"
35 #include "AliAlignObj.h"
39 //______________________________________________________________________________
40 AliCluster::AliCluster():
51 // Default constructor
52 fTracks[0]=fTracks[1]=fTracks[2]=-3141593;
55 //______________________________________________________________________________
56 AliCluster::AliCluster(UShort_t volId,
78 fTracks[0]=fTracks[1]=fTracks[2]=-3141593;
81 //______________________________________________________________________________
82 AliCluster::AliCluster(UShort_t volId,
83 Float_t x, Float_t y, Float_t z,
84 Float_t sy2, Float_t sz2, Float_t syz,
103 fTracks[0]=fTracks[1]=fTracks[2]=-3141593;
106 //______________________________________________________________________________
107 AliCluster::AliCluster(const AliCluster& cluster):
112 fSigmaY2(cluster.fSigmaY2),
113 fSigmaZ2(cluster.fSigmaZ2),
114 fSigmaYZ(cluster.fSigmaYZ),
115 fVolumeId(cluster.fVolumeId),
116 fIsMisaligned(cluster.fIsMisaligned)
119 fTracks[0] = cluster.fTracks[0];
120 fTracks[1] = cluster.fTracks[1];
121 fTracks[2] = cluster.fTracks[2];
124 //______________________________________________________________________________
125 AliCluster & AliCluster::operator=(const AliCluster& cluster)
127 // Assignment operator
129 if(&cluster == this) return *this;
134 fSigmaY2 = cluster.fSigmaY2;
135 fSigmaZ2 = cluster.fSigmaZ2;
136 fSigmaYZ = cluster.fSigmaYZ;
137 fVolumeId = cluster.fVolumeId;
138 fIsMisaligned = cluster.fIsMisaligned;
140 fTracks[0] = cluster.fTracks[0];
141 fTracks[1] = cluster.fTracks[1];
142 fTracks[2] = cluster.fTracks[2];
147 //______________________________________________________________________________
148 Bool_t AliCluster::GetGlobalXYZ(Float_t xyz[3]) const
150 // Get the global coordinates of the cluster
151 // All the needed information is taken only
154 xyz[0] = xyz[1] = xyz[2] = 0;
156 if (!gGeoManager || !gGeoManager->IsClosed()) {
157 AliError("Can't get the global coordinates! gGeoManager doesn't exist or it is still opened!");
161 const TGeoHMatrix *mt = GetTracking2LocalMatrix();
162 if (!mt) return kFALSE;
163 Double_t txyz[3] = {fX, fY, fZ};
164 Double_t lxyz[3] = {0, 0, 0};
165 mt->LocalToMaster(txyz,lxyz);
167 TGeoHMatrix *ml = GetMatrix();
168 if (!ml) return kFALSE;
169 Double_t gxyz[3] = {0, 0, 0};
170 ml->LocalToMaster(lxyz,gxyz);
171 xyz[0] = gxyz[0]; xyz[1] = gxyz[1]; xyz[2] = gxyz[2];
175 //______________________________________________________________________________
176 Bool_t AliCluster::GetGlobalCov(Float_t cov[6]) const
178 // Get the global covariance matrix of the cluster coordinates
179 // All the needed information is taken only
181 for (Int_t i = 0; i < 6; i++) cov[i] = 0;
183 if (!gGeoManager || !gGeoManager->IsClosed()) {
184 AliError("Can't get the global coordinates! gGeoManager doesn't exist or it is still opened!");
188 const TGeoHMatrix *mt = GetTracking2LocalMatrix();
189 if (!mt) return kFALSE;
191 TGeoHMatrix *ml = GetMatrix();
192 if (!ml) return kFALSE;
195 Double_t tcov[9] = { 0, 0, 0, 0, fSigmaY2, fSigmaYZ, 0, fSigmaYZ, fSigmaZ2 };
197 m.Multiply(&mt->Inverse());
198 m.Multiply(&ml->Inverse());
201 Double_t *ncov = m.GetRotationMatrix();
202 cov[0] = ncov[0]; cov[1] = ncov[1]; cov[2] = ncov[2];
203 cov[3] = ncov[4]; cov[4] = ncov[5];
209 //______________________________________________________________________________
210 Bool_t AliCluster::GetXRefPlane(Float_t &xref) const
212 // Get the distance between the origin and the ref.plane.
213 // All the needed information is taken only
217 const TGeoHMatrix *mt = GetTracking2LocalMatrix();
218 if (!mt) return kFALSE;
220 TGeoHMatrix *ml = GetMatrix();
221 if (!ml) return kFALSE;
226 xref = (m.Inverse()).GetTranslation()[0];
230 //______________________________________________________________________________
231 Bool_t AliCluster::Misalign()
234 // All the needed information is taken only
236 if (!gGeoManager || !gGeoManager->IsClosed()) {
237 AliError("Can't get the PN entry! gGeoManager doesn't exist or it is still opened!");
242 AliError("The cluster was already misaligned!");
246 const TGeoHMatrix *mt = GetTracking2LocalMatrix();
247 if (!mt) return kFALSE;
249 TGeoHMatrix *ml = GetMatrix();
250 if (!ml) return kFALSE;
252 TGeoHMatrix *mlorig = GetMatrix(kTRUE);
253 if (!mlorig) return kFALSE;
255 TGeoHMatrix delta = *mt;
256 delta.MultiplyLeft(ml);
257 delta.MultiplyLeft(&(mlorig->Inverse()));
258 delta.MultiplyLeft(&(mt->Inverse()));
260 Double_t xyzorig[3] = {fX, fY, fZ};
261 Double_t xyz[3] = {0, 0, 0};
262 delta.LocalToMaster(xyzorig,xyz);
263 fX = xyz[0]; fY = xyz[1]; fZ = xyz[2];
264 fIsMisaligned = kTRUE;
268 //______________________________________________________________________________
269 TGeoHMatrix* AliCluster::GetMatrix(Bool_t original) const
271 // Get the matrix which transforms from the
272 // local TGeo alignable volume c.s. to the global one.
273 // In case the cluster was already misaligned, get the
274 // ideal matrix from TGeo. The option 'original'
275 // can be used to force the calculation of the ideal
277 if (!fIsMisaligned && (original == kFALSE)) {
278 TGeoPNEntry *pne = GetPNEntry();
279 if (!pne) return NULL;
281 TGeoPhysicalNode *pnode = pne->GetPhysicalNode();
282 if (pnode) return pnode->GetMatrix();
284 const char* path = pne->GetTitle();
285 if (!gGeoManager->cd(path)) {
286 AliError(Form("Volume path %s not valid!",path));
289 return gGeoManager->GetCurrentMatrix();
292 const char* symname = AliAlignObj::SymName(fVolumeId);
293 if (!symname) return NULL;
295 static TGeoHMatrix m;
296 if (AliAlignObj::GetOrigGlobalMatrix(symname,m))
303 //______________________________________________________________________________
304 const TGeoHMatrix* AliCluster::GetTracking2LocalMatrix() const
306 // Get the matrix which is stored with the PN entries in TGeo.
307 // The matrix makes the transformation from the tracking c.s. to
309 TGeoPNEntry *pne = GetPNEntry();
310 if (!pne) return NULL;
312 const TGeoHMatrix *m = pne->GetMatrix();
314 AliError(Form("TGeoPNEntry (%s) contains no matrix !",pne->GetName()));
319 //______________________________________________________________________________
320 TGeoPNEntry* AliCluster::GetPNEntry() const
322 // Get a pointer to the physical node entry
323 // corresponding to the alignable volume to
324 // which the cluster belongs
326 if (!gGeoManager || !gGeoManager->IsClosed()) {
327 AliError("Can't get the PN entry! gGeoManager doesn't exist or it is still opened!");
331 const char* symname = AliAlignObj::SymName(fVolumeId);
332 if (!symname) return NULL;
334 TGeoPNEntry* pne = gGeoManager->GetAlignableEntry(symname);
336 AliError(Form("The symbolic volume name %s does not correspond to a physical entry!",