ROOT logo
// @(#)root/g3d:$Id$
// Author: Ping Yeh   19/12/97

/*************************************************************************
 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

//______________________________________________________________________________
// THelix has two different constructors.
//
//   If a particle with charge q passes through a point (x,y,z)
//   with momentum (px,py,pz) with magnetic field B along an axis (nx,ny,nz),
//   this helix can be constrcuted like
//
//      THelix p(x,y,z, px,py,pz, q*B, nx,ny,nz);
//
//     (nx,ny,nz) defaults to (0,0,1).
//
//   A helix in its own frame can be defined with a pivotal point
//   (x0,y0,z0), the velocity at that point (vx0,vy0,vz0), and
//   an angular frequency w.  Combining vx0 and vy0 to a transverse 
//   velocity vt0 one can parametrize the helix as
//
//    x(t) = x0 - vt0 / w * sin(-w * t + phi0)
//    y(t) = y0 + vt0 / w * cos(-w * t + phi0)
//    z(t) = z0 + vz0 * t
//
//
//   The second constructor has 6 parameters,
//
//       Example:
//                 THelix pl1(xyz, v, w, range, rtype, axis);
//
//         where:
//             xyz  : array of initial position
//             v    : array of initial velocity
//             w    : angular frequency
//             range: helix range
//             rtype: kHelixZ specifies allowed drawing range in helix Z direction, i.e., along B field.
//                    kLabZ specifies drawing range in lab frame.
//                    kHelixX, kHelixY, kLabX, kLabY, kUnchanged ... etc can also be specified
//             axis : helix axis
//
//
//
// Example constructing a helix with several default values and drawing it:
//
// BEGIN_MACRO(source)
// {
//   TCanvas* helix_example_c1 = new TCanvas("helix_example_c1");
//   TView *view = TView::CreateView(1);
//   view->SetRange(-1,-1,-1,1,1,1);
//   THelix *helix = new THelix(0., 0., 0., 1., 0., 0.3, 10.);
//   helix->Draw();
// }
// END_MACRO
//
// This initializes a helix with its axis in Z direction (rtype=kHelixZ).
//


#include "Riostream.h"
#include "TROOT.h"
#include "TVirtualPad.h"
#include "THelix.h"
#include "TClass.h"
#include "TMath.h"

Int_t THelix::fgMinNSeg=5;        // at least 5 line segments in TPolyLine3D

ClassImp(THelix)


//______________________________________________________________________________
void  THelix::SetHelix(Double_t *p,  Double_t *v,  Double_t w,
                       Double_t *range, EHelixRangeType rType,
                       Double_t *axis )
{
   // Set all helix parameters.

   // Define the helix frame by setting the helix axis and rotation matrix
   SetAxis(axis);

   // Calculate initial position and velocity in helix frame
   fW    = w;
   Double_t * m = fRotMat->GetMatrix();
   Double_t vx0, vy0, vz0;
   vx0   = v[0] * m[0] + v[1] * m[1] + v[2] * m[2];
   vy0   = v[0] * m[3] + v[1] * m[4] + v[2] * m[5];
   vz0   = v[0] * m[6] + v[1] * m[7] + v[2] * m[8];
   fVt   = TMath::Sqrt(vx0*vx0 + vy0*vy0);
   fPhi0 = TMath::ATan2(vy0,vx0);
   fVz   = vz0;
   fX0   = p[0] * m[0] +  p[1] * m[1] +  p[2] * m[2];
   fY0   = p[0] * m[3] +  p[1] * m[4] +  p[2] * m[5];
   fZ0   = p[0] * m[6] +  p[1] * m[7] +  p[2] * m[8];
   if (fW != 0) {
      fX0 += fVt / fW * TMath::Sin(fPhi0);
      fY0 -= fVt / fW * TMath::Cos(fPhi0);
   }

   // Then calculate the range in t and set the polyline representation
   Double_t r1 = 0;
   Double_t r2 = 1;
   if (range) {r1 = range[0]; r2 = range[1];}
   if (rType != kUnchanged) {
      fRange[0] = 0.0;   fRange[1] = TMath::Pi();   // initialize to half round
      SetRange(r1,r2,rType);
   }
}


//______________________________________________________________________________
THelix::THelix()
{
   // Helix default constructor.

   fX0 = fY0 = fZ0 = fVt = fPhi0 = fVz = fAxis[0] = fAxis[1] = 0.0;
   fAxis[2]  = 1.0;
   fW        = 1.5E7;   // roughly the cyclon frequency of proton in AMS
   fRange[0] = 0.0;
   fRange[1] = 1.0;
   fRotMat   = 0;
}


//______________________________________________________________________________
THelix::THelix(Double_t x,  Double_t y,  Double_t z,
               Double_t vx, Double_t vy, Double_t vz,
               Double_t w)
        : TPolyLine3D()
{
   // Helix normal constructor.
   Double_t p[3], v[3];
   p[0] = x;
   p[1] = y;
   p[2] = z;
   v[0] = vx;
   v[1] = vy;
   v[2] = vz;
   Double_t *range = 0;
   fRotMat   = 0;

   SetHelix(p, v, w, range, kHelixZ);
   fOption = "";
}


//______________________________________________________________________________
THelix::THelix(Double_t * p, Double_t * v, Double_t w,
               Double_t * range, EHelixRangeType rType, Double_t * axis)
        : TPolyLine3D()
{
   // Helix normal constructor.

   Double_t r[2];
   if ( range ) {
      r[0] = range[0];   r[1] = range[1];
   } else {
      r[0] = 0.0;        r[1] = 1.0;
   }

   fRotMat   = 0;
   if ( axis ) {                        // specify axis
      SetHelix(p, v, w, r, rType, axis);
   } else {                             // default axis
      SetHelix(p, v, w, r, rType);
   }

   fOption = "";
}


#if 0
//______________________________________________________________________________
THelix::THelix(const THelix &h) : TPolyLine3D()
{
   // Helix copy constructor.

   fX0   = h.fX0;
   fY0   = h.fY0;
   fZ0   = h.fZ0;
   fVt   = h.fVt;
   fPhi0 = h.fPhi0;
   fVz   = h.fVz;
   fW    = h.fW;
   for (Int_t i=0; i<3; i++) fAxis[i] = h.fAxis[i];
   fRotMat = new TRotMatrix(*(h.fRotMat));
   fRange[0] = h.fRange[0];
   fRange[1] = h.fRange[1];

   fOption = h.fOption;
}
#endif

//______________________________________________________________________________
THelix& THelix::operator=(const THelix& hx)
{
   //assignement operator
   if(this!=&hx) {
      TPolyLine3D::operator=(hx);
      fX0=hx.fX0;
      fY0=hx.fY0;
      fZ0=hx.fZ0;
      fVt=hx.fVt;
      fPhi0=hx.fPhi0;
      fVz=hx.fVz;
      fW=hx.fW;
      for(Int_t i=0; i<3; i++) 
         fAxis[i]=hx.fAxis[i];
      fRotMat=hx.fRotMat;
      for(Int_t i=0; i<2; i++) 
         fRange[i]=hx.fRange[i];
   } 
   return *this;
}

//______________________________________________________________________________
THelix::~THelix()
{
   // Helix destructor.

   if (fRotMat) delete fRotMat;
}


//______________________________________________________________________________
THelix::THelix(const THelix &helix) : TPolyLine3D(helix)
{
   // Helix copy constructor.

   fRotMat=0;
   ((THelix&)helix).THelix::Copy(*this);
}


//______________________________________________________________________________
void THelix::Copy(TObject &obj) const
{
   // Copy this helix to obj.

   TObject::Copy(obj);
   TAttLine::Copy(((THelix&)obj));

   ((THelix&)obj).fX0        = fX0;
   ((THelix&)obj).fY0        = fY0;
   ((THelix&)obj).fZ0        = fZ0;
   ((THelix&)obj).fVt        = fVt;
   ((THelix&)obj).fPhi0      = fPhi0;
   ((THelix&)obj).fVz        = fVz;
   ((THelix&)obj).fW         = fW;
   for (Int_t i=0; i<3; i++)
      ((THelix&)obj).fAxis[i] = fAxis[i];

   if (((THelix&)obj).fRotMat)
      delete ((THelix&)obj).fRotMat;
   ((THelix&)obj).fRotMat    = new TRotMatrix(*fRotMat);

   ((THelix&)obj).fRange[0]  = fRange[0];
   ((THelix&)obj).fRange[1]  = fRange[1];

   ((THelix&)obj).fOption    = fOption;

   //
   // Set range and make the graphic representation
   //
   ((THelix&)obj).SetRange(fRange[0], fRange[1], kHelixT);
}


//______________________________________________________________________________
void THelix::Draw(Option_t *option)
{
   // Draw this helix with its current attributes.

   AppendPad(option);
}


//______________________________________________________________________________
void THelix::Print(Option_t *option) const
{
   // Dump this helix with its attributes.

   cout <<"    THelix Printing N=" <<fN<<" Option="<<option<<endl;
}


//______________________________________________________________________________
void THelix::SavePrimitive(ostream &out, Option_t * /*= ""*/)
{
   // Save primitive as a C++ statement(s) on output stream out.

   char quote = '"';
   out<<"   "<<endl;
   if (gROOT->ClassSaved(THelix::Class())) {
      out<<"   ";
   } else {
      out<<"   THelix *";
   }
   out<<"helix = new THelix("<<fX0<<","<<fY0<<","<<fZ0<<","
      <<fVt*TMath::Cos(fPhi0)<<","<<fVt*TMath::Sin(fPhi0)<<","<<fVz<<","
      <<fW<<","<<fRange[0]<<","<<fRange[1]<<","<<(Int_t)kHelixT<<","
      <<fAxis[0]<<","<<fAxis[1]<<","<<fAxis[2]<<","
      <<quote<<fOption<<quote<<");"<<endl;

   SaveLineAttributes(out,"helix",1,1,1);

   out<<"   helix->Draw();"<<endl;
}


