```// @(#)root/geom:\$Id\$
// Author: Andrei Gheata   28/04/04

/*************************************************************************
*                                                                       *
* For the licensing terms see \$ROOTSYS/LICENSE.                         *
* For the list of contributors see \$ROOTSYS/README/CREDITS.             *
*************************************************************************/

////////////////////////////////////////////////////////////////////////////////
//   TGeoHelix - class representing a helix curve
//
//  A helix is a curve defined by the following equations:
//     x = (1/c) * COS(q*phi)
//     y = (1/c) * SIN(q*phi)
//     z = s * alfa
// where:
//     c = 1/Rxy  - curvature in XY plane
//     phi        - phi angle
//     S = 2*PI*s - vertical separation between helix loops
//     q = +/- 1  - (+)=left-handed, (-)=right-handed
//
//   In particular, a helix describes the trajectory of a charged particle in magnetic
// field. In such case, the helix is right-handed for negative particle charge.
// To define a helix, one must define:
//   - the curvature - positive defined
//   - the Z step made after one full turn of the helix
//   - the particle charge sign
//   - the initial particle position and direction (force normalization to unit)
//   - the magnetic field direction
//
// A helix provides:
//   - propagation to a given Z position (in global frame)
//   Double_t *point = TGeoHelix::PropagateToZ(Double_t z);
//   - propagation to an arbitrary plane, returning also the new point
//   - propagation in a geometry until the next crossed surface
//   - computation of the total track length along a helix

#include "TMath.h"
#include "TGeoShape.h"
#include "TGeoMatrix.h"
#include "TGeoHelix.h"

ClassImp(TGeoHelix)

//_____________________________________________________________________________
TGeoHelix::TGeoHelix()
{
// Dummy constructor
fC    = 0.;
fS    = 0.;
fStep = 0.;
fPhi  = 0.;
fPointInit[0] = fPointInit[1] = fPointInit[2] = 0.;
fDirInit[0] = fDirInit[1] = fDirInit[2] = 0.;
fPoint[0] = fPoint[1] = fPoint[2] = 0.;
fDir[0] = fDir[1] = fDir[2] = 0.;
fB[0] = fB[1] = fB[2] = 0.;
fQ    = 0;
fMatrix = 0;
TObject::SetBit(kHelixNeedUpdate, kTRUE);
TObject::SetBit(kHelixStraigth, kFALSE);
TObject::SetBit(kHelixCircle, kFALSE);
}

//_____________________________________________________________________________
TGeoHelix::TGeoHelix(Double_t curvature, Double_t hstep, Int_t charge)
{
// Normal constructor
SetXYcurvature(curvature);
SetHelixStep(hstep);
fQ    = 0;
SetCharge(charge);
fStep = 0.;
fPhi  = 0.;
fPointInit[0] = fPointInit[1] = fPointInit[2] = 0.;
fDirInit[0] = fDirInit[1] = fDirInit[2] = 0.;
fPoint[0] = fPoint[1] = fPoint[2] = 0.;
fDir[0] = fDir[1] = fDir[2] = 0.;
fB[0] = fB[1] = fB[2] = 0.;
fMatrix    = new TGeoHMatrix();
TObject::SetBit(kHelixNeedUpdate, kTRUE);
TObject::SetBit(kHelixStraigth, kFALSE);
TObject::SetBit(kHelixCircle, kFALSE);
}

//_____________________________________________________________________________
TGeoHelix::~TGeoHelix()
{
// Destructor
if (fMatrix)    delete fMatrix;
}

//_____________________________________________________________________________
Double_t TGeoHelix::ComputeSafeStep(Double_t epsil) const
{
// Compute safe linear step that can be made such that the error
// between linear-helix extrapolation is less than EPSIL.
if (TestBit(kHelixStraigth) || TMath::Abs(fC)<TGeoShape::Tolerance()) return 1.E30;
Double_t c = GetTotalCurvature();
Double_t step = TMath::Sqrt(2.*epsil/c);
return step;
}

//_____________________________________________________________________________
void TGeoHelix::InitPoint(Double_t x0, Double_t y0, Double_t z0)
{
// Initialize coordinates of a point on the helix
fPointInit[0] = x0;
fPointInit[1] = y0;
fPointInit[2] = z0;
TObject::SetBit(kHelixNeedUpdate, kTRUE);
}

//_____________________________________________________________________________
void TGeoHelix::InitPoint (Double_t *point)
{
// Set initial point on the helix.
InitPoint(point[0], point[1], point[2]);
}

//_____________________________________________________________________________
void TGeoHelix::InitDirection(Double_t dirx, Double_t diry, Double_t dirz, Bool_t is_normalized)
{
// Initialize particle direction (tangent on the helix in initial point)
fDirInit[0] = dirx;
fDirInit[1] = diry;
fDirInit[2] = dirz;
TObject::SetBit(kHelixNeedUpdate, kTRUE);
if (is_normalized) return;
Double_t norm = 1./TMath::Sqrt(dirx*dirx+diry*diry+dirz*dirz);
for (Int_t i=0; i<3; i++) fDirInit[i] *= norm;
}

//_____________________________________________________________________________
void TGeoHelix::InitDirection(Double_t *dir, Bool_t is_normalized)
{
// Initialize particle direction (tangent on the helix in initial point)
InitDirection(dir[0], dir[1], dir[2], is_normalized);
}

//_____________________________________________________________________________
Double_t TGeoHelix::GetTotalCurvature() const
{
// Compute helix total curvature
Double_t k = fC/(1.+fC*fC*fS*fS);
return k;
}

//_____________________________________________________________________________
void TGeoHelix::SetXYcurvature(Double_t curvature)
{
// Set XY curvature: c = 1/Rxy
fC    = curvature;
TObject::SetBit(kHelixNeedUpdate, kTRUE);
if (fC < 0) {
Error("SetXYcurvature", "Curvature %f not valid. Must be positive.", fC);
return;
}
if (TMath::Abs(fC) < TGeoShape::Tolerance()) {
Warning("SetXYcurvature", "Curvature is zero. Helix is a straigth line.");
TObject::SetBit(kHelixStraigth, kTRUE);
}
}

//_____________________________________________________________________________
void TGeoHelix::SetCharge(Int_t charge)
{
// Positive charge means left-handed helix.
if (charge==0) {
Error("ctor", "charge cannot be 0 - define it positive for a left-handed helix, negative otherwise");
return;
}
Int_t q = TMath::Sign(1, charge);
if (q == fQ) return;
fQ = q;
TObject::SetBit(kHelixNeedUpdate, kTRUE);
}

//_____________________________________________________________________________
void TGeoHelix::SetField(Double_t bx, Double_t by, Double_t bz, Bool_t is_normalized)
{
// Initialize particle direction (tangent on the helix in initial point)
fB[0] = bx;
fB[1] = by;
fB[2] = bz;
TObject::SetBit(kHelixNeedUpdate, kTRUE);
if (is_normalized) return;
Double_t norm = 1./TMath::Sqrt(bx*bx+by*by+bz*bz);
for (Int_t i=0; i<3; i++) fB[i] *= norm;
}

//_____________________________________________________________________________
void TGeoHelix::SetHelixStep(Double_t step)
{
// Set Z step of the helix on a complete turn. Positive or null.
if (step < 0) {
Error("ctor", "Z step %f not valid. Must be positive.", step);
return;
}
TObject::SetBit(kHelixNeedUpdate, kTRUE);
fS    = 0.5*step/TMath::Pi();
if (fS < TGeoShape::Tolerance()) TObject::SetBit(kHelixCircle, kTRUE);
}

//_____________________________________________________________________________
void TGeoHelix::ResetStep()
{
// Reset current point/direction to initial values
fStep = 0.;
memcpy(fPoint, fPointInit, 3*sizeof(Double_t));
memcpy(fDir, fDirInit, 3*sizeof(Double_t));
}

//_____________________________________________________________________________
void TGeoHelix::Step(Double_t step)
{
// Make a step from current point along the helix and compute new point, direction and angle
// To reach a plane/ shape boundary, one has to:
//  1. Compute the safety to the plane/boundary
//  2. Define / update a helix according local field and particle state (position, direction, charge)
//  3. Compute the magnetic safety (maximum distance for which the field can be considered constant)
//  4. Call TGeoHelix::Step() having as argument the minimum between 1. and 3.
//  5. Repeat from 1. until the step to be made is small enough.
//  6. Add to the total step the distance along a straigth line from the last point
//     to the plane/shape boundary
Int_t i;
fStep += step;
if (TObject::TestBit(kHelixStraigth)) {
for (i=0; i<3; i++) {
fPoint[i] = fPointInit[i]+fStep*fDirInit[i];
fDir[i] = fDirInit[i];
}
return;
}
if (TObject::TestBit(kHelixNeedUpdate)) UpdateHelix();
Double_t r = 1./fC;
fPhi = fStep/TMath::Sqrt(r*r+fS*fS);
Double_t vect[3];
vect[0] = r * TMath::Cos(fPhi);
vect[1] = -fQ * r * TMath::Sin(fPhi);
vect[2] = fS * fPhi;
fMatrix->LocalToMaster(vect, fPoint);

Double_t ddb = fDirInit[0]*fB[0]+fDirInit[1]*fB[1]+fDirInit[2]*fB[2];
Double_t f = -TMath::Sqrt(1.-ddb*ddb);
vect[0] = f*TMath::Sin(fPhi);
vect[1] = fQ*f*TMath::Cos(fPhi);
vect[2] = ddb;
TMath::Normalize(vect);
fMatrix->LocalToMasterVect(vect, fDir);
}

//_____________________________________________________________________________
Double_t TGeoHelix::StepToPlane(Double_t *point, Double_t *norm)
{
// Propagate initial point up to a given Z position in MARS.
Double_t step = 0.;
Double_t snext = 1.E30;
Double_t dx, dy, dz;
Double_t ddn, pdn;
if (TObject::TestBit(kHelixNeedUpdate)) UpdateHelix();
dx = point[0] - fPoint[0];
dy = point[1] - fPoint[1];
dz = point[2] - fPoint[2];
pdn = dx*norm[0]+dy*norm[1]+dz*norm[2];
ddn = fDir[0]*norm[0]+fDir[1]*norm[1]+fDir[2]*norm[2];
if (TObject::TestBit(kHelixStraigth)) {
// propagate straigth line to plane
if ((pdn*ddn) <= 0) return snext;
snext = pdn/ddn;
Step(snext);
return snext;
}

Double_t r = 1./fC;
Double_t dist;
Double_t safety = TMath::Abs(pdn);
Double_t safestep = ComputeSafeStep();
snext = 1.E30;
Bool_t approaching = (ddn*pdn>0)?kTRUE:kFALSE;
if (approaching) snext = pdn/ddn;
else if (safety > 2.*r) return snext;
while (snext > safestep) {
dist = TMath::Max(safety, safestep);
Step(dist);
step += dist;
dx = point[0] - fPoint[0];
dy = point[1] - fPoint[1];
dz = point[2] - fPoint[2];
pdn = dx*norm[0]+dy*norm[1]+dz*norm[2];
ddn = fDir[0]*norm[0]+fDir[1]*norm[1]+fDir[2]*norm[2];
safety = TMath::Abs(pdn);
approaching = (ddn*pdn>0)?kTRUE:kFALSE;
snext = 1.E30;
if (approaching) snext = pdn/ddn;
else if (safety > 2.*r) {
ResetStep();
return snext;
}
}
step += snext;
Step(snext);
return step;
}

//_____________________________________________________________________________
void TGeoHelix::UpdateHelix()
{
// Update the local helix matrix.
TObject::SetBit(kHelixNeedUpdate, kFALSE);
fStep = 0.;
memcpy(fPoint, fPointInit, 3*sizeof(Double_t));
memcpy(fDir, fDirInit, 3*sizeof(Double_t));
Double_t rot[9];
Double_t tr[3];
Double_t ddb = fDirInit[0]*fB[0]+fDirInit[1]*fB[1]+fDirInit[2]*fB[2];
if ((1.-TMath::Abs(ddb))<TGeoShape::Tolerance() || TMath::Abs(fC)<TGeoShape::Tolerance()) {
// helix is just a straigth line
TObject::SetBit(kHelixStraigth, kTRUE);
fMatrix->Clear();
return;
}
rot[2] = fB[0];
rot[5] = fB[1];
rot[8] = fB[2];
if (ddb < 0) fS = -TMath::Abs(fS);
Double_t fy = - fQ*TMath::Sqrt(1.-ddb*ddb);
fy = 1./fy;
rot[1] = fy*(fDirInit[0]-fB[0]*ddb);
rot[4] = fy*(fDirInit[1]-fB[1]*ddb);
rot[7] = fy*(fDirInit[2]-fB[2]*ddb);

rot[0] = rot[4]*rot[8] - rot[7]*rot[5];
rot[3] = rot[7]*rot[2] - rot[1]*rot[8];
rot[6] = rot[1]*rot[5] - rot[4]*rot[2];

tr[0] = fPointInit[0] - rot[0]/fC;
tr[1] = fPointInit[1] - rot[3]/fC;
tr[2] = fPointInit[2] - rot[6]/fC;

fMatrix->SetTranslation(tr);
fMatrix->SetRotation(rot);

}
```
TGeoHelix.cxx:1
TGeoHelix.cxx:2
TGeoHelix.cxx:3
TGeoHelix.cxx:4
TGeoHelix.cxx:5
TGeoHelix.cxx:6
TGeoHelix.cxx:7
TGeoHelix.cxx:8
TGeoHelix.cxx:9
TGeoHelix.cxx:10
TGeoHelix.cxx:11
TGeoHelix.cxx:12
TGeoHelix.cxx:13
TGeoHelix.cxx:14
TGeoHelix.cxx:15
TGeoHelix.cxx:16
TGeoHelix.cxx:17
TGeoHelix.cxx:18
TGeoHelix.cxx:19
TGeoHelix.cxx:20
TGeoHelix.cxx:21
TGeoHelix.cxx:22
TGeoHelix.cxx:23
TGeoHelix.cxx:24
TGeoHelix.cxx:25
TGeoHelix.cxx:26
TGeoHelix.cxx:27
TGeoHelix.cxx:28
TGeoHelix.cxx:29
TGeoHelix.cxx:30
TGeoHelix.cxx:31
TGeoHelix.cxx:32
TGeoHelix.cxx:33
TGeoHelix.cxx:34
TGeoHelix.cxx:35
TGeoHelix.cxx:36
TGeoHelix.cxx:37
TGeoHelix.cxx:38
TGeoHelix.cxx:39
TGeoHelix.cxx:40
TGeoHelix.cxx:41
TGeoHelix.cxx:42
TGeoHelix.cxx:43
TGeoHelix.cxx:44
TGeoHelix.cxx:45
TGeoHelix.cxx:46
TGeoHelix.cxx:47
TGeoHelix.cxx:48
TGeoHelix.cxx:49
TGeoHelix.cxx:50
TGeoHelix.cxx:51
TGeoHelix.cxx:52
TGeoHelix.cxx:53
TGeoHelix.cxx:54
TGeoHelix.cxx:55
TGeoHelix.cxx:56
TGeoHelix.cxx:57
TGeoHelix.cxx:58
TGeoHelix.cxx:59
TGeoHelix.cxx:60
TGeoHelix.cxx:61
TGeoHelix.cxx:62
TGeoHelix.cxx:63
TGeoHelix.cxx:64
TGeoHelix.cxx:65
TGeoHelix.cxx:66
TGeoHelix.cxx:67
TGeoHelix.cxx:68
TGeoHelix.cxx:69
TGeoHelix.cxx:70
TGeoHelix.cxx:71
TGeoHelix.cxx:72
TGeoHelix.cxx:73
TGeoHelix.cxx:74
TGeoHelix.cxx:75
TGeoHelix.cxx:76
TGeoHelix.cxx:77
TGeoHelix.cxx:78
TGeoHelix.cxx:79
TGeoHelix.cxx:80
TGeoHelix.cxx:81
TGeoHelix.cxx:82
TGeoHelix.cxx:83
TGeoHelix.cxx:84
TGeoHelix.cxx:85
TGeoHelix.cxx:86
TGeoHelix.cxx:87
TGeoHelix.cxx:88
TGeoHelix.cxx:89
TGeoHelix.cxx:90
TGeoHelix.cxx:91
TGeoHelix.cxx:92
TGeoHelix.cxx:93
TGeoHelix.cxx:94
TGeoHelix.cxx:95
TGeoHelix.cxx:96
TGeoHelix.cxx:97
TGeoHelix.cxx:98
TGeoHelix.cxx:99
TGeoHelix.cxx:100
TGeoHelix.cxx:101
TGeoHelix.cxx:102
TGeoHelix.cxx:103
TGeoHelix.cxx:104
TGeoHelix.cxx:105
TGeoHelix.cxx:106
TGeoHelix.cxx:107
TGeoHelix.cxx:108
TGeoHelix.cxx:109
TGeoHelix.cxx:110
TGeoHelix.cxx:111
TGeoHelix.cxx:112
TGeoHelix.cxx:113
TGeoHelix.cxx:114
TGeoHelix.cxx:115
TGeoHelix.cxx:116
TGeoHelix.cxx:117
TGeoHelix.cxx:118
TGeoHelix.cxx:119
TGeoHelix.cxx:120
TGeoHelix.cxx:121
TGeoHelix.cxx:122
TGeoHelix.cxx:123
TGeoHelix.cxx:124
TGeoHelix.cxx:125
TGeoHelix.cxx:126
TGeoHelix.cxx:127
TGeoHelix.cxx:128
TGeoHelix.cxx:129
TGeoHelix.cxx:130
TGeoHelix.cxx:131
TGeoHelix.cxx:132
TGeoHelix.cxx:133
TGeoHelix.cxx:134
TGeoHelix.cxx:135
TGeoHelix.cxx:136
TGeoHelix.cxx:137
TGeoHelix.cxx:138
TGeoHelix.cxx:139
TGeoHelix.cxx:140
TGeoHelix.cxx:141
TGeoHelix.cxx:142
TGeoHelix.cxx:143
TGeoHelix.cxx:144
TGeoHelix.cxx:145
TGeoHelix.cxx:146
TGeoHelix.cxx:147
TGeoHelix.cxx:148
TGeoHelix.cxx:149
TGeoHelix.cxx:150
TGeoHelix.cxx:151
TGeoHelix.cxx:152
TGeoHelix.cxx:153
TGeoHelix.cxx:154
TGeoHelix.cxx:155
TGeoHelix.cxx:156
TGeoHelix.cxx:157
TGeoHelix.cxx:158
TGeoHelix.cxx:159
TGeoHelix.cxx:160
TGeoHelix.cxx:161
TGeoHelix.cxx:162
TGeoHelix.cxx:163
TGeoHelix.cxx:164
TGeoHelix.cxx:165
TGeoHelix.cxx:166
TGeoHelix.cxx:167
TGeoHelix.cxx:168
TGeoHelix.cxx:169
TGeoHelix.cxx:170
TGeoHelix.cxx:171
TGeoHelix.cxx:172
TGeoHelix.cxx:173
TGeoHelix.cxx:174
TGeoHelix.cxx:175
TGeoHelix.cxx:176
TGeoHelix.cxx:177
TGeoHelix.cxx:178
TGeoHelix.cxx:179
TGeoHelix.cxx:180
TGeoHelix.cxx:181
TGeoHelix.cxx:182
TGeoHelix.cxx:183
TGeoHelix.cxx:184
TGeoHelix.cxx:185
TGeoHelix.cxx:186
TGeoHelix.cxx:187
TGeoHelix.cxx:188
TGeoHelix.cxx:189
TGeoHelix.cxx:190
TGeoHelix.cxx:191
TGeoHelix.cxx:192
TGeoHelix.cxx:193
TGeoHelix.cxx:194
TGeoHelix.cxx:195
TGeoHelix.cxx:196
TGeoHelix.cxx:197
TGeoHelix.cxx:198
TGeoHelix.cxx:199
TGeoHelix.cxx:200
TGeoHelix.cxx:201
TGeoHelix.cxx:202
TGeoHelix.cxx:203
TGeoHelix.cxx:204
TGeoHelix.cxx:205
TGeoHelix.cxx:206
TGeoHelix.cxx:207
TGeoHelix.cxx:208
TGeoHelix.cxx:209
TGeoHelix.cxx:210
TGeoHelix.cxx:211
TGeoHelix.cxx:212
TGeoHelix.cxx:213
TGeoHelix.cxx:214
TGeoHelix.cxx:215
TGeoHelix.cxx:216
TGeoHelix.cxx:217
TGeoHelix.cxx:218
TGeoHelix.cxx:219
TGeoHelix.cxx:220
TGeoHelix.cxx:221
TGeoHelix.cxx:222
TGeoHelix.cxx:223
TGeoHelix.cxx:224
TGeoHelix.cxx:225
TGeoHelix.cxx:226
TGeoHelix.cxx:227
TGeoHelix.cxx:228
TGeoHelix.cxx:229
TGeoHelix.cxx:230
TGeoHelix.cxx:231
TGeoHelix.cxx:232
TGeoHelix.cxx:233
TGeoHelix.cxx:234
TGeoHelix.cxx:235
TGeoHelix.cxx:236
TGeoHelix.cxx:237
TGeoHelix.cxx:238
TGeoHelix.cxx:239
TGeoHelix.cxx:240
TGeoHelix.cxx:241
TGeoHelix.cxx:242
TGeoHelix.cxx:243
TGeoHelix.cxx:244
TGeoHelix.cxx:245
TGeoHelix.cxx:246
TGeoHelix.cxx:247
TGeoHelix.cxx:248
TGeoHelix.cxx:249
TGeoHelix.cxx:250
TGeoHelix.cxx:251
TGeoHelix.cxx:252
TGeoHelix.cxx:253
TGeoHelix.cxx:254
TGeoHelix.cxx:255
TGeoHelix.cxx:256
TGeoHelix.cxx:257
TGeoHelix.cxx:258
TGeoHelix.cxx:259
TGeoHelix.cxx:260
TGeoHelix.cxx:261
TGeoHelix.cxx:262
TGeoHelix.cxx:263
TGeoHelix.cxx:264
TGeoHelix.cxx:265
TGeoHelix.cxx:266
TGeoHelix.cxx:267
TGeoHelix.cxx:268
TGeoHelix.cxx:269
TGeoHelix.cxx:270
TGeoHelix.cxx:271
TGeoHelix.cxx:272
TGeoHelix.cxx:273
TGeoHelix.cxx:274
TGeoHelix.cxx:275
TGeoHelix.cxx:276
TGeoHelix.cxx:277
TGeoHelix.cxx:278
TGeoHelix.cxx:279
TGeoHelix.cxx:280
TGeoHelix.cxx:281
TGeoHelix.cxx:282
TGeoHelix.cxx:283
TGeoHelix.cxx:284
TGeoHelix.cxx:285
TGeoHelix.cxx:286
TGeoHelix.cxx:287
TGeoHelix.cxx:288
TGeoHelix.cxx:289
TGeoHelix.cxx:290
TGeoHelix.cxx:291
TGeoHelix.cxx:292
TGeoHelix.cxx:293
TGeoHelix.cxx:294
TGeoHelix.cxx:295
TGeoHelix.cxx:296
TGeoHelix.cxx:297
TGeoHelix.cxx:298
TGeoHelix.cxx:299
TGeoHelix.cxx:300
TGeoHelix.cxx:301
TGeoHelix.cxx:302
TGeoHelix.cxx:303
TGeoHelix.cxx:304
TGeoHelix.cxx:305
TGeoHelix.cxx:306
TGeoHelix.cxx:307
TGeoHelix.cxx:308
TGeoHelix.cxx:309
TGeoHelix.cxx:310
TGeoHelix.cxx:311
TGeoHelix.cxx:312
TGeoHelix.cxx:313
TGeoHelix.cxx:314
TGeoHelix.cxx:315
TGeoHelix.cxx:316
TGeoHelix.cxx:317
TGeoHelix.cxx:318
TGeoHelix.cxx:319
TGeoHelix.cxx:320
TGeoHelix.cxx:321
TGeoHelix.cxx:322
TGeoHelix.cxx:323
TGeoHelix.cxx:324
TGeoHelix.cxx:325
TGeoHelix.cxx:326
TGeoHelix.cxx:327
TGeoHelix.cxx:328
TGeoHelix.cxx:329
TGeoHelix.cxx:330
TGeoHelix.cxx:331
TGeoHelix.cxx:332
TGeoHelix.cxx:333
TGeoHelix.cxx:334
TGeoHelix.cxx:335
TGeoHelix.cxx:336
TGeoHelix.cxx:337
TGeoHelix.cxx:338
TGeoHelix.cxx:339
TGeoHelix.cxx:340
TGeoHelix.cxx:341
TGeoHelix.cxx:342
TGeoHelix.cxx:343
TGeoHelix.cxx:344
TGeoHelix.cxx:345
TGeoHelix.cxx:346
TGeoHelix.cxx:347
TGeoHelix.cxx:348