__attribute__((noinline)) void benchmarkROOTNavigator(SOA3D<Precision> const &points, SOA3D<Precision> const &dirs)
{

  TGeoNavigator *rootnav      = ::gGeoManager->GetCurrentNavigator();
  auto nPoints                = points.size();
  TGeoBranchArray **instates  = new TGeoBranchArray *[nPoints];
  TGeoBranchArray **outstates = new TGeoBranchArray *[nPoints];
  Precision *steps            = new Precision[points.size()];
  Precision *safeties;
  if (WithSafety) {
    safeties = new Precision[points.size()];
  }
  // we don't have the input state container in ROOT form
  // we generate them but do not take this into account for the timing measurement
  for (size_t i = 0; i < nPoints; ++i) {
    Vector3D<Precision> const &pos = points[i];
    rootnav->ResetState();
    rootnav->FindNode(pos.x(), pos.y(), pos.z());
    instates[i]  = TGeoBranchArray::MakeInstance(GeoManager::Instance().getMaxDepth());
    outstates[i] = TGeoBranchArray::MakeInstance(GeoManager::Instance().getMaxDepth());
    instates[i]->InitFromNavigator(rootnav);
  }
#ifdef CALLGRIND_ENABLED
  CALLGRIND_START_INSTRUMENTATION;
#endif
  Stopwatch timer;
  timer.Start();
  for (size_t i = 0; i < nPoints; ++i) {
    Vector3D<Precision> const &pos = points[i];
    Vector3D<Precision> const &dir = dirs[i];
    rootnav->ResetState();
    instates[i]->UpdateNavigator(rootnav);

    rootnav->SetCurrentPoint(pos.x(), pos.y(), pos.z());
    rootnav->SetCurrentDirection(dir.x(), dir.y(), dir.z());
    if (WithSafety) {
      safeties[i] = rootnav->Safety(true);
    }
    if (WithReloc) {
      volatile TGeoNode *node = rootnav->FindNextBoundaryAndStep(kInfLength);
      (void)node;
    } else {
      volatile TGeoNode *node = rootnav->FindNextBoundary(kInfLength);
      (void)node;
    }
    steps[i] = rootnav->GetStep();
    if (WithReloc) {
      // save output states ( for fair comparison with VecGeom )
      outstates[i]->InitFromNavigator(rootnav);
    }
  }
  timer.Stop();
#ifdef CALLGRIND_ENABLED
  CALLGRIND_STOP_INSTRUMENTATION;
  CALLGRIND_DUMP_STATS;
#endif
  std::cerr << timer.Elapsed() << "\n";
  double accum(0.);
  double saccum(0.);
  size_t hittargetchecksum = 0L;
  for (decltype(points.size()) i = 0; i < points.size(); ++i) {
    accum += steps[i];
    if (WithSafety) {
      saccum += safeties[i];
    }
    // target checksum via the table held from RootGeoManager
    hittargetchecksum +=
        (size_t)RootGeoManager::Instance().Lookup(outstates[i]->GetNode(outstates[i]->GetLevel()))->id();
  }
  delete[] steps;
  if (WithSafety) {
    delete safeties;
  }

  // cleanup states
  for (decltype(points.size()) i = 0; i < points.size(); ++i) {
    delete instates[i];
    delete outstates[i];
  }
  delete[] instates;
  delete[] outstates;

  std::cerr << "accum  TGeo " << accum << " target checksum " << hittargetchecksum << "\n";
  if (WithSafety) {
    std::cerr << "safety accum  TGeo " << saccum << "\n";
  }
}
Esempio n. 2
0
void XRayWithROOT(int axis,
                 Vector3D<Precision> origin,
                 Vector3D<Precision> bbox,
                 Vector3D<Precision> dir,
                 double axis1_start, double axis1_end,
                 double axis2_start, double axis2_end,
                 int data_size_x,
                 int data_size_y,
                 double pixel_axis,
                 int * image) {

    int counter=0;

    // set start point of geantino
    Vector3D<Precision> p(0.,0.,0);

    TGeoNavigator * nav = gGeoManager->GetCurrentNavigator();
    nav->SetCurrentPoint( p.x(), p.y(), p.z() );
    nav->SetCurrentDirection( dir.x(), dir.y(), dir.z() );

    double distancetravelled=0.;
    int crossedvolumecount=0;

    if(VERBOSE) {
       std::cout << " StartPoint(" << p[0] << ", " << p[1] << ", " << p[2] << ")";
       std::cout << " Direction <" << dir[0] << ", " << dir[1] << ", " << dir[2] << ">"<< std::endl;
    }

    // propagate until we leave detector
    TGeoNode const * node = nav->FindNode();

    std::cout << "INITIAL MAT :" <<  node->GetVolume()->GetMaterial()->GetName() << "\n";

    //  if( node ) std::cout <<    node->GetVolume()->GetName() << "\t";
    while( node !=NULL ) {
       node = nav->FindNextBoundaryAndStep( vecgeom::kInfinity );
       distancetravelled+=nav->GetStep();
       counter++;

       if(VERBOSE) {
          if( node != NULL )
              std::cout << " *R " << counter << " * " << " point(" << p[0] << ", " << p[1] << ", " << p[2] << ") goes to " << " VolumeName: "<< node->GetVolume()->GetName()
              << " (MAT: " << node->GetVolume()->GetMaterial()->GetName() << ") :";
          else
              std::cout << "  NULL: ";

          std::cout << " step[" << nav->GetStep()<< "]"<< std::endl;
          double const * pROOT = nav->GetCurrentPoint();
          p = Vector3D<Precision>(pROOT[0],pROOT[1],pROOT[2]);
       }
       // Increase passed_volume
       // TODO: correct counting of travel in "world" bounding box
       crossedvolumecount++;
   } // end while
   // std::cout << crossedvolumecount << "\n";

    if(VERBOSE) {
        std::cout << " PassedVolume:" << "<"<< crossedvolumecount << " ";
        std::cout << " total distance travelled: " << distancetravelled<< std::endl;
    }
} // end XRayWithROOT
void XRayWithROOT(int axis,
                 Vector3D<Precision> origin,
                 Vector3D<Precision> bbox,
                 Vector3D<Precision> dir,
                 double axis1_start, double axis1_end,
                 double axis2_start, double axis2_end,
                 int data_size_x,
                 int data_size_y,
                 double pixel_axis,
                 int * image) {

if(VERBOSE){
    std::cout << "from [" << axis1_start << ";" << axis2_start
              << "] to [" << axis1_end   << ";" << axis2_end << "]\n";
    std::cout << "Xpixels " << data_size_x << " YPixels " << data_size_y << "\n";

    std::cout << pixel_axis << "\n";
}

double pixel_width_1 = (axis1_end-axis1_start)/data_size_x;
double pixel_width_2 = (axis2_end-axis2_start)/data_size_y;

    if(VERBOSE){
    std::cout << pixel_width_1 << "\n";
    std::cout << pixel_width_2 << "\n";
    }

    for( int pixel_count_2 = 0; pixel_count_2 < data_size_y; ++pixel_count_2 ){
        for( int pixel_count_1 = 0; pixel_count_1 < data_size_x; ++pixel_count_1 )
        {
            double axis1_count = axis1_start + pixel_count_1 * pixel_width_1 + 1E-6;
            double axis2_count = axis2_start + pixel_count_2 * pixel_width_2 + 1E-6;

            if(VERBOSE) {
                std::cout << "\n OutputPoint("<< axis1_count<< ", "<< axis2_count<< ")\n";
            }
            // set start point of XRay
            Vector3D<Precision> p;

            if( axis== 1 )
              p.Set( origin[0]-bbox[0], axis1_count, axis2_count);
            else if( axis== 2)
              p.Set( axis1_count, origin[1]-bbox[1], axis2_count);
            else if( axis== 3)
              p.Set( axis1_count, axis2_count, origin[2]-bbox[2]);

            TGeoNavigator * nav = gGeoManager->GetCurrentNavigator();
            nav->SetCurrentPoint( p.x(), p.y(), p.z() );
            nav->SetCurrentDirection( dir.x(), dir.y(), dir.z() );

            double distancetravelled=0.;
            int crossedvolumecount=0;
            double accumulateddensity =0.;

            if(VERBOSE) {
              std::cout << " StartPoint(" << p[0] << ", " << p[1] << ", " << p[2] << ")";
              std::cout << " Direction <" << dir[0] << ", " << dir[1] << ", " << dir[2] << ">"<< std::endl;
            }

            // propagate until we leave detector
            TGeoNode const * node = nav->FindNode();
            TGeoMaterial const * curmat = node->GetVolume()->GetMaterial();

          //  std::cout << pixel_count_1 << " " << pixel_count_2 << " " << dir << "\t" << p << "\t";
          //  std::cout << "IN|OUT" << nav->IsOutside() << "\n";
          //  if( node ) std::cout <<    node->GetVolume()->GetName() << "\t";
            while( node !=NULL ) {
                node = nav->FindNextBoundaryAndStep( vecgeom::kInfinity );
                distancetravelled+=nav->GetStep();
                accumulateddensity+=curmat->GetDensity() * distancetravelled;

                if(VERBOSE) {
                    if( node != NULL ){
                        std::cout << "  VolumeName: "<< node->GetVolume()->GetName();
                    }
                    else
                       std::cout << "  NULL: ";

                    std::cout << " step[" << nav->GetStep()<< "]"<< std::endl;
                    double const * pROOT = nav->GetCurrentPoint();
                    p = Vector3D<Precision>(pROOT[0],pROOT[1],pROOT[2]);
                    std::cout << " point(" << p[0] << ", " << p[1] << ", " << p[2] << ")";
                }
                // Increase passed_volume
                // TODO: correct counting of travel in "world" bounding box
                crossedvolumecount++;
                curmat = (node!=0) ? node->GetVolume()->GetMaterial() : 0;
            } // end while
            // std::cout << crossedvolumecount << "\n";

            ///////////////////////////////////
            // Store the number of passed volume at 'volume_result'
            *(image+pixel_count_2*data_size_x+pixel_count_1) = crossedvolumecount;// accumulateddensity ;// crossedvolumecount;

            if(VERBOSE) {
                std::cout << "  EndOfBoundingBox:";
                std::cout << " PassedVolume:" << "<"<< crossedvolumecount << " ";
                std::cout << " step[" << nav->GetStep()<< "]";
                std::cout << " Distance: " << distancetravelled<< std::endl;
            }
      } // end inner loop
    } // end outer loop
} // end XRayWithROOT
int main(int argc, char * argv[])
{

   // generate benchmark cases
   TransformationMatrix const * identity = new TransformationMatrix(0,0,0,0,0,0);

   double L = 10.;
   double Lz = 10.;
   const double Sqrt2 = sqrt(2.);

   TGeoManager * geom = new TGeoManager("simple1", "ToyDetector");
   TGeoMaterial * matVacuum = new TGeoMaterial("Vacuum",0,0,0);

   TGeoMedium * vac = new TGeoMedium("Vacuum",1,matVacuum);
   TGeoVolume * world = geom->MakeBox("world", vac, L, L, Lz  );

   geom->SetTopVolume( world );

   TGeoVolume * boxlevel2 = geom->MakeBox( "boxlevel2", vac, Sqrt2*L/2./2., Sqrt2*L/2./2.,Lz);
   TGeoVolume * boxlevel3 = geom->MakeBox( "boxlevel3", vac, L/2./2.,L/2./2.,Lz);
   TGeoVolume * boxlevel1 = geom->MakeBox( "boxlevel1", vac, L/2.,L/2., Lz);

   boxlevel2->AddNode( boxlevel3, 1, new TGeoRotation("mat1",0,0,-45));
   boxlevel1->AddNode( boxlevel2, 1, new TGeoRotation("mat2",0,0,45));
   world->AddNode( boxlevel1, 1, new TGeoTranslation("trans1",-L/2., 0,0 ) );
   world->AddNode( boxlevel1, 2, new TGeoTranslation("trans2",L/2., 0,0 ) );
   geom->CloseGeometry();
   delete world->GetVoxels();
   world->SetVoxelFinder(0);

    // perform basic tests
   TGeoNavigator * nav = geom->GetCurrentNavigator(); // new TGeoNavigator(geom);
   StopWatch timer;

   timer.Start();
   int stepsdone=0;
   for(int n=0;n<1000;n++)
     {
   for(int i=0;i<100000;i++)
   // testing the NavigationAndStepInterface
   {
      int localstepsdone=0;
      double distancetravelled=0.;
      Vector3D p;
      PhysicalVolume::samplePoint( p, L, L, Lz, 1. );

      //std::cerr << p << std::endl;
      //setup point in world
      Vector3D d(1,0,0);

      TGeoNode const * vol;
      nav->SetCurrentPoint( p.x, p.y, p.z );
      nav->SetCurrentDirection( d.x, d.y, d.z);
      vol=nav->FindNode(p.x,p.y,p.z);

      while( vol!=NULL )
      {
         localstepsdone++;

         // do one step ( this will internally adjust the current point and so on )
         vol = nav->FindNextBoundaryAndStep(Utils::kInfinity);

         distancetravelled+=nav->GetStep();
         //double const * p = nav->GetCurrentPoint();
         //double const * pl = nav->GetLastPoint();
         //double const * cd = nav->GetCurrentDirection();

         //std::cerr << " proposed step: " << nav->GetStep();
         //std::cerr << " current point " << p[0] << " " << p[1] << " " << p[2] << std::endl;
         //std::cerr << " last point " << pl[0] << " " << pl[1] << " " << pl[2] << std::endl;
         //std::cerr << " current dir " << cd[0] << " " << cd[1] << " " << cd[2] << std::endl;
      }
   //   std::cerr << localstepsdone << " " << distancetravelled << std::endl;
      stepsdone+=localstepsdone;
   }
     }
   timer.Stop();
   std::cout << " time for 100000 particles " << timer.getDeltaSecs( ) << std::endl;
   std::cout << " average steps done " << stepsdone / 100000. << std::endl;
   std::cout << " time per step " << timer.getDeltaSecs()/stepsdone << std::endl;
}