//______________________________________________________________________________
void THelix::SetAxis(Double_t * axis)
{
   // Set a new axis for the helix.  This will make a new rotation matrix.

   if (axis) {
      Double_t len = TMath::Sqrt(axis[0]*axis[0] + axis[1]*axis[1] + axis[2]*axis[2]);
      if (len <= 0) {
         Error("SetAxis()", "Impossible! axis length %lf <= 0!", len);
         return;
      }
      fAxis[0] = axis[0]/len;
      fAxis[1] = axis[1]/len;
      fAxis[2] = axis[2]/len;
   } else {
      fAxis[0] = 0;
      fAxis[1] = 0;
      fAxis[2] = 1;
   }

   // Construct the rotational matrix from the axis
   SetRotMatrix();
}


//______________________________________________________________________________
void THelix::SetAxis(Double_t x, Double_t y, Double_t z)
{
   // Set axis.

   Double_t axis[3];    axis[0] = x;    axis[1] = y;    axis[2] = z;
   SetAxis(axis);
}


//______________________________________________________________________________
void THelix::SetRange(Double_t * range, EHelixRangeType rType)
{
   // Set a new range for the helix.  This will remake the polyline.

   Double_t a[2];
   Double_t halfpi = TMath::Pi()/2.0;
   Int_t i;
   Double_t vx = fVt * TMath::Cos(fPhi0);
   Double_t vy = fVt * TMath::Sin(fPhi0);
   Double_t phase;

   if ( fW != 0 && fVz != 0 ) {         // general case
      switch ( rType ) {
         case kHelixT :
            fRange[0] = range[0];  fRange[1] = range[1];  break;

         case kHelixX :
            for (i=0; i<2; i++ ) {
               a[i] = fW / fVt * (range[i] - fX0);
               if ( a[i] < -1 || a[i] > 1 ) {
                  Error("SetRange()",
                        "range out of bound (%lf:%lf): %lf.  Default used: %lf",
                        fX0-fVt/fW, fX0+fVt/fW, range[i], fRange[i]);
                  return;
               }
               phase = FindClosestPhase(fPhi0+halfpi, a[i]);
               fRange[i] = ( fPhi0 + halfpi - phase ) / fW;
            }
            break;

         case kHelixY :
            for (i=0; i<2; i++ ) {
               a[i] = fW / fVt * (range[i] - fY0);
               if ( a[i] < -1 || a[i] > 1 ) {
                  Error("SetRange()",
                        "range out of bound (%lf:%lf): %lf.  Default used: %lf",
                         fY0-fVt/fW, fY0+fVt/fW, range[i], fRange[i]);
                  return;
               }
               phase = FindClosestPhase(fPhi0, a[i]);
               fRange[i] = ( fPhi0 - phase ) / fW;
            }
            break;

         case kHelixZ :
            if ( fVz != 0 ) {
               for (i=0; i<2; i++ ) {
                  fRange[i] = (range[i] - fZ0) / fVz;
               }
            } else {                // fVz = 0, z = constant = fZ0
               Error("SetRange()",
                     "Vz = 0 and attempts to set range along helix axis!");
               return;
            }
            break;

         case kLabX :
         case kLabY :
         case kLabZ :
            printf("setting range in lab axes is not implemented yet\n");
            break;
         default:
            Error("SetRange()","unknown range type %d", rType);
            break;
      }
   } else if ( fW == 0 ) {                // straight line: x = x0 + vx * t
      switch ( rType ) {
         case kHelixT :
            fRange[0] = range[0];  fRange[1] = range[1];
            break;
         case kHelixX :
            if ( vx != 0 ) {
               fRange[0] = (range[0] - fX0) / vx;
               fRange[1] = (range[1] - fX0) / vx;
            } else {
               Error("SetRange()",
                     "Vx = 0 and attempts to set range on helix x axis!");
               return;
            }
            break;
         case kHelixY :
            if ( vy != 0 ) {
               fRange[0] = (range[0] - fY0) / vy;
               fRange[1] = (range[1] - fY0) / vy;
            } else {
               Error("SetRange()",
                     "Vy = 0 and attempts to set range on helix y axis!");
               return;
            }
            break;
         case kHelixZ :
            if ( fVz != 0 ) {
               fRange[0] = (range[0] - fZ0) / fVz;
               fRange[1] = (range[1] - fZ0) / fVz;
            } else {
               Error("SetRange()",
                     "Vz = 0 and attempts to set range on helix z axis!");
               return;
            }
            break;
         case kLabX   :
         case kLabY   :
         case kLabZ   :
            printf("setting range in lab axes is not implemented yet\n");
            break;
         default      :
            Error("SetRange()","unknown range type %d", rType);
            break;
      }
   } else if ( fVz == 0 ) {               // a circle, not fully implemented yet
      switch ( rType ) {
         case kHelixT :
            fRange[0] = range[0];  fRange[1] = range[1];  break;
         case kHelixX :
            if ( vx != 0 ) {
               fRange[0] = (range[0] - fX0) / vx;
               fRange[1] = (range[1] - fX0) / vx;
            } else {
               Error("SetRange()",
                     "Vx = 0 and attempts to set range on helix x axis!");
               return;
            }
            break;
         case kHelixY :
            if ( vy != 0 ) {
               fRange[0] = (range[0] - fY0) / vy;
               fRange[1] = (range[1] - fY0) / vy;
            } else {
               Error("SetRange()",
                     "Vy = 0 and attempts to set range on helix y axis!");
               return;
            }
            break;
         case kHelixZ :
            Error("SetRange()",
                  "Vz = 0 and attempts to set range on helix z axis!");
            return;
         case kLabX   :
         case kLabY   :
         case kLabZ   :
            printf("setting range in lab axes is not implemented yet\n");
            break;
         default      :
            Error("SetRange()","unknown range type %d", rType);
            break;
      }
   }

   if ( fRange[0] > fRange[1] ) {
      Double_t temp = fRange[1];   fRange[1] = fRange[0];  fRange[0] = temp;
   }

   // Set the polylines in global coordinates
   Double_t degrad  = TMath::Pi() / 180.0;
   Double_t segment = 5.0 * degrad;             // 5 degree segments
   Double_t dt      = segment / TMath::Abs(fW); // parameter span on each segm.

   Int_t    nSeg    = Int_t((fRange[1]-fRange[0]) / dt) + 1;
   if (nSeg < THelix::fgMinNSeg) {
      nSeg = THelix::fgMinNSeg;
      dt = (fRange[1]-fRange[0])/nSeg;
   }

   Double_t * xl    = new Double_t[nSeg+1];     // polyline in local coordinates
   Double_t * yl    = new Double_t[nSeg+1];
   Double_t * zl    = new Double_t[nSeg+1];

   for (i=0; i<=nSeg; i++) {                    // calculate xl[], yl[], zl[];
      Double_t t, phase2;
      if (i==nSeg) t = fRange[1];                // the last point
      else         t = fRange[0] + dt * i;
      phase2 = -fW * t + fPhi0;
      xl[i] = fX0 - fVt/fW * TMath::Sin(phase2);
      yl[i] = fY0 + fVt/fW * TMath::Cos(phase2);
      zl[i] = fZ0 + fVz * t;
   }

   Float_t xg, yg,zg;     // global coordinates
                          // must be Float_t to call TPolyLine3D::SetPoint()
   Double_t * m = fRotMat->GetMatrix();
   TPolyLine3D::SetPolyLine(nSeg+1);
   for (i=0; i<=nSeg; i++) {                    // m^{-1} = transpose of m
      xg =  xl[i] * m[0]  +  yl[i] * m[3]  +  zl[i] * m[6] ;
      yg =  xl[i] * m[1]  +  yl[i] * m[4]  +  zl[i] * m[7] ;
      zg =  xl[i] * m[2]  +  yl[i] * m[5]  +  zl[i] * m[8] ;
      TPolyLine3D::SetPoint(i,xg,yg,zg);
   }

   delete[] xl;  delete[] yl;    delete[] zl;
}


