SND@LHC Software
Loading...
Searching...
No Matches
DetPlane.cc
Go to the documentation of this file.
1/* Copyright 2008-2010, Technische Universitaet Muenchen,
2 Authors: Christian Hoeppner & Sebastian Neubert & Johannes Rauch
3
4 This file is part of GENFIT.
5
6 GENFIT is free software: you can redistribute it and/or modify
7 it under the terms of the GNU Lesser General Public License as published
8 by the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
10
11 GENFIT is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public License
17 along with GENFIT. If not, see <http://www.gnu.org/licenses/>.
18*/
19
20#include "DetPlane.h"
21
22#include <cassert>
23#include <iostream>
24#include <cmath>
25#include <TMath.h>
26#include <TClass.h>
27#include <TBuffer.h>
28
29
30namespace genfit {
31
32
34 :finitePlane_(finite)
35{
36 // default constructor
37 o_.SetXYZ(0.,0.,0.);
38 u_.SetXYZ(1.,0.,0.);
39 v_.SetXYZ(0.,1.,0.);
40 // sane() not needed here
41}
42
43
44DetPlane::DetPlane(const TVector3& o,
45 const TVector3& u,
46 const TVector3& v,
47 AbsFinitePlane* finite)
48 :o_(o), u_(u), v_(v), finitePlane_(finite)
49{
50 sane();
51}
52
53DetPlane::DetPlane(const TVector3& o,
54 const TVector3& n,
55 AbsFinitePlane* finite)
56 :o_(o), finitePlane_(finite)
57{
58 setNormal(n);
59}
60
61
65
66
68 TObject(rhs),
69 o_(rhs.o_),
70 u_(rhs.u_),
71 v_(rhs.v_)
72{
73 if(rhs.finitePlane_)
74 finitePlane_.reset(rhs.finitePlane_->clone());
75 else finitePlane_.reset();
76}
77
78
80 swap(other);
81 return *this;
82}
83
84
86 // by swapping the members of two classes,
87 // the two classes are effectively swapped
88 std::swap(this->o_, other.o_);
89 std::swap(this->u_, other.u_);
90 std::swap(this->v_, other.v_);
91 this->finitePlane_.swap(other.finitePlane_);
92}
93
94
95void DetPlane::set(const TVector3& o,
96 const TVector3& u,
97 const TVector3& v)
98{
99 o_ = o;
100 u_ = u;
101 v_ = v;
102 sane();
103}
104
105
106void DetPlane::setO(const TVector3& o)
107{
108 o_ = o;
109}
110
111void DetPlane::setO(double X,double Y,double Z)
112{
113 o_.SetXYZ(X,Y,Z);
114}
115
116void DetPlane::setU(const TVector3& u)
117{
118 u_ = u;
119 sane(); // sets v_ perpendicular to u_
120}
121
122void DetPlane::setU(double X,double Y,double Z)
123{
124 u_.SetXYZ(X,Y,Z);
125 sane(); // sets v_ perpendicular to u_
126}
127
128void DetPlane::setV(const TVector3& v)
129{
130 v_ = v;
131 u_ = getNormal().Cross(v_);
132 u_ *= -1.;
133 sane();
134}
135
136void DetPlane::setV(double X,double Y,double Z)
137{
138 v_.SetXYZ(X,Y,Z);
139 u_ = getNormal().Cross(v_);
140 u_ *= -1.;
141 sane();
142}
143
144void DetPlane::setUV(const TVector3& u,const TVector3& v)
145{
146 u_ = u;
147 v_ = v;
148 sane();
149}
150
151void DetPlane::setON(const TVector3& o,const TVector3& n){
152 o_ = o;
153 setNormal(n);
154}
155
156
157TVector3 DetPlane::getNormal() const
158{
159 return u_.Cross(v_);
160}
161
162void DetPlane::setNormal(double X,double Y,double Z){
163 setNormal( TVector3(X,Y,Z) );
164}
165
166void DetPlane::setNormal(const TVector3& n){
167 u_ = n.Orthogonal();
168 v_ = n.Cross(u_);
169 u_.SetMag(1.);
170 v_.SetMag(1.);
171}
172
173void DetPlane::setNormal(const double& theta, const double& phi){
174 setNormal( TVector3(TMath::Sin(theta)*TMath::Cos(phi),TMath::Sin(theta)*TMath::Sin(phi),TMath::Cos(theta)) );
175}
176
177
178TVector2 DetPlane::project(const TVector3& x)const
179{
180 return TVector2(u_*x, v_*x);
181}
182
183
184TVector2 DetPlane::LabToPlane(const TVector3& x)const
185{
186 return project(x-o_);
187}
188
189
190TVector3 DetPlane::toLab(const TVector2& x)const
191{
192 TVector3 d(o_);
193 d += x.X()*u_;
194 d += x.Y()*v_;
195 return d;
196}
197
198
199TVector3 DetPlane::dist(const TVector3& x)const
200{
201 return toLab(LabToPlane(x)) - x;
202}
203
204
206 assert(u_!=v_);
207
208 // ensure unit vectors
209 u_.SetMag(1.);
210 v_.SetMag(1.);
211
212 // check if already orthogonal
213 if (u_.Dot(v_) < 1.E-5) return;
214
215 // ensure orthogonal system
216 v_ = getNormal().Cross(u_);
217}
218
219
220void DetPlane::Print(const Option_t* option) const
221{
222 std::cout<<"DetPlane: "
223 <<"O("<<o_.X()<<", "<<o_.Y()<<", "<<o_.Z()<<") "
224 <<"u("<<u_.X()<<", "<<u_.Y()<<", "<<u_.Z()<<") "
225 <<"v("<<v_.X()<<", "<<v_.Y()<<", "<<v_.Z()<<") "
226 <<"n("<<getNormal().X()<<", "<<getNormal().Y()<<", "<<getNormal().Z()<<") "
227 <<std::endl;
228 if(finitePlane_ != NULL) {
229 finitePlane_->Print(option);
230 }
231
232}
233
234
235/*
236 I could write pages of comments about correct equality checking for
237 floating point numbers, but: When two planes are as close as 10E-5 cm
238 in all nine numbers that define the plane, this will be enough for all
239 practical purposes
240 */
241bool operator== (const DetPlane& lhs, const DetPlane& rhs){
242 if (&lhs == &rhs)
243 return true;
244 static const double detplaneEpsilon = 1.E-5;
245 if(
246 fabs( (lhs.o_.X()-rhs.o_.X()) ) > detplaneEpsilon ||
247 fabs( (lhs.o_.Y()-rhs.o_.Y()) ) > detplaneEpsilon ||
248 fabs( (lhs.o_.Z()-rhs.o_.Z()) ) > detplaneEpsilon
249 ) return false;
250 else if(
251 fabs( (lhs.u_.X()-rhs.u_.X()) ) > detplaneEpsilon ||
252 fabs( (lhs.u_.Y()-rhs.u_.Y()) ) > detplaneEpsilon ||
253 fabs( (lhs.u_.Z()-rhs.u_.Z()) ) > detplaneEpsilon
254 ) return false;
255 else if(
256 fabs( (lhs.v_.X()-rhs.v_.X()) ) > detplaneEpsilon ||
257 fabs( (lhs.v_.Y()-rhs.v_.Y()) ) > detplaneEpsilon ||
258 fabs( (lhs.v_.Z()-rhs.v_.Z()) ) > detplaneEpsilon
259 ) return false;
260 return true;
261}
262
263bool operator!= (const DetPlane& lhs, const DetPlane& rhs){
264 return !(lhs==rhs);
265}
266
267
268double DetPlane::distance(const TVector3& point) const {
269 // |(point - o_)*(u_ x v_)|
270 return fabs( (point.X()-o_.X()) * (u_.Y()*v_.Z() - u_.Z()*v_.Y()) +
271 (point.Y()-o_.Y()) * (u_.Z()*v_.X() - u_.X()*v_.Z()) +
272 (point.Z()-o_.Z()) * (u_.X()*v_.Y() - u_.Y()*v_.X()));
273}
274
275double DetPlane::distance(double x, double y, double z) const {
276 // |(point - o_)*(u_ x v_)|
277 return fabs( (x-o_.X()) * (u_.Y()*v_.Z() - u_.Z()*v_.Y()) +
278 (y-o_.Y()) * (u_.Z()*v_.X() - u_.X()*v_.Z()) +
279 (z-o_.Z()) * (u_.X()*v_.Y() - u_.Y()*v_.X()));
280}
281
282
283TVector2 DetPlane::straightLineToPlane (const TVector3& point, const TVector3& dir) const {
284 TVector3 dirNorm(dir.Unit());
285 TVector3 normal = getNormal();
286 double dirTimesN = dirNorm*normal;
287 if(fabs(dirTimesN)<1.E-6){//straight line is parallel to plane, so return infinity
288 return TVector2(1.E100,1.E100);
289 }
290 double t = 1./dirTimesN * ((o_-point)*normal);
291 return project(point - o_ + t * dirNorm);
292}
293
294
296void DetPlane::straightLineToPlane(const double& posX, const double& posY, const double& posZ,
297 const double& dirX, const double& dirY, const double& dirZ,
298 double& u, double& v) const {
299
300 TVector3 W = getNormal();
301 double dirTimesN = dirX*W.X() + dirY*W.Y() + dirZ*W.Z();
302 if(fabs(dirTimesN)<1.E-6){//straight line is parallel to plane, so return infinity
303 u = 1.E100;
304 v = 1.E100;
305 return;
306 }
307 double t = 1./dirTimesN * ((o_.X()-posX)*W.X() +
308 (o_.Y()-posY)*W.Y() +
309 (o_.Z()-posZ)*W.Z());
310
311 double posOnPlaneX = posX-o_.X() + t*dirX;
312 double posOnPlaneY = posY-o_.Y() + t*dirY;
313 double posOnPlaneZ = posZ-o_.Z() + t*dirZ;
314
315 u = u_.X()*posOnPlaneX + u_.Y()*posOnPlaneY + u_.Z()*posOnPlaneZ;
316 v = v_.X()*posOnPlaneX + v_.Y()*posOnPlaneY + v_.Z()*posOnPlaneZ;
317}
318
319
320void DetPlane::rotate(double angle) {
321 TVector3 normal = getNormal();
322 u_.Rotate(angle, normal);
323 v_.Rotate(angle, normal);
324
325 sane();
326}
327
328
330 o_.SetXYZ(0.,0.,0.);
331 u_.SetXYZ(1.,0.,0.);
332 v_.SetXYZ(0.,1.,0.);
333 finitePlane_.reset();
334}
335
336
337void DetPlane::Streamer(TBuffer &R__b)
338{
339 // Stream an object of class genfit::DetPlane.
340 // This is modified from the streamer generated by ROOT in order to
341 // account for the scoped_ptr.
342 //This works around a msvc bug and should be harmless on other platforms
343 typedef ::genfit::DetPlane thisClass;
344 UInt_t R__s, R__c;
345 if (R__b.IsReading()) {
346 Version_t R__v = R__b.ReadVersion(&R__s, &R__c); if (R__v) { }
347 //TObject::Streamer(R__b);
348 o_.Streamer(R__b);
349 u_.Streamer(R__b);
350 v_.Streamer(R__b);
352 char flag;
353 R__b >> flag;
354 if (flag) {
355 // Read AbsFinitePlane with correct overload ... see comment
356 // in writing code.
357 TClass* cl = TClass::Load(R__b);
358 AbsFinitePlane *p = (AbsFinitePlane*)(cl->New());
359 cl->Streamer(p, R__b);
360 finitePlane_.reset(p);
361 }
362 R__b.CheckByteCount(R__s, R__c, thisClass::IsA());
363 } else {
364 R__c = R__b.WriteVersion(thisClass::IsA(), kTRUE);
365 //TObject::Streamer(R__b);
366 o_.Streamer(R__b);
367 u_.Streamer(R__b);
368 v_.Streamer(R__b);
369 if (finitePlane_) {
370 R__b << (char)1;
371
372 // finitPlane_ is a scoped_ptr, but a shared plane may be
373 // written several times in different places (e.g. it may also
374 // be stored in the measurement class). Since we have no way
375 // of knowing in which other places the same plane is written
376 // (it may even be in another track!), we cannot synchronize
377 // these writes and have to duplicate the SharedPlanePtr's
378 // instead. ROOT caches which pointers were written and read
379 // if one uses 'R__b << p' or equivalent. This can lead to
380 // trouble have no way of synchronizing two reads to
381 // shared_ptr's pointing to the same memory location. But
382 // even if we break the link between the two shared_ptr's,
383 // ROOT will still try to outsmart us, and it will notice that
384 // the finitePlane_ was the same during writing. This will
385 // lead to the same address being attached to two different
386 // scoped_ptrs in reading. Highly undesirable. Since we
387 // cannot know whether other parts of code implicitly or
388 // explicitly rely on TBuffer's caching, we cannot just
389 // disable this caching via R__b.ResetMap() (it's not
390 // documented in any elucidating manner anyway).
391 //
392 // Therefore, we have to write and read the AbsFinitePlane*
393 // manually, bypassing ROOT's caching. In order to do this,
394 // we need the information on the actual type, because
395 // otherwise we couldn't read it back reliably. Finally, the
396 // _working_ means of reading and writing class information
397 // are TClass::Store and TClass::Load, again barely
398 // documented, but if one tries any of the other ways that
399 // suggest themselves, weird breakage will occur.
400 finitePlane_->IsA()->Store(R__b);
401 finitePlane_->Streamer(R__b);
402 } else {
403 R__b << (char)0;
404 }
405 R__b.SetByteCount(R__c, kTRUE);
406 }
407}
408} /* End of namespace genfit */
Abstract base class for finite detector planes.
Detector plane.
Definition DetPlane.h:61
void swap(DetPlane &other)
Definition DetPlane.cc:85
void setV(const TVector3 &v)
Definition DetPlane.cc:128
DetPlane(AbsFinitePlane *finite=NULL)
Definition DetPlane.cc:33
void rotate(double angle)
rotate u and v around normal. Angle is in rad. More for debugging than for actual use.
Definition DetPlane.cc:320
TVector3 getNormal() const
Definition DetPlane.cc:157
boost::scoped_ptr< AbsFinitePlane > finitePlane_
Definition DetPlane.h:191
double distance(const TVector3 &point) const
absolute distance from a point to the plane
Definition DetPlane.cc:268
TVector3 toLab(const TVector2 &x) const
transform from plane coordinates to lab system
Definition DetPlane.cc:190
void Print(const Option_t *="") const
Definition DetPlane.cc:220
void reset()
delete finitePlane_ and set O, U, V to default values
Definition DetPlane.cc:329
void setO(const TVector3 &o)
Definition DetPlane.cc:106
DetPlane & operator=(DetPlane)
Definition DetPlane.cc:79
void set(const TVector3 &o, const TVector3 &u, const TVector3 &v)
Definition DetPlane.cc:95
virtual ~DetPlane()
Definition DetPlane.cc:62
void setUV(const TVector3 &u, const TVector3 &v)
Definition DetPlane.cc:144
void setON(const TVector3 &o, const TVector3 &n)
Definition DetPlane.cc:151
void setU(const TVector3 &u)
Definition DetPlane.cc:116
TVector2 project(const TVector3 &x) const
projecting a direction onto the plane:
Definition DetPlane.cc:178
TVector2 LabToPlane(const TVector3 &x) const
transform from Lab system into plane
Definition DetPlane.cc:184
void sane()
ensures orthonormal coordinates
Definition DetPlane.cc:205
void setNormal(const TVector3 &n)
Definition DetPlane.cc:166
TVector3 dist(const TVector3 &point) const
Definition DetPlane.cc:199
TVector2 straightLineToPlane(const TVector3 &point, const TVector3 &dir) const
gives u,v coordinates of the intersection point of a straight line with plane
Definition DetPlane.cc:283
Matrix inversion tools.
Definition AbsBField.h:29
bool operator==(const DetPlane &lhs, const DetPlane &rhs)
Definition DetPlane.cc:241
bool operator!=(const DetPlane &lhs, const DetPlane &rhs)
Definition DetPlane.cc:263