From 351dff90d7b27d8cd5e27af68ca83546741140cf Mon Sep 17 00:00:00 2001
From: Riccardo Maria Bianchi <riccardo.maria.bianchi@cern.ch>
Date: Mon, 8 Jul 2024 06:15:19 +0200
Subject: [PATCH] Fixed UnidentifiedShape I/O (in particular, the restore part)
 and introduced a new unit test for GeoUnidentifiedShape writing and reading

---
 ...ep1_create_store_geo_and_publish_nodes.cpp |  5 +-
 GeoModelIO/GeoModelIOHelpers/CMakeLists.txt   |  8 +-
 .../tests/test_io_UnidentifiedShape.cpp       | 89 +++++++++++++++++++
 .../test_io_shared_serialtransformers.cpp     |  1 -
 .../src/BuildGeoShapes_UnidentifiedShape.cpp  |  4 +-
 5 files changed, 101 insertions(+), 6 deletions(-)
 create mode 100644 GeoModelIO/GeoModelIOHelpers/tests/test_io_UnidentifiedShape.cpp

diff --git a/GeoModelExamples/HelloToy/step1_create_store_geo_and_publish_nodes.cpp b/GeoModelExamples/HelloToy/step1_create_store_geo_and_publish_nodes.cpp
index aa5c96125..b0ed32fe4 100644
--- a/GeoModelExamples/HelloToy/step1_create_store_geo_and_publish_nodes.cpp
+++ b/GeoModelExamples/HelloToy/step1_create_store_geo_and_publish_nodes.cpp
@@ -441,8 +441,9 @@ int main(int argc, char *argv[])
 
 
   // Add a test "UnidentifiedShape" shape node
-  const std::string nameUnidentifiedShape = "LAr::Example";
-  GeoUnidentifiedShape* sUnidentifiedShape = new GeoUnidentifiedShape("LArCustomShape",nameUnidentifiedShape);
+  const std::string shapeUnidName = "LArCustomShape";
+  const std::string shapeUnidAscii = "LAr::Example";
+  GeoUnidentifiedShape* sUnidentifiedShape = new GeoUnidentifiedShape(shapeUnidName, shapeUnidAscii);
   const GeoLogVol* lUnidentifiedShape = new GeoLogVol("UnidentifiedShape", sUnidentifiedShape, steel);
   GeoPhysVol *pUnidentifiedShape = new GeoPhysVol(lUnidentifiedShape);
   GeoNameTag *nUnidentifiedShape = new GeoNameTag("UnidentifiedShape");
