Esempio n. 1
0
int main()
{
   Vectors3DSOA points, dirs, intermediatepoints, intermediatedirs;
   StructOfCoord rpoints, rintermediatepoints, rdirs, rintermediatedirs;


   int np=1024;
   int NREPS = 1000;

   points.alloc(np);
   dirs.alloc(np);

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

   // the world volume is a tube
   double worlddx = 100.;
   double worlddy = 100;
   double worlddz = 10.;
   BoxParameters *   worldp =  new BoxParameters(worlddx, worlddy, worlddz);
   PhysicalVolume * world = GeoManager::MakePlacedBox( worldp , identity );
   double volworld = worldp->GetVolume();


   BoxParameters * cellparams = new BoxParameters( worlddx/20., worlddy/20., worlddz/4 );
   BoxParameters * waiverparams = new BoxParameters( worlddx/3., worlddy/3., worlddz/2 );
   double volcell = cellparams->GetVolume();
   double volwaiver = waiverparams->GetVolume();

   PhysicalVolume *waiver = GeoManager::MakePlacedBox( waiverparams, identity);

   // this just adds daughters which have been created in a placed way
   waiver->AddDaughter(GeoManager::MakePlacedBox( cellparams, new TransformationMatrix( -waiverparams->GetDX()/2., waiverparams->GetDY()/2., 0, 0, 0, 0) ));
   waiver->AddDaughter(GeoManager::MakePlacedBox( cellparams, new TransformationMatrix( waiverparams->GetDX()/2., waiverparams->GetDY()/2., 0, 0, 0, 45) ));
   waiver->AddDaughter(GeoManager::MakePlacedBox( cellparams, new TransformationMatrix( waiverparams->GetDX()/2., -waiverparams->GetDY()/2., 0, 0, 0, 0) ));
   waiver->AddDaughter(GeoManager::MakePlacedBox( cellparams, new TransformationMatrix( -waiverparams->GetDX()/2., -waiverparams->GetDY()/2., 0, 0, 0, 45)));

   // at this moment the waiver is not yet placed into the world; this will be done now with the new interface
   // we are basically replacing the waiver by using its existing parameters and daughterlist
   // TODO: the future interface will hide much of the details here
   world->PlaceDaughter(GeoManager::MakePlacedBox(waiverparams, new TransformationMatrix( worlddx/2., worlddy/2., 0, 0, 0, 45 )), waiver->GetDaughterList());
   world->PlaceDaughter(GeoManager::MakePlacedBox(waiverparams, new TransformationMatrix( -worlddx/2., worlddy/2., 0, 0, 0, 0  )), waiver->GetDaughterList());
   world->PlaceDaughter(GeoManager::MakePlacedBox(waiverparams, new TransformationMatrix( -worlddx/2., -worlddy/2., 0, 0, 0, 45 )), waiver->GetDaughterList());
   world->PlaceDaughter(GeoManager::MakePlacedBox(waiverparams, new TransformationMatrix( worlddx/2., -worlddy/2., 0, 0, 0, 0 )), waiver->GetDaughterList());


   world->fillWithRandomPoints(points,np);
   world->fillWithBiasedDirections(points, dirs, np, 9/10.);

   std::cerr << " Number of daughters " << world->GetNumberOfDaughters() << std::endl;

   // try to locate a global point

   StopWatch timer;
   timer.Start();
   VolumePath path(4), newpath(4);
   std::map<PhysicalVolume const *, int> volcounter;
   int total=0;
   TransformationMatrix * globalm=new TransformationMatrix();
   TransformationMatrix * globalm2 = new TransformationMatrix();
   SimpleVecNavigator nav(1, world);
   Vector3D displacementvector( worlddx/20, 0., 0. );
   int counter[2]={0,0};
   for(int i=0;i<1000000;i++)
   {
      globalm->SetToIdentity();
      globalm2->SetToIdentity();
      Vector3D point;
      Vector3D localpoint;
      Vector3D newlocalpoint;
      Vector3D cmppoint;
      PhysicalVolume::samplePoint( point, worlddx, worlddy, worlddz, 1 );
      //   PhysicalVolume const * deepestnode = nav.LocateGlobalPoint( world, point, localpoint, path, globalm2 );
      localpoint.x = point.x;
      localpoint.y = point.y;
      localpoint.z = point.z;
      PhysicalVolume const * deepestnode = nav.LocateGlobalPoint( world, point, localpoint, path );
      /*
      if(volcounter.find(deepestnode) == volcounter.end())
        {
          volcounter[deepestnode]=1;
        }
      else
        {
          volcounter[deepestnode]++;
        }
      */

      // do the cross check

//      Vector3D localpoint;

      // check one thing
      localpoint.x = localpoint.x + displacementvector.x;
      localpoint.y = localpoint.y + displacementvector.y;
      localpoint.z = localpoint.z + displacementvector.z;
      PhysicalVolume const * newnode = nav.LocateLocalPointFromPath( localpoint, path, newpath, globalm2 );
      if( newnode == deepestnode )
      {
         counter[0]++;
      }
      else
      {
         counter[1]++;
      }


   //   path.GetGlobalMatrixFromPath(globalm);
    //   globalm->LocalToMaster(localpoint, cmppoint);
   //  std::cerr << " ######################## " << std::endl;
   //   point.print();
   //   globalm->print();
   //   cmppoint.print();
   //   std::cerr << " ------------------------ " << std::endl;

      /*
      std::cerr << " ######################## " << std::endl;
      globalm->print();
      std::cerr << " ;;;;;;; " << std::endl;
      globalm2->print();
      std::cerr << " ------------------- " << std::endl;

      //globalm2->MasterToLocal<1,-1>( point, localpoint );
      PhysicalVolume const * cmpnode = nav.LocateLocalPointFromPath( localpoint, path, newpath );

      //assert( cmpnode == deepestnode );

*/
      // path.Print();
      path.Clear();
      newpath.Clear();
      //      deepestnode->printInfo();
   }
   timer.Stop();
   std::cerr << " step took " << timer.getDeltaSecs() << " seconds " << std::endl;
   std::cerr << counter[0] << std::endl;
   std::cerr << counter[1] << std::endl;
   
   for(auto k=volcounter.begin();k!=volcounter.end();k++)
     {
       total+=k->second;
     }
   
   for(auto k=volcounter.begin();k!=volcounter.end();k++)
     {
       std::cerr << k->first << " " << k->second << " " << k->second/(1.*total) << std::endl; 
     }
   std::cerr << 4*volcell/volworld << std::endl;
   std::cerr << volwaiver/volworld << std::endl;
   std::cerr << (volworld-4*volwaiver)/volworld << std::endl;
}
int main()
{
	Vectors3DSOA points, dirs, intermediatepoints, intermediatedirs;
	StructOfCoord rpoints, rintermediatepoints, rdirs, rintermediatedirs;


	int np=1024;
	int NREPS = 1000;

	points.alloc(np);
	dirs.alloc(np);
	intermediatepoints.alloc(np);
	intermediatedirs.alloc(np);

	rpoints.alloc(np);
	rdirs.alloc(np);
	rintermediatepoints.alloc(np);
	rintermediatedirs.alloc(np);

	double *distances = (double *) _mm_malloc(np*sizeof(double), ALIGNMENT_BOUNDARY);
	double *distancesROOTSCALAR = (double *) _mm_malloc(np*sizeof(double), ALIGNMENT_BOUNDARY);
	double *distancesUSOLIDSCALAR = (double *) _mm_malloc(np*sizeof(double), ALIGNMENT_BOUNDARY);
	double *distances2 = (double *) _mm_malloc(np*sizeof(double), ALIGNMENT_BOUNDARY);
	double *steps = (double *) _mm_malloc(np*sizeof(double), ALIGNMENT_BOUNDARY);
	for(auto i=0;i<np;++i) steps[i] = Utils::kInfinity;

	std::vector<Vector3D> conventionalpoints(np);
	std::vector<Vector3D> conventionaldirs(np);
	Vector3D * conventionalpoints2 = (Vector3D *) new Vector3D[np];
	Vector3D * conventionaldirs2 = (Vector3D *) new Vector3D[np];

	StopWatch timer;

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

	// the world volume is a tube
	double worldrmax = 100.;
	double worldrmin = 0.;
	double worldz = 200.;
	PhysicalVolume * world = GeoManager::MakePlacedTube( new TubeParameters<>(worldrmin, worldrmax, worldz, 0, 2.*M_PI), identity );
	PhysicalVolume * beampipe = GeoManager::MakePlacedTube( new TubeParameters<>(worldrmax/40., worldrmax/20., worldz), identity );
	world->AddDaughter( beampipe );
	BoxParameters * plateparams = new BoxParameters(30,5.,2.*worldz/3.);

	//PhysicalVolume * plate1 = GeoManager::MakePlacedBox( plateparams, new TransformationMatrix(50, 0, 0, 35, 0, 10) );
	//PhysicalVolume * plate2 = GeoManager::MakePlacedBox( plateparams, new TransformationMatrix(-50, 0, 0, 35, 0, 10) );
	//PhysicalVolume * plate3 = GeoManager::MakePlacedBox( plateparams, new TransformationMatrix(0, 50, 0, -35, 0, 10) );
	//PhysicalVolume * plate4 = GeoManager::MakePlacedBox( plateparams, new TransformationMatrix(0, -50, 0, -35, 0, 10) );
	PhysicalVolume * plate1 = GeoManager::MakePlacedBox( plateparams, TransformationMatrix::createSpecializedMatrix(50, 0, 0, 35, 0, 10) );
	PhysicalVolume * plate2 = GeoManager::MakePlacedBox( plateparams, TransformationMatrix::createSpecializedMatrix(-50, 0, 0, 35, 0, 10) );
	PhysicalVolume * plate3 = GeoManager::MakePlacedBox( plateparams, TransformationMatrix::createSpecializedMatrix(0, 50, 0, -35, 0, 10) );
	PhysicalVolume * plate4 = GeoManager::MakePlacedBox( plateparams, TransformationMatrix::createSpecializedMatrix(0, -50, 0, -35, 0, 10) );


	world->AddDaughter( plate1 );
	world->AddDaughter( plate2 );
	world->AddDaughter( plate3 );
	world->AddDaughter( plate4 );

	PhysicalVolume * shield = GeoManager::MakePlacedTube( new TubeParameters<>(9*worldrmax/11, 9*worldrmax/10, 8*worldz/10), identity );
	world->AddDaughter( shield );

	ConeParameters<double> * endcapparams = new ConeParameters<double>( worldrmax/20., worldrmax,
					worldrmax/20., worldrmax/10., worldz/10., 0, 2.*M_PI );
	PhysicalVolume * endcap1 = GeoManager::MakePlacedCone( endcapparams, TransformationMatrix::createSpecializedMatrix(0,0,-9.*worldz/10., 0, 0, 0) );
	PhysicalVolume * endcap2 = GeoManager::MakePlacedCone( endcapparams, TransformationMatrix::createSpecializedMatrix( 0,0,9*worldz/10, 0, 180, 0) );
	world->AddDaughter( endcap1 );
	world->AddDaughter( endcap2 );

	world->fillWithRandomPoints(points,np);
	world->fillWithBiasedDirections(points, dirs, np, 9/10.);

	points.toStructureOfVector3D( conventionalpoints );
	dirs.toStructureOfVector3D( conventionaldirs );
	points.toStructureOfVector3D( conventionalpoints2 );
	dirs.toStructureOfVector3D( conventionaldirs2 );

	std::cerr << " Number of daughters " << world->GetNumberOfDaughters() << std::endl;

	// time performance for this placement ( we should probably include some random physical steps )

	// do some navigation with a simple Navigator
	SimpleVecNavigator vecnav(np);
	const PhysicalVolume ** nextvolumes  = (const PhysicalVolume ** ) _mm_malloc(sizeof(PhysicalVolume *)*np, ALIGNMENT_BOUNDARY);

	timer.Start();
	for(int reps=0 ;reps < NREPS; reps++ )
	{
		vecnav.DistToNextBoundary( world, points, dirs, steps, distances, nextvolumes , np );
	}
	timer.Stop();
	double t0 = timer.getDeltaSecs();
	std::cerr << t0 << std::endl;
	// give out hit pointers
	double d0=0.;
	for(auto k=0;k<np;k++)
	{
		d0+=distances[k];
	}


	timer.Start();
	for(int reps=0 ;reps < NREPS; reps++ )
	{
		vecnav.DistToNextBoundaryUsingUnplacedVolumes( world, points, dirs, steps, distances, nextvolumes , np );
	}
	timer.Stop();
	double t1 = timer.getDeltaSecs();
	std::cerr << t1 << std::endl;
	double d1;
	for(auto k=0;k<np;k++)
		{
			d1+=distances[k];
		}
	std::cerr << d0 << " " << d1 << std::endl;


	//vecnav.DistToNextBoundaryUsingUnplacedVolumes( world, points, dirs, steps, distances, nextvolumes , np );
	//( world, points, dirs,  );


	// give out hit pointers
	/*
	for(auto k=0;k<np;k++)
	{
		if( nextvolumes[k] !=0 )
		{
			nextvolumes[k]->printInfo();
		}
		else
		{
			std::cerr << "hitting boundary of world"  << std::endl;
		}
	}
*/
    _mm_free(distances);
    return 1;
}