PremModel.cxx
//......................................................................
///
/// Fill the path sequence in a vector.
///
/// This will start at the upper-most layer and find straight paths
/// to the boundary of the next layer down. When reaching the inner-most
/// layer in the given direction, the paths move back to outer layers
/// until hitting the detector.
///
/// The path sequence is stored as an attribute and can be retrieved with
/// the function GetNuPath.
///
/// @param cosT - The cosine of the neutrino direction
/// @return The number of path segments in the sequence
///
Fill the path sequence in a vector.

This will start at the upper-most layer and find straight paths
to the boundary of the next layer down. When reaching the inner-most
layer in the given direction, the paths move back to outer layers
until hitting the detector.

The path sequence is stored as an attribute and can be retrieved with
the function GetNuPath.
Fill the path sequence in a vector . This will start at the upper - most layer and find straight paths to the boundary of the next layer down . When reaching the inner - most layer in the given direction the paths move back to outer layers until hitting the detector . The path sequence is stored as an attribute and can be retrieved with the function GetNuPath .
int PremModel::FillPath(double cosT)
{
  fNuPath.clear();
  if(fabs(cosT) > 1) return 0;
  double minR = fPremLayers[fDetLayer].radius * sqrt(1 - cosT*cosT);
  int toplayer = fPremLayers.size() - 1;
  int minlayer = 0;
  while(fPremLayers[minlayer].radius < minR) minlayer++;
  int nsteps = toplayer - fDetLayer;
  if(cosT < 0) nsteps += 2*(fDetLayer - minlayer) + 1;
  int layer = toplayer;
  int dl = -1;
  for(int i=0; i<nsteps; i++){
    double L1 = pow(fPremLayers[layer].radius,2) - minR*minR;
    if(L1 < 0) return true;
    double L2 = -minR*minR;
    if(layer>0) L2 += pow(fPremLayers[layer-1].radius,2);
    bool ismin = (L2<=0 && cosT < 0);
    double dL;
    if(ismin)      dL = 2 * sqrt(L1);
    else if(L2>=0) dL = sqrt(L1) - sqrt(L2);
    else           dL = sqrt(L1); 
    AddPath(dL, fPremLayers[layer]);
    if(ismin) dl = 1;
    layer += dl;
  }
  return fNuPath.size();
}
int PremModel :: FillPath ( double cosT ) { fNuPath . clear ( ) ; if ( fabs ( cosT ) > 1 ) return 0 ; double minR = fPremLayers [ fDetLayer ] . radius * sqrt ( 1 - cosT * cosT ) ; int toplayer = fPremLayers . size ( ) - 1 ; int minlayer = 0 ; while ( fPremLayers [ minlayer ] . radius < minR ) minlayer ++ ; int nsteps = toplayer - fDetLayer ; if ( cosT < 0 ) nsteps += 2 * ( fDetLayer - minlayer ) + 1 ; int layer = toplayer ; int dl = -1 ; for ( int i = 0 ; i < nsteps ; i ++ ) { double L1 = pow ( fPremLayers [ layer ] . radius , 2 ) - minR * minR ; if ( L1 < 0 ) return true ; double L2 = - minR * minR ; if ( layer > 0 ) L2 += pow ( fPremLayers [ layer - 1 ] . radius , 2 ) ; bool ismin = ( L2 <= 0 && cosT < 0 ) ; double dL ; if ( ismin ) dL = 2 * sqrt ( L1 ) ; else if ( L2 >= 0 ) dL = sqrt ( L1 ) - sqrt ( L2 ) ; else dL = sqrt ( L1 ) ; AddPath ( dL , fPremLayers [ layer ] ) ; if ( ismin ) dl = 1 ; layer += dl ; } return fNuPath . size ( ) ; }
......................................................................
......................................................................
// Clear current path sequence // Do nothing if cosine is unphysical // Define the minimum path radius // Set the top layer index // Find the inner-most crossed layer // Compute the number of path segments needed // Start at the top layer and go down // Loop over all path segments // Get square of the path length between this layer's // outer radius and  inner-most radius // If L1 is negative, outer radius is not crossed. // This only happens if detector is at the top layer and the // neutrino is coming from above. // Get square of the path length between this layer's // inner radius and  inner-most radius // If L2 is negative, inner radius is not crossed, // so set this as the minimum layer. // Store the path segment length // If it's the minimum layer, connect two outer radius // crossing points. If not, compute difference between // inner and outer radius crossings. // This should never actually happen, // but protect in case L2 is slightly // negative when it should be zero. // e.g. arriving at the detector from above. // Add this path segment to the sequence // If we reached the inner-most layer, // start moving up again. // Move to next layer // Return the number of path segments