BOSS 8.0.0
BESIII Offline Software System
Loading...
Searching...
No Matches
ZHelix.cxx
Go to the documentation of this file.
1//
2// ZHelix.cxx
3//
4// $Author: maqm $
5// $Date: 2022/03/04 04:44:37 $
6// $Revision: 1.6 $
7//
8
9#include "BesVisLib/ZHelix.h"
10#include <iostream>
11
12#include <TMath.h>
13
14#ifndef ROOT_TString
15# include <TString.h>
16#endif
17
18#ifndef ZEVIS_ZView
19# include "BesVisLib/BesView.h"
20#endif
21
22#ifndef ZEVIS_ZPad
23# include "TPad.h"
24#endif
25
26using namespace std;
27
28#ifndef __CINT__
30#endif
31
32 //__________________________________________________________
33 // ZHelix
34 // Helix class
35 //
36 // Drawing options:
37 // '3D' - 3 dimensional view
38 // 'XY' - XY projection
39 // 'ZR' - ZR projection
40 //
42 : TPolyLine3D() {
43 //
44 // ZHelix standard constructor
45 if ( gDebug ) cout << "ZHelix default ctor called" << endl;
46
47 fRSign = 0;
48 // fSegment = 1.;
49}
50
51//__________________________________________________________
52
53ZHelix::ZHelix( Double_t Azim, Double_t QovR, Double_t QxDh, Double_t refx, Double_t refy,
54 Double_t refz, Double_t TDip, Double_t phii, Double_t phio, Float_t Chi2,
55 Int_t NDoF, EZHelixRangeType RangeType, Double_t RangeMin, Double_t RangeMax )
56 : TPolyLine3D() {
57 //
58 // ZHelix normal constructor
59 if ( gDebug ) cout << "ZHelix normal ctor called" << endl;
60
61 fAzim = Azim;
62 fSinAzim = TMath::Sin( Azim );
63 fCosAzim = TMath::Cos( Azim );
64 fQovR = QovR;
65 fQxDh = QxDh;
66 fRefX = refx;
67 fRefY = refy;
68 fRefZ = refz;
69 fTDip = TDip;
70 fPhiI = phii;
71 fPhiO = phio;
72 fChi2 = Chi2;
73 fNDoF = NDoF;
74 fRType = RangeType;
75 fEnable = kTRUE;
76
77 fRSign = 0;
78 // fSegment = 1.;
79 SetRange( RangeType, RangeMin, RangeMax );
80}
81
82//__________________________________________________________
83
85 //
86 // ZHelix standard destructor
87 if ( gDebug ) { cout << "ZHelix dtor called" << endl; }
88}
89
90//__________________________________________________________
91
92void ZHelix::SetRange( EZHelixRangeType RangeType, Double_t RangeMin, Double_t RangeMax ) {
93 //
94 // Set range for drawing
95 switch ( RangeType )
96 {
97 case kBesHelixPhi:
98 fRange[0] = RangeMin;
99 fRange[1] = RangeMax;
100 break;
101 case kBesHelixX:
102 fRange[0] = X2Phi( RangeMin );
103 fRange[1] = X2Phi( RangeMax );
104 break;
105 case kBesHelixY:
106 fRange[0] = Y2Phi( RangeMin );
107 fRange[1] = Y2Phi( RangeMax );
108 break;
109 case kBesHelixZ:
110 fRange[0] = Z2Phi( RangeMin );
111 fRange[1] = Z2Phi( RangeMax );
112 break;
113 case kBesHelixR:
114 fRange[0] = R2Phi( RangeMin );
115 fRange[1] = R2Phi( RangeMax );
116 break;
117 }
118}
119
120//__________________________________________________________
121
122void ZHelix::SetPoints( Option_t* option ) {
123 //
124 // Set PolyLine3D points
125 TString opt = option;
126 opt.ToUpper();
127
128 // Get view
129 BesView* view = dynamic_cast<BesView*>( gPad->GetView() );
130
131 // check with which sign the segmnents have to added to fRange[0]
132 Int_t sign = 0;
133 if ( fQovR >= 0 ) sign = -1;
134 else sign = +1;
135
136 // calculate distance between ranges in rad
137 Double_t degrad = TMath::Pi() / 180.0;
138 Double_t segment = 1. * degrad; // 1 degree segments
139 Double_t df = 0;
140 if ( sign == +1 )
141 {
142 if ( fRange[1] > fRange[0] ) df = fRange[1] - fRange[0];
143 else df = 2 * TMath::Pi() + fRange[1] - fRange[0];
144 }
145 else
146 {
147 if ( fRange[1] < fRange[0] ) df = fRange[1] - fRange[0];
148 else df = 2 * TMath::Pi() - fRange[1] + fRange[0];
149 }
150 // number of segments with degree distance
151 Int_t nSeg = Int_t( TMath::Abs( df ) / segment ) + 1;
152
153 // solve problem with nseg = 1 , means df too small compared to
154 // segment -> new segment
155 if ( nSeg < 2 )
156 {
157 segment = 0.01 * degrad;
158 nSeg = Int_t( TMath::Abs( df ) / segment ) + 1;
159 }
160 // if ( nSeg < 10 ) nSeg = 10;
161
162 // newly calculation of segment
163 segment = TMath::Abs( df ) / nSeg;
164
165 Double_t phi, x, y, z, r;
166 TPolyLine3D::SetPolyLine( nSeg + 1 );
167
168 if ( opt.Contains( "3D" ) )
169 {
170 // 3D view
171 for ( Int_t i = 0; i <= nSeg; i++ )
172 {
173 phi = fRange[0] + segment * i * sign;
174 Phi2XYZ( phi, x, y, z );
175 TPolyLine3D::SetPoint( i, x, y, z );
176 }
177 }
178 else if ( opt.Contains( "XY" ) )
179 {
180 // XY view
181 for ( Int_t i = 0; i <= nSeg; i++ )
182 {
183 phi = fRange[0] + segment * i * sign;
184 Phi2XYZ( phi, x, y, z );
185 TPolyLine3D::SetPoint( i, x, y, 0 );
186 }
187 }
188 else if ( opt.Contains( "ZR" ) )
189 {
190 // ZR view
191
192 // The track is drawn either in the upper or lower region of
193 // the ZR view depending on how many of its segements lay in
194 // each region. If these numbers are unbalanced, the starting
195 // point of the track is taken as criterium
196 Int_t isgn = 0;
197 for ( Int_t i = 0; i <= nSeg; i++ )
198 {
199
200 // Get ZR coordinates
201 phi = fRange[0] + segment * i * sign;
202 Phi2ZR( phi, z, r );
203
204 // Set point
205 TPolyLine3D::SetPoint( i, z, r, 0 );
206
207 // Get sign for R coordinate
208 isgn += view->GetRSign( phi );
209 if ( i == 0 ) fRSign = view->GetRSign( phi );
210 }
211 if ( isgn != 0 ) fRSign = TMath::Sign( 1, isgn );
212
213 // The vertex fitted tracks need to be displaced otherwise they are
214 // are not drawn to emanate from the vertex.
215
216 Float_t z, r, rref, rdisp;
217
218 rref = TMath::Sqrt( ( fRefX * fRefX ) + ( fRefY * fRefY ) );
219
220 if ( ( fTrackType != kVctpar ) || ( fTrackType != kVcparsec ) ||
221 ( fTrackType != kZttrprm ) || ( fTrackType != kZttrsec ) )
222 {
223
224 // Set R sign for each point
225 for ( Int_t i = 0; i <= nSeg; i++ )
226 {
227 z = GetP()[i * 3];
228 r = GetP()[i * 3 + 1];
229 SetPoint( i, z, r * fRSign, 0 );
230 }
231 }
232 else
233 {
234
235 for ( Int_t i = 0; i <= nSeg; i++ )
236 {
237 z = GetP()[i * 3];
238 r = GetP()[i * 3 + 1];
239 rdisp = r * fRSign;
240 if ( fRSign < 0 ) rdisp += 2 * rref;
241 SetPoint( i, z, rdisp, 0 );
242 }
243 }
244 }
245}
246
247//__________________________________________________________
248
249void ZHelix::Phi2XYZ( Double_t phi, Double_t& x, Double_t& y, Double_t& z ) {
250 //
251 // Calculate XYZ for a given azimuth
252 x = fRefX - TMath::Sin( phi ) / fQovR + fSinAzim * ( 1 / fQovR + fQxDh );
253 y = fRefY + TMath::Cos( phi ) / fQovR - fCosAzim * ( 1 / fQovR + fQxDh );
254 z = fRefZ + ( fAzim - phi ) * fTDip / fQovR;
255}
256
257//__________________________________________________________
258
259void ZHelix::Phi2ZR( Double_t phi, Double_t& z, Double_t& r ) {
260 //
261 // Calculate ZR for a given azimuth
262 Double_t x, y;
263 Phi2XYZ( phi, x, y, z );
264 r = TMath::Sqrt( TMath::Power( x, 2 ) + TMath::Power( y, 2 ) );
265}
266
267//__________________________________________________________
268
269Double_t ZHelix::X2Phi( Double_t x ) {
270 //
271 // Convert x to phi
272 Double_t phi = TMath::ASin( fQovR * ( fSinAzim * ( 1 / fQovR + fQxDh ) - x + fRefX ) );
273
274 return phi;
275}
276
277//__________________________________________________________
278
279Double_t ZHelix::Y2Phi( Double_t y ) {
280 //
281 // Convert y to phi
282 Double_t phi = TMath::ACos( fQovR * ( fCosAzim * ( 1 / fQovR + fQxDh ) + y - fRefY ) );
283
284 return phi;
285}
286
287//__________________________________________________________
288
289Double_t ZHelix::Z2Phi( Double_t z ) {
290 //
291 // Convert z to phi
292 Double_t phi = fAzim - fQovR * ( z - fRefZ ) / fTDip;
293
294 return phi;
295}
296
297//__________________________________________________________
298
299Double_t ZHelix::R2Phi( Double_t r ) {
300 //
301 // Convert r to phi
302 Double_t k = 1 / fQovR + fQxDh;
303 Double_t my_value =
304 fQovR / ( 2 * k ) *
305 ( -TMath::Power( r, 2 ) + 1 / TMath::Power( fQovR, 2 ) + TMath::Power( k, 2 ) );
306 // check if my_value is ouside acos validity range
307 if ( ( my_value < -1 ) || ( my_value > 1 ) ) return 999999999;
308 Double_t my_phi = TMath::ACos( my_value );
309
310 Double_t phi1 = fAzim - my_phi;
311 Double_t phi2 = fAzim + my_phi;
312
313 Double_t x1 = 0;
314 Double_t y1 = 0;
315 Double_t z1 = 0;
316 Double_t x2 = 0;
317 Double_t y2 = 0;
318 Double_t z2 = 0;
319 Double_t phi = 0;
320 ;
321 this->Phi2XYZ( phi1, x1, y1, z1 );
322 this->Phi2XYZ( phi2, x2, y2, z2 );
323
324 // check if phi1 would result in a z value with the correct sign corrsponding
325 // to fTDip
326 if ( TMath::Sign( 1., fTDip ) == TMath::Sign( 1., ( z1 - fRefZ ) ) )
327 {
328 // check if phi2 would result in a z value with the correct sign corrsponding
329 // to fTDip
330 if ( TMath::Sign( 1., fTDip ) == TMath::Sign( 1., ( z2 - fRefZ ) ) )
331 {
332 // take phi with smallest resulting z difference to fRefZ (Zh)
333 if ( TMath::Abs( z1 - fRefZ ) <= TMath::Abs( z2 - fRefZ ) ) phi = phi1;
334 else phi = phi2;
335 }
336 else phi = phi1;
337 }
338 else { phi = phi2; }
339
340 return phi;
341}
342
343//__________________________________________________________
344
345void ZHelix::Print( Option_t* option ) const {
346 //
347 // Dump the helix attributes
348 TString opt = option;
349 opt.ToUpper();
350
351 cout << endl
352 << "Parameters of helix " << this->GetName() << ":" << endl
353 << "Azimuth = " << fAzim << endl
354 << "Q/R = " << fQovR << endl
355 << "Q*D_h = " << fQxDh << endl
356 << "Z_h = " << fRefZ << endl
357 << "cot(Dip) = " << fTDip << endl
358 << "PhiI = " << fPhiI << endl
359 << "PhiO = " << fPhiO << endl
360 << "Chi2 = " << fChi2 << endl
361 << "D.o.F. = " << fNDoF << endl
362 << "RangeType = " << fRType << endl
363 << "Range: " << fRange[0] << " -> " << fRange[1] << endl;
364 if ( opt.Contains( "ALL" ) ) TPolyLine3D::Print( "ALL" );
365 cout << endl;
366}
367
368//__________________________________________________________
369
370void ZHelix::Draw( Option_t* option ) {
371 //
372 // Draw this helix with its current attributes.
373 AppendPad( option );
374}
375
376//__________________________________________________________
377
378void ZHelix::Paint( Option_t* option ) {
379 //
380 // Draw this helix with its current attributes
381 TString opt = option;
382 opt.ToUpper();
383
384 if ( ( ( fRange[1] < fRange[0] ) || ( fRange[1] > fRange[0] ) ) && fEnable )
385 {
386 SetPoints( option );
387 TPolyLine3D::Paint( "SAME" );
388 }
389}
390
391//__________________________________________________________
392
393Double_t ZHelix::Phi2S( Double_t phi ) {
394 //
395 // calculates pathlength for phi
396
397 return -( phi - fAzim ) / fQovR;
398}
Double_t phi2
Double_t phi1
ClassImp(ZHelix) ZHelix
Definition ZHelix.cxx:29
virtual Int_t GetRSign(Float_t Phi)
Definition BesView.cxx:625
Double_t R2Phi(Double_t r)
Definition ZHelix.cxx:299
void Phi2ZR(Double_t phi, Double_t &z, Double_t &r)
Definition ZHelix.cxx:259
void SetRange(EZHelixRangeType RangeType, Double_t RangeMin, Double_t RangeMax)
Definition ZHelix.cxx:92
Double_t Y2Phi(Double_t y)
Definition ZHelix.cxx:279
virtual void Print(Option_t *option="") const
Definition ZHelix.cxx:345
virtual void SetPoints(Option_t *option="3D")
Definition ZHelix.cxx:122
Double_t X2Phi(Double_t x)
Definition ZHelix.cxx:269
virtual void Paint(Option_t *option="3D")
Definition ZHelix.cxx:378
void Phi2XYZ(Double_t phi, Double_t &x, Double_t &y, Double_t &z)
Definition ZHelix.cxx:249
virtual void Draw(Option_t *option="3D")
Definition ZHelix.cxx:370
Double_t Phi2S(Double_t phi)
Definition ZHelix.cxx:393
virtual ~ZHelix()
Definition ZHelix.cxx:84
virtual void SetPoint(Int_t point, Double_t x, Double_t y, Double_t z)
Double_t Z2Phi(Double_t z)
Definition ZHelix.cxx:289