__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"; } }
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; }