From e2165084b08cb7897dd3f3d7329ee7d1393b851a Mon Sep 17 00:00:00 2001
From: Andre Sailer <andre.philippe.sailer@cern.ch>
Date: Wed, 17 Jun 2015 14:04:08 +0000
Subject: [PATCH] Add Segmentation::cellDimensions function

Needed to access cell dimensions in a segmentation agnostic way
Implemented unit tests for cellDimensions
Implemented default function throwing exception
Implemented cellDimensions for CartesianGridXY, XZ, YZ, XZY
Added c++11 definition to DD4hep.cmake (implemented functions with and without c++11)
---
 .../include/DDSegmentation/CartesianGridXY.h  |  10 ++
 .../include/DDSegmentation/CartesianGridXYZ.h |  11 ++
 .../include/DDSegmentation/CartesianGridXZ.h  |  10 ++
 .../include/DDSegmentation/CartesianGridYZ.h  |  10 ++
 .../include/DDSegmentation/Segmentation.h     |   7 ++
 DDSegmentation/src/CartesianGridXY.cpp        |  11 ++
 DDSegmentation/src/CartesianGridXYZ.cpp       |  12 ++
 DDSegmentation/src/CartesianGridXZ.cpp        |  11 ++
 DDSegmentation/src/CartesianGridYZ.cpp        |  11 ++
 DDSegmentation/src/Segmentation.cpp           |   6 +
 DDTest/CMakeLists.txt                         |   9 ++
 DDTest/src/test_cellDimensions.cc             | 112 ++++++++++++++++++
 cmake/DD4hep.cmake                            |   1 +
 doc/release.notes                             |   5 +
 14 files changed, 226 insertions(+)
 create mode 100644 DDTest/src/test_cellDimensions.cc

diff --git a/DDSegmentation/include/DDSegmentation/CartesianGridXY.h b/DDSegmentation/include/DDSegmentation/CartesianGridXY.h
index 55b674e86..ca9e6cdda 100644
--- a/DDSegmentation/include/DDSegmentation/CartesianGridXY.h
+++ b/DDSegmentation/include/DDSegmentation/CartesianGridXY.h
@@ -72,6 +72,16 @@ public:
 	void setFieldNameY(const std::string& fieldName) {
 		_yId = fieldName;
 	}
+	/** \brief Returns a vector<double> of the cellDimensions of the given cell ID
+	    in natural order of dimensions, e.g., dx/dy/dz, or dr/r*dPhi
+
+	    Returns a vector of the cellDimensions of the given cell ID
+	    \param cellID is ignored as all cells have the same dimension
+	    \return std::vector<double> size 2:
+	    -# size in x
+	    -# size in y
+	*/
+	virtual std::vector<double> cellDimensions(const CellID& cellID) const;
 
 protected:
 	/// the grid size in X
diff --git a/DDSegmentation/include/DDSegmentation/CartesianGridXYZ.h b/DDSegmentation/include/DDSegmentation/CartesianGridXYZ.h
index d13cb09b9..c8e45780f 100644
--- a/DDSegmentation/include/DDSegmentation/CartesianGridXYZ.h
+++ b/DDSegmentation/include/DDSegmentation/CartesianGridXYZ.h
@@ -48,6 +48,17 @@ public:
 	void setFieldNameZ(const std::string& fieldName) {
 		_zId = fieldName;
 	}
+	/** \brief Returns a vector<double> of the cellDimensions of the given cell ID
+	    in natural order of dimensions, e.g., dx/dy/dz, or dr/r*dPhi
+
+	    Returns a vector of the cellDimensions of the given cell ID
+	    \param cellID is ignored as all cells have the same dimension
+	    \return std::vector<double> size 3:
+	    -# size in x
+	    -# size in y
+	    -# size in z
+	*/
+	virtual std::vector<double> cellDimensions(const CellID& cellID) const;
 
 protected:
 	/// the grid size in Z
diff --git a/DDSegmentation/include/DDSegmentation/CartesianGridXZ.h b/DDSegmentation/include/DDSegmentation/CartesianGridXZ.h
index 583d55ed0..9a13ccbbb 100644
--- a/DDSegmentation/include/DDSegmentation/CartesianGridXZ.h
+++ b/DDSegmentation/include/DDSegmentation/CartesianGridXZ.h
@@ -72,6 +72,16 @@ public:
 	void setFieldNameZ(const std::string& fieldName) {
 		_zId = fieldName;
 	}
+	/** \brief Returns a vector<double> of the cellDimensions of the given cell ID
+	    in natural order of dimensions, e.g., dx/dy/dz, or dr/r*dPhi
+
+	    Returns a vector of the cellDimensions of the given cell ID
+	    \param cellID is ignored as all cells have the same dimension
+	    \return std::vector<double> size:
+	    -# size in x
+	    -# size in z
+	*/
+	virtual std::vector<double> cellDimensions(const CellID& cellID) const;
 
 protected:
 	/// the grid size in X
