int main()
{
	Vectors3DSOA points, dirs, intermediatepoints, intermediatedirs;
	StructOfCoord rpoints, rintermediatepoints, rdirs, rintermediatedirs;


	int np=1024;

	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 *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]=1E30;

	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
    for( int r=0; r< EulerAngles.size(); ++r ) // rotation cases
    		for( int t=0; t<TransCases.size(); ++t ) // translation cases
    		  {
    				TransformationMatrix const * identity = new TransformationMatrix(0,0,0,0,0,0);
    				PhysicalVolume * world = GeoManager::MakePlacedBox( new BoxParameters(100,100,100), identity );

    				TransformationMatrix * tm = new TransformationMatrix(TransCases[t][0], TransCases[t][1], TransCases[t][2],
    						EulerAngles[r][0], EulerAngles[r][1], EulerAngles[r][2]);

    				// these dispatch to specialized matrices
    				TransformationMatrix const * sm = TransformationMatrix::createSpecializedMatrix( TransCases[t][0], TransCases[t][1], TransCases[t][2],
    											EulerAngles[r][0], EulerAngles[r][1], EulerAngles[r][2] );


    				PhysicalVolume * daughter = GeoManager::MakePlacedBox( new BoxParameters(10,15,20), tm );

    				world->AddDaughter(daughter);

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

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


    				// time performance for this placement ( we should probably include some random physical steps )
    				timer.Start();
    				for(int reps=0;reps<1000;reps++)
    				{
    					daughter->DistanceToIn(points,dirs,steps,distances);
    				}
    				timer.Stop();
    				double t0 = timer.getDeltaSecs();

    			// std::cerr << tm->GetTranslationIdType() << " " << tm->getNumberOfZeroEntries() << " " << timer.getDeltaSecs() << std::endl;

    				timer.Start();
    				for(int reps=0;reps<1000;reps++)
    				{
    					daughter->DistanceToInIL(points,dirs,steps,distances);
    				}
    				timer.Stop();
    				double til = timer.getDeltaSecs();

    				timer.Start();
    				for(int reps=0;reps<1000;reps++)
    				{
    					daughter->DistanceToInIL( conventionalpoints2, conventionaldirs2, steps, distances, np );
    				}
    				timer.Stop();
    				double til2 = timer.getDeltaSecs();


    				// compare with case that uses external unspecialized transformation
    				PhysicalVolume * unplaceddaughter = GeoManager::MakePlacedBox(new BoxParameters(10,15,20), identity);
    				timer.Start();
    				for(int reps=0;reps<1000;reps++)
    				{
    					if(! tm->isIdentity() )
    					{
    						tm->MasterToLocal(points, intermediatepoints );
    						tm->MasterToLocalVec( dirs, intermediatedirs );
    						unplaceddaughter->DistanceToIn( intermediatepoints, intermediatedirs, steps, distances2);
    					}
    					else
    					{
    						unplaceddaughter->DistanceToIn( points, dirs, steps, distances2);
    					}
    				}
    				timer.Stop();
    				double t1 = timer.getDeltaSecs();


    				// compare with external specialized transformation ( sm )
    				sm->print();
    				timer.Start();
    				for(int reps=0;reps<1000;reps++)
    				{
    					sm->MasterToLocal(points, intermediatepoints );
    					sm->MasterToLocalVec( dirs, intermediatedirs );
    					unplaceddaughter->DistanceToIn( intermediatepoints, intermediatedirs, steps, distances2);
    				}
    				timer.Stop();
    				double t2 = timer.getDeltaSecs();

    				std::cerr << "VECTOR " << tm->isTranslation() << " " << tm->isRotation() << "("<<tm->getNumberOfZeroEntries()<<")" << " " << t0 <<  " " << t1 << " " << t2 << " " << til << " " << til2 << std::endl;

    				cmpresults( distances, distances2, np );


    				// now we do the scalar interface: first of all placed version
    				timer.Start();
    				for(int reps=0;reps<1000;reps++)
    				{
    					for(auto j=0;j<np;++j)
    					{
    						distances[j]=daughter->DistanceToIn( conventionalpoints[j], conventionaldirs[j], steps[j]);
    					}
    				}
    				timer.Stop();
    				double t3 = timer.getDeltaSecs();

    				// now unplaced version
    				timer.Start();
    				for(int reps=0;reps<1000;reps++)
    				{
    					for(auto j=0;j<np;++j)
    		    			{
    		    				Vector3D localp, localdir;
    		    				tm->MasterToLocal(conventionalpoints[j], localp);
    		    				tm->MasterToLocalVec(conventionaldirs[j], localdir);
    		    				distances2[j]=unplaceddaughter->DistanceToIn( localp, localdir, steps[j]);
    		    			}
    				}
    				timer.Stop();
    				double t4 = timer.getDeltaSecs();

    				// now unplaced version
    				timer.Start();
    				for(int reps=0;reps<1000;reps++)
    				{
    					for(auto j=0;j<np;++j)
    		      			{
    		       				Vector3D localp, localdir;
    		       				sm->MasterToLocal(conventionalpoints[j], localp);
    		       				sm->MasterToLocalVec(conventionaldirs[j], localdir);
    		       				distances2[j]=unplaceddaughter->DistanceToIn( localp, localdir, steps[j]);
    		      			}
    				}
    				timer.Stop();
    				double t5 = timer.getDeltaSecs();

    				// now unplaced version but inlined matrices
    				timer.Start();
    				for(int reps=0;reps<1000;reps++)
    				{
    					for(auto j=0;j<np;++j)
    					{
    		        	     Vector3D localp, localdir;
    		        	     // this inlines I think
    		           		 tm->MasterToLocal<-1,-1>(conventionalpoints[j], localp);
    		           		 tm->MasterToLocalVec<-1>(conventionaldirs[j], localdir);
    		           		 distances2[j]=unplaceddaughter->DistanceToIn( localp, localdir, 1E30);
    		            }
    				}
    				timer.Stop();
    				double t6 = timer.getDeltaSecs();

    				std::cerr << "SCALAR " << tm->isTranslation() << " " << tm->isRotation() << "("<<tm->getNumberOfZeroEntries()<<")" << " " << t3 <<  " " << t4 << " " << t5 << " " << t6 << std::endl;

    				TGeoMatrix * rootmatrix= new TGeoCombiTrans(TransCases[t][0], TransCases[t][1], TransCases[t][2],
						   new TGeoRotation("rot1",EulerAngles[r][0], EulerAngles[r][1], EulerAngles[r][2]));
    				TGeoManager *geom = new TGeoManager("","");
    		     TGeoVolume * vol = geom->MakeBox("abox",0,10,15,20);
    		     TGeoShape *  rootbox=vol->GetShape();

    		     // now the scalar version from ROOTGeantV
    		     timer.Start();
    		     for(int reps=0;reps<1000;reps++)
    		     {
    		    	 for(auto j=0;j<np;++j)
    		    	 {
    		    		 Vector3D localp, localdir;
    		    		 // this inlines I think
    		    		 rootmatrix->MasterToLocal( &conventionalpoints[j].x, &localp.x );
    		        	 rootmatrix->MasterToLocalVect( &conventionaldirs[j].x, &localdir.x );
    		             distances[j]=rootbox->DistFromOutside( &localp.x, &localdir.x, 3,1e30, 0);
    		         }
    		     }
    		     timer.Stop();
    		     double t7 = timer.getDeltaSecs();

    		     // now the VECTOR version from ROOT
    		     // now the scalar version from ROOTGeantV
    		     timer.Start();
    		     for(int reps=0;reps<1000;reps++)
    		     {
    		    	 rootmatrix->MasterToLocalCombined_v( reinterpret_cast<StructOfCoord const &>(points), reinterpret_cast<StructOfCoord &>(intermediatepoints),
    		    			     		    			 reinterpret_cast<StructOfCoord const &>(dirs), reinterpret_cast<StructOfCoord &>(intermediatedirs), np );
    		         rootbox->DistFromOutsideSOA_v( reinterpret_cast<StructOfCoord const &>(intermediatepoints),
    		        		 	 reinterpret_cast<StructOfCoord const &>(intermediatedirs), 3, steps, 0, distances2, np);
    		     }
    		     timer.Stop();
    		     double t8 = timer.getDeltaSecs();
    		     std::cerr << "RSCAL " << tm->isTranslation() << " " << tm->isRotation() << "("<<tm->getNumberOfZeroEntries()<<")" << " " << t7 << std::endl;
    		     std::cerr << "RVEC " << tm->isTranslation() << " " << tm->isRotation() << "("<<tm->getNumberOfZeroEntries()<<")" << " " << t8 << std::endl;

    		     cmpresults( distances, distances2, np );

    		    delete tm;
    			delete sm;
    		  }

    _mm_free(distances);
    return 1;
}
int main()
{
	Vectors3DSOA points, dirs, intermediatepoints, intermediatedirs;

	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);

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

	BoxParameters *	worldp =  new BoxParameters(L, L, Lz );
	PhysicalVolume * world = GeoManager::MakePlacedBox( worldp , identity );
	double volworld = worldp->GetVolume();

	BoxParameters * boxlevel2 = new BoxParameters( Sqrt2*L/2./2., Sqrt2*L/2./2., Lz );
	BoxParameters * boxlevel3 = new BoxParameters( L/2./2. ,L/2./2., Lz);
	BoxParameters * boxlevel1 = new BoxParameters( L/2., L/2., Lz );

	PhysicalVolume * box2 = GeoManager::MakePlacedBox(boxlevel2, new TransformationMatrix(0,0,0,0,0,45));
	PhysicalVolume * box3 = GeoManager::MakePlacedBox( boxlevel3, new TransformationMatrix(0,0,0,0,0,-45));
	box2->AddDaughter( box3 ); // rotated 45 degree around z axis

	PhysicalVolume * box1 = GeoManager::MakePlacedBox(boxlevel1, identity);
	box1->AddDaughter( box2 );

	PhysicalVolume const * box1left  = world->PlaceDaughter(GeoManager::MakePlacedBox(boxlevel1, new TransformationMatrix(-L/2.,0.,0.,0.,0.,0)), box1->GetDaughters());
	PhysicalVolume const * box1right = world->PlaceDaughter(GeoManager::MakePlacedBox(boxlevel1, new TransformationMatrix(+L/2.,0.,0.,0.,0.,0)), box1->GetDaughters());


    // perform basic tests
	SimpleVecNavigator nav(1, world);
	Vector3D result;
	VolumePath path(4);
	PhysicalVolume const * vol;

	{
	// point should be in world
	Vector3D p1(0, 9*L/10., 0); path.Clear();
	vol=nav.LocatePoint( world, p1, result, path );
	assert(vol==world);
	}

	{
	// outside world check
	Vector3D p2(-2*L, 9*L/10., 0); path.Clear();
	vol=nav.LocatePoint( world, p2, result, path );
	assert(vol==NULL);
	}

	{
		// inside box3 check
		Vector3D p3(-L/2., 0., 0.); path.Clear();
		vol=nav.LocatePoint( world, p3, result, path );
		assert(vol==box3);
		std::cerr << path.GetCurrentLevel() << std::endl;
		assert(path.GetCurrentLevel( ) == 4);
		assert(result == Vector3D(0.,0.,0));
		}

	{
		// inside box3 check iterative
		Vector3D p3(-L/2., 0., 0.); path.Clear();
		TransformationMatrix * m = new TransformationMatrix();
		vol=nav.LocatePoint_iterative( world, p3, result, path, m );
		path.Print();
		assert(vol==box3);
		std::cerr << path.GetCurrentLevel() << std::endl;
		assert(path.GetCurrentLevel( ) == 4);
		assert(result == Vector3D(0.,0.,0));
	}


	{
	// inside box3 check ( but second box )
	Vector3D p3(L/2., 0., 0.); path.Clear();
	TransformationMatrix * m1, * m2;
	m1=new TransformationMatrix();
	m2=new TransformationMatrix();

	vol=nav.LocatePoint( world, p3, result, path, m1 );
	assert(vol==box3);
	std::cerr << path.GetCurrentLevel() << std::endl;
	assert(path.GetCurrentLevel( ) == 4);
	assert(result == Vector3D(0.,0.,0));
	path.GetGlobalMatrixFromPath( m2 );
	assert( m1->Equals(m2) );
	delete m1; delete m2;
	}

	{
	// inside box2 check
	Vector3D p4(-L/2., 9*L/2./10., 0.); path.Clear();
	vol=nav.LocatePoint( world, p4, result, path );
	assert(vol==box2);
	}

	{
	// inside box2 check ( on other side )
	Vector3D p4(L/2., 9*L/2./10., 0.); path.Clear();
	vol=nav.LocatePoint( world, p4, result, path );
	assert(vol==box2);
	}

	{
	// inside box1 check
	Vector3D p5(-9.*L/10., 9*L/2./10., 0.); path.Clear();
	vol=nav.LocatePoint( world, p5, result, path );
	assert(vol == box1left );
	}

	{
	// inside box1 check
	Vector3D p6(9.*L/10., 9*L/2./10., 0.); path.Clear();
	vol=nav.LocatePoint( world, p6, result, path );
	assert(vol == box1right );
	assert(path.GetCurrentLevel( ) == 2); // this means actuall "next" free level
	}


	// now do location and transportation
	{
	  Vector3D p3(-L/2., 0., 0.); path.Clear();
	  Vector3D newpoint;
	  Vector3D d(9*L/2./10.,0,0);
	  TransformationMatrix * m=new TransformationMatrix();
	  TransformationMatrix * m2=new TransformationMatrix();

	  vol=nav.LocatePoint_iterative( world, p3, result, path, m );
	  assert(vol==box3);
	  // move point in local reference frame
	  Vector3D p = result+d;
	  vol=nav.LocateLocalPointFromPath_Relative_Iterative( p, newpoint, path, m );
	  // LocateLocalPointFromPath_Relative(Vector3D const & point, Vector3D & localpoint, VolumePath & path, TransformationMatrix * ) const;
	  assert( vol==box2 );
	  path.Print();
	  assert( path.GetCurrentLevel() == 3 );

	  // check the global transformation matrix
	  path.GetGlobalMatrixFromPath( m2 );
	  assert( m->Equals( m2 ) );

	  delete m;
	  delete m2;
	}



	// now do location and transportation
	{
		Vector3D p3(-L/2., 0., 0.); path.Clear();
		Vector3D newpoint;
		Vector3D d(0.1,0.,0.);
		TransformationMatrix * m=new TransformationMatrix();
		TransformationMatrix * m2=new TransformationMatrix();

		vol=nav.LocatePoint_iterative( world, p3, result, path, m );
		// move point in local reference frame
		Vector3D p = result+d;
		vol=nav.LocateLocalPointFromPath_Relative_Iterative( p, newpoint, path, m );
		// LocateLocalPointFromPath_Relative(Vector3D const & point, Vector3D & localpoint, VolumePath & path, TransformationMatrix * ) const;
		assert( vol==box3 );
		assert( path.GetCurrentLevel() == 4 );
		path.GetGlobalMatrixFromPath( m2 );
		assert(m2->Equals(m));
// testing new point also
		assert(newpoint == d);

		delete m;
		delete m2;
	}


	// now do location and transportation
	{
		Vector3D p3(-L/2., 0., 0.); path.Clear();
		Vector3D newpoint;
		Vector3D d(Sqrt2*L/4.+0.1,Sqrt2*L/4.+0.1,0);
		TransformationMatrix * m=new TransformationMatrix();
		vol=nav.LocatePoint_iterative( world, p3, result, path, m );
		// move point in local reference frame
		Vector3D p = result+d;
		vol=nav.LocateLocalPointFromPath_Relative_Iterative( p, newpoint, path, m );
		// LocateLocalPointFromPath_Relative(Vector3D const & point, Vector3D & localpoint, VolumePath & path, TransformationMatrix * ) const;
		assert( vol==box1left );
		assert( path.GetCurrentLevel() == 2 );

		delete m;
	}


	// now do location and transportation

	{
		Vector3D p3(-L/2., 0., 0.); path.Clear();
		Vector3D newpoint;
		Vector3D d(Sqrt2*L/2.+0.1,Sqrt2*L/2.+0.1,0);
		TransformationMatrix * m=new TransformationMatrix();
		TransformationMatrix * m2=new TransformationMatrix();

		vol=nav.LocatePoint_iterative( world, p3, result, path, m );
		// move point in local reference frame
		Vector3D p = result+d;
		vol=nav.LocateLocalPointFromPath_Relative_Iterative( p, newpoint, path, m );

		// LocateLocalPointFromPath_Relative(Vector3D const & point, Vector3D & localpoint, VolumePath & path, TransformationMatrix * ) const;
		path.Print();
		assert( vol==world );
		assert( path.GetCurrentLevel() == 1 );
		path.GetGlobalMatrixFromPath( m2 );
		assert( m2->Equals( m ) );

		delete m;
	}


	// now do location and transportation
	{
			Vector3D p3(-L/2., 0., 0.); path.Clear();
			Vector3D newpoint;
			Vector3D d(4*L,4*L,0);
			TransformationMatrix * m=new TransformationMatrix();
			vol=nav.LocatePoint_iterative( world, p3, result, path, m );
			// move point in local reference frame
			Vector3D p = result+d;
			vol=nav.LocateLocalPointFromPath_Relative_Iterative( p, newpoint, path, m );
			// LocateLocalPointFromPath_Relative(Vector3D const & point, Vector3D & localpoint, VolumePath & path, TransformationMatrix * ) const;
			assert( vol==NULL );

			delete m;
	}


	// now do location and transportation
	{
	  Vector3D p3(-L/2., 0., 0.); path.Clear();
	  Vector3D newpoint;
	  Vector3D d(L,0,0);
	  TransformationMatrix * m=new TransformationMatrix();
	  TransformationMatrix * m2=new TransformationMatrix();

	  vol=nav.LocatePoint_iterative( world, p3, result, path, m );
	  assert( vol==box3 );

	  // move point in local reference frame
	  Vector3D p = result+d;
	  vol=nav.LocateLocalPointFromPath_Relative_Iterative( p, newpoint, path, m );
	  // LocateLocalPointFromPath_Relative(Vector3D const & point, Vector3D & localpoint, VolumePath & path, TransformationMatrix * ) const;
	  assert( vol==box3 );
	  assert( path.GetCurrentLevel() == 4 );

	  path.GetGlobalMatrixFromPath( m2 );
	  assert( m2->Equals(m) );
	  assert(newpoint==Vector3D(0,0,0));

	  delete m;
	  delete m2;
	}

	// now do location and transportation
	{
	  Vector3D p3(-L/2., 0., 0.); path.Clear();
	  Vector3D newpoint;
	  Vector3D d(L+9*L/20.,0,0);
	  TransformationMatrix * m=new TransformationMatrix();

	  vol=nav.LocatePoint( world, p3, result, path );
	  assert( vol==box3 );

	  // move point in local reference frame
	  Vector3D p = result+d;
	  vol=nav.LocateLocalPointFromPath_Relative( p, newpoint, path, m );
	  // LocateLocalPointFromPath_Relative(Vector3D const & point, Vector3D & localpoint, VolumePath & path, TransformationMatrix * ) const;
	  assert( vol==box2 );
	  assert( path.GetCurrentLevel() == 3 );
	  delete m;
	}

	// now do location and transportation
	{
	  Vector3D p3(-9*L/10., -9*L/20., 0.); path.Clear();
	  Vector3D newpoint;
	  Vector3D d(L/2.,L/2.,0);
	  TransformationMatrix * m=new TransformationMatrix();

	  vol=nav.LocatePoint( world, p3, result, path );
	  assert( vol==box1left );

	  // move point in local reference frame
	  Vector3D p = result+d;
	  vol=nav.LocateLocalPointFromPath_Relative( p, newpoint, path, m );
	  // LocateLocalPointFromPath_Relative(Vector3D const & point, Vector3D & localpoint, VolumePath & path, TransformationMatrix * ) const;
	  assert( vol==box3 );
	  assert( path.GetCurrentLevel() == 4 );
	  delete m;
	}


	// testing the NavigationAndStepInterface
	{
		// setup point in world
		Vector3D p(-L/2, 9*L/10., 0 );
		Vector3D d(0,-1,0);
		Vector3D resultpoint;
		VolumePath path(4), newpath(4);
		TransformationMatrix *m = new TransformationMatrix();
		TransformationMatrix *m2 = new TransformationMatrix();
		vol = nav.LocatePoint_iterative( world, p, resultpoint, path, m );
		assert(vol==world);

		// do one step
		double step;
		nav.FindNextBoundaryAndStep_iterative(m, p, d, path, newpath, resultpoint, step);
		newpath.Print();
		resultpoint.print();
		std::cerr << " step "  << step << std::endl;
		std::cerr << " current global point " << resultpoint << std::endl;
		// at this moment we can do some tests
		assert( newpath.Top() == box2 );
		newpath.GetGlobalMatrixFromPath(m2);
		assert( m2->Equals(m) );

		// go on with navigation ( enter daughter here ( from box2 to box3 ) )
		p=resultpoint;
		path=newpath;
		nav.FindNextBoundaryAndStep_iterative(m, p, d, path, newpath, resultpoint, step);
		std::cerr << " step "  << step << std::endl;
		std::cerr << " current global point " << resultpoint << std::endl;
		newpath.Print();
		newpath.GetGlobalMatrixFromPath(m2);
		assert( m2->Equals(m) );
		assert( newpath.Top() == box3 );

		// go on with navigation
		p = resultpoint;
		path=newpath;
		nav.FindNextBoundaryAndStep(m, p, d, path, newpath, resultpoint, step);
		std::cerr << " step "  << step << std::endl;
		std::cerr << " current global point " << resultpoint << std::endl;
		assert( newpath.Top() == box2 );

		// go on with navigation
		p = resultpoint;
		path=newpath;
		nav.FindNextBoundaryAndStep(m, p, d, path, newpath, resultpoint, step);
		std::cerr << " step "  << step << std::endl;
		std::cerr << " current global point " << resultpoint << std::endl;
		assert( newpath.Top() == world );

		// go on with navigation ( particle should now leave the world )
		p = resultpoint;
		path=newpath;
		newpath.Clear();
		nav.FindNextBoundaryAndStep(m, p, d, path, newpath, resultpoint, step);
		std::cerr << " step "  << step << std::endl;
		std::cerr << " current global point " << resultpoint << std::endl;
		assert( newpath.Top() == NULL );
	}


	std::cout << " ALL tests passed " << std::endl;

}
Beispiel #3
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;
}
int main(int argc, char * argv[])
{
   bool iterative=true;
   if(argc>1) iterative=false;
   Vectors3DSOA points, dirs, intermediatepoints, intermediatedirs;

   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);

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

   BoxParameters *   worldp =  new BoxParameters(L, L, Lz );
   PhysicalVolume * world = GeoManager::MakePlacedBox( worldp , identity );
   double volworld = worldp->GetVolume();

   BoxParameters * boxlevel2 = new BoxParameters( Sqrt2*L/2./2., Sqrt2*L/2./2., Lz );
   BoxParameters * boxlevel3 = new BoxParameters( L/2./2. ,L/2./2., Lz);
   BoxParameters * boxlevel1 = new BoxParameters( L/2., L/2., Lz );

   PhysicalVolume * box2 = GeoManager::MakePlacedBox(boxlevel2, new TransformationMatrix(0,0,0,0,0,45));
   PhysicalVolume * box3 = GeoManager::MakePlacedBox( boxlevel3, new TransformationMatrix(0,0,0,0,0,-45));
   box2->AddDaughter( box3 ); // rotated 45 degree around z axis

   PhysicalVolume * box1 = GeoManager::MakePlacedBox(boxlevel1, identity);
   box1->AddDaughter( box2 );

   PhysicalVolume const * box1left  = world->PlaceDaughter(GeoManager::MakePlacedBox(boxlevel1, new TransformationMatrix(-L/2.,0.,0.,0.,0.,0)), box1->GetDaughters());
   PhysicalVolume const * box1right = world->PlaceDaughter(GeoManager::MakePlacedBox(boxlevel1, new TransformationMatrix(+L/2.,0.,0.,0.,0.,0)), box1->GetDaughters());


    // perform basic tests
   SimpleVecNavigator nav(1, world);

   StopWatch timer;
   // some object which are expensive to create
   FastTransformationMatrix * m = new FastTransformationMatrix();
   VolumePath path(4);
   VolumePath newpath(4);

   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.;
      Vector3DFast p;
      PhysicalVolume::samplePoint( p, worldp->GetDX(), worldp->GetDY(), worldp->GetDZ(), 1. );
