From 0a9034951d562a941fa2b84837fee871a1eb8d51 Mon Sep 17 00:00:00 2001
From: Marilena Bandieramonte <marilena.bandieramonte@cern.ch>
Date: Thu, 9 Jul 2020 19:01:49 +0200
Subject: [PATCH] Fix the precision error introduced by I/O operations

---
 GeoModelWrite/src/WriteGeoModel.cpp | 201 +++++++++++++++-------------
 1 file changed, 105 insertions(+), 96 deletions(-)

diff --git a/GeoModelWrite/src/WriteGeoModel.cpp b/GeoModelWrite/src/WriteGeoModel.cpp
index a85161b14..2b5d93d01 100644
--- a/GeoModelWrite/src/WriteGeoModel.cpp
+++ b/GeoModelWrite/src/WriteGeoModel.cpp
@@ -43,6 +43,15 @@
 
 namespace GeoModelIO {
 
+template <typename T>
+std::string to_string_with_precision(const T a_value, const int n = 16)
+{
+    std::ostringstream out;
+    out.precision(n);
+    out << std::fixed << a_value;
+    return out.str();
+}
+
   // TODO: should go to an utility class
   // FIXME: should go to an utility class
   std::string joinVectorStrings(std::vector<std::string> vec, std::string sep="") {
@@ -73,7 +82,7 @@ namespace GeoModelIO {
   unsigned int WriteGeoModel::getChildPosition(const unsigned int &parentId, const std::string &parentType, const unsigned int &copyN)
 {
   unsigned int tableId = getIdFromNodeType(parentType);
-  std::string key = std::to_string(tableId) + ":" + std::to_string(parentId) + ":" + std::to_string(copyN);
+  std::string key = to_string_with_precision(tableId) + ":" + to_string_with_precision(parentId) + ":" + to_string_with_precision(copyN);
   
   std::unordered_map<std::string, unsigned int>::iterator it = m_parentChildrenMap.find(key);
 	if ( it == m_parentChildrenMap.end() ) {
@@ -88,7 +97,7 @@ namespace GeoModelIO {
 {
 	//JFB Commented out: qDebug() << "WriteGeoModel::setVolumeCopyNumber()";
 	const unsigned int tableId = getIdFromNodeType(volType);
-  std::string key = std::to_string(tableId) + ":" + std::to_string(volId);
+  std::string key = to_string_with_precision(tableId) + ":" + to_string_with_precision(volId);
 
   std::unordered_map<std::string, unsigned int>::iterator it = m_volumeCopiesMap.find(key);
   if ( it == m_volumeCopiesMap.end() ) {
@@ -103,7 +112,7 @@ namespace GeoModelIO {
   unsigned int WriteGeoModel::getLatestParentCopyNumber(const unsigned int &parentId, const std::string &parentType)
 {
   const unsigned int tableId = getIdFromNodeType(parentType);
-  std::string key = std::to_string(tableId) + ":" + std::to_string(parentId);
+  std::string key = to_string_with_precision(tableId) + ":" + to_string_with_precision(parentId);
 
   std::unordered_map<std::string, unsigned int>::iterator it = m_volumeCopiesMap.find(key);
   if ( it == m_volumeCopiesMap.end() ) {
@@ -571,7 +580,7 @@ void WriteGeoModel::handleNameTag(const GeoNameTag* node)
 		}
 
   std::vector<std::string> parentList;
-  parentList.insert(parentList.begin(), {std::to_string(parentId), parentType});
+  parentList.insert(parentList.begin(), {to_string_with_precision(parentId), parentType});
 
 		return  parentList;
 }
@@ -614,9 +623,9 @@ unsigned int WriteGeoModel::storeMaterial(const GeoMaterial* mat)
 		unsigned int elementId = storeElement(element);
 
 		//Gets the fraction by weight of the i-th element
-    const std::string elementFraction = std::to_string( mat->getFraction(i) );
+    const std::string elementFraction = to_string_with_precision( mat->getFraction(i) );
 
-    matElementsList.push_back( std::to_string(elementId) + ":" + elementFraction );
+    matElementsList.push_back( to_string_with_precision(elementId) + ":" + elementFraction );
 	}
 	matElements = joinVectorStrings(matElementsList, ";");
 
@@ -814,19 +823,19 @@ std::string WriteGeoModel::getShapeParameters(const GeoShape* shape)
 
 	if (shapeType == "Box") {
 		const GeoBox* box = dynamic_cast<const GeoBox*>(shape);
-		pars.push_back("XHalfLength=" + std::to_string(box->getXHalfLength())) ;
-		pars.push_back("YHalfLength=" + std::to_string(box->getYHalfLength())) ;
-		pars.push_back("ZHalfLength=" + std::to_string(box->getZHalfLength())) ;
+		pars.push_back("XHalfLength=" + to_string_with_precision(box->getXHalfLength())) ;
+		pars.push_back("YHalfLength=" + to_string_with_precision(box->getYHalfLength())) ;
+		pars.push_back("ZHalfLength=" + to_string_with_precision(box->getZHalfLength())) ;
 		shapePars = joinVectorStrings(pars,";");
 	} else if (shapeType == "Cons") {
 		const GeoCons* shapeIn = dynamic_cast<const GeoCons*>(shape);
-		pars.push_back("RMin1=" + std::to_string(shapeIn->getRMin1())) ;
-		pars.push_back("RMin2=" + std::to_string(shapeIn->getRMin2())) ;
-		pars.push_back("RMax1=" + std::to_string(shapeIn->getRMax1())) ;
-		pars.push_back("RMax2=" + std::to_string(shapeIn->getRMax2())) ;
-		pars.push_back("DZ=" + std::to_string(shapeIn->getDZ())) ;
-		pars.push_back("SPhi=" + std::to_string(shapeIn->getSPhi())) ;
-		pars.push_back("DPhi=" + std::to_string(shapeIn->getDPhi())) ;
+		pars.push_back("RMin1=" + to_string_with_precision(shapeIn->getRMin1())) ;
+		pars.push_back("RMin2=" + to_string_with_precision(shapeIn->getRMin2())) ;
+		pars.push_back("RMax1=" + to_string_with_precision(shapeIn->getRMax1())) ;
+		pars.push_back("RMax2=" + to_string_with_precision(shapeIn->getRMax2())) ;
+		pars.push_back("DZ=" + to_string_with_precision(shapeIn->getDZ())) ;
+		pars.push_back("SPhi=" + to_string_with_precision(shapeIn->getSPhi())) ;
+		pars.push_back("DPhi=" + to_string_with_precision(shapeIn->getDPhi())) ;
 	} else if (shapeType == "Torus") {
 		// Member Data:
 		// * Rmax - outside radius of the torus tube
@@ -837,100 +846,100 @@ std::string WriteGeoModel::getShapeParameters(const GeoShape* shape)
 		// * DPhi - delta angle of the segment in radians
 		//
 		const GeoTorus* shapeIn = dynamic_cast<const GeoTorus*>(shape);
-		pars.push_back("Rmin=" + std::to_string(shapeIn->getRMin())) ;
-		pars.push_back("Rmax=" + std::to_string(shapeIn->getRMax())) ;
-		pars.push_back("Rtor=" + std::to_string(shapeIn->getRTor())) ;
-		pars.push_back("SPhi=" + std::to_string(shapeIn->getSPhi())) ;
-		pars.push_back("DPhi=" + std::to_string(shapeIn->getDPhi())) ;
+		pars.push_back("Rmin=" + to_string_with_precision(shapeIn->getRMin())) ;
+		pars.push_back("Rmax=" + to_string_with_precision(shapeIn->getRMax())) ;
+		pars.push_back("Rtor=" + to_string_with_precision(shapeIn->getRTor())) ;
+		pars.push_back("SPhi=" + to_string_with_precision(shapeIn->getSPhi())) ;
+		pars.push_back("DPhi=" + to_string_with_precision(shapeIn->getDPhi())) ;
 	}
   else if (shapeType == "Para") {
 		const GeoPara* shapeIn = dynamic_cast<const GeoPara*>(shape);
-		pars.push_back("XHalfLength=" + std::to_string(shapeIn->getXHalfLength())) ;
-		pars.push_back("YHalfLength=" + std::to_string(shapeIn->getYHalfLength())) ;
-		pars.push_back("ZHalfLength=" + std::to_string(shapeIn->getZHalfLength())) ;
-		pars.push_back("Alpha=" + std::to_string(shapeIn->getAlpha())) ;
-		pars.push_back("Theta=" + std::to_string(shapeIn->getTheta())) ;
-		pars.push_back("Phi=" + std::to_string(shapeIn->getPhi())) ;
+		pars.push_back("XHalfLength=" + to_string_with_precision(shapeIn->getXHalfLength())) ;
+		pars.push_back("YHalfLength=" + to_string_with_precision(shapeIn->getYHalfLength())) ;
+		pars.push_back("ZHalfLength=" + to_string_with_precision(shapeIn->getZHalfLength())) ;
+		pars.push_back("Alpha=" + to_string_with_precision(shapeIn->getAlpha())) ;
+		pars.push_back("Theta=" + to_string_with_precision(shapeIn->getTheta())) ;
+		pars.push_back("Phi=" + to_string_with_precision(shapeIn->getPhi())) ;
 	}
   else if (shapeType == "Pcon") {
 		const GeoPcon* shapeIn = dynamic_cast<const GeoPcon*>(shape);
-		pars.push_back("SPhi=" + std::to_string(shapeIn->getSPhi()));
-		pars.push_back("DPhi=" + std::to_string(shapeIn->getDPhi()));
+		pars.push_back("SPhi=" + to_string_with_precision(shapeIn->getSPhi()));
+		pars.push_back("DPhi=" + to_string_with_precision(shapeIn->getDPhi()));
 		// get number of Z planes and loop over them
 		const int nZplanes = shapeIn->getNPlanes();
-		pars.push_back("NZPlanes=" + std::to_string(nZplanes));
+		pars.push_back("NZPlanes=" + to_string_with_precision(nZplanes));
 		for (int i=0; i<nZplanes; ++i) {
-			pars.push_back("ZPos=" + std::to_string(shapeIn->getZPlane(i)));
-			pars.push_back("ZRmin=" + std::to_string(shapeIn->getRMinPlane(i)));
-			pars.push_back("ZRmax=" + std::to_string(shapeIn->getRMaxPlane(i)));
+			pars.push_back("ZPos=" + to_string_with_precision(shapeIn->getZPlane(i)));
+			pars.push_back("ZRmin=" + to_string_with_precision(shapeIn->getRMinPlane(i)));
+			pars.push_back("ZRmax=" + to_string_with_precision(shapeIn->getRMaxPlane(i)));
 		}
 	}
   else if (shapeType == "Pgon") {
 		const GeoPgon* shapeIn = dynamic_cast<const GeoPgon*>(shape);
-		pars.push_back("SPhi=" + std::to_string(shapeIn->getSPhi())) ;
-		pars.push_back("DPhi=" + std::to_string(shapeIn->getDPhi())) ;
-		pars.push_back("NSides=" + std::to_string(shapeIn->getNSides())) ;
+		pars.push_back("SPhi=" + to_string_with_precision(shapeIn->getSPhi())) ;
+		pars.push_back("DPhi=" + to_string_with_precision(shapeIn->getDPhi())) ;
+		pars.push_back("NSides=" + to_string_with_precision(shapeIn->getNSides())) ;
 		// get number of Z planes and loop over them
 		const int nZplanes = shapeIn->getNPlanes();
-		pars.push_back("NZPlanes=" + std::to_string(nZplanes));
+		pars.push_back("NZPlanes=" + to_string_with_precision(nZplanes));
 		for (int i=0; i<nZplanes; ++i) {
-			pars.push_back("ZPos=" + std::to_string(shapeIn->getZPlane(i)));
-			pars.push_back("ZRmin=" + std::to_string(shapeIn->getRMinPlane(i)));
-			pars.push_back("ZRmax=" + std::to_string(shapeIn->getRMaxPlane(i)));
+			pars.push_back("ZPos=" + to_string_with_precision(shapeIn->getZPlane(i)));
+			pars.push_back("ZRmin=" + to_string_with_precision(shapeIn->getRMinPlane(i)));
+			pars.push_back("ZRmax=" + to_string_with_precision(shapeIn->getRMaxPlane(i)));
 		}
 	}
   else if (shapeType == "SimplePolygonBrep") {
 		const GeoSimplePolygonBrep* shapeIn = dynamic_cast<const GeoSimplePolygonBrep*>(shape);
-		pars.push_back("DZ=" + std::to_string(shapeIn->getDZ())) ;
+		pars.push_back("DZ=" + to_string_with_precision(shapeIn->getDZ())) ;
 		// get number of vertices and loop over them
 		const int nVertices = shapeIn->getNVertices();
-		pars.push_back("NVertices=" + std::to_string(nVertices));
+		pars.push_back("NVertices=" + to_string_with_precision(nVertices));
 		for (int i=0; i<nVertices; ++i) {
-			pars.push_back("xV=" + std::to_string(shapeIn->getXVertex(i)));
-			pars.push_back("yV=" + std::to_string(shapeIn->getYVertex(i)));
+			pars.push_back("xV=" + to_string_with_precision(shapeIn->getXVertex(i)));
+			pars.push_back("yV=" + to_string_with_precision(shapeIn->getYVertex(i)));
 		}
 	}
   else if (shapeType == "Trap") {
 		const GeoTrap* shapeIn = dynamic_cast<const GeoTrap*>(shape);
-		pars.push_back("ZHalfLength=" + std::to_string(shapeIn->getZHalfLength())) ;
-		pars.push_back("Theta=" + std::to_string(shapeIn->getTheta())) ;
-		pars.push_back("Phi=" + std::to_string(shapeIn->getPhi())) ;
-		pars.push_back("Dydzn=" + std::to_string(shapeIn->getDydzn())) ;
-		pars.push_back("Dxdyndzn=" + std::to_string(shapeIn->getDxdyndzn())) ;
-		pars.push_back("Dxdypdzn=" + std::to_string(shapeIn->getDxdypdzn())) ;
-		pars.push_back("Angleydzn=" + std::to_string(shapeIn->getAngleydzn())) ;
-		pars.push_back("Dydzp=" + std::to_string(shapeIn->getDydzp())) ;
-		pars.push_back("Dxdyndzp=" + std::to_string(shapeIn->getDxdyndzp())) ;
-		pars.push_back("Dxdypdzp=" + std::to_string(shapeIn->getDxdypdzp())) ;
-		pars.push_back("Angleydzp=" + std::to_string(shapeIn->getAngleydzp())) ;
+		pars.push_back("ZHalfLength=" + to_string_with_precision(shapeIn->getZHalfLength())) ;
+		pars.push_back("Theta=" + to_string_with_precision(shapeIn->getTheta())) ;
+		pars.push_back("Phi=" + to_string_with_precision(shapeIn->getPhi())) ;
+		pars.push_back("Dydzn=" + to_string_with_precision(shapeIn->getDydzn())) ;
+		pars.push_back("Dxdyndzn=" + to_string_with_precision(shapeIn->getDxdyndzn())) ;
+		pars.push_back("Dxdypdzn=" + to_string_with_precision(shapeIn->getDxdypdzn())) ;
+		pars.push_back("Angleydzn=" + to_string_with_precision(shapeIn->getAngleydzn())) ;
+		pars.push_back("Dydzp=" + to_string_with_precision(shapeIn->getDydzp())) ;
+		pars.push_back("Dxdyndzp=" + to_string_with_precision(shapeIn->getDxdyndzp())) ;
+		pars.push_back("Dxdypdzp=" + to_string_with_precision(shapeIn->getDxdypdzp())) ;
+		pars.push_back("Angleydzp=" + to_string_with_precision(shapeIn->getAngleydzp())) ;
 	}
   else if (shapeType == "Trd") {
 		const GeoTrd* shapeIn = dynamic_cast<const GeoTrd*>(shape);
-		pars.push_back("XHalfLength1=" + std::to_string(shapeIn->getXHalfLength1())) ;
-		pars.push_back("XHalfLength2=" + std::to_string(shapeIn->getXHalfLength2())) ;
-		pars.push_back("YHalfLength1=" + std::to_string(shapeIn->getYHalfLength1())) ;
-		pars.push_back("YHalfLength2=" + std::to_string(shapeIn->getYHalfLength2())) ;
-		pars.push_back("ZHalfLength=" + std::to_string(shapeIn->getZHalfLength())) ;
+		pars.push_back("XHalfLength1=" + to_string_with_precision(shapeIn->getXHalfLength1())) ;
+		pars.push_back("XHalfLength2=" + to_string_with_precision(shapeIn->getXHalfLength2())) ;
+		pars.push_back("YHalfLength1=" + to_string_with_precision(shapeIn->getYHalfLength1())) ;
+		pars.push_back("YHalfLength2=" + to_string_with_precision(shapeIn->getYHalfLength2())) ;
+		pars.push_back("ZHalfLength=" + to_string_with_precision(shapeIn->getZHalfLength())) ;
 	}
   else if (shapeType == "Tube") {
 		const GeoTube* tube = dynamic_cast<const GeoTube*>(shape);
-		pars.push_back("RMin=" + std::to_string(tube->getRMin())) ;
-		pars.push_back("RMax=" + std::to_string(tube->getRMax())) ;
-		pars.push_back("ZHalfLength=" + std::to_string(tube->getZHalfLength())) ;
+		pars.push_back("RMin=" + to_string_with_precision(tube->getRMin())) ;
+		pars.push_back("RMax=" + to_string_with_precision(tube->getRMax())) ;
+		pars.push_back("ZHalfLength=" + to_string_with_precision(tube->getZHalfLength())) ;
 	}
   else if (shapeType == "Tubs") {
 		const GeoTubs* shapeIn = dynamic_cast<const GeoTubs*>(shape);
-		pars.push_back("RMin=" + std::to_string(shapeIn->getRMin())) ;
-		pars.push_back("RMax=" + std::to_string(shapeIn->getRMax())) ;
-		pars.push_back("ZHalfLength=" + std::to_string(shapeIn->getZHalfLength())) ;
-		pars.push_back("SPhi=" + std::to_string(shapeIn->getSPhi())) ;
-		pars.push_back("DPhi=" + std::to_string(shapeIn->getDPhi())) ;
+		pars.push_back("RMin=" + to_string_with_precision(shapeIn->getRMin())) ;
+		pars.push_back("RMax=" + to_string_with_precision(shapeIn->getRMax())) ;
+		pars.push_back("ZHalfLength=" + to_string_with_precision(shapeIn->getZHalfLength())) ;
+		pars.push_back("SPhi=" + to_string_with_precision(shapeIn->getSPhi())) ;
+		pars.push_back("DPhi=" + to_string_with_precision(shapeIn->getDPhi())) ;
 	}
   else if (shapeType == "TessellatedSolid") {
 		const GeoTessellatedSolid* shapeIn = dynamic_cast<const GeoTessellatedSolid*>(shape);
 		// get number of facets
 		const size_t nFacets = shapeIn->getNumberOfFacets();
-		pars.push_back("nFacets=" + std::to_string(nFacets));
+		pars.push_back("nFacets=" + to_string_with_precision(nFacets));
 		// loop over the facets
 		for (size_t i=0; i<nFacets; ++i) {
 			GeoFacet* facet = shapeIn->getFacet(i);
@@ -943,12 +952,12 @@ std::string WriteGeoModel::getShapeParameters(const GeoShape* shape)
 			if (facetVertexType == GeoFacet::RELATIVE) pars.push_back("vT=RELATIVE");
 			// get number of vertices and loop over them
 			const size_t nVertices = facet->getNumberOfVertices();
-			pars.push_back("nV=" + std::to_string(nVertices));
+			pars.push_back("nV=" + to_string_with_precision(nVertices));
 			for (size_t i=0; i<nVertices; ++i) {
 				GeoFacetVertex facetVertex = facet->getVertex(i);
-				pars.push_back("xV=" + std::to_string( facetVertex[0] ));
-				pars.push_back("yV=" + std::to_string( facetVertex[1] ));
-				pars.push_back("zV=" + std::to_string( facetVertex[2] ));
+				pars.push_back("xV=" + to_string_with_precision( facetVertex[0] ));
+				pars.push_back("yV=" + to_string_with_precision( facetVertex[1] ));
+				pars.push_back("zV=" + to_string_with_precision( facetVertex[2] ));
 			}
 		}
 	}
@@ -959,8 +968,8 @@ std::string WriteGeoModel::getShapeParameters(const GeoShape* shape)
 		const unsigned int shapeIdA = storeShape(shapeOpA);
 		const GeoShape* shapeOpB = shapeIn->getOpB();
 		const unsigned int shapeIdB = storeShape(shapeOpB);
-		pars.push_back("opA=" + std::to_string( shapeIdA )) ;
-		pars.push_back("opB=" + std::to_string( shapeIdB )) ;
+		pars.push_back("opA=" + to_string_with_precision( shapeIdA )) ;
+		pars.push_back("opB=" + to_string_with_precision( shapeIdB )) ;
 	}
 	else if (shapeType == "Shift") {
 		const GeoShapeShift* shapeIn = dynamic_cast<const GeoShapeShift*>(shape);
@@ -973,8 +982,8 @@ std::string WriteGeoModel::getShapeParameters(const GeoShape* shape)
 		GeoTransform* transf = new GeoTransform( shapeIn->getX() );
 		const unsigned int trId = storeTranform(transf);
 
-		pars.push_back("A=" + std::to_string( shapeId ));
-		pars.push_back("X=" + std::to_string( trId ));
+		pars.push_back("A=" + to_string_with_precision( shapeId ));
+		pars.push_back("X=" + to_string_with_precision( trId ));
 	}
 	else if (shapeType == "Subtraction") {
 		const GeoShapeSubtraction* shapeIn = dynamic_cast<const GeoShapeSubtraction*>(shape);
@@ -983,8 +992,8 @@ std::string WriteGeoModel::getShapeParameters(const GeoShape* shape)
 		const unsigned int shapeIdA = storeShape(shapeOpA);
 		const GeoShape* shapeOpB = shapeIn->getOpB();
 		const unsigned int shapeIdB = storeShape(shapeOpB);
-		pars.push_back("opA=" + std::to_string( shapeIdA ));
-		pars.push_back("opB=" + std::to_string( shapeIdB ));
+		pars.push_back("opA=" + to_string_with_precision( shapeIdA ));
+		pars.push_back("opB=" + to_string_with_precision( shapeIdB ));
 	}
 	else if (shapeType == "Union") {
 		const GeoShapeUnion* shapeIn = dynamic_cast<const GeoShapeUnion*>(shape);
@@ -995,16 +1004,16 @@ std::string WriteGeoModel::getShapeParameters(const GeoShape* shape)
 		const GeoShape* shapeOpB = shapeIn->getOpB();
 		unsigned int shapeIdB = storeShape(shapeOpB);
 
-		pars.push_back("opA=" + std::to_string( shapeIdA )) ;
-		pars.push_back("opB=" + std::to_string( shapeIdB )) ;
+		pars.push_back("opA=" + to_string_with_precision( shapeIdA )) ;
+		pars.push_back("opB=" + to_string_with_precision( shapeIdB )) ;
 	}
 	else if (shapeType=="GenericTrap") {
 	  const GeoGenericTrap * shapeIn = dynamic_cast<const GeoGenericTrap*>(shape);
-	  pars.push_back("ZHalfLength=" + std::to_string(shapeIn->getZHalfLength()));
-	  pars.push_back("NVertices="   + std::to_string(shapeIn->getVertices().size()));
+	  pars.push_back("ZHalfLength=" + to_string_with_precision(shapeIn->getZHalfLength()));
+	  pars.push_back("NVertices="   + to_string_with_precision(shapeIn->getVertices().size()));
 	  for (int i=0; i<shapeIn->getVertices().size(); ++i) {
-	    pars.push_back("X=" + std::to_string(shapeIn->getVertices()[i](0)));
-	    pars.push_back("Y=" + std::to_string(shapeIn->getVertices()[i](1)));
+	    pars.push_back("X=" + to_string_with_precision(shapeIn->getVertices()[i](0)));
+	    pars.push_back("Y=" + to_string_with_precision(shapeIn->getVertices()[i](1)));
 	  }
 	}
 	else if (shapeType=="UnidentifiedShape") {
@@ -1334,7 +1343,7 @@ unsigned int WriteGeoModel::storeObj(const GeoAlignableTransform* pointer, const
   std::vector<std::vector<std::string>>* container = &m_materials;
   std::vector<std::string> values;
   values.push_back( name );
-  values.push_back( std::to_string(density) );
+  values.push_back( to_string_with_precision(density) );
   values.push_back( elements );
 	return addRecord(container, values);
 }
@@ -1344,7 +1353,7 @@ unsigned int WriteGeoModel::addElement(const std::string &name, const std::strin
 {
   std::vector<std::vector<std::string>>* container = &m_elements;
   std::vector<std::string> values;
-  values.insert(values.begin(), { name, symbol, std::to_string(elZ), std::to_string(elA)} );
+  values.insert(values.begin(), { name, symbol, to_string_with_precision(elZ), to_string_with_precision(elA)} );
 	return addRecord(container, values);
 }
 
@@ -1380,7 +1389,7 @@ unsigned int WriteGeoModel::addAlignableTransform(const std::vector<double> &par
 	std::vector<std::vector<std::string>>* container = &m_alignableTransforms;
 	std::vector<std::string> values;
   for(const double& par : params) {
-    values.push_back( std::to_string(par) );
+    values.push_back( to_string_with_precision(par) );
 	}
 	return addRecord(container, values);
 }
@@ -1392,7 +1401,7 @@ unsigned int WriteGeoModel::addTransform(const std::vector<double> &params)
 	std::vector<std::vector<std::string>>* container = &m_transforms;
 	std::vector<std::string> values;
   for(const double& par : params) {
-		values.push_back( std::to_string(par) );
+		values.push_back( to_string_with_precision(par) );
 	}
 	return addRecord(container, values);
 }
@@ -1412,7 +1421,7 @@ unsigned int WriteGeoModel::addTransform(const std::vector<double> &params)
   const unsigned int volTypeID = getIdFromNodeType(volType);
 
   std::vector<std::string> values;
-  values.insert( values.begin(),  {std::to_string(funcId), std::to_string(physvolId), std::to_string(volTypeID), std::to_string(copies)} );
+  values.insert( values.begin(),  {to_string_with_precision(funcId), to_string_with_precision(physvolId), to_string_with_precision(volTypeID), to_string_with_precision(copies)} );
 
 	return addRecord(container, values);
 }
@@ -1431,11 +1440,11 @@ unsigned int WriteGeoModel::addPhysVol(const unsigned int &logVolId, const unsig
 {
 	std::vector<std::vector<std::string>>* container = &m_physVols;
   std::vector<std::string> values;
-  values.push_back( std::to_string(logVolId) );
+  values.push_back( to_string_with_precision(logVolId) );
 	unsigned int idx = addRecord(container, values);
 	if (isRootVolume) {
 		std::vector<std::string> rootValues;
-    rootValues.insert(rootValues.begin(), { std::to_string(idx), "GeoPhysVol"} );
+    rootValues.insert(rootValues.begin(), { to_string_with_precision(idx), "GeoPhysVol"} );
 		m_rootVolume = rootValues;
 	}
 	return idx;
@@ -1446,12 +1455,12 @@ unsigned int WriteGeoModel::addFullPhysVol(const unsigned int &logVolId, const u
 {
 	std::vector<std::vector<std::string>>* container = &m_fullPhysVols;
 	std::vector<std::string> values;
-  values.push_back( std::to_string(logVolId) );
+  values.push_back( to_string_with_precision(logVolId) );
 	unsigned int idx = addRecord(container, values);
 	if (isRootVolume) {
 		std::vector<std::string> rootValues;
 //    rootValues << QString::number(idx) << "GeoFullPhysVol";
-    rootValues.insert(rootValues.begin(), { std::to_string(idx), "GeoPhysVol"} );
+    rootValues.insert(rootValues.begin(), { to_string_with_precision(idx), "GeoPhysVol"} );
 		m_rootVolume = rootValues;
 	}
 	return idx;
@@ -1461,7 +1470,7 @@ unsigned int WriteGeoModel::addLogVol(const std::string &name, const unsigned in
 {
 	std::vector<std::vector<std::string>>* container = &m_logVols;
   std::vector<std::string> values;
-  values.insert( values.begin(), {name, std::to_string(shapeId), std::to_string(materialId)} );
+  values.insert( values.begin(), {name, to_string_with_precision(shapeId), to_string_with_precision(materialId)} );
 	return addRecord(container, values);
 }
 
@@ -1474,7 +1483,7 @@ unsigned int WriteGeoModel::addLogVol(const std::string &name, const unsigned in
 
 	std::vector<std::string> values;
 //  values << parentId.toString() << parentTableID <<  QString::number(parentCopyN) << QString::number(childPos) << childTableID << childId.toString() << QString::number(childCopyN);
-  values.insert(values.begin(), { std::to_string(parentId), std::to_string(parentTableID), std::to_string(parentCopyN), std::to_string(childPos), std::to_string(childTableID), std::to_string(childId), std::to_string(childCopyN)} );
+  values.insert(values.begin(), { to_string_with_precision(parentId), to_string_with_precision(parentTableID), to_string_with_precision(parentCopyN), to_string_with_precision(childPos), to_string_with_precision(childTableID), to_string_with_precision(childId), to_string_with_precision(childCopyN)} );
 	addRecord(container, values);
 	return;
 }
-- 
GitLab