diff --git a/DDSegmentation/include/DDSegmentation/CartesianGridYZ.h b/DDSegmentation/include/DDSegmentation/CartesianGridYZ.h
index 322291f41..1a9aa13bf 100644
--- a/DDSegmentation/include/DDSegmentation/CartesianGridYZ.h
+++ b/DDSegmentation/include/DDSegmentation/CartesianGridYZ.h
@@ -74,6 +74,16 @@ public:
 	void setFieldNameZ(const std::string& fieldName) {
 		_zId = fieldName;
 	}
+	/** \brief Returns a vector<double> of the cellDimensions of the given cell ID
+	    in natural order of dimensions, e.g., dx/dy/dz, or dr/r*dPhi
+
+	    Returns a vector of the cellDimensions of the given cell ID
+	    \param cellID is ignored as all cells have the same dimension
+	    \return std::vector<double> size:
+	    -# size in y
+	    -# size in z
+	*/
+	virtual std::vector<double> cellDimensions(const CellID& cellID) const;
 
 protected:
 	/// the grid size in Y
diff --git a/DDSegmentation/include/DDSegmentation/Segmentation.h b/DDSegmentation/include/DDSegmentation/Segmentation.h
index 68de568d6..68a7bf13d 100644
--- a/DDSegmentation/include/DDSegmentation/Segmentation.h
+++ b/DDSegmentation/include/DDSegmentation/Segmentation.h
@@ -111,6 +111,13 @@ public:
 	virtual Parameters parameters() const;
 	/// Set all parameters from an existing set of parameters
 	virtual void setParameters(const Parameters& parameters);
+	/** \brief Returns a vector<double> of the cellDimensions of the given cell ID
+	    in natural order of dimensions, e.g., dx/dy/dz, or dr/r*dPhi
+
+	    \param cellID cellID of the cell for which parameters are returned
+	    \return vector<double> in natural order of dimensions, e.g., dx/dy/dz, or dr/r*dPhi
+	*/
+	virtual std::vector<double> cellDimensions(const CellID& cellID) const;
 
 protected:
 	/// Default constructor used by derived classes passing the encoding string
diff --git a/DDSegmentation/src/CartesianGridXY.cpp b/DDSegmentation/src/CartesianGridXY.cpp
index 20f17e4fb..66741c20c 100644
--- a/DDSegmentation/src/CartesianGridXY.cpp
+++ b/DDSegmentation/src/CartesianGridXY.cpp
@@ -48,6 +48,17 @@ Vector3D CartesianGridXY::position(const CellID& cID) const {
 	return _decoder->getValue();
 }
 
+std::vector<double> CartesianGridXY::cellDimensions(const CellID&) const {
+#ifdef DD4HEP_USE_CXX11
+  return {_gridSizeX, _gridSizeY};
+#else
+  std::vector<double> cellDims(2,0.0);
+  cellDims[0] = _gridSizeX;
+  cellDims[1] = _gridSizeY;
+  return cellDims;
+#endif
+}
+
 REGISTER_SEGMENTATION(CartesianGridXY)
 
 } /* namespace DDSegmentation */
diff --git a/DDSegmentation/src/CartesianGridXYZ.cpp b/DDSegmentation/src/CartesianGridXYZ.cpp
index 20d1f7834..629df9311 100644
--- a/DDSegmentation/src/CartesianGridXYZ.cpp
+++ b/DDSegmentation/src/CartesianGridXYZ.cpp
@@ -47,6 +47,18 @@ Vector3D CartesianGridXYZ::position(const CellID& cID) const {
 	return _decoder->getValue();
 }
 
+std::vector<double> CartesianGridXYZ::cellDimensions(const CellID&) const {
+#ifdef DD4HEP_USE_CXX11
+  return {_gridSizeX, _gridSizeY, _gridSizeZ};
+#else
+  std::vector<double> cellDimensions(3,0.0);
+  cellDimensions[0] = _gridSizeX;
+  cellDimensions[1] = _gridSizeY;
+  cellDimensions[2] = _gridSizeZ;
+  return cellDimensions;
+#endif
+}
+
 REGISTER_SEGMENTATION(CartesianGridXYZ)
 
 } /* namespace DDSegmentation */
diff --git a/DDSegmentation/src/CartesianGridXZ.cpp b/DDSegmentation/src/CartesianGridXZ.cpp
index e21e3118f..88cc3147d 100644
--- a/DDSegmentation/src/CartesianGridXZ.cpp
+++ b/DDSegmentation/src/CartesianGridXZ.cpp
@@ -52,6 +52,17 @@ Vector3D CartesianGridXZ::position(const CellID& cID) const {
 	return _decoder->getValue();
 }
 