#ifdef DEBUG
      std::cerr << p << " " << worldp->GetDX()-p.GetX() << " ";
#endif

      // setup point in world
      Vector3DFast d(1,0,0);
      Vector3DFast resultpoint;

      m->SetToIdentity();
      PhysicalVolume const * vol;
#ifdef ITERATIVE
         vol = nav.LocatePoint_iterative( world, p, resultpoint, path, m );
#else
         vol = nav.LocatePoint( world, p, resultpoint, path, m );
#endif
         while( vol!=NULL )
      {
         localstepsdone++;
         // do one step
         double step;
#ifdef ITERATIVE
         nav.FindNextBoundaryAndStep_iterative(m, p, d, path, newpath, resultpoint, step);
#else
         nav.FindNextBoundaryAndStep(m, p, d, path, newpath, resultpoint, step);
#endif
         distancetravelled+=step;
#ifdef DEBUG
         std::cerr << "  proposed step: " << step << std::endl;
         std::cerr << "  next point " << resultpoint << std::endl;
         std::cerr << "  in vol " << newpath.Top() << std::endl;
#endif

         // go on with navigation
         p = resultpoint;
         path=newpath;
         vol=path.Top();
      }
#ifdef DEBUG
         std::cerr << localstepsdone << " " << distancetravelled << std::endl;