diff --git a/GeoModelIO/GeoModelIOHelpers/CMakeLists.txt b/GeoModelIO/GeoModelIOHelpers/CMakeLists.txt
index a341f58b4..48dbc3ba4 100644
--- a/GeoModelIO/GeoModelIOHelpers/CMakeLists.txt
+++ b/GeoModelIO/GeoModelIOHelpers/CMakeLists.txt
@@ -51,5 +51,11 @@ install( FILES ${HEADERS}
 # global I/O tests
 add_executable(test_io_shared_serialtransformers tests/test_io_shared_serialtransformers.cpp)
 target_link_libraries( test_io_shared_serialtransformers GeoModelIO::GeoModelDBManager GeoModelCore::GeoModelHelpers GeoModelCore::GeoModelKernel GeoModelIO::GeoModelIOHelpers)
-add_test(NAME testIOSharedSerialTransformers
+add_test(NAME test_IO_SharedSerialTransformers
          COMMAND test_io_shared_serialtransformers)
+
+# I/O Unit tests
+add_executable(test_io_shapes_unidentifiedshape tests/test_io_UnidentifiedShape.cpp)
+target_link_libraries( test_io_shapes_unidentifiedshape GeoModelIO::GeoModelDBManager GeoModelCore::GeoModelHelpers GeoModelCore::GeoModelKernel GeoModelIO::GeoModelIOHelpers)
+add_test(NAME test_IO_Shapes_UnidentifiedShape
+         COMMAND test_io_shapes_unidentifiedshape)
diff --git a/GeoModelIO/GeoModelIOHelpers/tests/test_io_UnidentifiedShape.cpp b/GeoModelIO/GeoModelIOHelpers/tests/test_io_UnidentifiedShape.cpp
new file mode 100644
index 000000000..c5b0ba8f3
--- /dev/null
+++ b/GeoModelIO/GeoModelIOHelpers/tests/test_io_UnidentifiedShape.cpp
@@ -0,0 +1,89 @@
+// Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
+
+/*
+ * This example tests the I/O of GeoUnidentifiedShape.
+ *
+ *  Author:     Riccardo Maria BIANCHI @ CERN
+ *  Created on: July, 2024
+ */
+
+// GeoModel includes
+#include "GeoModelIOHelpers/GMTests_IO.h"
+#include "GeoModelKernel/GeoUnidentifiedShape.h"
+#include "GeoModelHelpers/defineWorld.h"
+
+// C++ includes
+#include <iostream>
+
+// Units
+#include "GeoModelKernel/Units.h"
+#define SYSTEM_OF_UNITS \
+    GeoModelKernelUnits // so we will get, e.g., 'GeoModelKernelUnits::cm'
+
+int main(int argc, char *argv[])
+{
+// Define the units
+#define gr SYSTEM_OF_UNITS::gram
+#define mole SYSTEM_OF_UNITS::mole
+
+    // get the World volume,
+    // we build it outside the class for convenience only
+    GeoIntrusivePtr<GeoPhysVol> world{createGeoWorld()};
+
+    // Define elements used in this example:
+    GeoElement *elAluminum = new GeoElement("Aluminum", "Al", 13, 26 * gr / mole);
+
+    // Define materials used in this example:
+    double densityOfAluminum = 2.7; // g/cm^3
+    GeoMaterial *matAluminum = new GeoMaterial("Aluminum", densityOfAluminum);
+    matAluminum->add(elAluminum, 1.0);
+    matAluminum->lock();
+
+    // Add a test "UnidentifiedShape" shape node
+    const std::string shapeDataAscii = "LAr::Example";
+    const std::string shapeDataName = "LArCustomShape";
+    GeoUnidentifiedShape *sUnidentifiedShape = new GeoUnidentifiedShape(shapeDataName, shapeDataAscii);
+    const GeoLogVol *lUnidentifiedShape = new GeoLogVol("UnidentifiedShape", sUnidentifiedShape, matAluminum);
+    GeoPhysVol *pUnidentifiedShape = new GeoPhysVol(lUnidentifiedShape);
+    GeoNameTag *nUnidentifiedShape = new GeoNameTag("UnidentifiedShape");
+    world->add(nUnidentifiedShape);
+    world->add(pUnidentifiedShape);
+
+    // write to the test DB
+    std::string testDB = "test_io_unidentifiedshape.db";
+    unsigned loglevel = 2;
+    const bool forceDelete = true;
+    GeoModelIO::IO::saveToDB(world, testDB, loglevel, forceDelete);
+
+    // load from the test DB
+    const GeoVPhysVol *world2 = GeoModelIO::IO::loadDB(testDB);
+
+    // get the child volume, then the shape from its logVol
+    GeoIntrusivePtr<const GeoVPhysVol> childVol = world2->getChildVol(0);
+    const GeoUnidentifiedShape *shape = dynamic_cast<const GeoUnidentifiedShape *>(childVol->getLogVol()->getShape());
+    const std::string restoredShapeDataAscii = shape->asciiData();
+    const std::string restoredShapeDataName = shape->name();
+
+    bool test = true;
+    if (restoredShapeDataAscii != shapeDataAscii)
+    {
+        std::cout << "\nERROR!!! The restored 'AsciiData' is different from the stored version!!!" << std::endl;
+        std::cout << "Stored 'AsciiData': " << shapeDataAscii << std::endl;
+        std::cout << "Restored 'AsciiData': " << restoredShapeDataAscii << std::endl;
+        test = false;
+    }
+    if (restoredShapeDataName != shapeDataName)
+    {
+        std::cout << "\nERROR!!! The restored 'name' is different from the stored version!!!" << std::endl;
+        std::cout << "\t==> Stored 'name': " << shapeDataName << std::endl;
+        std::cout << "\t==> Restored 'name': " << restoredShapeDataName << std::endl;
+        test = false;
+    }
+
+    // Return 0 if all OK! :-)
+    // Return 1 otherwise... :-(
+    if (test)
+        return 0;
+    return 1;
+    // ----------------
+}
diff --git a/GeoModelIO/GeoModelIOHelpers/tests/test_io_shared_serialtransformers.cpp b/GeoModelIO/GeoModelIOHelpers/tests/test_io_shared_serialtransformers.cpp
index fd68c274f..33968c542 100644
--- a/GeoModelIO/GeoModelIOHelpers/tests/test_io_shared_serialtransformers.cpp
+++ b/GeoModelIO/GeoModelIOHelpers/tests/test_io_shared_serialtransformers.cpp
@@ -16,7 +16,6 @@
  *
  */
 
-//pipppo  
 // GeoModel includes
 #include "GeoGenericFunctions/AbsFunction.h"
 #include "GeoGenericFunctions/Cos.h"
diff --git a/GeoModelIO/GeoModelRead/src/BuildGeoShapes_UnidentifiedShape.cpp b/GeoModelIO/GeoModelRead/src/BuildGeoShapes_UnidentifiedShape.cpp
index a7d87a835..3bb6fd04e 100644
--- a/GeoModelIO/GeoModelRead/src/BuildGeoShapes_UnidentifiedShape.cpp
+++ b/GeoModelIO/GeoModelRead/src/BuildGeoShapes_UnidentifiedShape.cpp
@@ -23,10 +23,10 @@ void BuildGeoShapes_UnidentifiedShape::buildShape(const DBRowEntry row)
     // shape volume
     const double shapeVolume = GeoModelHelpers::variantHelper::getFromVariant_Double(row[1], "UnidentifiedShape:shapeVolume");
     // shape parameters
-    const std::string type = GeoModelHelpers::variantHelper::getFromVariant_String(row[2], "UnidentifiedShape:type");
     const std::string name = GeoModelHelpers::variantHelper::getFromVariant_String(row[2], "UnidentifiedShape:name");
+    const std::string asciiData = GeoModelHelpers::variantHelper::getFromVariant_String(row[3], "UnidentifiedShape:asciiData");
 
-    GeoUnidentifiedShape *shape = new GeoUnidentifiedShape(type, name);
+    GeoUnidentifiedShape *shape = new GeoUnidentifiedShape(name, asciiData);
 
     storeBuiltShape(shapeId, shape);
 
-- 
GitLab