00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "BesVisLib/ZHelix.h"
00010 #include <iostream>
00011
00012 #include <TMath.h>
00013
00014 #ifndef ROOT_TString
00015 #include <TString.h>
00016 #endif
00017
00018 #ifndef ZEVIS_ZView
00019 #include "BesVisLib/BesView.h"
00020 #endif
00021
00022 #ifndef ZEVIS_ZPad
00023 #include "TPad.h"
00024 #endif
00025
00026 using namespace std;
00027
00028 #ifndef __CINT__
00029 ClassImp(ZHelix)
00030 #endif
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041 ZHelix::ZHelix() : TPolyLine3D() {
00042
00043
00044 if ( gDebug ) cout << "ZHelix default ctor called" << endl;
00045
00046 fRSign = 0;
00047
00048 }
00049
00050
00051
00052 ZHelix::ZHelix(Double_t Azim, Double_t QovR, Double_t QxDh,
00053 Double_t refx, Double_t refy,
00054 Double_t refz, Double_t TDip,
00055 Double_t phii, Double_t phio,
00056 Float_t Chi2, Int_t NDoF,
00057 EZHelixRangeType RangeType,
00058 Double_t RangeMin, Double_t RangeMax) :
00059 TPolyLine3D() {
00060
00061
00062 if ( gDebug ) cout << "ZHelix normal ctor called" << endl;
00063
00064 fAzim = Azim;
00065 fSinAzim = TMath::Sin(Azim);
00066 fCosAzim = TMath::Cos(Azim);
00067 fQovR = QovR;
00068 fQxDh = QxDh;
00069 fRefX = refx;
00070 fRefY = refy;
00071 fRefZ = refz;
00072 fTDip = TDip;
00073 fPhiI = phii;
00074 fPhiO = phio;
00075 fChi2 = Chi2;
00076 fNDoF = NDoF;
00077 fRType = RangeType;
00078 fEnable = kTRUE;
00079
00080 fRSign = 0;
00081
00082 SetRange(RangeType, RangeMin, RangeMax);
00083 }
00084
00085
00086
00087 ZHelix::~ZHelix() {
00088
00089
00090 if ( gDebug ) {
00091 cout << "ZHelix dtor called" << endl;
00092 }
00093 }
00094
00095
00096
00097 void ZHelix::SetRange(EZHelixRangeType RangeType,
00098 Double_t RangeMin, Double_t RangeMax) {
00099
00100
00101 switch (RangeType) {
00102 case kHelixPhi:
00103 fRange[0] = RangeMin;
00104 fRange[1] = RangeMax;
00105 break;
00106 case kHelixX:
00107 fRange[0] = X2Phi(RangeMin);
00108 fRange[1] = X2Phi(RangeMax);
00109 break;
00110 case kHelixY:
00111 fRange[0] = Y2Phi(RangeMin);
00112 fRange[1] = Y2Phi(RangeMax);
00113 break;
00114 case kHelixZ:
00115 fRange[0] = Z2Phi(RangeMin);
00116 fRange[1] = Z2Phi(RangeMax);
00117 break;
00118 case kHelixR:
00119 fRange[0] = R2Phi(RangeMin);
00120 fRange[1] = R2Phi(RangeMax);
00121 break;
00122 }
00123 }
00124
00125
00126
00127 void ZHelix::SetPoints(Option_t *option) {
00128
00129
00130 TString opt = option;
00131 opt.ToUpper();
00132
00133
00134 BesView *view = (BesView*)gPad->GetView();
00135
00136
00137 Int_t sign = 0;
00138 if ( fQovR >= 0 )
00139 sign = -1;
00140 else
00141 sign = +1;
00142
00143
00144 Double_t degrad = TMath::Pi() / 180.0;
00145 Double_t segment = 1. * degrad;
00146 Double_t df = 0;
00147 if ( sign == +1 ) {
00148 if ( fRange[1] > fRange[0] )
00149 df = fRange[1]-fRange[0];
00150 else
00151 df = 2*TMath::Pi() + fRange[1]-fRange[0];
00152 } else {
00153 if ( fRange[1] < fRange[0] )
00154 df = fRange[1]-fRange[0];
00155 else
00156 df = 2*TMath::Pi() - fRange[1]+fRange[0];
00157 }
00158
00159 Int_t nSeg = Int_t(TMath::Abs(df) / segment) + 1;
00160
00161
00162
00163 if ( nSeg < 2 ) {
00164 segment = 0.01 * degrad;
00165 nSeg = Int_t(TMath::Abs(df) / segment) + 1;
00166 }
00167
00168
00169
00170 segment = TMath::Abs(df) / nSeg;
00171
00172 Double_t phi, x, y, z, r;
00173 TPolyLine3D::SetPolyLine(nSeg+1);
00174
00175 if ( opt.Contains("3D") ) {
00176
00177 for ( Int_t i = 0; i <= nSeg; i++ ) {
00178 phi = fRange[0] + segment * i * sign;
00179 Phi2XYZ(phi, x, y, z);
00180 TPolyLine3D::SetPoint(i, x, y, z);
00181 }
00182 } else if ( opt.Contains("XY") ) {
00183
00184 for ( Int_t i = 0; i <= nSeg; i++ ) {
00185 phi = fRange[0] + segment * i * sign;
00186 Phi2XYZ(phi, x, y, z);
00187 TPolyLine3D::SetPoint(i, x, y, 0);
00188 }
00189 } else if ( opt.Contains("ZR") ) {
00190
00191
00192
00193
00194
00195
00196 Int_t isgn = 0;
00197 for ( Int_t i = 0; i <= nSeg; i++ ) {
00198
00199
00200 phi = fRange[0] + segment * i * sign;
00201 Phi2ZR(phi, z, r);
00202
00203
00204 TPolyLine3D::SetPoint(i, z, r, 0);
00205
00206
00207 isgn += view->GetRSign(phi);
00208 if ( i == 0 ) fRSign = view->GetRSign(phi);
00209 }
00210 if ( isgn != 0 ) fRSign = TMath::Sign(1, isgn);
00211
00212
00213
00214
00215 Float_t z, r, rref, rdisp;
00216
00217 rref = TMath::Sqrt((fRefX*fRefX)+(fRefY*fRefY));
00218
00219 if ( (fTrackType != kVctpar) || (fTrackType != kVcparsec) || (fTrackType != kZttrprm) || (fTrackType != kZttrsec) ) {
00220
00221
00222 for ( Int_t i = 0; i <= nSeg; i++ ) {
00223 z = GetP()[i*3];
00224 r = GetP()[i*3+1];
00225 SetPoint(i, z, r*fRSign, 0);
00226 }
00227
00228 } else {
00229
00230 for ( Int_t i = 0; i <= nSeg; i++ ) {
00231 z = GetP()[i*3];
00232 r = GetP()[i*3+1];
00233 rdisp = r*fRSign;
00234 if (fRSign < 0) rdisp += 2*rref;
00235 SetPoint(i, z, rdisp, 0);
00236 }
00237
00238 }
00239
00240 }
00241
00242 }
00243
00244
00245
00246 void ZHelix::Phi2XYZ(Double_t phi, Double_t& x, Double_t& y, Double_t& z) {
00247
00248
00249 x = fRefX - TMath::Sin(phi) / fQovR + fSinAzim * (1/fQovR + fQxDh);
00250 y = fRefY + TMath::Cos(phi) / fQovR - fCosAzim * (1/fQovR + fQxDh);
00251 z = fRefZ + (fAzim - phi) * fTDip / fQovR;
00252 }
00253
00254
00255
00256 void ZHelix::Phi2ZR(Double_t phi, Double_t& z, Double_t& r) {
00257
00258
00259 Double_t x, y;
00260 Phi2XYZ(phi, x, y, z);
00261 r = TMath::Sqrt(TMath::Power(x,2) + TMath::Power(y,2));
00262 }
00263
00264
00265
00266 Double_t ZHelix::X2Phi(Double_t x) {
00267
00268
00269 Double_t phi = TMath::ASin(fQovR * (fSinAzim*(1/fQovR + fQxDh) - x + fRefX));
00270
00271 return phi;
00272 }
00273
00274
00275
00276 Double_t ZHelix::Y2Phi(Double_t y) {
00277
00278
00279 Double_t phi = TMath::ACos(fQovR * (fCosAzim*(1/fQovR + fQxDh) + y - fRefY));
00280
00281 return phi;
00282 }
00283
00284
00285
00286 Double_t ZHelix::Z2Phi(Double_t z) {
00287
00288
00289 Double_t phi = fAzim - fQovR * (z - fRefZ) / fTDip;
00290
00291 return phi;
00292 }
00293
00294
00295
00296 Double_t ZHelix::R2Phi(Double_t r) {
00297
00298
00299 Double_t k = 1/fQovR + fQxDh;
00300 Double_t my_value = fQovR/(2*k) * (-TMath::Power(r,2) + 1/TMath::Power(fQovR,2) + TMath::Power(k,2));
00301
00302 if ( (my_value < -1) || (my_value > 1 ) )
00303 return 999999999;
00304 Double_t my_phi = TMath::ACos(my_value);
00305
00306 Double_t phi1 = fAzim - my_phi;
00307 Double_t phi2 = fAzim + my_phi;
00308
00309 Double_t x1 = 0;
00310 Double_t y1 = 0;
00311 Double_t z1 = 0;
00312 Double_t x2 = 0;
00313 Double_t y2 = 0;
00314 Double_t z2 = 0;
00315 Double_t phi = 0;;
00316 this->Phi2XYZ(phi1,x1,y1,z1);
00317 this->Phi2XYZ(phi2,x2,y2,z2);
00318
00319
00320
00321
00322 if ( TMath::Sign(1.,fTDip) == TMath::Sign(1.,(z1-fRefZ)) ) {
00323
00324
00325 if ( TMath::Sign(1.,fTDip) == TMath::Sign(1.,(z2-fRefZ)) ) {
00326
00327 if ( TMath::Abs(z1-fRefZ) <= TMath::Abs(z2-fRefZ) )
00328 phi = phi1;
00329 else
00330 phi = phi2;
00331 } else
00332 phi = phi1;
00333 } else {
00334 phi = phi2;
00335 }
00336
00337 return phi;
00338 }
00339
00340
00341
00342 void ZHelix::Print(Option_t *option) const {
00343
00344
00345 TString opt = option;
00346 opt.ToUpper();
00347
00348 cout << endl
00349 << "Parameters of helix " << this->GetName() << ":" << endl
00350 << "Azimuth = " << fAzim << endl
00351 << "Q/R = " << fQovR << endl
00352 << "Q*D_h = " << fQxDh << endl
00353 << "Z_h = " << fRefZ << endl
00354 << "cot(Dip) = " << fTDip << endl
00355 << "PhiI = " << fPhiI << endl
00356 << "PhiO = " << fPhiO << endl
00357 << "Chi2 = " << fChi2 << endl
00358 << "D.o.F. = " << fNDoF << endl
00359 << "RangeType = " << fRType << endl
00360 << "Range: " << fRange[0] << " -> " << fRange[1] << endl;
00361 if ( opt.Contains("ALL") ) TPolyLine3D::Print("ALL");
00362 cout << endl;
00363 }
00364
00365
00366
00367 void ZHelix::Draw(Option_t *option) {
00368
00369
00370 AppendPad(option);
00371 }
00372
00373
00374
00375 void ZHelix::Paint(Option_t *option) {
00376
00377
00378 TString opt = option;
00379 opt.ToUpper();
00380
00381 if ( ( (fRange[1] < fRange[0]) || (fRange[1] > fRange[0]) ) && fEnable ) {
00382 SetPoints(option);
00383 TPolyLine3D::Paint("SAME");
00384 }
00385 }
00386
00387
00388
00389 Double_t ZHelix::Phi2S(Double_t phi) {
00390
00391
00392
00393 return -(phi-fAzim)/fQovR;
00394
00395 }
00396
00397
00398
00399