#endif
         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;

   delete m;
}
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]=1E30;

   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 = new TransformationMatrix(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)  );
   world->AddDaughter( plate1 );
   world->AddDaughter( plate2 );
   world->AddDaughter( plate3 );
   world->AddDaughter( plate4 );

    //         TransformationMatrix * tm = new TransformationMatrix(TransCases[t][0], TransCases[t][1], TransCases[t][2],
    //               EulerAngles[r][0], EulerAngles[r][1], EulerAngles[r][2]);

             // these dispatch to specialized matrices
    //         TransformationMatrix const * sm = TransformationMatrix::createSpecializedMatrix( TransCases[t][0], TransCases[t][1], TransCases[t][2],
    //                  EulerAngles[r][0], EulerAngles[r][1], EulerAngles[r][2] );

             double rmin = 10.;
             double rmax = 20.;
             double dz = 30.;
             double phis  =0.;
             //double dphi = 2.*M_PI;
             double dphi = M_PI;

             TubeParameters<double> const *tp = gTestShapeContainer.GetTubeParams(0);
             PhysicalVolume * daughter = GeoManager::MakePlacedTube( tp, tm );

             //std::cerr << daughter->UnplacedContains( Vector3D(15, 1, 15) ) << std::endl;
             //std::cerr << daughter->UnplacedContains( Vector3D(-15, 1, 15) ) << std::endl;
             // testing UnplacedContains
             //   for(auto k=0;k<100;k++)
             //   {
             //      Vector3D x( cos(k/(100.)*2*M_PI), sin(k/(100.)*2*M_PI), 0 );
             //      std::cerr << "## " << k/100.*2*M_PI << " "  << daughter->UnplacedContains( x ) << std::endl;
             //   }
             world->AddDaughter(daughter);
             world->fillWithRandomPoints(points,np);
             world->fillWithBiasedDirections(points, dirs, np, 8/10.);

             daughter->fillWithRandomPoints(points,np);


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

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

             timer.Start();
             for(int reps=0;reps< NREPS ;reps++)
             {
                daughter->DistanceToOut(points,dirs,steps,distances);
             }
             timer.Stop();
             double t0 = timer.getDeltaSecs();

                //