+std::vector<double> CartesianGridXZ::cellDimensions(const CellID&) const {
+#ifdef DD4HEP_USE_CXX11
+  return {_gridSizeX, _gridSizeZ};
+#else
+  std::vector<double> cellDimensions(2,0.0);
+  cellDimensions[0] = _gridSizeX;
+  cellDimensions[1] = _gridSizeZ;
+  return cellDimensions;
+#endif
+}
+
 REGISTER_SEGMENTATION(CartesianGridXZ)
 
 } /* namespace DDSegmentation */
diff --git a/DDSegmentation/src/CartesianGridYZ.cpp b/DDSegmentation/src/CartesianGridYZ.cpp
index 44b104824..66be1861d 100644
--- a/DDSegmentation/src/CartesianGridYZ.cpp
+++ b/DDSegmentation/src/CartesianGridYZ.cpp
@@ -49,6 +49,17 @@ Vector3D CartesianGridYZ::position(const CellID& cID) const {
 	return _decoder->getValue();
 }
 
+std::vector<double> CartesianGridYZ::cellDimensions(const CellID&) const {
+#ifdef DD4HEP_USE_CXX11
+  return {_gridSizeY, _gridSizeZ};
+#else
+  std::vector<double> cellDimensions(2,0.0);
+  cellDimensions[0] = _gridSizeY;
+  cellDimensions[1] = _gridSizeZ;
+  return cellDimensions;
+#endif
+}
+
 REGISTER_SEGMENTATION(CartesianGridYZ)
 
 } /* namespace DDSegmentation */
diff --git a/DDSegmentation/src/Segmentation.cpp b/DDSegmentation/src/Segmentation.cpp
index d30dc47ee..dfabc427c 100644
--- a/DDSegmentation/src/Segmentation.cpp
+++ b/DDSegmentation/src/Segmentation.cpp
@@ -188,5 +188,11 @@ int Segmentation::positionToBin(double position, std::vector<double> const& cell
 
 }
 
+std::vector<double> Segmentation::cellDimensions(const CellID&) const {
+  std::stringstream errorMessage;
+  errorMessage << __func__ << " is not implemented for " << _type;
+  throw std::logic_error(errorMessage.str());
+}
+
 } /* namespace DDSegmentation */
 } /* namespace DD4hep */