//______________________________________________________________________________
void THelix::SetRange(Double_t r1, Double_t r2, EHelixRangeType rType)
{
   // Set range.

   Double_t range[2];
   range[0] = r1;       range[1] = r2;
   SetRange(range, rType);
}


////////////////////////////////////////////////////////////////////////////////
//                                                                            //
//                   Protected     Member     Functions                       //
//                                                                            //
////////////////////////////////////////////////////////////////////////////////


//______________________________________________________________________________
void THelix::SetRotMatrix()
{
   // Set the rotational matrix according to the helix axis.

   // Calculate all 6 angles.
   // Note that TRotMatrix::TRotMatrix() expects angles in degrees.
   Double_t raddeg = 180.0 / TMath::Pi();
   Double_t halfpi = TMath::Pi()/2.0 * raddeg;
                                 // (theta3,phi3) is the helix axis
   Double_t theta3 = TMath::ACos(fAxis[2]) * raddeg;
   Double_t phi3   = TMath::ATan2(fAxis[1], fAxis[0]) * raddeg;
                                 //  (theta1,phi1) is the x-axis in helix frame
   Double_t theta1 = theta3 + halfpi;
   Double_t phi1   = phi3;
                                 //  (theta2,phi2) is the y-axis in helix frame
   Double_t theta2 = halfpi;
   Double_t phi2   = phi1 + halfpi;

   // Delete the old rotation matrix
   if (fRotMat) delete fRotMat;

   // Make a new rotation matrix
   fRotMat = new TRotMatrix("HelixRotMat", "Master frame -> Helix frame",
                            theta1, phi1,  theta2, phi2,  theta3, phi3 );
   return;
}