//             // std::cerr << tm->GetTranslationIdType() << " " << tm->getNumberOfZeroEntries() << " " << timer.getDeltaSecs() << std::endl;
//
//                timer.Start();
//               for(int reps=0;reps<NREPS;reps++)
//                {
//                   daughter->DistanceToInIL(points,dirs,steps,distances);
//                }
//                timer.Stop();
//                double til = timer.getDeltaSecs();
//
//                timer.Start();
//                for(int reps=0;reps<NREPS;reps++)
//                {
//                   daughter->DistanceToInIL( conventionalpoints2, conventionaldirs2, steps, distances, np );
//                }
//                timer.Stop();
//                double til2 = timer.getDeltaSecs();
//
//
                // compare with case that uses external unspecialized transformation
                //0, 20, 30, M_PI

                PhysicalVolume * unplaceddaughter = GeoManager::MakePlacedTube( new TubeParameters<>( rmin, rmax ,dz, phis, dphi ), identity );
                timer.Start();
                for(int reps=0;reps<NREPS;reps++)
                {
                   if(! tm->isIdentity() )
                   {
                      tm->MasterToLocal(points, intermediatepoints );
                      tm->MasterToLocalVec( dirs, intermediatedirs );
                      unplaceddaughter->DistanceToIn( intermediatepoints, intermediatedirs, steps, distances2);
                   }
                   else
                   {
                      unplaceddaughter->DistanceToIn( points, dirs, steps, distances2);
                   }
                }
                timer.Stop();
                double t1 = timer.getDeltaSecs();

                //