diff --git a/DDTest/CMakeLists.txt b/DDTest/CMakeLists.txt
index 0bead5226..2531d55b1 100644
--- a/DDTest/CMakeLists.txt
+++ b/DDTest/CMakeLists.txt
@@ -62,6 +62,15 @@ ADD_TEST( t_${test_name} "${CMAKE_INSTALL_PREFIX}/bin/run_test.sh"
 SET_TESTS_PROPERTIES( t_${test_name} PROPERTIES PASS_REGULAR_EXPRESSION "TEST_PASSED" )
 SET_TESTS_PROPERTIES( t_${test_name} PROPERTIES FAIL_REGULAR_EXPRESSION "TEST_FAILED" )
 
+
+SET( test_name "test_cellDimensions" )
+ADD_EXECUTABLE( ${test_name} ./src/${test_name}.cc )
+TARGET_LINK_LIBRARIES(${test_name} ${test_link_libraries})
+ADD_TEST( t_${test_name} "${CMAKE_INSTALL_PREFIX}/bin/run_test.sh"
+  ${EXECUTABLE_OUTPUT_PATH}/${test_name}  )
+SET_TESTS_PROPERTIES( t_${test_name} PROPERTIES PASS_REGULAR_EXPRESSION "TEST_PASSED" )
+SET_TESTS_PROPERTIES( t_${test_name} PROPERTIES FAIL_REGULAR_EXPRESSION "TEST_FAILED" )
+
 #--------------------------------------------------
 
 
diff --git a/DDTest/src/test_cellDimensions.cc b/DDTest/src/test_cellDimensions.cc
new file mode 100644
index 000000000..5d4412d40
--- /dev/null
+++ b/DDTest/src/test_cellDimensions.cc
@@ -0,0 +1,112 @@
+#include "DDSegmentation/Segmentation.h"
+#include "DDSegmentation/CartesianGridXY.h"
+#include "DDSegmentation/CartesianGridYZ.h"
+#include "DDSegmentation/CartesianGridXZ.h"
+#include "DDSegmentation/CartesianGridXYZ.h"
+#include "DD4hep/DDTest.h"
+
+#include <iostream>
+#include <iomanip>
+#include <vector>
+#include <algorithm>
+#include <exception>
+#include <cmath>
+
+
+DD4hep::DDTest test = DD4hep::DDTest( "CellDimensions" ) ;
+
+
+int main() {
+  try{
+
+    DD4hep::DDSegmentation::CartesianGridXY seg("system:8,barrel:3,layer:8,slice:5,x:16,y:16");
+
+    const double xSize=12343.43243;
+    const double ySize=M_PI;
+
+    seg.setGridSizeX(xSize);
+    seg.setGridSizeY(ySize);
+
+    DD4hep::DDSegmentation::VolumeID volID = 0;
+
+    test( fabs(seg.cellDimensions(volID)[0] - xSize )  < 1e-11, " CG_XY: Dimension for X" );
+    test( fabs(seg.cellDimensions(volID)[1] - ySize )  < 1e-11, " CG_XY: Dimension for Y" );
+
+  } catch( std::exception &e ){
+    //} catch( ... ){
+
+    test.log( e.what() );
+    test.error( "exception occurred" );
+  }
+
+  try{
+
+    DD4hep::DDSegmentation::CartesianGridXZ seg("system:8,barrel:3,layer:8,slice:5,x:16,z:16");
+
+    const double xSize=12343.43243;
+    const double zSize=M_PI;
+
+    seg.setGridSizeX(xSize);
+    seg.setGridSizeZ(zSize);
+
+    DD4hep::DDSegmentation::VolumeID volID = 0;
+
+    test( fabs(seg.cellDimensions(volID)[0] - xSize )  < 1e-11, " CG_XZ: Dimension for X" );
+    test( fabs(seg.cellDimensions(volID)[1] - zSize )  < 1e-11, " CG_XZ: Dimension for Z" );
+
+  } catch( std::exception &e ){
+    //} catch( ... ){
+
+    test.log( e.what() );
+    test.error( "exception occurred" );
+  }
+
+  try{
+
+    DD4hep::DDSegmentation::CartesianGridYZ seg("system:8,barrel:3,layer:8,slice:5,y:16,z:16");
+
+    const double ySize=12343.43243;
+    const double zSize=M_PI;
+
+    seg.setGridSizeY(ySize);
+    seg.setGridSizeZ(zSize);
+
+    DD4hep::DDSegmentation::VolumeID volID = 0;
+
+    test( fabs(seg.cellDimensions(volID)[0] - ySize )  < 1e-11, " CG_YZ: Dimension for Y" );
+    test( fabs(seg.cellDimensions(volID)[1] - zSize )  < 1e-11, " CG_YZ: Dimension for Z" );
+
+  } catch( std::exception &e ){
+    //} catch( ... ){
+
+    test.log( e.what() );
+    test.error( "exception occurred" );
+  }
+
+  try{
+
+    DD4hep::DDSegmentation::CartesianGridXYZ seg("system:8,barrel:3,layer:8,slice:7,x:10,y:10,z:10");
+
+    const double xSize=42.24;
+    const double ySize=12343.43243;
+    const double zSize=M_PI;
+
+    seg.setGridSizeX(xSize);
+    seg.setGridSizeY(ySize);
+    seg.setGridSizeZ(zSize);
+
+    DD4hep::DDSegmentation::VolumeID volID = 0;
+
+    test( fabs(seg.cellDimensions(volID)[0] - xSize )  < 1e-11, " CG_XYZ: Dimension for X" );
+    test( fabs(seg.cellDimensions(volID)[1] - ySize )  < 1e-11, " CG_XYZ: Dimension for Y" );
+    test( fabs(seg.cellDimensions(volID)[2] - zSize )  < 1e-11, " CG_XYZ: Dimension for Z" );
+
+  } catch( std::exception &e ){
+    //} catch( ... ){
+
+    test.log( e.what() );
+    test.error( "exception occurred" );
+  }
+
+  return 0;
+}
diff --git a/cmake/DD4hep.cmake b/cmake/DD4hep.cmake
index 454ef5108..a69ba7e48 100644
--- a/cmake/DD4hep.cmake
+++ b/cmake/DD4hep.cmake
@@ -1,6 +1,7 @@
 #---------------------------------------------------------------------------------------------------
 if(DD4HEP_USE_CXX11)
   SET( CMAKE_CXX_FLAGS "-std=c++11 -Wall -Wextra -pedantic -Wno-long-long -Wdeprecated -Wformat-security -Wshadow")
+  ADD_DEFINITIONs(-DDD4HEP_USE_CXX11)
 else()
   SET( CMAKE_CXX_FLAGS "-Wall -Wextra -pedantic -Wno-long-long")
 endif()
diff --git a/doc/release.notes b/doc/release.notes
index 11020da6a..a8c808664 100644
--- a/doc/release.notes
+++ b/doc/release.notes
@@ -7,6 +7,11 @@ DD4hep  ----  Release Notes
 | v00-12 |  
  --------   
 
+A. Sailer
+-----
+  - DDSegmentation: Added function cellDimension which returns the dimension of any given cell
+
+
 S.Lu:
 -----
   - Added a switch for BirksLaw to Geant4StepHandler. 
-- 
GitLab