//______________________________________________________________________________
Double_t  THelix::FindClosestPhase(Double_t phi0,  Double_t cosine)
{
   // Finds the closest phase to phi0 that gives cos(phase) = cosine

   const Double_t pi    = TMath::Pi();
   const Double_t twopi = TMath::Pi() * 2.0;
   Double_t phi1 = TMath::ACos(cosine);
   Double_t phi2 = - phi1;

   while ( phi1 - phi0 >  pi )   phi1 -= twopi;
   while ( phi1 - phi0 < -pi )   phi1 += twopi;

   while ( phi2 - phi0 >  pi )   phi2 -= twopi;
   while ( phi2 - phi0 < -pi )   phi2 += twopi;

   // Now phi1, phi2 and phi0 are within the same 2pi range
   // and cos(phi1) = cos(phi2) = cosine
   if ( TMath::Abs(phi1-phi0) < TMath::Abs(phi2-phi0) )  return phi1;
   else                                                  return phi2;
}


//______________________________________________________________________________
void THelix::Streamer(TBuffer &R__b)
{
   // Stream an object of class THelix.

   if (R__b.IsReading()) {
      UInt_t R__s, R__c;
      Version_t R__v = R__b.ReadVersion(&R__s, &R__c); if (R__v) { }
      if (R__v > 1) {
         R__b.ReadClassBuffer(THelix::Class(), this, R__v, R__s, R__c);
         return;
      }
      //====process old versions before automatic schema evolution
      TPolyLine3D::Streamer(R__b);
      R__b >> fX0;
      R__b >> fY0;
      R__b >> fZ0;
      R__b >> fVt;
      R__b >> fPhi0;
      R__b >> fVz;
      R__b >> fW;
      R__b.ReadStaticArray(fAxis);
      R__b >> fRotMat;
      R__b.ReadStaticArray(fRange);
      R__b.CheckByteCount(R__s, R__c, THelix::IsA());
      //====end of old versions

   } else {
      R__b.WriteClassBuffer(THelix::Class(),this);
   }
}
 THelix.cxx:1
 THelix.cxx:2
 THelix.cxx:3
 THelix.cxx:4
 THelix.cxx:5
 THelix.cxx:6
 THelix.cxx:7
 THelix.cxx:8
 THelix.cxx:9
 THelix.cxx:10
 THelix.cxx:11
 THelix.cxx:12
 THelix.cxx:13
 THelix.cxx:14
 THelix.cxx:15
 THelix.cxx:16
 THelix.cxx:17
 THelix.cxx:18
 THelix.cxx:19
 THelix.cxx:20
 THelix.cxx:21
 THelix.cxx:22
 THelix.cxx:23
 THelix.cxx:24
 THelix.cxx:25
 THelix.cxx:26
 THelix.cxx:27
 THelix.cxx:28
 THelix.cxx:29
 THelix.cxx:30
 THelix.cxx:31
 THelix.cxx:32
 THelix.cxx:33
 THelix.cxx:34
 THelix.cxx:35
 THelix.cxx:36
 THelix.cxx:37
 THelix.cxx:38
 THelix.cxx:39
 THelix.cxx:40
 THelix.cxx:41
 THelix.cxx:42
 THelix.cxx:43
 THelix.cxx:44
 THelix.cxx:45
 THelix.cxx:46
 THelix.cxx:47
 THelix.cxx:48
 THelix.cxx:49
 THelix.cxx:50
 THelix.cxx:51
 THelix.cxx:52
 THelix.cxx:53
 THelix.cxx:54
 THelix.cxx:55
 THelix.cxx:56
 THelix.cxx:57
 THelix.cxx:58
 THelix.cxx:59
 THelix.cxx:60
 THelix.cxx:61
 THelix.cxx:62
 THelix.cxx:63
 THelix.cxx:64
 THelix.cxx:65
 THelix.cxx:66
 THelix.cxx:67
 THelix.cxx:68
 THelix.cxx:69
 THelix.cxx:70
 THelix.cxx:71
 THelix.cxx:72
 THelix.cxx:73
 THelix.cxx:74
 THelix.cxx:75
 THelix.cxx:76
 THelix.cxx:77
 THelix.cxx:78
 THelix.cxx:79
 THelix.cxx:80
 THelix.cxx:81
 THelix.cxx:82
 THelix.cxx:83
 THelix.cxx:84
 THelix.cxx:85
 THelix.cxx:86
 THelix.cxx:87
 THelix.cxx:88
 THelix.cxx:89
 THelix.cxx:90
 THelix.cxx:91
 THelix.cxx:92
 THelix.cxx:93
 THelix.cxx:94
 THelix.cxx:95
 THelix.cxx:96
 THelix.cxx:97
 THelix.cxx:98
 THelix.cxx:99
 THelix.cxx:100
 THelix.cxx:101
 THelix.cxx:102
 THelix.cxx:103
 THelix.cxx:104
 THelix.cxx:105
 THelix.cxx:106
 THelix.cxx:107
 THelix.cxx:108
 THelix.cxx:109
 THelix.cxx:110
 THelix.cxx:111
 THelix.cxx:112
 THelix.cxx:113
 THelix.cxx:114
 THelix.cxx:115
 THelix.cxx:116
 THelix.cxx:117
 THelix.cxx:118
 THelix.cxx:119
 THelix.cxx:120
 THelix.cxx:121
 THelix.cxx:122
 THelix.cxx:123
 THelix.cxx:124
 THelix.cxx:125
 THelix.cxx:126
 THelix.cxx:127
 THelix.cxx:128
 THelix.cxx:129
 THelix.cxx:130
 THelix.cxx:131
 THelix.cxx:132
 THelix.cxx:133
 THelix.cxx:134
 THelix.cxx:135
 THelix.cxx:136
 THelix.cxx:137
 THelix.cxx:138
 THelix.cxx:139
 THelix.cxx:140
 THelix.cxx:141
 THelix.cxx:142
 THelix.cxx:143
 THelix.cxx:144
 THelix.cxx:145
 THelix.cxx:146
 THelix.cxx:147
 THelix.cxx:148
 THelix.cxx:149
 THelix.cxx:150
 THelix.cxx:151
 THelix.cxx:152
 THelix.cxx:153
 THelix.cxx:154
 THelix.cxx:155
 THelix.cxx:156
 THelix.cxx:157
 THelix.cxx:158
 THelix.cxx:159
 THelix.cxx:160
 THelix.cxx:161
 THelix.cxx:162
 THelix.cxx:163
 THelix.cxx:164
 THelix.cxx:165
 THelix.cxx:166
 THelix.cxx:167
 THelix.cxx:168
 THelix.cxx:169
 THelix.cxx:170
 THelix.cxx:171
 THelix.cxx:172
 THelix.cxx:173
 THelix.cxx:174
 THelix.cxx:175
 THelix.cxx:176
 THelix.cxx:177
 THelix.cxx:178
 THelix.cxx:179
 THelix.cxx:180
 THelix.cxx:181
 THelix.cxx:182
 THelix.cxx:183
 THelix.cxx:184
 THelix.cxx:185
 THelix.cxx:186
 THelix.cxx:187
 THelix.cxx:188
 THelix.cxx:189
 THelix.cxx:190
 THelix.cxx:191
 THelix.cxx:192
 THelix.cxx:193
 THelix.cxx:194
 THelix.cxx:195
 THelix.cxx:196
 THelix.cxx:197
 THelix.cxx:198
 THelix.cxx:199
 THelix.cxx:200
 THelix.cxx:201
 THelix.cxx:202
 THelix.cxx:203
 THelix.cxx:204
 THelix.cxx:205
 THelix.cxx:206
 THelix.cxx:207
 THelix.cxx:208
 THelix.cxx:209
 THelix.cxx:210
 THelix.cxx:211
 THelix.cxx:212
 THelix.cxx:213
 THelix.cxx:214
 THelix.cxx:215
 THelix.cxx:216
 THelix.cxx:217
 THelix.cxx:218
 THelix.cxx:219
 THelix.cxx:220
 THelix.cxx:221
 THelix.cxx:222
 THelix.cxx:223
 THelix.cxx:224
 THelix.cxx:225
 THelix.cxx:226
 THelix.cxx:227
 THelix.cxx:228
 THelix.cxx:229
 THelix.cxx:230
 THelix.cxx:231
 THelix.cxx:232
 THelix.cxx:233
 THelix.cxx:234
 THelix.cxx:235
 THelix.cxx:236
 THelix.cxx:237
 THelix.cxx:238
 THelix.cxx:239
 THelix.cxx:240
 THelix.cxx:241
 THelix.cxx:242
 THelix.cxx:243
 THelix.cxx:244
 THelix.cxx:245
 THelix.cxx:246
 THelix.cxx:247
 THelix.cxx:248
 THelix.cxx:249
 THelix.cxx:250
 THelix.cxx:251
 THelix.cxx:252
 THelix.cxx:253
 THelix.cxx:254
 THelix.cxx:255
 THelix.cxx:256
 THelix.cxx:257
 THelix.cxx:258
 THelix.cxx:259
 THelix.cxx:260
 THelix.cxx:261
 THelix.cxx:262
 THelix.cxx:263
 THelix.cxx:264
 THelix.cxx:265
 THelix.cxx:266
 THelix.cxx:267
 THelix.cxx:268
 THelix.cxx:269
 THelix.cxx:270
 THelix.cxx:271
 THelix.cxx:272
 THelix.cxx:273
 THelix.cxx:274
 THelix.cxx:275
 THelix.cxx:276
 THelix.cxx:277
 THelix.cxx:278
 THelix.cxx:279
 THelix.cxx:280
 THelix.cxx:281
 THelix.cxx:282
 THelix.cxx:283
 THelix.cxx:284
 THelix.cxx:285
 THelix.cxx:286
 THelix.cxx:287
 THelix.cxx:288
 THelix.cxx:289
 THelix.cxx:290
 THelix.cxx:291
 THelix.cxx:292
 THelix.cxx:293
 THelix.cxx:294
 THelix.cxx:295
 THelix.cxx:296
 THelix.cxx:297
 THelix.cxx:298
 THelix.cxx:299
 THelix.cxx:300
 THelix.cxx:301
 THelix.cxx:302
 THelix.cxx:303
 THelix.cxx:304
 THelix.cxx:305
 THelix.cxx:306
 THelix.cxx:307
 THelix.cxx:308
 THelix.cxx:309
 THelix.cxx:310
 THelix.cxx:311
 THelix.cxx:312
 THelix.cxx:313
 THelix.cxx:314
 THelix.cxx:315
 THelix.cxx:316
 THelix.cxx:317
 THelix.cxx:318
 THelix.cxx:319
 THelix.cxx:320
 THelix.cxx:321
 THelix.cxx:322
 THelix.cxx:323
 THelix.cxx:324
 THelix.cxx:325
 THelix.cxx:326
 THelix.cxx:327
 THelix.cxx:328
 THelix.cxx:329
 THelix.cxx:330
 THelix.cxx:331
 THelix.cxx:332
 THelix.cxx:333
 THelix.cxx:334
 THelix.cxx:335
 THelix.cxx:336
 THelix.cxx:337
 THelix.cxx:338
 THelix.cxx:339
 THelix.cxx:340
 THelix.cxx:341
 THelix.cxx:342
 THelix.cxx:343
 THelix.cxx:344
 THelix.cxx:345
 THelix.cxx:346
 THelix.cxx:347
 THelix.cxx:348
 THelix.cxx:349
 THelix.cxx:350
 THelix.cxx:351
 THelix.cxx:352
 THelix.cxx:353
 THelix.cxx:354
 THelix.cxx:355
 THelix.cxx:356
 THelix.cxx:357
 THelix.cxx:358
 THelix.cxx:359
 THelix.cxx:360
 THelix.cxx:361
 THelix.cxx:362
 THelix.cxx:363
 THelix.cxx:364
 THelix.cxx:365
 THelix.cxx:366
 THelix.cxx:367
 THelix.cxx:368
 THelix.cxx:369
 THelix.cxx:370
 THelix.cxx:371
 THelix.cxx:372
 THelix.cxx:373
 THelix.cxx:374
 THelix.cxx:375
 THelix.cxx:376
 THelix.cxx:377
 THelix.cxx:378
 THelix.cxx:379
 THelix.cxx:380
 THelix.cxx:381
 THelix.cxx:382
 THelix.cxx:383
 THelix.cxx:384
 THelix.cxx:385
 THelix.cxx:386
 THelix.cxx:387
 THelix.cxx:388
 THelix.cxx:389
 THelix.cxx:390
 THelix.cxx:391
 THelix.cxx:392
 THelix.cxx:393
 THelix.cxx:394
 THelix.cxx:395
 THelix.cxx:396
 THelix.cxx:397
 THelix.cxx:398
 THelix.cxx:399
 THelix.cxx:400
 THelix.cxx:401
 THelix.cxx:402
 THelix.cxx:403
 THelix.cxx:404
 THelix.cxx:405
 THelix.cxx:406
 THelix.cxx:407
 THelix.cxx:408
 THelix.cxx:409
 THelix.cxx:410
 THelix.cxx:411
 THelix.cxx:412
 THelix.cxx:413
 THelix.cxx:414
 THelix.cxx:415
 THelix.cxx:416
 THelix.cxx:417
 THelix.cxx:418
 THelix.cxx:419
 THelix.cxx:420
 THelix.cxx:421
 THelix.cxx:422
 THelix.cxx:423
 THelix.cxx:424
 THelix.cxx:425
 THelix.cxx:426
 THelix.cxx:427
 THelix.cxx:428
 THelix.cxx:429
 THelix.cxx:430
 THelix.cxx:431
 THelix.cxx:432
 THelix.cxx:433
 THelix.cxx:434
 THelix.cxx:435
 THelix.cxx:436
 THelix.cxx:437
 THelix.cxx:438
 THelix.cxx:439
 THelix.cxx:440
 THelix.cxx:441
 THelix.cxx:442
 THelix.cxx:443
 THelix.cxx:444
 THelix.cxx:445
 THelix.cxx:446
 THelix.cxx:447
 THelix.cxx:448
 THelix.cxx:449
 THelix.cxx:450
 THelix.cxx:451
 THelix.cxx:452
 THelix.cxx:453
 THelix.cxx:454
 THelix.cxx:455
 THelix.cxx:456
 THelix.cxx:457
 THelix.cxx:458
 THelix.cxx:459
 THelix.cxx:460
 THelix.cxx:461
 THelix.cxx:462
 THelix.cxx:463
 THelix.cxx:464
 THelix.cxx:465
 THelix.cxx:466
 THelix.cxx:467
 THelix.cxx:468
 THelix.cxx:469
 THelix.cxx:470
 THelix.cxx:471
 THelix.cxx:472
 THelix.cxx:473
 THelix.cxx:474
 THelix.cxx:475
 THelix.cxx:476
 THelix.cxx:477
 THelix.cxx:478
 THelix.cxx:479
 THelix.cxx:480
 THelix.cxx:481
 THelix.cxx:482
 THelix.cxx:483
 THelix.cxx:484
 THelix.cxx:485
 THelix.cxx:486
 THelix.cxx:487
 THelix.cxx:488
 THelix.cxx:489
 THelix.cxx:490
 THelix.cxx:491
 THelix.cxx:492
 THelix.cxx:493
 THelix.cxx:494
 THelix.cxx:495
 THelix.cxx:496
 THelix.cxx:497
 THelix.cxx:498
 THelix.cxx:499
 THelix.cxx:500
 THelix.cxx:501
 THelix.cxx:502
 THelix.cxx:503
 THelix.cxx:504
 THelix.cxx:505
 THelix.cxx:506
 THelix.cxx:507
 THelix.cxx:508
 THelix.cxx:509
 THelix.cxx:510
 THelix.cxx:511
 THelix.cxx:512
 THelix.cxx:513
 THelix.cxx:514
 THelix.cxx:515
 THelix.cxx:516
 THelix.cxx:517
 THelix.cxx:518
 THelix.cxx:519
 THelix.cxx:520
 THelix.cxx:521
 THelix.cxx:522
 THelix.cxx:523
 THelix.cxx:524
 THelix.cxx:525
 THelix.cxx:526
 THelix.cxx:527
 THelix.cxx:528
 THelix.cxx:529
 THelix.cxx:530
 THelix.cxx:531
 THelix.cxx:532
 THelix.cxx:533
 THelix.cxx:534
 THelix.cxx:535
 THelix.cxx:536
 THelix.cxx:537
 THelix.cxx:538
 THelix.cxx:539
 THelix.cxx:540
 THelix.cxx:541
 THelix.cxx:542
 THelix.cxx:543
 THelix.cxx:544
 THelix.cxx:545
 THelix.cxx:546
 THelix.cxx:547
 THelix.cxx:548
 THelix.cxx:549
 THelix.cxx:550
 THelix.cxx:551
 THelix.cxx:552
 THelix.cxx:553
 THelix.cxx:554
 THelix.cxx:555
 THelix.cxx:556
 THelix.cxx:557
 THelix.cxx:558
 THelix.cxx:559
 THelix.cxx:560
 THelix.cxx:561
 THelix.cxx:562
 THelix.cxx:563
 THelix.cxx:564
 THelix.cxx:565
 THelix.cxx:566
 THelix.cxx:567
 THelix.cxx:568
 THelix.cxx:569
 THelix.cxx:570
 THelix.cxx:571
 THelix.cxx:572
 THelix.cxx:573
 THelix.cxx:574
 THelix.cxx:575
 THelix.cxx:576
 THelix.cxx:577
 THelix.cxx:578
 THelix.cxx:579
 THelix.cxx:580
 THelix.cxx:581
 THelix.cxx:582
 THelix.cxx:583
 THelix.cxx:584
 THelix.cxx:585
 THelix.cxx:586
 THelix.cxx:587
 THelix.cxx:588
 THelix.cxx:589
 THelix.cxx:590
 THelix.cxx:591
 THelix.cxx:592
 THelix.cxx:593
 THelix.cxx:594
 THelix.cxx:595
 THelix.cxx:596
 THelix.cxx:597
 THelix.cxx:598
 THelix.cxx:599
 THelix.cxx:600
 THelix.cxx:601
 THelix.cxx:602
 THelix.cxx:603
 THelix.cxx:604
 THelix.cxx:605
 THelix.cxx:606
 THelix.cxx:607
 THelix.cxx:608
 THelix.cxx:609
 THelix.cxx:610
 THelix.cxx:611
 THelix.cxx:612
 THelix.cxx:613
 THelix.cxx:614
 THelix.cxx:615
 THelix.cxx:616
 THelix.cxx:617
 THelix.cxx:618
 THelix.cxx:619
 THelix.cxx:620
 THelix.cxx:621
 THelix.cxx:622
 THelix.cxx:623
 THelix.cxx:624
 THelix.cxx:625
 THelix.cxx:626
 THelix.cxx:627
 THelix.cxx:628
 THelix.cxx:629
 THelix.cxx:630
 THelix.cxx:631
 THelix.cxx:632
 THelix.cxx:633
 THelix.cxx:634
 THelix.cxx:635
 THelix.cxx:636
 THelix.cxx:637
 THelix.cxx:638
 THelix.cxx:639
 THelix.cxx:640
 THelix.cxx:641
 THelix.cxx:642
 THelix.cxx:643
 THelix.cxx:644
 THelix.cxx:645