//
//                // compare with external specialized transformation ( sm )
//                sm->print();
                timer.Start();
                for(int reps=0;reps<NREPS;reps++)
                {
                   sm->MasterToLocal(points, intermediatepoints );
                   sm->MasterToLocalVec( dirs, intermediatedirs );
                   unplaceddaughter->DistanceToIn( intermediatepoints, intermediatedirs, steps, distances2);
                }
                timer.Stop();
                double t2 = timer.getDeltaSecs();


//                std::cerr << "VECTOR " << tm->isTranslation() << " " << tm->isRotation() << "("<<tm->getNumberOfZeroEntries()<<")" << " " << t0 <<  " " << t1 << " " << t2 << " " << til << " " << til2 << std::endl;
//                cmpresults( distances, distances2, np );
//
//
//                // now we do the scalar interface: first of all placed version
//                timer.Start();
//                for(int reps=0;reps<NREPS;reps++)
//                {
//                   for(auto j=0;j<np;++j)
//                   {
//                      distances[j]=daughter->DistanceToIn( conventionalpoints[j], conventionaldirs[j], steps[j]);
//                   }
//                }
//                timer.Stop();
//                double t3 = timer.getDeltaSecs();
//
//                // now unplaced version
//                timer.Start();
//                for(int reps=0;reps<NREPS;reps++)
//                {
//                   for(auto j=0;j<np;++j)
//                       {
//                          Vector3D localp, localdir;
//                          tm->MasterToLocal(conventionalpoints[j], localp);
//                          tm->MasterToLocalVec(conventionaldirs[j], localdir);
//                          distances2[j]=unplaceddaughter->DistanceToIn( localp, localdir, steps[j]);
//                       }
//                }
//                timer.Stop();
//                double t4 = timer.getDeltaSecs();
//
//                // now unplaced version
//                timer.Start();
//                for(int reps=0;reps<NREPS;reps++)
//                {
//                   for(auto j=0;j<np;++j)
//                         {
//                             Vector3D localp, localdir;
//                             sm->MasterToLocal(conventionalpoints[j], localp);
//                             sm->MasterToLocalVec(conventionaldirs[j], localdir);
//                             distances2[j]=unplaceddaughter->DistanceToIn( localp, localdir, steps[j]);
//                         }
//                }
//                timer.Stop();
//                double t5 = timer.getDeltaSecs();
//
//                // now unplaced version but inlined matrices
//                timer.Start();
//                for(int reps=0;reps<NREPS;reps++)
//                {
//                   for(auto j=0;j<np;++j)
//                   {
//                          Vector3D localp, localdir;
//                          // this inlines I think
//                            tm->MasterToLocal<-1,-1>(conventionalpoints[j], localp);
//                            tm->MasterToLocalVec<-1>(conventionaldirs[j], localdir);
//                            distances2[j]=unplaceddaughter->DistanceToIn( localp, localdir, 1E30);
//                      }
//                }
//                timer.Stop();
//                double t6 = timer.getDeltaSecs();
//
//                std::cerr << "SCALAR " << tm->isTranslation() << " " << tm->isRotation() << "("<<tm->getNumberOfZeroEntries()<<")" << " " << t3 <<  " " << t4 << " " << t5 << " " << t6 << std::endl;
//
              TGeoMatrix * rootmatrix= new TGeoCombiTrans(TransCases[t][0], TransCases[t][1], TransCases[t][2],
                     new TGeoRotation("rot1",EulerAngles[r][0], EulerAngles[r][1], EulerAngles[r][2]));
              TGeoManager *geom = new TGeoManager("","");
               TGeoVolume * vol = geom->MakeTubs("atube",0, tp->GetRmin(), tp->GetRmax(), tp->GetDZ(),tp->GetSPhi() *360/(2.*M_PI), tp->GetSPhi()+360*tp->GetDPhi()/(2.*M_PI));
               TGeoShape *  roottube=vol->GetShape();

               // now the scalar version from ROOTGeantV
           //    timer.Start();
           //    for(int reps=0;reps<NREPS;reps++)
           //    {
           //       for(auto j=0;j<np;++j)
           //       {
           //          Vector3D localp, localdir;
           //          rootmatrix->MasterToLocal( &conventionalpoints[j].x, &localp.x );
           //           rootmatrix->MasterToLocalVect( &conventionaldirs[j].x, &localdir.x );
           //            distancesROOTSCALAR[j]=roottube->DistFromOutside( &localp.x, &localdir.x, 3, Utils::kInfinity, 0);
           //        }
           //    }
           //    timer.Stop();
           //    double t7 = timer.getDeltaSecs();

               // now the scalar version from ROOTGeantV
               timer.Start();
               for(int reps=0;reps<NREPS;reps++)
               {
                  for(auto j=0;j<np;++j)
                  {
                     Vector3D localp, localdir;
                     rootmatrix->MasterToLocal( &conventionalpoints[j].x, &localp.x );
                      rootmatrix->MasterToLocalVect( &conventionaldirs[j].x, &localdir.x );
                      distancesROOTSCALAR[j]=roottube->DistFromInside( &conventionalpoints[j].x, &conventionaldirs[j].x, 3, Utils::kInfinity, 0);
                  }
               }
               timer.Stop();
               double t7 = timer.getDeltaSecs();

               // now the VECTOR version from ROOT
               // now the scalar version from ROOTGeantV
               timer.Start();
               for(int reps=0;reps<NREPS;reps++)
               {
                  rootmatrix->MasterToLocalCombined_v( reinterpret_cast<StructOfCoord const &>(points), reinterpret_cast<StructOfCoord &>(intermediatepoints),
                                                reinterpret_cast<StructOfCoord const &>(dirs), reinterpret_cast<StructOfCoord &>(intermediatedirs), np );
                   roottube->DistFromOutsideSOA_v( reinterpret_cast<StructOfCoord const &>(intermediatepoints),
                             reinterpret_cast<StructOfCoord const &>(intermediatedirs), 3, steps, 0, distances2, np);
               }
               timer.Stop();
               double t8 = timer.getDeltaSecs();

               cmpresults( distancesROOTSCALAR, distances, np, daughter, conventionalpoints, conventionaldirs );

               // now we compare with loop over USolids version (scalar; trying to inline matrices as done in Geant4 typically)
               VUSolid * utub =  new UTubs("utubs1",rmin,rmax,dz, phis, dphi);
               timer.Start();
               for(int reps=0;reps<NREPS;reps++)
               {
                      for(auto j=0;j<np;++j)
                       {
                         Vector3D localp, localdir;
                          // this inlines I think
                         tm->MasterToLocal<1,-1>( conventionalpoints[j], localp );
                         tm->MasterToLocalVec<-1>( conventionaldirs[j], localdir );
                         distancesUSOLIDSCALAR[j]=utub->DistanceToIn( reinterpret_cast<UVector3 const & > (localp), reinterpret_cast<UVector3 &> ( localdir ), 1e30);
                       }
                }
               timer.Stop();
               double t9 = timer.getDeltaSecs();

               std::cerr << "new vec (placed)" << tm->isTranslation() << " " << tm->isRotation() << "("<<tm->getNumberOfZeroEntries()<<")" << " " << t0 << std::endl;
               std::cerr << "new vec (old matrix)" << tm->isTranslation() << " " << tm->isRotation() << "("<<tm->getNumberOfZeroEntries()<<")" << " " << t1 << std::endl;
               std::cerr << "new vec (unplaced)" << tm->isTranslation() << " " << tm->isRotation() << "("<<tm->getNumberOfZeroEntries()<<")" << " " << t2 << std::endl;
               std::cerr << "RSCAL " << tm->isTranslation() << " " << tm->isRotation() << "("<<tm->getNumberOfZeroEntries()<<")" << " " << t7 << std::endl;
               std::cerr << "RVEC " << tm->isTranslation() << " " << tm->isRotation() << "("<<tm->getNumberOfZeroEntries()<<")" << " " << t8 << std::endl;
               std::cerr << "USOLIDS SCAL " << tm->isTranslation() << " " << tm->isRotation() << "("<<tm->getNumberOfZeroEntries()<<")" << " " << t9 << std::endl;

               delete tm;
               delete sm;
            }