/home/bes3soft/bes3soft/Boss/7.0.2/dist/7.0.2/EventDisplay/BesVisLib/BesVisLib-00-04-04/src/ZHelix.cxx

Go to the documentation of this file.
00001 //
00002 // ZHelix.cxx
00003 //
00004 // $Author: tianhl $
00005 // $Date: 2007/12/10 07:50:42 $
00006 // $Revision: 1.2 $
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 // ZHelix
00034 // Helix class
00035 //
00036 // Drawing options:
00037 //   '3D'     - 3 dimensional view
00038 //   'XY'     - XY projection
00039 //   'ZR'     - ZR projection
00040 //
00041 ZHelix::ZHelix() : TPolyLine3D() {
00042     //
00043     // ZHelix standard constructor
00044     if ( gDebug ) cout << "ZHelix default ctor called" << endl;
00045 
00046     fRSign = 0;
00047     //  fSegment = 1.;
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     // ZHelix normal constructor
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     //  fSegment = 1.;
00082     SetRange(RangeType, RangeMin, RangeMax);
00083 }
00084 
00085 //__________________________________________________________
00086 
00087 ZHelix::~ZHelix() {
00088     //
00089     // ZHelix standard destructor
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     // Set range for drawing
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     // Set PolyLine3D points
00130     TString opt = option;
00131     opt.ToUpper();
00132 
00133     // Get view
00134     BesView *view = (BesView*)gPad->GetView();
00135 
00136     // check with which sign the segmnents have to added to fRange[0]
00137     Int_t sign = 0;
00138     if ( fQovR >= 0 )
00139         sign = -1;
00140     else
00141         sign = +1;
00142 
00143     // calculate distance between ranges in rad
00144     Double_t degrad  = TMath::Pi() / 180.0;
00145     Double_t segment = 1. * degrad;   // 1 degree segments
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     // number of segments with degree distance
00159     Int_t nSeg = Int_t(TMath::Abs(df) / segment) + 1;
00160 
00161     // solve problem with nseg = 1 , means df too small compared to
00162     // segment -> new segment
00163     if ( nSeg < 2 ) {
00164         segment = 0.01 * degrad;
00165         nSeg = Int_t(TMath::Abs(df) / segment) + 1;
00166     }
00167     //  if ( nSeg < 10 ) nSeg = 10;
00168 
00169     // newly calculation of segment
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         // 3D view
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         // XY view
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         // ZR view
00191 
00192         // The track is drawn either in the upper or lower region of
00193         // the ZR view depending on how many of its segements lay in
00194         // each region. If these numbers are unbalanced, the starting
00195         // point of the track is taken as criterium
00196         Int_t isgn = 0;
00197         for ( Int_t i = 0; i <= nSeg; i++ ) {
00198 
00199             // Get ZR coordinates
00200             phi = fRange[0] + segment * i * sign;
00201             Phi2ZR(phi, z, r);
00202 
00203             // Set point
00204             TPolyLine3D::SetPoint(i, z, r, 0);
00205 
00206             // Get sign for R coordinate
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         // The vertex fitted tracks need to be displaced otherwise they are
00213         // are not drawn to emanate from the vertex.
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             // Set R sign for each point
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     // Calculate XYZ for a given azimuth
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     // Calculate ZR for a given azimuth
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     // Convert x to phi
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     // Convert y to phi
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     // Convert z to phi
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     // Convert r to phi
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     // check if my_value is ouside acos validity range
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     // check if phi1 would result in a z value with the correct sign corrsponding
00321     // to fTDip
00322     if ( TMath::Sign(1.,fTDip) == TMath::Sign(1.,(z1-fRefZ)) ) {
00323         // check if phi2 would result in a z value with the correct sign corrsponding
00324         // to fTDip
00325         if ( TMath::Sign(1.,fTDip) == TMath::Sign(1.,(z2-fRefZ)) ) {
00326             // take phi with smallest resulting z difference to fRefZ (Zh)
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     // Dump the helix attributes
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     // Draw this helix with its current attributes.
00370     AppendPad(option);
00371 }
00372 
00373 //__________________________________________________________
00374 
00375 void ZHelix::Paint(Option_t *option) {
00376     //
00377     // Draw this helix with its current attributes
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     // calculates pathlength for phi
00392 
00393     return -(phi-fAzim)/fQovR;
00394 
00395 }
00396 
00397 
00398 
00399 

Generated on Tue Nov 29 23:12:04 2016 for BOSS_7.0.2 by  doxygen 1.4.7